Merge branch 'x86/urgent' into x86/setup
authorH. Peter Anvin <hpa@zytor.com>
Sat, 23 May 2009 23:42:19 +0000 (16:42 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Sat, 23 May 2009 23:42:19 +0000 (16:42 -0700)
Resolved conflicts:
arch/x86/boot/memory.c

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1  2 
arch/x86/boot/memory.c

  static int detect_memory_e820(void)
  {
        int count = 0;
 -      u32 next = 0;
 -      u32 size, id, edi;
 -      u8 err;
 +      struct biosregs ireg, oreg;
        struct e820entry *desc = boot_params.e820_map;
-       static struct e820_ext_entry buf; /* static so it is zeroed */
+       static struct e820entry buf; /* static so it is zeroed */
  
 +      initregs(&ireg);
 +      ireg.ax  = 0xe820;
 +      ireg.cx  = sizeof buf;
 +      ireg.edx = SMAP;
 +      ireg.di  = (size_t)&buf;
 +
        /*
-        * Set this here so that if the BIOS doesn't change this field
-        * but still doesn't change %ecx, we're still okay...
+        * Note: at least one BIOS is known which assumes that the
+        * buffer pointed to by one e820 call is the same one as
+        * the previous call, and only changes modified fields.  Therefore,
+        * we use a temporary buffer and copy the results entry by entry.
+        *
+        * This routine deliberately does not try to account for
+        * ACPI 3+ extended attributes.  This is because there are
+        * BIOSes in the field which report zero for the valid bit for
+        * all ranges, and we don't currently make any use of the
+        * other attribute bits.  Revisit this if we see the extended
+        * attribute bits deployed in a meaningful way in the future.
         */
-       buf.ext_flags = 1;
  
        do {
 -              size = sizeof buf;
 -
 -              /* Important: %edx and %esi are clobbered by some BIOSes,
 -                 so they must be either used for the error output
 -                 or explicitly marked clobbered.  Given that, assume there
 -                 is something out there clobbering %ebp and %edi, too. */
 -              asm("pushl %%ebp; int $0x15; popl %%ebp; setc %0"
 -                  : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
 -                    "=D" (edi), "+m" (buf)
 -                  : "D" (&buf), "d" (SMAP), "a" (0xe820)
 -                  : "esi");
 +              intcall(0x15, &ireg, &oreg);
 +              ireg.ebx = oreg.ebx; /* for next iteration... */
  
                /* BIOSes which terminate the chain with CF = 1 as opposed
                   to %ebx = 0 don't always report the SMAP signature on
                        break;
                }
  
-               /* ACPI 3.0 added the extended flags support.  If bit 0
-                  in the extended flags is zero, we're supposed to simply
-                  ignore the entry -- a backwards incompatible change! */
-               if (oreg.cx > 20 && !(buf.ext_flags & 1))
-                       continue;
-               *desc++ = buf.std;
+               *desc++ = buf;
                count++;
 -      } while (next && count < ARRAY_SIZE(boot_params.e820_map));
 +      } while (ireg.ebx && count < ARRAY_SIZE(boot_params.e820_map));
  
        return boot_params.e820_entries = count;
  }