kexec-tools in user space collects rtas, crash , tce region ranges 
from /proc/device-tree/ and passes them as linux,usable-memory properties to 
second/kdump kernel in the device tree buffer. With drconf memory in power6 
machines, we need a similar method to preserve those regions in the kdump 
kernel.  This patch adopts a method to append the number 'n' from n'th lmb 
entry in ibm,dynamic-memory as a string to "linux,usable-memory" string , so 
as to distinguish each usable-memory region and it's size.  Another place 
that needs similar change but not included in this patch is in  
arch/powerpc/mm/numa.c. 

Signed-off-by: Chandru S <[EMAIL PROTECTED]>
---

--- arch/powerpc/kernel/prom.c.orig     2008-06-13 11:42:45.000000000 +0530
+++ arch/powerpc/kernel/prom.c  2008-06-13 12:09:04.000000000 +0530
@@ -884,9 +884,10 @@ static u64 __init dt_mem_next_cell(int s
  */
 static int __init early_init_dt_scan_drconf_memory(unsigned long node)
 {
-       cell_t *dm, *ls;
-       unsigned long l, n, flags;
+       cell_t *dm, *ls, *udm, *reg, *endp;
+       unsigned long l, n, un, flags;
        u64 base, size, lmb_size;
+       char buf[64], t[8];
 
        ls = (cell_t *)of_get_flat_dt_prop(node, "ibm,lmb-size", &l);
        if (ls == NULL || l < dt_root_size_cells * sizeof(cell_t))
@@ -919,6 +920,41 @@ static int __init early_init_dt_scan_drc
                }
                lmb_add(base, size);
        }
+
+       /* Scan usable-memory properties */
+       for (; un != 0; --un) {
+               base = dt_mem_next_cell(dt_root_addr_cells, &udm);
+               flags = dm[3];
+               udm += 4;
+               if ((flags & 0x80) || !(flags & 0x8))
+                       continue;
+               strcpy(buf, "linux,usable-memory");
+               sprintf(t, "%d", (int)un);
+               strcat(buf, t);
+               reg = (cell_t *)of_get_flat_dt_prop(node,
+                                       (const char *)buf, &l);
+               if (reg == NULL)
+                       continue;
+               /* remove the previously added lmb */
+               lmb_remove(base, (base+lmb_size));
+               endp = reg + (l / sizeof(cell_t));
+               while ((endp - reg) >= (dt_root_addr_cells +
+                                               dt_root_size_cells)) {
+
+                       base = dt_mem_next_cell(dt_root_addr_cells, &reg);
+                       size = dt_mem_next_cell(dt_root_size_cells, &reg);
+
+                       if (size == 0)
+                               continue;
+                       if (iommu_is_off) {
+                               if (base >= 0x80000000ul)
+                                       continue;
+                               if ((base + size) > 0x80000000ul)
+                                       size = 0x80000000ul - base;
+                       }
+                       lmb_add(base, size);
+               }
+       }
        lmb_dump_all();
        return 0;
 }
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to