Drop support for ACPI 3 E820 extended memory attributes
authorH. Peter Anvin <hpa@zytor.com>
Thu, 21 May 2009 23:03:15 +0000 (16:03 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Thu, 21 May 2009 23:03:15 +0000 (16:03 -0700)
Drop all support for ACPI 3 E820 extended memory attributes.  There
are BIOSes in the field that report completely bogus information here,
resulting in no memory at all being detected (we then fall back to
E801 detection, but that is problematic in its own ways.)

There is strong reasons to believe at this point that the extended
memory attributes are not usable in their current form, so drop them
and revert back to simple 20-byte support, including for MEMDISK
spoofing.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
NEWS
com32/lib/syslinux/memscan.c
com32/mboot/mem.c
core/highmem.inc
memdisk/e820.h
memdisk/e820func.c
memdisk/e820test.c
memdisk/memdisk.inc
memdisk/msetup.c
memdisk/setup.c

diff --git a/NEWS b/NEWS
index aadf835..7acd25b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,7 @@ Changes in 3.81:
          This unfortunately means that the isohybrid handoff protocol
          has changed, so the isohybrid utility must version-match
          isolinux.bin.
+       * Drop support for ACPI 3 extended memory flags.
 
 Changes in 3.80:
        * New shuffler mechanism and API.
index 1f9bd8a..0743920 100644 (file)
@@ -45,7 +45,6 @@ struct e820_entry {
   uint64_t start;
   uint64_t len;
   uint32_t type;
-  uint32_t extattr;
 };
 
 int syslinux_scan_memory(scan_memory_callback_t callback, void *data)
@@ -82,8 +81,6 @@ int syslinux_scan_memory(scan_memory_callback_t callback, void *data)
   ireg.es       = SEG(e820buf);
   ireg.edi.w[0] = OFFS(e820buf);
   memset(e820buf, 0, sizeof *e820buf);
-  /* Set this in case the BIOS doesn't, but doesn't change %ecx to match. */
-  e820buf->extattr = 1;
 
   do {
     __intcall(0x15, &ireg, &oreg);
@@ -93,12 +90,6 @@ int syslinux_scan_memory(scan_memory_callback_t callback, void *data)
        (oreg.ecx.l < 20))
       break;
 
-    if (oreg.ecx.l < 24)
-      e820buf->extattr = 1;    /* Enabled, normal */
-
-    if (!(e820buf->extattr & 1))
-      continue;
-
     start = e820buf->start;
     len = e820buf->len;
 
index e9d8bbd..07ccb62 100644 (file)
@@ -42,7 +42,6 @@ struct e820_entry {
   uint64_t start;
   uint64_t len;
   uint32_t type;
-  uint32_t extattr;
 };
 
 #define RANGE_ALLOC_BLOCK      128
@@ -83,8 +82,6 @@ static int mboot_scan_memory(struct AddrRangeDesc **ardp, uint32_t *dosmem)
   ireg.es       = SEG(e820buf);
   ireg.edi.w[0] = OFFS(e820buf);
   memset(e820buf, 0, sizeof *e820buf);
-  /* Set this in case the BIOS doesn't, but doesn't change %ecx to match. */
-  e820buf->extattr = 1;
 
   do {
     __intcall(0x15, &ireg, &oreg);
@@ -94,12 +91,6 @@ static int mboot_scan_memory(struct AddrRangeDesc **ardp, uint32_t *dosmem)
        (oreg.ecx.l < 20))
       break;
 
-    if (oreg.ecx.l < 24)
-      e820buf->extattr = 1;    /* Enabled, normal */
-
-    if (!(e820buf->extattr & 1))
-      continue;
-
     if (ard_count >= ard_space) {
       ard_space += RANGE_ALLOC_BLOCK;
       *ardp = ard = realloc(ard, ard_space*sizeof *ard);
index c7e602f..1f8349b 100644 (file)
@@ -43,9 +43,8 @@ get_e820:
 .start_over:
                mov di,E820Buf
                xor ax,ax
-               mov cx,12
+               mov cx,10
                rep stosw                       ; Clear buffer
-               mov byte [di-4],01h             ; Initial extattr value
                xor ebx,ebx                     ; Start with first record
                jmp short .do_e820              ; Skip "at end" check first time!
 .int_loop:     and ebx,ebx                     ; If we're back at beginning...
@@ -53,7 +52,7 @@ get_e820:
 .do_e820:      mov eax,0000E820h
                mov edx,534D4150h               ; "SMAP" backwards
                xor ecx,ecx
-               mov cl,24                       ; ECX <- 24 (size of buffer)
+               mov cl,20                       ; ECX <- 20 (size of buffer)
                mov di,E820Buf
                int 15h
                jnc .no_carry
@@ -64,15 +63,9 @@ get_e820:
 .no_carry:
                cmp eax,534D4150h
                jne no_e820
-               cmp cl,24
-               jb .no_ext_attr
-               ;
-               ; Some blithering idiot added a whole new field to E820,
-               ; completely without regard for its implications...
-               ;
-               test byte [E820Buf+20],1        ; AddressRangeEnabled
-               jz .not_ram
-.no_ext_attr:
+               cmp cx,20
+               jb no_e820
+
 ;
 ; Look for a memory block starting at <= 1 MB and continuing upward
 ;
@@ -159,7 +152,7 @@ got_highmem:
 
                section .bss
                alignb 4
-E820Buf                resd 6                  ; INT 15:E820 data buffer
+E820Buf                resd 5                  ; INT 15:E820 data buffer
 E820Mem                resd 1                  ; Memory detected by E820
 E820Max                resd 1                  ; Is E820 memory capped?
 HighMemSize    resd 1                  ; End of memory pointer (bytes)
index 429b98c..04b4448 100644 (file)
@@ -21,7 +21,6 @@
 struct e820range {
   uint64_t start;
   uint32_t type;
-  uint32_t extattr;
 } __attribute__((packed));
 
 extern struct e820range ranges[];
@@ -29,6 +28,6 @@ extern int nranges;
 extern uint32_t dos_mem, low_mem, high_mem;
 
 extern void e820map_init(void);
-extern void insertrange(uint64_t, uint64_t, uint32_t, uint32_t);
+extern void insertrange(uint64_t, uint64_t, uint32_t);
 extern void get_mem(void);
 extern void parse_mem(void);
index ccfc38e..80471a9 100644 (file)
@@ -37,8 +37,7 @@ void e820map_init(void)
   ranges[1].type = -1U;
 }
 
-static void insertrange_at(int where, uint64_t start,
-                          uint32_t type, uint32_t extattr)
+static void insertrange_at(int where, uint64_t start, uint32_t type)
 {
   int i;
 
@@ -47,18 +46,16 @@ static void insertrange_at(int where, uint64_t start,
 
   ranges[where].start   = start;
   ranges[where].type    = type;
-  ranges[where].extattr = extattr;
 
   nranges++;
   ranges[nranges].start   = 0ULL;
   ranges[nranges].type    = -1U;
-  ranges[nranges].extattr = 0;
 }
 
-void insertrange(uint64_t start, uint64_t len, uint32_t type, uint32_t extattr)
+void insertrange(uint64_t start, uint64_t len, uint32_t type)
 {
   uint64_t last;
-  uint32_t oldtype, oldattr;
+  uint32_t oldtype;
   int i, j;
 
   /* Remove this to make len == 0 mean all of memory */
@@ -69,40 +66,34 @@ void insertrange(uint64_t start, uint64_t len, uint32_t type, uint32_t extattr)
 
   i = 0;
   oldtype = -2U;
-  oldattr = 0;
   while ( start > ranges[i].start && ranges[i].type != -1U ) {
     oldtype = ranges[i].type;
-    oldattr = ranges[i].extattr;
     i++;
   }
 
   /* Consider the replacement policy.  This current one is "overwrite." */
 
   if ( start < ranges[i].start || ranges[i].type == -1U )
-    insertrange_at(i++, start, type, extattr);
+    insertrange_at(i++, start, type);
 
   while ( i == 0 || last > ranges[i].start-1 ) {
     oldtype = ranges[i].type;
-    oldattr = ranges[i].extattr;
     ranges[i].type    = type;
-    ranges[i].extattr = extattr;
     i++;
   }
 
   if ( last < ranges[i].start-1 )
-    insertrange_at(i, last+1, oldtype, oldattr);
+    insertrange_at(i, last+1, oldtype);
 
   /* Now the map is correct, but quite possibly not optimal.  Scan the
      map for ranges which are redundant and remove them. */
   i = j = 1;
   oldtype = ranges[0].type;
-  oldattr = ranges[0].extattr;
   while ( i < nranges ) {
-    if ( ranges[i].type == oldtype && ranges[i].extattr == oldattr ) {
+    if ( ranges[i].type == oldtype ) {
       i++;
     } else {
       oldtype = ranges[i].type;
-      oldattr = ranges[i].extattr;
       if ( i != j )
        ranges[j] = ranges[i];
       i++; j++;
index 41fee00..2de7fd4 100644 (file)
@@ -36,17 +36,17 @@ void printranges(void) {
   int i;
 
   for ( i = 0 ; i < nranges ; i++ ) {
-    printf("%016llx %016llx %d %x\n",
+    printf("%016llx %016llx %d\n",
           ranges[i].start,
           ranges[i+1].start - ranges[i].start,
-          ranges[i].type, ranges[i].extattr);
+          ranges[i].type);
   }
 }
 
 int main(void)
 {
   uint64_t start, len;
-  uint32_t type, extattr;
+  uint32_t type;
   char line[BUFSIZ], *p;
 
   e820map_init();
@@ -55,12 +55,11 @@ int main(void)
   while ( fgets(line, BUFSIZ, stdin) ) {
     p = strchr(line, ':');
     p = p ? p+1 : line;
-    extattr = 1;
-    if ( sscanf(p, " %llx %llx %d %x", &start, &len, &type, &extattr) >= 3 ) {
+    if ( sscanf(p, " %llx %llx %d", &start, &len, &type) == 3 ) {
       putchar('\n');
-      printf("%016llx %016llx %d %x <-\n", start, len, type, extattr);
+      printf("%016llx %016llx %d <-\n", start, len, type);
       putchar('\n');
-      insertrange(start, len, type, extattr);
+      insertrange(start, len, type);
       printranges();
     }
   }
index fa4fe3e..00537a8 100644 (file)
@@ -540,26 +540,19 @@ int15_e820:
                jne .renew
                mov ebx,E820Table
 .renew:
-               add bx,16               ; Advance to next
-               mov eax,[bx-8]          ; Type
+               add bx,12               ; Advance to next
+               mov eax,[bx-4]          ; Type
                and eax,eax             ; Null type?
                jz .renew               ; If so advance to next
                mov [es:di+16],eax
-               and cl,~3
-               cmp ecx,24
-               jb .no_extattr
-               mov eax,[bx-4]          ; Extended attributes
-               mov [es:di+20],eax
-               mov ecx,24              ; Bytes loaded
-.no_extattr:
-               mov eax,[bx-16]         ; Start addr (low)
-               mov edx,[bx-12]         ; Start addr (high)
+               mov eax,[bx-12]         ; Start addr (low)
+               mov edx,[bx-8]          ; Start addr (high)
                mov [es:di],eax
                mov [es:di+4],edx
                mov eax,[bx]            ; End addr (low)
                mov edx,[bx+4]          ; End addr (high)
-               sub eax,[bx-16]         ; Derive the length
-               sbb edx,[bx-12]
+               sub eax,[bx-12]         ; Derive the length
+               sbb edx,[bx-8]
                mov [es:di+8],eax       ; Length (low)
                mov [es:di+12],edx      ; Length (high)
                cmp dword [bx+8],-1     ; Type of next = end?
@@ -568,6 +561,7 @@ int15_e820:
 .notdone:
                pop eax                 ; "SMAP"
                mov edx,eax             ; Some systems expect eax = edx = SMAP
+               mov ecx,20              ; Bytes loaded
                pop ds
 int15_success:
                mov byte [bp+6], 02h    ; Clear CF
index a206701..e511117 100644 (file)
@@ -38,7 +38,6 @@ static inline int get_e820(void)
     uint64_t base;
     uint64_t len;
     uint32_t type;
-    uint32_t extattr;
   } *buf = sys_bounce;
   uint32_t copied;
   int range_count = 0;
@@ -46,7 +45,6 @@ static inline int get_e820(void)
 
   memset(&regs, 0, sizeof regs);
   memset(buf, 0, sizeof *buf);
-  buf->extattr = 1;
 
   do {
     regs.eax.l = 0x0000e820;
@@ -61,18 +59,12 @@ static inline int get_e820(void)
     if ( regs.eax.l != 0x534d4150 || copied < 20 )
       break;
 
-    if ( copied < 24 )
-      buf->extattr = 1;
-
-    printf("e820: %08x%08x %08x%08x %d [%x]\n",
+    printf("e820: %08x%08x %08x%08x %d\n",
           (uint32_t)(buf->base >> 32), (uint32_t)buf->base,
           (uint32_t)(buf->len >> 32), (uint32_t)buf->len,
-          buf->type, buf->extattr);
-
-    if ( !(buf->extattr & 1) )
-      continue;                        /* Disabled range, just ignore */
+          buf->type);
 
-    insertrange(buf->base, buf->len, buf->type, buf->extattr);
+    insertrange(buf->base, buf->len, buf->type);
     range_count++;
 
   } while ( regs.ebx.l );
@@ -86,7 +78,7 @@ static inline void get_dos_mem(void)
 
   memset(&regs, 0, sizeof regs);
   syscall(0x12, &regs, &regs);
-  insertrange(0, (uint64_t)((uint32_t)regs.eax.w[0] << 10), 1, 1);
+  insertrange(0, (uint64_t)((uint32_t)regs.eax.w[0] << 10), 1);
   printf(" DOS: %d K\n", regs.eax.w[0]);
 }
 
@@ -102,10 +94,10 @@ static inline int get_e801(void)
 
   if ( !(err = regs.eflags.l & 1) ) {
     if ( regs.eax.w[0] ) {
-      insertrange(0x100000, (uint64_t)((uint32_t)regs.eax.w[0] << 10), 1, 1);
+      insertrange(0x100000, (uint64_t)((uint32_t)regs.eax.w[0] << 10), 1);
     }
     if ( regs.ebx.w[0] ) {
-      insertrange(0x1000000, (uint64_t)((uint32_t)regs.ebx.w[0] << 16), 1, 1);
+      insertrange(0x1000000, (uint64_t)((uint32_t)regs.ebx.w[0] << 16), 1);
     }
 
     printf("e801: %04x %04x\n", regs.eax.w[0], regs.ebx.w[0]);
@@ -127,7 +119,7 @@ static inline int get_88(void)
 
   if ( !(err = regs.eflags.l & 1) ) {
     if ( regs.eax.w[0] ) {
-      insertrange(0x100000, (uint64_t)((uint32_t)regs.eax.w[0] << 10), 1, 1);
+      insertrange(0x100000, (uint64_t)((uint32_t)regs.eax.w[0] << 10), 1);
     }
 
     printf("  88: %04x\n", regs.eax.w[0]);
index 61f9bfb..94a8011 100644 (file)
@@ -295,8 +295,6 @@ void unzip_if_needed(uint32_t *where_p, uint32_t *size_p)
       /* Must be memory */
       if ( ranges[i].type != 1 )
        continue;
-      if (!(ranges[i].extattr & 1))
-       continue;
 
       /* Range start */
       if ( ranges[i].start >= 0xFFFFFFFF )
@@ -752,7 +750,7 @@ __cdecl void setup(__cdecl syscall_t cs_syscall, void *cs_bounce)
   }
 
   /* Reserve the ramdisk memory */
-  insertrange(ramdisk_image, ramdisk_size, 2, 1);
+  insertrange(ramdisk_image, ramdisk_size, 2);
   parse_mem();                 /* Recompute variables */
 
   /* Figure out where it needs to go */
@@ -896,7 +894,7 @@ __cdecl void setup(__cdecl syscall_t cs_syscall, void *cs_bounce)
 
   /* Reserve this range of memory */
   wrz_16(BIOS_BASEMEM, driveraddr >> 10);
-  insertrange(driveraddr, dos_mem-driveraddr, 2, 1);
+  insertrange(driveraddr, dos_mem-driveraddr, 2);
   parse_mem();
 
   pptr->mem1mb     = low_mem  >> 10;