From owner-svn-src-projects@FreeBSD.ORG Thu May 26 19:18:56 2011 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 CE9D6106564A; Thu, 26 May 2011 19:18:56 +0000 (UTC) (envelope-from andreast@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id BF9F08FC08; Thu, 26 May 2011 19:18:56 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p4QJIuIb077473; Thu, 26 May 2011 19:18:56 GMT (envelope-from andreast@svn.freebsd.org) Received: (from andreast@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p4QJIuYI077469; Thu, 26 May 2011 19:18:56 GMT (envelope-from andreast@svn.freebsd.org) Message-Id: <201105261918.p4QJIuYI077469@svn.freebsd.org> From: Andreas Tobler Date: Thu, 26 May 2011 19:18:56 +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: r222321 - in projects/pseries/powerpc: aim ofw 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: Thu, 26 May 2011 19:18:56 -0000 Author: andreast Date: Thu May 26 19:18:56 2011 New Revision: 222321 URL: http://svn.freebsd.org/changeset/base/222321 Log: Increase the OFMEM_REGIONS to 128 and replace it with PHYS_AVAIL_SZ. Add dynamic memory reconfiguration readout for PAPR compatible machines. This allows us to use the full equipped physical memory instead of only the first 128MB. Move the qsort memory compare functionality from mmu_oea64.c and mmu_oea.c to ofw_machdep.c. Reviewed by: nwhitehorn (mentor) Modified: projects/pseries/powerpc/aim/mmu_oea.c projects/pseries/powerpc/aim/mmu_oea64.c projects/pseries/powerpc/ofw/ofw_machdep.c Modified: projects/pseries/powerpc/aim/mmu_oea.c ============================================================================== --- projects/pseries/powerpc/aim/mmu_oea.c Thu May 26 18:54:07 2011 (r222320) +++ projects/pseries/powerpc/aim/mmu_oea.c Thu May 26 19:18:56 2011 (r222321) @@ -584,26 +584,9 @@ moea_pte_change(struct pte *pt, struct p /* * Quick sort callout for comparing memory regions. */ -static int mr_cmp(const void *a, const void *b); static int om_cmp(const void *a, const void *b); static int -mr_cmp(const void *a, const void *b) -{ - const struct mem_region *regiona; - const struct mem_region *regionb; - - regiona = a; - regionb = b; - if (regiona->mr_start < regionb->mr_start) - return (-1); - else if (regiona->mr_start > regionb->mr_start) - return (1); - else - return (0); -} - -static int om_cmp(const void *a, const void *b) { const struct ofw_map *mapa; @@ -720,7 +703,6 @@ moea_bootstrap(mmu_t mmup, vm_offset_t k mem_regions(&pregions, &pregions_sz, ®ions, ®ions_sz); CTR0(KTR_PMAP, "moea_bootstrap: physical memory"); - qsort(pregions, pregions_sz, sizeof(*pregions), mr_cmp); for (i = 0; i < pregions_sz; i++) { vm_offset_t pa; vm_offset_t end; @@ -749,7 +731,7 @@ moea_bootstrap(mmu_t mmup, vm_offset_t k if (sizeof(phys_avail)/sizeof(phys_avail[0]) < regions_sz) panic("moea_bootstrap: phys_avail too small"); - qsort(regions, regions_sz, sizeof(*regions), mr_cmp); + phys_avail_count = 0; physsz = 0; hwphyssz = 0; Modified: projects/pseries/powerpc/aim/mmu_oea64.c ============================================================================== --- projects/pseries/powerpc/aim/mmu_oea64.c Thu May 26 18:54:07 2011 (r222320) +++ projects/pseries/powerpc/aim/mmu_oea64.c Thu May 26 19:18:56 2011 (r222321) @@ -473,26 +473,9 @@ moea64_calc_wimg(vm_offset_t pa, vm_mema /* * Quick sort callout for comparing memory regions. */ -static int mr_cmp(const void *a, const void *b); static int om_cmp(const void *a, const void *b); static int -mr_cmp(const void *a, const void *b) -{ - const struct mem_region *regiona; - const struct mem_region *regionb; - - regiona = a; - regionb = b; - if (regiona->mr_start < regionb->mr_start) - return (-1); - else if (regiona->mr_start > regionb->mr_start) - return (1); - else - return (0); -} - -static int om_cmp(const void *a, const void *b) { const struct ofw_map *mapa; @@ -707,10 +690,9 @@ moea64_early_bootstrap(mmu_t mmup, vm_of mem_regions(&pregions, &pregions_sz, ®ions, ®ions_sz); CTR0(KTR_PMAP, "moea64_bootstrap: physical memory"); - qsort(pregions, pregions_sz, sizeof(*pregions), mr_cmp); if (sizeof(phys_avail)/sizeof(phys_avail[0]) < regions_sz) panic("moea64_bootstrap: phys_avail too small"); - qsort(regions, regions_sz, sizeof(*regions), mr_cmp); + phys_avail_count = 0; physsz = 0; hwphyssz = 0; Modified: projects/pseries/powerpc/ofw/ofw_machdep.c ============================================================================== --- projects/pseries/powerpc/ofw/ofw_machdep.c Thu May 26 18:54:07 2011 (r222320) +++ projects/pseries/powerpc/ofw/ofw_machdep.c Thu May 26 19:18:56 2011 (r222321) @@ -60,9 +60,8 @@ __FBSDID("$FreeBSD$"); #include #include -#define OFMEM_REGIONS 32 -static struct mem_region OFmem[OFMEM_REGIONS + 1], OFavail[OFMEM_REGIONS + 3]; -static struct mem_region OFfree[OFMEM_REGIONS + 3]; +static struct mem_region OFmem[PHYS_AVAIL_SZ], OFavail[PHYS_AVAIL_SZ]; +static struct mem_region OFfree[PHYS_AVAIL_SZ]; extern register_t ofmsr[5]; extern void *openfirmware_entry; @@ -133,11 +132,32 @@ memr_merge(struct mem_region *from, stru to->mr_size = end - to->mr_start; } +/* + * Quick sort callout for comparing memory regions. + */ +static int mr_cmp(const void *a, const void *b); + +static int +mr_cmp(const void *a, const void *b) +{ + const struct mem_region *regiona; + const struct mem_region *regionb; + + regiona = a; + regionb = b; + if (regiona->mr_start < regionb->mr_start) + return (-1); + else if (regiona->mr_start > regionb->mr_start) + return (1); + else + return (0); +} + static int parse_ofw_memory(phandle_t node, const char *prop, struct mem_region *output) { cell_t address_cells, size_cells; - cell_t OFmem[4*(OFMEM_REGIONS + 1)]; + cell_t OFmem[4 * PHYS_AVAIL_SZ]; int sz, i, j; int apple_hack_mode; phandle_t phandle; @@ -174,7 +194,7 @@ parse_ofw_memory(phandle_t node, const c * Get memory. */ if ((node == -1) || (sz = OF_getprop(node, prop, - OFmem, sizeof(OFmem[0]) * 4 * OFMEM_REGIONS)) <= 0) + OFmem, sizeof(OFmem[0]) * 4 * PHYS_AVAIL_SZ)) <= 0) panic("Physical memory map not found"); i = 0; @@ -224,7 +244,7 @@ parse_ofw_memory(phandle_t node, const c #ifdef __powerpc64__ if (apple_hack_mode) { /* Add in regions above 4 GB to the available list */ - struct mem_region himem[OFMEM_REGIONS]; + struct mem_region himem[PHYS_AVAIL_SZ]; int hisz; hisz = parse_ofw_memory(node, "reg", himem); @@ -242,6 +262,81 @@ parse_ofw_memory(phandle_t node, const c return (sz); } +static int +parse_drconf_memory(int *msz, int *asz, struct mem_region *ofmem, + struct mem_region *ofavail) +{ + phandle_t phandle; + vm_offset_t base; + int i, idx, len, lasz, lmsz, res; + uint32_t lmb_size[2]; + unsigned long *dmem, flags; + + lmsz = *msz; + lasz = *asz; + + phandle = OF_finddevice("/ibm,dynamic-reconfiguration-memory"); + if (phandle == -1) + /* No drconf node, return. */ + return (0); + + res = OF_getprop(phandle, "ibm,lmb-size", lmb_size, sizeof(lmb_size)); + if (res == -1) + return (0); + + /* Parse the /ibm,dynamic-memory. + The first position gives the # of entries. The next two words + reflect the address of the memory block. The next four words are + the DRC index, reserved, list index and flags. + (see PAPR C.6.6.2 ibm,dynamic-reconfiguration-memory) + + #el Addr DRC-idx res list-idx flags + ------------------------------------------------- + | 4 | 8 | 4 | 4 | 4 | 4 |.... + ------------------------------------------------- + */ + + len = OF_getproplen(phandle, "ibm,dynamic-memory"); + if (len > 0) { + + /* We have to use a variable length array on the stack + since we have very limited stack space. + */ + cell_t arr[len/sizeof(cell_t)]; + + res = OF_getprop(phandle, "ibm,dynamic-memory", &arr, + sizeof(arr)); + if (res == -1) + return (0); + + /* Number of elements */ + idx = arr[0]; + + /* First address. */ + dmem = (void*)&arr[1]; + + for (i = 0; i < idx; i++) { + base = *dmem; + dmem += 2; + flags = *dmem; + /* Use region only if available and not reserved. */ + if ((flags & 0x8) && !(flags & 0x80)) { + ofmem[lmsz].mr_start = base; + ofmem[lmsz].mr_size = (vm_size_t)lmb_size[1]; + ofavail[lasz].mr_start = base; + ofavail[lasz].mr_size = (vm_size_t)lmb_size[1]; + lmsz++; + lasz++; + } + dmem++; + } + } + + *msz = lmsz; + *asz = lasz; + + return (1); +} /* * This is called during powerpc_init, before the system is really initialized. * It shall provide the total and the available regions of RAM. @@ -256,7 +351,7 @@ ofw_mem_regions(struct mem_region **memp phandle_t phandle; vm_offset_t maxphysaddr; int asz, msz, fsz; - int i, j; + int i, j, res; int still_merging; asz = msz = 0; @@ -273,6 +368,14 @@ ofw_mem_regions(struct mem_region **memp asz = parse_ofw_memory(phandle, "available", OFavail); asz /= sizeof(struct mem_region); + res = parse_drconf_memory(&msz, &asz, OFmem, OFavail); + if (res == 0) + /* tbd. */ + printf("no ibm machine\n"); + + qsort(OFmem, msz, sizeof(*OFmem), mr_cmp); + qsort(OFavail, asz, sizeof(*OFavail), mr_cmp); + *memp = OFmem; *memsz = msz;