From owner-svn-src-projects@FreeBSD.ORG Wed Jul 29 21:36:40 2009 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8F8C1106570E; Wed, 29 Jul 2009 21:36:40 +0000 (UTC) (envelope-from nwhitehorn@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7CF7F8FC1C; Wed, 29 Jul 2009 21:36:40 +0000 (UTC) (envelope-from nwhitehorn@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n6TLaeVE082976; Wed, 29 Jul 2009 21:36:40 GMT (envelope-from nwhitehorn@svn.freebsd.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n6TLae2B082973; Wed, 29 Jul 2009 21:36:40 GMT (envelope-from nwhitehorn@svn.freebsd.org) Message-Id: <200907292136.n6TLae2B082973@svn.freebsd.org> From: Nathan Whitehorn Date: Wed, 29 Jul 2009 21:36:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r195952 - in projects/ppc64/sys/powerpc: aim aim64 X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Jul 2009 21:36:40 -0000 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); /*