Date: Wed, 29 Jul 2009 21:36:40 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r195952 - in projects/ppc64/sys/powerpc: aim aim64 Message-ID: <200907292136.n6TLae2B082973@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: nwhitehorn Date: Wed Jul 29 21:36:40 2009 New Revision: 195952 URL: http://svn.freebsd.org/changeset/base/195952 Log: Fix physical memory map detection on IBM-style machines like the Cell simulator. Modified: projects/ppc64/sys/powerpc/aim/ofw_machdep.c projects/ppc64/sys/powerpc/aim64/mmu_oea64.c Modified: projects/ppc64/sys/powerpc/aim/ofw_machdep.c ============================================================================== --- projects/ppc64/sys/powerpc/aim/ofw_machdep.c Wed Jul 29 21:09:03 2009 (r195951) +++ projects/ppc64/sys/powerpc/aim/ofw_machdep.c Wed Jul 29 21:36:40 2009 (r195952) @@ -62,12 +62,6 @@ __FBSDID("$FreeBSD$"); static struct mem_region OFmem[OFMEM_REGIONS + 1], OFavail[OFMEM_REGIONS + 3]; static struct mem_region OFfree[OFMEM_REGIONS + 3]; -struct mem_region64 { - vm_offset_t mr_start_hi; - vm_offset_t mr_start_lo; - vm_size_t mr_size; -}; - extern register_t ofmsr[5]; extern struct pmap ofw_pmap; static int (*ofwcall)(void *); @@ -146,24 +140,13 @@ memr_merge(struct mem_region *from, stru to->mr_size = end - to->mr_start; } -/* - * This is called during powerpc_init, before the system is really initialized. - * It shall provide the total and the available regions of RAM. - * Both lists must have a zero-size entry as terminator. - * The available regions need not take the kernel into account, but needs - * to provide space for two additional entry beyond the terminating one. - */ -void -ofw_mem_regions(struct mem_region **memp, int *memsz, - struct mem_region **availp, int *availsz) +static int +parse_ofw_memory(phandle_t node, const char *prop, struct mem_region *output) { + cell_t address_cells, size_cells; + int sz, i, j; phandle_t phandle; - int asz, msz, fsz; - int i, j; - int still_merging; - cell_t address_cells; - - asz = msz = 0; + sz = 0; /* * Get #address-cells from root node, defaulting to 1 if it cannot @@ -173,71 +156,97 @@ ofw_mem_regions(struct mem_region **memp if (OF_getprop(phandle, "#address-cells", &address_cells, sizeof(address_cells)) < sizeof(address_cells)) address_cells = 1; + if (OF_getprop(phandle, "#size-cells", &size_cells, + sizeof(size_cells)) < sizeof(size_cells)) + size_cells = 1; /* * Get memory. */ - if ((phandle = OF_finddevice("/memory")) == -1 - || (asz = OF_getprop(phandle, "available", - 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 (address_cells == 2) { - struct mem_region64 OFmem64[OFMEM_REGIONS + 1]; - 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 { + if (address_cells > 1 || size_cells > 1) { + cell_t OFmem[4*(OFMEM_REGIONS + 1)]; + if ((node == -1) || (sz = OF_getprop(node, prop, + OFmem, sizeof(OFmem[0]) * 4 * OFMEM_REGIONS)) <= 0) panic("Physical memory map not found"); + + i = 0; + j = 0; + while (i < sz/sizeof(cell_t)) { + #ifndef __powerpc64__ + /* On 32-bit PPC, ignore regions starting above 4 GB */ + if (OFmem[i] > 0) { + i += address_cells + size_cells; + continue; + } + #endif + + output[j].mr_start = OFmem[i++]; + if (address_cells == 2) { + output[j].mr_start <<= 32; + output[j].mr_start += OFmem[i++]; + } + + output[j].mr_size = OFmem[i++]; + if (size_cells == 2) { + output[j].mr_size <<= 32; + output[j].mr_size += OFmem[i++]; } - } - for (i = 0, j = 0; i < msz/sizeof(OFmem64[0]); i++) { - if (OFmem64[i].mr_start_hi == 0) { - OFmem[i].mr_start = OFmem64[i].mr_start_lo; - OFmem[i].mr_size = OFmem64[i].mr_size; - - /* - * Check for memory regions extending above 32-bit - * memory space, and restrict them to stay there. - */ - if (((uint64_t)OFmem[i].mr_start + - (uint64_t)OFmem[i].mr_size) > - BUS_SPACE_MAXADDR_32BIT) { - OFmem[i].mr_size = BUS_SPACE_MAXADDR_32BIT - - OFmem[i].mr_start; - } - j++; + #ifndef __powerpc64__ + /* + * Check for memory regions extending above 32-bit + * memory space, and restrict them to stay there. + */ + if (((uint64_t)output[j].mr_start + + (uint64_t)output[j].mr_size) > + BUS_SPACE_MAXADDR_32BIT) { + ouptut[j].mr_size = BUS_SPACE_MAXADDR_32BIT - + output[j].mr_start; } + #endif + j++; } - msz = j*sizeof(OFmem[0]); + sz = j*sizeof(output[0]); } else { - if ((msz = OF_getprop(phandle, "reg", - OFmem, sizeof OFmem[0] * OFMEM_REGIONS)) <= 0) + if ((sz = OF_getprop(node, prop, + output, sizeof(output[0]) * OFMEM_REGIONS)) <= 0) panic("Physical memory map not found"); } + return (sz); +} + +/* + * This is called during powerpc_init, before the system is really initialized. + * It shall provide the total and the available regions of RAM. + * Both lists must have a zero-size entry as terminator. + * The available regions need not take the kernel into account, but needs + * to provide space for two additional entry beyond the terminating one. + */ +void +ofw_mem_regions(struct mem_region **memp, int *memsz, + struct mem_region **availp, int *availsz) +{ + phandle_t phandle; + int asz, msz, fsz; + int i, j; + int still_merging; + + asz = msz = 0; + + /* + * Get memory. + */ + phandle = OF_finddevice("/memory"); + if (phandle == -1) + phandle = OF_finddevice("/memory@0"); + + msz = parse_ofw_memory(phandle, "reg", OFmem); + asz = parse_ofw_memory(phandle, "available", OFavail); + *memp = OFmem; *memsz = msz / sizeof(struct mem_region); - /* * OFavail may have overlapping regions - collapse these * and copy out remaining regions to OFfree Modified: projects/ppc64/sys/powerpc/aim64/mmu_oea64.c ============================================================================== --- projects/ppc64/sys/powerpc/aim64/mmu_oea64.c Wed Jul 29 21:09:03 2009 (r195951) +++ projects/ppc64/sys/powerpc/aim64/mmu_oea64.c Wed Jul 29 21:36:40 2009 (r195952) @@ -820,6 +820,38 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_o phys_avail_count++; physsz += regions[i].mr_size; } + + /* Check for overlap with the kernel and exception vectors */ + for (j = 0; j < 2*phys_avail_count; j+=2) { + if (phys_avail[j] < EXC_LAST) + phys_avail[j] += EXC_LAST; + + if (kernelstart >= phys_avail[j] && + kernelstart < phys_avail[j+1]) { + if (kernelend < phys_avail[j+1]) { + phys_avail[2*phys_avail_count] = + (kernelend & ~PAGE_MASK) + PAGE_SIZE; + phys_avail[2*phys_avail_count + 1] = + phys_avail[j+1]; + phys_avail_count++; + } + + phys_avail[j+1] = kernelstart & ~PAGE_MASK; + } + + if (kernelend >= phys_avail[j] && + kernelend < phys_avail[j+1]) { + if (kernelstart > phys_avail[j]) { + phys_avail[2*phys_avail_count] = phys_avail[j]; + phys_avail[2*phys_avail_count + 1] = + kernelstart & ~PAGE_MASK; + phys_avail_count++; + } + + phys_avail[j] = (kernelend & ~PAGE_MASK) + PAGE_SIZE; + } + } + physmem = btoc(physsz); /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907292136.n6TLae2B082973>