Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 Feb 2006 05:30:22 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 91729 for review
Message-ID:  <200602140530.k1E5UMhY061481@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=91729

Change 91729 by kmacy@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
  */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200602140530.k1E5UMhY061481>