svn commit: r330306 - head/sys/powerpc/ps3

Nathan Whitehorn nwhitehorn at FreeBSD.org
Sat Mar 3 02:06:49 UTC 2018


Author: nwhitehorn
Date: Sat Mar  3 02:06:48 2018
New Revision: 330306
URL: https://svnweb.freebsd.org/changeset/base/330306

Log:
  Honor physical memory regions marked unavailable in the FDT, when present.
  The most notable of these is the FDT itself, which it is a bad idea to
  overwrite.

Modified:
  head/sys/powerpc/ps3/platform_ps3.c

Modified: head/sys/powerpc/ps3/platform_ps3.c
==============================================================================
--- head/sys/powerpc/ps3/platform_ps3.c	Sat Mar  3 02:04:40 2018	(r330305)
+++ head/sys/powerpc/ps3/platform_ps3.c	Sat Mar  3 02:06:48 2018	(r330306)
@@ -141,37 +141,38 @@ void
 ps3_mem_regions(platform_t plat, struct mem_region *phys, int *physsz,
     struct mem_region *avail_regions, int *availsz)
 {
-	uint64_t lpar_id, junk, ppe_id;
+	uint64_t lpar_id, junk;
+	int i;
 
-	/* Get real mode memory region */
-	avail_regions[0].mr_start = 0;
-	lv1_get_logical_partition_id(&lpar_id);
-	lv1_get_logical_ppe_id(&ppe_id);
-	lv1_get_repository_node_value(lpar_id,
-	    lv1_repository_string("bi") >> 32, lv1_repository_string("pu"),
-	    ppe_id, lv1_repository_string("rm_size"),
-	    &avail_regions[0].mr_size, &junk);
+	/* Prefer device tree information if available */
+	if (OF_finddevice("/") != -1) {
+		ofw_mem_regions(phys, physsz, avail_regions, availsz);
+	} else {
+		/* Real mode memory region is first segment */
+		phys[0].mr_start = 0;
+		phys[0].mr_size = ps3_real_maxaddr(plat);
+		*physsz = *availsz = 1;
+		avail_regions[0] = phys[0];
+	}
 
 	/* Now get extended memory region */
+	lv1_get_logical_partition_id(&lpar_id);
 	lv1_get_repository_node_value(lpar_id,
 	    lv1_repository_string("bi") >> 32,
 	    lv1_repository_string("rgntotal"), 0, 0,
-	    &avail_regions[1].mr_size, &junk);
+	    &phys[*physsz].mr_size, &junk);
+	for (i = 0; i < *physsz; i++)
+		phys[*physsz].mr_size -= phys[i].mr_size;
 
 	/* Convert to maximum amount we can allocate in 16 MB pages */
-	avail_regions[1].mr_size -= avail_regions[0].mr_size;
-	avail_regions[1].mr_size -= avail_regions[1].mr_size % (16*1024*1024);
+	phys[*physsz].mr_size -= phys[*physsz].mr_size % (16*1024*1024);
 
 	/* Allocate extended memory region */
-	lv1_allocate_memory(avail_regions[1].mr_size, 24 /* 16 MB pages */,
-	    0, 0x04 /* any address */, &avail_regions[1].mr_start, &junk);
-
-	*availsz = 2;
-
-	if (phys != NULL) {
-		memcpy(phys, avail_regions, sizeof(*phys)*2);
-		*physsz = 2;
-	}
+	lv1_allocate_memory(phys[*physsz].mr_size, 24 /* 16 MB pages */,
+	    0, 0x04 /* any address */, &phys[*physsz].mr_start, &junk);
+	avail_regions[*availsz] = phys[*physsz];
+	(*physsz)++;
+	(*availsz)++;
 }
 
 static u_long
@@ -260,12 +261,22 @@ ps3_reset(platform_t plat)
 static vm_offset_t
 ps3_real_maxaddr(platform_t plat)
 {
-	struct mem_region *phys, *avail;
-	int nphys, navail;
+	uint64_t lpar_id, junk, ppe_id;
+	static uint64_t rm_maxaddr = 0;
 
-	mem_regions(&phys, &nphys, &avail, &navail);
+	if (rm_maxaddr == 0) {
+		/* Get real mode memory region */
+		lv1_get_logical_partition_id(&lpar_id);
+		lv1_get_logical_ppe_id(&ppe_id);
 
-	return (phys[0].mr_start + phys[0].mr_size);
+		lv1_get_repository_node_value(lpar_id,
+		    lv1_repository_string("bi") >> 32,
+		    lv1_repository_string("pu"),
+		    ppe_id, lv1_repository_string("rm_size"),
+		    &rm_maxaddr, &junk);
+	}
+	
+	return (rm_maxaddr);
 }
 
 static void


More information about the svn-src-head mailing list