Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 26 May 2011 19:18:56 +0000 (UTC)
From:      Andreas Tobler <andreast@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r222321 - in projects/pseries/powerpc: aim ofw
Message-ID:  <201105261918.p4QJIuYI077469@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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, &regions, &regions_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, &regions, &regions_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 <machine/platform.h>
 #include <machine/ofw_machdep.h>
 
-#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;
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105261918.p4QJIuYI077469>