aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/e820.c59
-rw-r--r--arch/x86/kernel/setup.c3
-rw-r--r--include/asm-x86/bootparam.h1
-rw-r--r--include/asm-x86/e820.h2
4 files changed, 52 insertions, 13 deletions
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index ed46b7a6bc13..544dd12c70f4 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -359,6 +359,26 @@ static struct e820entry new_bios[E820_X_MAX] __initdata;
359 return 0; 359 return 0;
360} 360}
361 361
362static int __init __copy_e820_map(struct e820entry *biosmap, int nr_map)
363{
364 while (nr_map) {
365 u64 start = biosmap->addr;
366 u64 size = biosmap->size;
367 u64 end = start + size;
368 u32 type = biosmap->type;
369
370 /* Overflow in 64 bits? Ignore the memory map. */
371 if (start > end)
372 return -1;
373
374 e820_add_region(start, size, type);
375
376 biosmap++;
377 nr_map--;
378 }
379 return 0;
380}
381
362/* 382/*
363 * Copy the BIOS e820 map into a safe place. 383 * Copy the BIOS e820 map into a safe place.
364 * 384 *
@@ -374,19 +394,7 @@ int __init copy_e820_map(struct e820entry *biosmap, int nr_map)
374 if (nr_map < 2) 394 if (nr_map < 2)
375 return -1; 395 return -1;
376 396
377 do { 397 return __copy_e820_map(biosmap, nr_map);
378 u64 start = biosmap->addr;
379 u64 size = biosmap->size;
380 u64 end = start + size;
381 u32 type = biosmap->type;
382
383 /* Overflow in 64 bits? Ignore the memory map. */
384 if (start > end)
385 return -1;
386
387 e820_add_region(start, size, type);
388 } while (biosmap++, --nr_map);
389 return 0;
390} 398}
391 399
392u64 __init e820_update_range(u64 start, u64 size, unsigned old_type, 400u64 __init e820_update_range(u64 start, u64 size, unsigned old_type,
@@ -496,6 +504,31 @@ __init void e820_setup_gap(void)
496 pci_mem_start, gapstart, gapsize); 504 pci_mem_start, gapstart, gapsize);
497} 505}
498 506
507/**
508 * Because of the size limitation of struct boot_params, only first
509 * 128 E820 memory entries are passed to kernel via
510 * boot_params.e820_map, others are passed via SETUP_E820_EXT node of
511 * linked list of struct setup_data, which is parsed here.
512 */
513void __init parse_e820_ext(struct setup_data *sdata, unsigned long pa_data)
514{
515 u32 map_len;
516 int entries;
517 struct e820entry *extmap;
518
519 entries = sdata->len / sizeof(struct e820entry);
520 map_len = sdata->len + sizeof(struct setup_data);
521 if (map_len > PAGE_SIZE)
522 sdata = early_ioremap(pa_data, map_len);
523 extmap = (struct e820entry *)(sdata->data);
524 __copy_e820_map(extmap, entries);
525 sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
526 if (map_len > PAGE_SIZE)
527 early_iounmap(sdata, map_len);
528 printk(KERN_INFO "extended physical RAM map:\n");
529 e820_print_map("extended");
530}
531
499#if defined(CONFIG_X86_64) || \ 532#if defined(CONFIG_X86_64) || \
500 (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION)) 533 (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
501/** 534/**
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 45a5e247d450..5b0de38cde48 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -150,6 +150,9 @@ void __init parse_setup_data(void)
150 while (pa_data) { 150 while (pa_data) {
151 data = early_ioremap(pa_data, PAGE_SIZE); 151 data = early_ioremap(pa_data, PAGE_SIZE);
152 switch (data->type) { 152 switch (data->type) {
153 case SETUP_E820_EXT:
154 parse_e820_ext(data, pa_data);
155 break;
153 default: 156 default:
154 break; 157 break;
155 } 158 }
diff --git a/include/asm-x86/bootparam.h b/include/asm-x86/bootparam.h
index 0a073904168b..876f21136660 100644
--- a/include/asm-x86/bootparam.h
+++ b/include/asm-x86/bootparam.h
@@ -11,6 +11,7 @@
11 11
12/* setup data types */ 12/* setup data types */
13#define SETUP_NONE 0 13#define SETUP_NONE 0
14#define SETUP_E820_EXT 1
14 15
15/* extensible setup data list node */ 16/* extensible setup data list node */
16struct setup_data { 17struct setup_data {
diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h
index 55d310596907..77fc24d89163 100644
--- a/include/asm-x86/e820.h
+++ b/include/asm-x86/e820.h
@@ -69,6 +69,8 @@ extern u64 e820_update_range(u64 start, u64 size, unsigned old_type,
69 unsigned new_type); 69 unsigned new_type);
70extern void update_e820(void); 70extern void update_e820(void);
71extern void e820_setup_gap(void); 71extern void e820_setup_gap(void);
72struct setup_data;
73extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data);
72 74
73#if defined(CONFIG_X86_64) || \ 75#if defined(CONFIG_X86_64) || \
74 (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION)) 76 (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))