aboutsummaryrefslogtreecommitdiff
path: root/arch/x86/boot/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/boot/memory.c')
-rw-r--r--arch/x86/boot/memory.c29
1 files changed, 13 insertions, 16 deletions
diff --git a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c
index d989de810ca..cae3feb1035 100644
--- a/arch/x86/boot/memory.c
+++ b/arch/x86/boot/memory.c
@@ -17,17 +17,12 @@
#define SMAP 0x534d4150 /* ASCII "SMAP" */
-struct e820_ext_entry {
- struct e820entry std;
- u32 ext_flags;
-} __attribute__((packed));
-
static int detect_memory_e820(void)
{
int count = 0;
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;
@@ -36,10 +31,18 @@ static int detect_memory_e820(void)
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 {
intcall(0x15, &ireg, &oreg);
@@ -61,13 +64,7 @@ static int detect_memory_e820(void)
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 (ireg.ebx && count < ARRAY_SIZE(boot_params.e820_map));