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