aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/boot
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/boot')
-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 d989de810cac..cae3feb1035e 100644
--- a/arch/x86/boot/memory.c
+++ b/arch/x86/boot/memory.c
@@ -17,17 +17,12 @@
17 17
18#define SMAP 0x534d4150 /* ASCII "SMAP" */ 18#define SMAP 0x534d4150 /* ASCII "SMAP" */
19 19
20struct e820_ext_entry {
21 struct e820entry std;
22 u32 ext_flags;
23} __attribute__((packed));
24
25static int detect_memory_e820(void) 20static int detect_memory_e820(void)
26{ 21{
27 int count = 0; 22 int count = 0;
28 struct biosregs ireg, oreg; 23 struct biosregs ireg, oreg;
29 struct e820entry *desc = boot_params.e820_map; 24 struct e820entry *desc = boot_params.e820_map;
30 static struct e820_ext_entry buf; /* static so it is zeroed */ 25 static struct e820entry buf; /* static so it is zeroed */
31 26
32 initregs(&ireg); 27 initregs(&ireg);
33 ireg.ax = 0xe820; 28 ireg.ax = 0xe820;
@@ -36,10 +31,18 @@ static int detect_memory_e820(void)
36 ireg.di = (size_t)&buf; 31 ireg.di = (size_t)&buf;
37 32
38 /* 33 /*
39 * Set this here so that if the BIOS doesn't change this field 34 * Note: at least one BIOS is known which assumes that the
40 * but still doesn't change %ecx, we're still okay... 35 * buffer pointed to by one e820 call is the same one as
36 * the previous call, and only changes modified fields. Therefore,
37 * we use a temporary buffer and copy the results entry by entry.
38 *
39 * This routine deliberately does not try to account for
40 * ACPI 3+ extended attributes. This is because there are
41 * BIOSes in the field which report zero for the valid bit for
42 * all ranges, and we don't currently make any use of the
43 * other attribute bits. Revisit this if we see the extended
44 * attribute bits deployed in a meaningful way in the future.
41 */ 45 */
42 buf.ext_flags = 1;
43 46
44 do { 47 do {
45 intcall(0x15, &ireg, &oreg); 48 intcall(0x15, &ireg, &oreg);
@@ -61,13 +64,7 @@ static int detect_memory_e820(void)
61 break; 64 break;
62 } 65 }
63 66
64 /* ACPI 3.0 added the extended flags support. If bit 0 67 *desc++ = buf;
65 in the extended flags is zero, we're supposed to simply
66 ignore the entry -- a backwards incompatible change! */
67 if (oreg.cx > 20 && !(buf.ext_flags & 1))
68 continue;
69
70 *desc++ = buf.std;
71 count++; 68 count++;
72 } while (ireg.ebx && count < ARRAY_SIZE(boot_params.e820_map)); 69 } while (ireg.ebx && count < ARRAY_SIZE(boot_params.e820_map));
73 70