aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorBernhard Walle <bwalle@suse.de>2008-06-27 07:12:55 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-08 11:55:42 -0400
commit5dfcf14d5b28174f94cbe9b4fb35d415db61c64a (patch)
treed5e6c47d8a635e07b3dfb3c115f8cae34fc7c553 /arch
parent69ac9cd629ca96e59f34eb4ccd12d00b2c8276a7 (diff)
x86: use FIRMWARE_MEMMAP on x86/E820
This patch uses the /sys/firmware/memmap interface provided in the last patch on the x86 architecture when E820 is used. The patch copies the E820 memory map very early, and registers the E820 map afterwards via firmware_map_add_early(). Signed-off-by: Bernhard Walle <bwalle@suse.de> Acked-by: Greg KH <gregkh@suse.de> Acked-by: Vivek Goyal <vgoyal@redhat.com> Cc: kexec@lists.infradead.org Cc: yhlu.kernel@gmail.com Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/e820.c44
1 files changed, 37 insertions, 7 deletions
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index d0335853ff52..fc1d579f212b 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -19,6 +19,7 @@
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/pfn.h> 20#include <linux/pfn.h>
21#include <linux/suspend.h> 21#include <linux/suspend.h>
22#include <linux/firmware-map.h>
22 23
23#include <asm/pgtable.h> 24#include <asm/pgtable.h>
24#include <asm/page.h> 25#include <asm/page.h>
@@ -27,7 +28,22 @@
27#include <asm/setup.h> 28#include <asm/setup.h>
28#include <asm/trampoline.h> 29#include <asm/trampoline.h>
29 30
31/*
32 * The e820 map is the map that gets modified e.g. with command line parameters
33 * and that is also registered with modifications in the kernel resource tree
34 * with the iomem_resource as parent.
35 *
36 * The e820_saved is directly saved after the BIOS-provided memory map is
37 * copied. It doesn't get modified afterwards. It's registered for the
38 * /sys/firmware/memmap interface.
39 *
40 * That memory map is not modified and is used as base for kexec. The kexec'd
41 * kernel should get the same memory map as the firmware provides. Then the
42 * user can e.g. boot the original kernel with mem=1G while still booting the
43 * next kernel with full memory.
44 */
30struct e820map e820; 45struct e820map e820;
46struct e820map e820_saved;
31 47
32/* For PCI or other memory-mapped resources */ 48/* For PCI or other memory-mapped resources */
33unsigned long pci_mem_start = 0xaeedbabe; 49unsigned long pci_mem_start = 0xaeedbabe;
@@ -1198,6 +1214,17 @@ void __init finish_e820_parsing(void)
1198 } 1214 }
1199} 1215}
1200 1216
1217static inline const char *e820_type_to_string(int e820_type)
1218{
1219 switch (e820_type) {
1220 case E820_RESERVED_KERN:
1221 case E820_RAM: return "System RAM";
1222 case E820_ACPI: return "ACPI Tables";
1223 case E820_NVS: return "ACPI Non-volatile Storage";
1224 default: return "reserved";
1225 }
1226}
1227
1201/* 1228/*
1202 * Mark e820 reserved areas as busy for the resource manager. 1229 * Mark e820 reserved areas as busy for the resource manager.
1203 */ 1230 */
@@ -1209,13 +1236,6 @@ void __init e820_reserve_resources(void)
1209 1236
1210 res = alloc_bootmem_low(sizeof(struct resource) * e820.nr_map); 1237 res = alloc_bootmem_low(sizeof(struct resource) * e820.nr_map);
1211 for (i = 0; i < e820.nr_map; i++) { 1238 for (i = 0; i < e820.nr_map; i++) {
1212 switch (e820.map[i].type) {
1213 case E820_RESERVED_KERN:
1214 case E820_RAM: res->name = "System RAM"; break;
1215 case E820_ACPI: res->name = "ACPI Tables"; break;
1216 case E820_NVS: res->name = "ACPI Non-volatile Storage"; break;
1217 default: res->name = "reserved";
1218 }
1219 end = e820.map[i].addr + e820.map[i].size - 1; 1239 end = e820.map[i].addr + e820.map[i].size - 1;
1220#ifndef CONFIG_RESOURCES_64BIT 1240#ifndef CONFIG_RESOURCES_64BIT
1221 if (end > 0x100000000ULL) { 1241 if (end > 0x100000000ULL) {
@@ -1223,6 +1243,7 @@ void __init e820_reserve_resources(void)
1223 continue; 1243 continue;
1224 } 1244 }
1225#endif 1245#endif
1246 res->name = e820_type_to_string(e820.map[i].type);
1226 res->start = e820.map[i].addr; 1247 res->start = e820.map[i].addr;
1227 res->end = end; 1248 res->end = end;
1228 1249
@@ -1230,6 +1251,13 @@ void __init e820_reserve_resources(void)
1230 insert_resource(&iomem_resource, res); 1251 insert_resource(&iomem_resource, res);
1231 res++; 1252 res++;
1232 } 1253 }
1254
1255 for (i = 0; i < e820_saved.nr_map; i++) {
1256 struct e820entry *entry = &e820_saved.map[i];
1257 firmware_map_add_early(entry->addr,
1258 entry->addr + entry->size - 1,
1259 e820_type_to_string(entry->type));
1260 }
1233} 1261}
1234 1262
1235char *__init default_machine_specific_memory_setup(void) 1263char *__init default_machine_specific_memory_setup(void)
@@ -1266,6 +1294,8 @@ char *__init default_machine_specific_memory_setup(void)
1266 e820_add_region(HIGH_MEMORY, mem_size << 10, E820_RAM); 1294 e820_add_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
1267 } 1295 }
1268 1296
1297 memcpy(&e820_saved, &e820, sizeof(struct e820map));
1298
1269 /* In case someone cares... */ 1299 /* In case someone cares... */
1270 return who; 1300 return who;
1271} 1301}