PERFORCE change 153267 for review

Nathan Whitehorn nwhitehorn at FreeBSD.org
Thu Nov 20 09:07:40 PST 2008


http://perforce.freebsd.org/chv.cgi?CH=153267

Change 153267 by nwhitehorn at nwhitehorn_trantor on 2008/11/20 17:07:25

	Make ofw_real work on kernels with options SMP by making the bounce
	page static. On SMP systems, we can get OF calls after the MMU is on
	but before the VM is up. This means contigmalloc() is not available.
	This is not a good solution, but I can't think of anything else.
	
	Also: style(9)

Affected files ...

.. //depot/projects/ppc-g5/sys/powerpc/aim/mmu_oea64.c#9 edit
.. //depot/projects/ppc-g5/sys/powerpc/ofw/ofw_real.c#3 edit

Differences ...

==== //depot/projects/ppc-g5/sys/powerpc/aim/mmu_oea64.c#9 (text+ko) ====

@@ -297,13 +297,14 @@
  * PVO data.
  */
 struct	pvo_head *moea64_pvo_table;		/* pvo entries by pteg index */
+/* lists of unmanaged pages */
 struct	pvo_head moea64_pvo_kunmanaged =
-    LIST_HEAD_INITIALIZER(moea64_pvo_kunmanaged);	/* list of unmanaged pages */
+    LIST_HEAD_INITIALIZER(moea64_pvo_kunmanaged);
 struct	pvo_head moea64_pvo_unmanaged =
-    LIST_HEAD_INITIALIZER(moea64_pvo_unmanaged);	/* list of unmanaged pages */
+    LIST_HEAD_INITIALIZER(moea64_pvo_unmanaged);
 
-uma_zone_t	moea64_upvo_zone;	/* zone for pvo entries for unmanaged pages */
-uma_zone_t	moea64_mpvo_zone;	/* zone for pvo entries for managed pages */
+uma_zone_t	moea64_upvo_zone; /* zone for pvo entries for unmanaged pages */
+uma_zone_t	moea64_mpvo_zone; /* zone for pvo entries for managed pages */
 
 vm_offset_t	pvo_allocator_start;
 vm_offset_t	pvo_allocator_end;

==== //depot/projects/ppc-g5/sys/powerpc/ofw/ofw_real.c#3 (text+ko) ====

@@ -60,7 +60,6 @@
 
 #include <sys/param.h>
 #include <sys/kernel.h>
-#include <sys/malloc.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/systm.h>
@@ -147,15 +146,22 @@
 };
 OFW_DEF(ofw_real);
 
-MALLOC_DEFINE(M_OFWREAL, "ofwreal", "Open Firmware Real Mode Bounce Page");
-
 static int (*openfirmware)(void *);
 
 static vm_offset_t	of_bounce_phys;
 static caddr_t		of_bounce_virt;
 static off_t		of_bounce_offset;
+static size_t		of_bounce_size;
 static struct mtx	of_bounce_mtx;
 
+/*
+ * We need a statically allocated bounce buffer to handle the case when
+ * there are Open Firmware calls after the MMU has been enabled but before
+ * the VM has been initialized to the point that we can allocate memory.
+ * Make it 4K and 8 byte aligned.
+ */
+static uint64_t		of_bounce_buffer[512];
+
 static void
 ofw_real_start(void)
 {
@@ -180,9 +186,10 @@
 		if (!pmap_bootstrapped)
 			return (cell_t)buf;
 
-		of_bounce_virt = contigmalloc(PAGE_SIZE, M_OFWREAL, 0,
-		    0, BUS_SPACE_MAXADDR_32BIT, PAGE_SIZE, PAGE_SIZE);
-		of_bounce_phys = vtophys(of_bounce_virt);
+		of_bounce_virt = (caddr_t)of_bounce_buffer;
+		of_bounce_size = sizeof(of_bounce_buffer);
+
+		of_bounce_phys = vtophys(of_bounce_buffer);
 	}
 
 	/*
@@ -191,6 +198,9 @@
 	 */
 	of_bounce_offset += of_bounce_offset % sizeof(register_t);
 
+	if (of_bounce_offset + len > of_bounce_size)
+		return 0;
+
 	memcpy(of_bounce_virt + of_bounce_offset, buf, len);
 	phys = of_bounce_phys + of_bounce_offset;
 
@@ -204,7 +214,7 @@
 {
 	mtx_assert(&of_bounce_mtx, MA_OWNED);
 
-	if (!pmap_bootstrapped)
+	if (of_bounce_virt == NULL)
 		return;
 
 	memcpy(buf,of_bounce_virt + (physaddr - of_bounce_phys),len);
@@ -243,8 +253,8 @@
 
 	ofw_real_start();
 
-	args.service = ofw_real_map(name,strlen(name) + 1);
-	if (openfirmware(&args) == -1) {
+	args.service = ofw_real_map(name, strlen(name) + 1);
+	if (args.service == 0 || openfirmware(&args) == -1) {
 		ofw_real_stop();
 		return (-1);
 	}
@@ -365,7 +375,7 @@
 
 	args.package = package;
 	args.propname = ofw_real_map(propname, strlen(propname) + 1);
-	if (openfirmware(&args) == -1) {
+	if (args.propname == 0 || openfirmware(&args) == -1) {
 		ofw_real_stop();
 		return (-1);
 	}
@@ -396,14 +406,14 @@
 	ofw_real_start();
 
 	args.package = package;
-	args.propname = ofw_real_map(propname,strlen(propname) + 1);
-	args.buf = ofw_real_map(buf,buflen);
+	args.propname = ofw_real_map(propname, strlen(propname) + 1);
+	args.buf = ofw_real_map(buf, buflen);
 	args.buflen = buflen;
-	if (openfirmware(&args) == -1) {
+	if (args.propname == 0 || args.buf == 0 || openfirmware(&args) == -1) {
 		ofw_real_stop();
 		return (-1);
 	}
-	ofw_real_unmap(args.buf,buf,buflen);
+	ofw_real_unmap(args.buf, buf, buflen);
 
 	ofw_real_stop();
 	return (args.size);
@@ -431,13 +441,13 @@
 	ofw_real_start();
 
 	args.package = package;
-	args.previous = ofw_real_map(previous,strlen(previous) + 1);
-	args.buf = ofw_real_map(buf,size);
-	if (openfirmware(&args) == -1) {
+	args.previous = ofw_real_map(previous, strlen(previous) + 1);
+	args.buf = ofw_real_map(buf, size);
+	if (args.previous == 0 || args.buf == 0 || openfirmware(&args) == -1) {
 		ofw_real_stop();
 		return (-1);
 	}
-	ofw_real_unmap(args.buf,buf,size);
+	ofw_real_unmap(args.buf, buf, size);
 
 	ofw_real_stop();
 	return (args.flag);
@@ -467,10 +477,10 @@
 	ofw_real_start();
 
 	args.package = package;
-	args.propname = ofw_real_map(propname,strlen(propname) + 1);
-	args.buf = ofw_real_map(buf,len);
+	args.propname = ofw_real_map(propname, strlen(propname) + 1);
+	args.buf = ofw_real_map(buf, len);
 	args.len = len;
-	if (openfirmware(&args) == -1) {
+	if (args.propname == 0 || args.buf == 0 || openfirmware(&args) == -1) {
 		ofw_real_stop();
 		return (-1);
 	}
@@ -498,14 +508,14 @@
 
 	ofw_real_start();
 
-	args.device = ofw_real_map(device,strlen(device) + 1);
-	args.buf = ofw_real_map(buf,len);
+	args.device = ofw_real_map(device, strlen(device) + 1);
+	args.buf = ofw_real_map(buf, len);
 	args.len = len;
-	if (openfirmware(&args) == -1) {
+	if (args.device == 0 || args.buf == 0 || openfirmware(&args) == -1) {
 		ofw_real_stop();
 		return (-1);
 	}
-	ofw_real_unmap(args.buf,buf,len);
+	ofw_real_unmap(args.buf, buf, len);
 
 	ofw_real_stop();
 	return (args.size);
@@ -529,8 +539,8 @@
 
 	ofw_real_start();
 
-	args.device = ofw_real_map(device,strlen(device) + 1);
-	if (openfirmware(&args) == -1) {
+	args.device = ofw_real_map(device, strlen(device) + 1);
+	if (args.device == 0 || openfirmware(&args) == -1) {
 		ofw_real_stop();
 		return (-1);
 	}
@@ -559,13 +569,13 @@
 	ofw_real_start();
 
 	args.instance = instance;
-	args.buf = ofw_real_map(buf,len);
+	args.buf = ofw_real_map(buf, len);
 	args.len = len;
-	if (openfirmware(&args) == -1) {
+	if (args.buf == 0 || openfirmware(&args) == -1) {
 		ofw_real_stop();
 		return (-1);
 	}
-	ofw_real_unmap(args.buf,buf,len);
+	ofw_real_unmap(args.buf, buf, len);
 
 	ofw_real_stop();
 	return (args.size);
@@ -592,13 +602,13 @@
 	ofw_real_start();
 
 	args.package = package;
-	args.buf = ofw_real_map(buf,len);
+	args.buf = ofw_real_map(buf, len);
 	args.len = len;
-	if (openfirmware(&args) == -1) {
+	if (args.buf == 0 || openfirmware(&args) == -1) {
 		ofw_real_stop();
 		return (-1);
 	}
-	ofw_real_unmap(args.buf,buf,len);
+	ofw_real_unmap(args.buf, buf, len);
 
 	ofw_real_stop();
 	return (args.size);
@@ -631,13 +641,13 @@
 	ofw_real_start();
 	args.nargs = nargs + 2;
 	args.nreturns = nreturns + 1;
-	args.method = ofw_real_map(method,strlen(method) + 1);
+	args.method = ofw_real_map(method, strlen(method) + 1);
 	args.instance = instance;
 
 	ap = args_and_returns;
 	for (cp = args.args_n_results + (n = nargs); --n >= 0;)
 		*--cp = *(ap++);
-	if (openfirmware(&args) == -1) {
+	if (args.method == 0 || openfirmware(&args) == -1) {
 		ofw_real_stop();
 		return (-1);
 	}
@@ -671,8 +681,9 @@
 
 	ofw_real_start();
 
-	args.device = ofw_real_map(device,strlen(device) + 1);
-	if (openfirmware(&args) == -1 || args.instance == 0) {
+	args.device = ofw_real_map(device, strlen(device) + 1);
+	if (args.device == 0 || openfirmware(&args) == -1 
+	    || args.instance == 0) {
 		ofw_real_stop();
 		return (-1);
 	}
@@ -719,13 +730,13 @@
 	ofw_real_start();
 
 	args.instance = instance;
-	args.addr = ofw_real_map(addr,len);
+	args.addr = ofw_real_map(addr, len);
 	args.len = len;
-	if (openfirmware(&args) == -1) {
+	if (args.addr == 0 || openfirmware(&args) == -1) {
 		ofw_real_stop();
 		return (-1);
 	}
-	ofw_real_unmap(args.addr,addr,len);
+	ofw_real_unmap(args.addr, addr, len);
 
 	ofw_real_stop();
 	return (args.actual);
@@ -752,9 +763,9 @@
 	ofw_real_start();
 
 	args.instance = instance;
-	args.addr = ofw_real_map(addr,len);
+	args.addr = ofw_real_map(addr, len);
 	args.len = len;
-	if (openfirmware(&args) == -1) {
+	if (args.addr == 0 || openfirmware(&args) == -1) {
 		ofw_real_stop();
 		return (-1);
 	}


More information about the p4-projects mailing list