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
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to