From owner-p4-projects@FreeBSD.ORG Fri Oct 17 00:10:52 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6CCFF1065696; Fri, 17 Oct 2008 00:10:52 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1772C106568D for ; Fri, 17 Oct 2008 00:10:52 +0000 (UTC) (envelope-from nwhitehorn@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 03D288FC19 for ; Fri, 17 Oct 2008 00:10:52 +0000 (UTC) (envelope-from nwhitehorn@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id m9H0Apxi025030 for ; Fri, 17 Oct 2008 00:10:51 GMT (envelope-from nwhitehorn@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id m9H0Apfm025028 for perforce@freebsd.org; Fri, 17 Oct 2008 00:10:51 GMT (envelope-from nwhitehorn@freebsd.org) Date: Fri, 17 Oct 2008 00:10:51 GMT Message-Id: <200810170010.m9H0Apfm025028@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to nwhitehorn@freebsd.org using -f From: Nathan Whitehorn To: Perforce Change Reviews Cc: Subject: PERFORCE change 151466 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Oct 2008 00:10:52 -0000 http://perforce.freebsd.org/chv.cgi?CH=151466 Change 151466 by nwhitehorn@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); }