PERFORCE change 151466 for review
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Fri Oct 17 00:10:52 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=151466
Change 151466 by nwhitehorn at nwhitehorn_trantor on 2008/10/17 00:09:58
Add support for real mode Open Firmware accesses, at least for i
64-bit machines. This lets us boot a decent way into the IBM
Mambo simulator and should give us a prayer of support on real
IBM and Genesi hardware.
MFP4 after: 10 days
Affected files ...
.. //depot/projects/ppc-g5/sys/dev/ofw/openfirm.c#2 edit
.. //depot/projects/ppc-g5/sys/dev/ofw/openfirm.h#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/aim/mmu_oea64.c#6 edit
.. //depot/projects/ppc-g5/sys/powerpc/aim/ofw_machdep.c#5 edit
.. //depot/projects/ppc-g5/sys/sparc64/sparc64/ofw_machdep.c#2 edit
Differences ...
==== //depot/projects/ppc-g5/sys/dev/ofw/openfirm.c#2 (text+ko) ====
@@ -117,7 +117,7 @@
1,
};
- args.service = (cell_t)name;
+ args.service = openfirm_mapptr(name);
if (openfirmware(&args) == -1)
return (-1);
return (args.missing);
@@ -141,7 +141,7 @@
va_start(ap, nreturns);
args.nreturns = ++nreturns;
- args.slot[i++] = (cell_t)cmd;
+ args.slot[i++] = openfirm_mapptr(cmd);
while (i < 1)
args.slot[i++] = va_arg(ap, cell_t);
if (openfirmware(&args) == -1) {
@@ -284,7 +284,7 @@
};
args.package = package;
- args.propname = (cell_t)propname;
+ args.propname = openfirm_mapptr(propname);
if (openfirmware(&args) == -1)
return (-1);
return (args.proplen);
@@ -310,8 +310,8 @@
};
args.package = package;
- args.propname = (cell_t)propname;
- args.buf = (cell_t)buf;
+ args.propname = openfirm_mapptr(propname);
+ args.buf = openfirm_mapptr(buf);
args.buflen = buflen;
if (openfirmware(&args) == -1)
return (-1);
@@ -361,8 +361,8 @@
};
args.package = package;
- args.previous = (cell_t)previous;
- args.buf = (cell_t)buf;
+ args.previous = openfirm_mapptr(previous);
+ args.buf = openfirm_mapptr(buf);
if (openfirmware(&args) == -1)
return (-1);
return (args.flag);
@@ -389,8 +389,8 @@
};
args.package = package;
- args.propname = (cell_t)propname;
- args.buf = (cell_t)buf;
+ args.propname = openfirm_mapptr(propname);
+ args.buf = openfirm_mapptr(buf);
args.len = len;
if (openfirmware(&args) == -1)
return (-1);
@@ -415,8 +415,8 @@
1,
};
- args.device = (cell_t)device;
- args.buf = (cell_t)buf;
+ args.device = openfirm_mapptr(device);
+ args.buf = openfirm_mapptr(buf);
args.len = len;
if (openfirmware(&args) == -1)
return (-1);
@@ -439,7 +439,7 @@
1,
};
- args.device = (cell_t)device;
+ args.device = openfirm_mapptr(device);
if (openfirmware(&args) == -1)
return (-1);
return (args.package);
@@ -464,7 +464,7 @@
};
args.instance = instance;
- args.buf = (cell_t)buf;
+ args.buf = openfirm_mapptr(buf);
args.len = len;
if (openfirmware(&args) == -1)
return (-1);
@@ -490,7 +490,7 @@
};
args.package = package;
- args.buf = (cell_t)buf;
+ args.buf = openfirm_mapptr(buf);
args.len = len;
if (openfirmware(&args) == -1)
return (-1);
@@ -521,7 +521,7 @@
return (-1);
args.nargs = nargs + 2;
args.nreturns = nreturns + 1;
- args.method = (cell_t)method;
+ args.method = openfirm_mapptr(method);
args.instance = instance;
va_start(ap, nreturns);
for (cp = args.args_n_results + (n = nargs); --n >= 0;)
@@ -556,7 +556,7 @@
1,
};
- args.device = (cell_t)device;
+ args.device = openfirm_mapptr(device);
if (openfirmware(&args) == -1 || args.instance == 0) {
return (-1);
}
@@ -600,7 +600,7 @@
};
args.instance = instance;
- args.addr = (cell_t)addr;
+ args.addr = openfirm_mapptr(addr);
args.len = len;
if (openfirmware(&args) == -1)
return (-1);
@@ -627,7 +627,7 @@
};
args.instance = instance;
- args.addr = (cell_t)addr;
+ args.addr = openfirm_mapptr(addr);
args.len = len;
if (openfirmware(&args) == -1)
return (-1);
@@ -728,7 +728,7 @@
1,
};
- args.bootspec = (cell_t)bootspec;
+ args.bootspec = openfirm_mapptr(bootspec);
openfirmware(&args);
for (;;) /* just in case */
;
==== //depot/projects/ppc-g5/sys/dev/ofw/openfirm.h#2 (text+ko) ====
@@ -81,6 +81,7 @@
*/
void set_openfirm_callback(int (*)(void *));
int openfirmware(void *);
+cell_t openfirm_mapptr(const void *);
/*
* This isn't actually an Open Firmware function, but it seemed like the right
==== //depot/projects/ppc-g5/sys/powerpc/aim/mmu_oea64.c#6 (text+ko) ====
@@ -271,8 +271,9 @@
*/
static struct mem_region *regions;
static struct mem_region *pregions;
-extern u_int phys_avail_count;
-extern int regions_sz, pregions_sz;
+extern u_int phys_avail_count;
+extern int regions_sz, pregions_sz;
+extern int ofw_real_mode;
static struct ofw_map translations[64];
extern struct pmap ofw_pmap;
@@ -697,6 +698,25 @@
}
static void
+moea64_bridge_cpu_bootstrap(int ap)
+{
+ int i = 0;
+
+ /*
+ * Initialize segment registers and MMU
+ */
+
+ mtmsr(mfmsr() & ~PSL_DR & ~PSL_IR); isync();
+ for (i = 0; i < 16; i++) {
+ mtsrin(i << ADDR_SR_SHFT, kernel_pmap->pm_sr[i]);
+ }
+ __asm __volatile ("sync; mtsdr1 %0; isync"
+ :: "r"((u_int)moea64_pteg_table
+ | (32 - cntlzw(moea64_pteg_mask >> 11))));
+ tlbia();
+}
+
+static void
moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
{
ihandle_t mmui;
@@ -766,10 +786,9 @@
moea64_pteg_count >>= 1;
#endif /* PTEGCOUNT */
-
size = moea64_pteg_count * sizeof(struct lpteg);
- CTR2(KTR_PMAP, "moea64_bootstrap: %d PTEGs, %d bytes", moea64_pteg_count,
- size);
+ CTR2(KTR_PMAP, "moea64_bootstrap: %d PTEGs, %d bytes",
+ moea64_pteg_count, size);
/* We now need to allocate memory. This memory, to be allocated,
has to reside in a page table. The page table we are about to
@@ -867,31 +886,32 @@
moea64_kenter(mmup, pa, pa);
ENABLE_TRANS(msr);
- /*
- * Set up the Open Firmware pmap and add it's mappings.
- */
+ if (!ofw_real_mode) {
+ /*
+ * Set up the Open Firmware pmap and add its mappings.
+ */
- moea64_pinit(mmup, &ofw_pmap);
- ofw_pmap.pm_sr[KERNEL_SR] = kernel_pmap->pm_sr[KERNEL_SR];
- ofw_pmap.pm_sr[KERNEL2_SR] = kernel_pmap->pm_sr[KERNEL2_SR];
+ moea64_pinit(mmup, &ofw_pmap);
+ ofw_pmap.pm_sr[KERNEL_SR] = kernel_pmap->pm_sr[KERNEL_SR];
+ ofw_pmap.pm_sr[KERNEL2_SR] = kernel_pmap->pm_sr[KERNEL2_SR];
- if ((chosen = OF_finddevice("/chosen")) == -1)
+ if ((chosen = OF_finddevice("/chosen")) == -1)
panic("moea64_bootstrap: can't find /chosen");
- OF_getprop(chosen, "mmu", &mmui, 4);
- if ((mmu = OF_instance_to_package(mmui)) == -1)
+ OF_getprop(chosen, "mmu", &mmui, 4);
+ if ((mmu = OF_instance_to_package(mmui)) == -1)
panic("moea64_bootstrap: can't get mmu package");
- if ((sz = OF_getproplen(mmu, "translations")) == -1)
+ if ((sz = OF_getproplen(mmu, "translations")) == -1)
panic("moea64_bootstrap: can't get ofw translation count");
- bzero(translations, sz);
- if (OF_getprop(mmu, "translations", translations, sz) == -1)
+ bzero(translations, sz);
+ if (OF_getprop(mmu, "translations", translations, sz) == -1)
panic("moea64_bootstrap: can't get ofw translations");
- CTR0(KTR_PMAP, "moea64_bootstrap: translations");
- sz /= sizeof(*translations);
- qsort(translations, sz, sizeof (*translations), om_cmp);
+ CTR0(KTR_PMAP, "moea64_bootstrap: translations");
+ sz /= sizeof(*translations);
+ qsort(translations, sz, sizeof (*translations), om_cmp);
- for (i = 0, ofw_mappings = 0; i < sz; i++) {
+ for (i = 0, ofw_mappings = 0; i < sz; i++) {
CTR3(KTR_PMAP, "translation: pa=%#x va=%#x len=%#x",
(uint32_t)(translations[i].om_pa_lo), translations[i].om_va,
translations[i].om_len);
@@ -940,6 +960,7 @@
PMAP_UNLOCK(kernel_pmap);
PMAP_UNLOCK(&ofw_pmap);
+ }
}
#ifdef SMP
@@ -954,15 +975,9 @@
Maxmem = powerpc_btop(phys_avail[i + 1]);
/*
- * Initialize segment registers and MMU
+ * Initialize MMU
*/
- mtmsr(mfmsr() & ~PSL_DR & ~PSL_IR); isync();
- for (i = 0; i < 16; i++) {
- mtsrin(i << ADDR_SR_SHFT, kernel_pmap->pm_sr[i]);
- }
- __asm __volatile ("sync; mtsdr1 %0; isync"
- :: "r"((u_int)moea64_pteg_table | (32 - cntlzw(moea64_pteg_mask >> 11))));
- tlbia();
+ moea64_bridge_cpu_bootstrap(0);
mtmsr(mfmsr() | PSL_DR | PSL_IR); isync();
pmap_bootstrapped++;
==== //depot/projects/ppc-g5/sys/powerpc/aim/ofw_machdep.c#5 (text+ko) ====
@@ -71,6 +71,7 @@
extern register_t ofmsr[5];
extern struct pmap ofw_pmap;
static int (*ofwcall)(void *);
+int ofw_real_mode;
/*
* Saved SPRG0-3 from OpenFirmware. Will be restored prior to the callback.
@@ -147,21 +148,43 @@
int asz, msz, fsz;
int i, j;
int still_merging;
+
+ asz = msz = 0;
/*
* Get memory.
*/
if ((phandle = OF_finddevice("/memory")) == -1
|| (asz = OF_getprop(phandle, "available",
- OFavail, sizeof OFavail[0] * OFMEM_REGIONS))
- <= 0)
- panic("no memory?");
+ OFavail, sizeof OFavail[0] * OFMEM_REGIONS)) <= 0)
+ {
+ if (ofw_real_mode) {
+ /* XXX MAMBO */
+ printf("Physical memory unknown -- guessing 128 MB\n");
+
+ /* Leave the first 0xA000000 bytes for the kernel */
+ OFavail[0].mr_start = 0xA00000;
+ OFavail[0].mr_size = 0x75FFFFF;
+ asz = sizeof(OFavail[0]);
+ } else {
+ panic("no memory?");
+ }
+ }
if (ppc64) {
struct mem_region64 OFmem64[OFMEM_REGIONS + 1];
- if ((msz = OF_getprop(phandle, "reg",
- OFmem64, sizeof OFmem64[0] * OFMEM_REGIONS)) <= 0)
- panic("Physical memory map not found");
+ if ((phandle == -1) || (msz = OF_getprop(phandle, "reg",
+ OFmem64, sizeof OFmem64[0] * OFMEM_REGIONS)) <= 0) {
+ if (ofw_real_mode) {
+ /* XXX MAMBO */
+ OFmem64[0].mr_start_hi = 0;
+ OFmem64[0].mr_start_lo = 0x0;
+ OFmem64[0].mr_size = 0x7FFFFFF;
+ msz = sizeof(OFmem64[0]);
+ } else {
+ panic("Physical memory map not found");
+ }
+ }
for (i = 0; i < msz/sizeof(OFmem64[0]); i++) {
if (OFmem64[i].mr_start_hi == 0) {
@@ -220,10 +243,23 @@
void
set_openfirm_callback(int (*openfirm)(void *))
{
+ if (ofmsr[0] & PSL_DR)
+ ofw_real_mode = 0;
+ else
+ ofw_real_mode = 1;
ofwcall = openfirm;
}
+cell_t
+openfirm_mapptr(const void *arg)
+{
+ if (ofw_real_mode && pmap_bootstrapped)
+ return ((cell_t)pmap_kextract((vm_offset_t)arg));
+
+ return ((cell_t)arg);
+}
+
int
openfirmware(void *args)
{
@@ -232,6 +268,9 @@
u_int srsave[16];
u_int i;
+ if (pmap_bootstrapped && ofw_real_mode)
+ args = (void *)pmap_kextract((vm_offset_t)args);
+
__asm __volatile( "\t"
"sync\n\t"
"mfmsr %0\n\t"
@@ -243,7 +282,7 @@
ofw_sprg_prepare();
- if (pmap_bootstrapped) {
+ if (pmap_bootstrapped && !ofw_real_mode) {
/*
* Swap the kernel's address space with Open Firmware's
*/
@@ -264,7 +303,7 @@
result = ofwcall(args);
- if (pmap_bootstrapped) {
+ if (pmap_bootstrapped && !ofw_real_mode) {
/*
* Restore the kernel's addr space. The isync() doesn;t
* work outside the loop unless mtsrin() is open-coded
@@ -458,3 +497,4 @@
return (EFAULT);
}
+
==== //depot/projects/ppc-g5/sys/sparc64/sparc64/ofw_machdep.c#2 (text+ko) ====
@@ -268,4 +268,15 @@
return (0);
}
return (ENXIO);
+}
+
+/*
+ * Map a pointer from kernel address space to OFW address space. Since OFW
+ * lives in the same address space, do nothing.
+ */
+
+cell_t
+openfirm_mapptr(const void *arg)
+{
+ return ((cell_t)arg);
}
More information about the p4-projects
mailing list