Port-sparc64 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Early crash on SB2000 (panic: init: no memory)



Hi,

> >   memlist start 0 size 1ffea0000
> 
> This could be the mapping issue. Though not sure. because below the
> size for the same is 1fe000000.

Yes.  So, it appears that we have more memory available when the PROM
entries are corrupted/overlapping.  I'm still not sure what causes this.
On a suggestion, I tried to use the list but to trim overlapping entries
(see attached patch).  This allows the kernel to boot:

  Available physical memory after cleanup:
  avail start 2000 size 1fe006000
  avail start 1fe008000 size 7f8000
  avail start 1fec00000 size 3fe000
  avail start 1ffc00000 size 1a0000
  avail start 1ffdb0000 size a0000
  avail start 1ffe8c000 size 4000
  avail start 1ffea0000 size 2000
  End of available physical memory after cleanup

but `dmesg` fails with "dmesg: can't get msgbuf: Device not configured", so
something is still not right.  I'm inclined to use the previous method of
reading the length twice in pmap_read_memlist(), as that seems a simpler
workaround.

Thanks,

J

-- 
   NetBSD: simple; works; documented    /        Sailing at Newbiggin
        http://www.netbsd.org/        /   http://www.newbigginsailingclub.org/
Index: pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/pmap.c,v
retrieving revision 1.278
diff -u -r1.278 pmap.c
--- pmap.c      25 Mar 2012 02:31:00 -0000      1.278
+++ pmap.c      11 Nov 2012 10:07:38 -0000
@@ -641,11 +641,16 @@
                                device, property);
                prom_halt();
        }
+       /*
+        * Add an extra two entries, as calling OF_getproplen can cause
+        * the number of entries to grow.
+        */
+       size += 2;
        if ( (va = (void*)(* ml_alloc)(size, sizeof(uint64_t))) == NULL) {
                prom_printf("pmap_read_memlist(): Cannot allocate memlist.\n");
                prom_halt();
        }
-       if (OF_getprop(handle, property, va, size) <= 0) {
+       if ((size = OF_getprop(handle, property, va, size)) <= 0) {
                prom_printf("pmap_read_memlist(): Cannot read %s/%s.\n",
                                device, property);
                prom_halt();
@@ -904,6 +909,22 @@
                }
        }
 
+       /*
+        * Handle overlapping entries by reducing the size of the
+        * overlapping entry with the lowest start address.
+        */
+       for (i = 0; i < pcnt; i++) {
+               uint64_t stmp;
+
+               stmp = avail[i].start + avail[i].size;
+               for (j = i + 1; j < pcnt; j++) {
+                       if (avail[j].start < stmp) {
+                               avail[i].size = avail[j].start;
+                               stmp = avail[i].start + avail[i].size;
+                       }
+               }
+       }
+
        /* Throw away page zero if we have it. */
        if (avail->start == 0) {
                avail->start += PAGE_SIZE;


Home | Main Index | Thread Index | Old Index