PERFORCE change 91729 for review
Kip Macy
kmacy at FreeBSD.org
Mon Feb 13 21:30:23 PST 2006
http://perforce.freebsd.org/chv.cgi?CH=91729
Change 91729 by kmacy at kmacy_storage:sun4v_work on 2006/02/14 05:30:06
fixes to loader to support sun4v
Affected files ...
.. //depot/projects/kmacy_sun4v/src/sys/boot/sparc64/loader/main.c#2 edit
.. //depot/projects/kmacy_sun4v/src/sys/sparc64/include/asm.h#2 edit
.. //depot/projects/kmacy_sun4v/src/sys/sparc64/include/hypervisor_api.h#1 add
Differences ...
==== //depot/projects/kmacy_sun4v/src/sys/boot/sparc64/loader/main.c#2 (text+ko) ====
@@ -34,6 +34,8 @@
#include <machine/metadata.h>
#include <machine/tte.h>
#include <machine/upa.h>
+#include <machine/hypervisor_api.h>
+
#include "bootstrap.h"
#include "libofw.h"
@@ -50,6 +52,15 @@
vm_offset_t size;
};
+struct mmu_ops {
+ void (*tlb_init)(void);
+ int (*mmu_mapin)(vm_offset_t va, vm_size_t len);
+} *mmu_ops;
+
+
+
+#define UNIMPLEMENTED printf("%s function not implemented\n", __FUNCTION__);
+
typedef void kernel_entry_t(vm_offset_t mdp, u_long o1, u_long o2, u_long o3,
void *openfirmware);
@@ -60,18 +71,35 @@
extern vm_offset_t md_load(char *, vm_offset_t *);
static int __elfN(exec)(struct preloaded_file *);
static int sparc64_autoload(void);
-static int mmu_mapin(vm_offset_t, vm_size_t);
+static int mmu_mapin_sun4u(vm_offset_t, vm_size_t);
+static int mmu_mapin_sun4v(vm_offset_t, vm_size_t);
+static void tlb_init_sun4u(void);
+static void tlb_init_sun4v(void);
+
+struct mmu_ops mmu_ops_sun4u = { tlb_init_sun4u, mmu_mapin_sun4u };
+struct mmu_ops mmu_ops_sun4v = { tlb_init_sun4v, mmu_mapin_sun4v };
extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
+/* sun4u */
struct tlb_entry *dtlb_store;
struct tlb_entry *itlb_store;
-
int dtlb_slot;
int itlb_slot;
int dtlb_slot_max;
int itlb_slot_max;
+/* sun4v */
+struct tlb_entry *tlb_store;
+/*
+ * no direct TLB access on sun4v
+ * we somewhat arbitrarily declare enough
+ * slots to cover a 4GB AS with 4MB pages
+ */
+#define SUN4V_TLB_SLOT_MAX (1 << 10)
+
+
+
vm_offset_t curkva = 0;
vm_offset_t heapva;
phandle_t pmemh; /* OFW memory handle */
@@ -204,14 +232,14 @@
static ssize_t
sparc64_readin(const int fd, vm_offset_t va, const size_t len)
{
- mmu_mapin(va, len);
+ mmu_ops->mmu_mapin(va, len);
return read(fd, (void *)va, len);
}
static ssize_t
sparc64_copyin(const void *src, vm_offset_t dest, size_t len)
{
- mmu_mapin(dest, len);
+ mmu_ops->mmu_mapin(dest, len);
memcpy((void *)dest, src, len);
return len;
}
@@ -252,7 +280,7 @@
}
static int
-mmu_mapin(vm_offset_t va, vm_size_t len)
+mmu_mapin_sun4u(vm_offset_t va, vm_size_t len)
{
vm_offset_t pa, mva;
u_long data;
@@ -310,6 +338,53 @@
return 0;
}
+static int
+mmu_mapin_sun4v(vm_offset_t va, vm_size_t len)
+{
+
+ vm_offset_t pa, mva;
+ u_long data;
+ int ret;
+
+ if (va + len > curkva)
+ curkva = va + len;
+
+ pa = (vm_offset_t)-1;
+ len += va & PAGE_MASK_4M;
+ va &= ~PAGE_MASK_4M;
+ while (len) {
+ if ((va >> 22) > SUN4V_TLB_SLOT_MAX)
+ panic("trying to map more than 4GB");
+ if (tlb_store[va >> 22].te_pa == -1) {
+ /* Allocate a physical page, claim the virtual area */
+ if (pa == (vm_offset_t)-1) {
+ pa = (vm_offset_t)OF_alloc_phys(PAGE_SIZE_4M,
+ PAGE_SIZE_4M);
+ if (pa == (vm_offset_t)-1)
+ panic("out of memory");
+ mva = (vm_offset_t)OF_claim_virt(va,
+ PAGE_SIZE_4M, 0);
+ if (mva != va) {
+ panic("can't claim virtual page "
+ "(wanted %#lx, got %#lx)",
+ va, mva);
+ }
+ }
+
+ tlb_store[va >> 22].te_pa = pa;
+ data = VTD_V | VTD_PA(pa) | VTD_CP | VTD_CV | VTD_P | VTD_W | VTD_4M;
+ if ((ret = hv_mmu_map_perm_addr(va, 0, data, MAP_DTLB | MAP_ITLB)) != 0)
+ printf("hv_mmu_map_perm_addr failed: %d\n", ret);;
+ pa = (vm_offset_t)-1;
+ }
+ len -= len > PAGE_SIZE_4M ? PAGE_SIZE_4M : len;
+ va += PAGE_SIZE_4M;
+ }
+ if (pa != (vm_offset_t)-1)
+ OF_release_phys(pa, PAGE_SIZE_4M);
+ return 0;
+}
+
static vm_offset_t
init_heap(void)
{
@@ -324,7 +399,7 @@
}
static void
-tlb_init(void)
+tlb_init_sun4u(void)
{
phandle_t child;
phandle_t root;
@@ -361,11 +436,20 @@
panic("init_tlb: malloc");
}
+static void
+tlb_init_sun4v(void)
+{
+ tlb_store = malloc(SUN4V_TLB_SLOT_MAX * sizeof(*tlb_store));
+ memset(tlb_store, 0xFF, SUN4V_TLB_SLOT_MAX * sizeof(*tlb_store));
+}
+
int
main(int (*openfirm)(void *))
{
char bootpath[64];
+ char compatible[32];
struct devsw **dp;
+ phandle_t rooth;
phandle_t chosenh;
/*
@@ -381,13 +465,22 @@
init_heap();
setheap((void *)heapva, (void *)(heapva + HEAPSZ));
-
/*
* Probe for a console.
*/
cons_probe();
- tlb_init();
+ rooth = OF_peer(0);
+ OF_getprop(rooth, "compatible", compatible, sizeof(compatible));
+ if (!strcmp(compatible, "sun4v")) {
+ printf("\nnice machine\n");
+ mmu_ops = &mmu_ops_sun4v;
+ } else {
+ printf("\nHere's a quarter kid. Go buy yourself a new computer.\n");
+ mmu_ops = &mmu_ops_sun4u;
+ }
+
+ mmu_ops->tlb_init();
bcache_init(32, 512);
==== //depot/projects/kmacy_sun4v/src/sys/sparc64/include/asm.h#2 (text+ko) ====
@@ -95,6 +95,13 @@
#define ENTRY(x) _ENTRY(x)
#define END(x) .size x, . - x
+#define STACK_ALIGN 16
+#define SET_SIZE(x) END(x)
+#define SA(X) (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
+#define WINDOWSIZE64 (16*8)
+#define MINFRAME64 (WINDOWSIZE64 + 48)
+#define MINFRAME MINFRAME64
+
/*
* Kernel RCS ID tag and copyright macros
*/
More information about the p4-projects
mailing list