aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/efi.c101
-rw-r--r--arch/i386/kernel/setup.c14
-rw-r--r--arch/i386/mm/init.c5
-rw-r--r--include/asm-i386/setup.h2
-rw-r--r--include/linux/efi.h14
5 files changed, 67 insertions, 69 deletions
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c
index 385883ea8c19..850648ae8305 100644
--- a/arch/i386/kernel/efi.c
+++ b/arch/i386/kernel/efi.c
@@ -233,22 +233,23 @@ void __init efi_map_memmap(void)
233{ 233{
234 memmap.map = NULL; 234 memmap.map = NULL;
235 235
236 memmap.map = (efi_memory_desc_t *) 236 memmap.map = bt_ioremap((unsigned long) memmap.phys_map,
237 bt_ioremap((unsigned long) memmap.phys_map, 237 (memmap.nr_map * memmap.desc_size));
238 (memmap.nr_map * sizeof(efi_memory_desc_t)));
239
240 if (memmap.map == NULL) 238 if (memmap.map == NULL)
241 printk(KERN_ERR PFX "Could not remap the EFI memmap!\n"); 239 printk(KERN_ERR PFX "Could not remap the EFI memmap!\n");
240
241 memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
242} 242}
243 243
244#if EFI_DEBUG 244#if EFI_DEBUG
245static void __init print_efi_memmap(void) 245static void __init print_efi_memmap(void)
246{ 246{
247 efi_memory_desc_t *md; 247 efi_memory_desc_t *md;
248 void *p;
248 int i; 249 int i;
249 250
250 for (i = 0; i < memmap.nr_map; i++) { 251 for (p = memmap.map, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) {
251 md = &memmap.map[i]; 252 md = p;
252 printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, " 253 printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, "
253 "range=[0x%016llx-0x%016llx) (%lluMB)\n", 254 "range=[0x%016llx-0x%016llx) (%lluMB)\n",
254 i, md->type, md->attribute, md->phys_addr, 255 i, md->type, md->attribute, md->phys_addr,
@@ -271,10 +272,10 @@ void efi_memmap_walk(efi_freemem_callback_t callback, void *arg)
271 } prev, curr; 272 } prev, curr;
272 efi_memory_desc_t *md; 273 efi_memory_desc_t *md;
273 unsigned long start, end; 274 unsigned long start, end;
274 int i; 275 void *p;
275 276
276 for (i = 0; i < memmap.nr_map; i++) { 277 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
277 md = &memmap.map[i]; 278 md = p;
278 279
279 if ((md->num_pages == 0) || (!is_available_memory(md))) 280 if ((md->num_pages == 0) || (!is_available_memory(md)))
280 continue; 281 continue;
@@ -325,6 +326,7 @@ void __init efi_init(void)
325 memmap.phys_map = EFI_MEMMAP; 326 memmap.phys_map = EFI_MEMMAP;
326 memmap.nr_map = EFI_MEMMAP_SIZE/EFI_MEMDESC_SIZE; 327 memmap.nr_map = EFI_MEMMAP_SIZE/EFI_MEMDESC_SIZE;
327 memmap.desc_version = EFI_MEMDESC_VERSION; 328 memmap.desc_version = EFI_MEMDESC_VERSION;
329 memmap.desc_size = EFI_MEMDESC_SIZE;
328 330
329 efi.systab = (efi_system_table_t *) 331 efi.systab = (efi_system_table_t *)
330 boot_ioremap((unsigned long) efi_phys.systab, 332 boot_ioremap((unsigned long) efi_phys.systab,
@@ -428,22 +430,30 @@ void __init efi_init(void)
428 printk(KERN_ERR PFX "Could not map the runtime service table!\n"); 430 printk(KERN_ERR PFX "Could not map the runtime service table!\n");
429 431
430 /* Map the EFI memory map for use until paging_init() */ 432 /* Map the EFI memory map for use until paging_init() */
431 433 memmap.map = boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE);
432 memmap.map = (efi_memory_desc_t *)
433 boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE);
434
435 if (memmap.map == NULL) 434 if (memmap.map == NULL)
436 printk(KERN_ERR PFX "Could not map the EFI memory map!\n"); 435 printk(KERN_ERR PFX "Could not map the EFI memory map!\n");
437 436
438 if (EFI_MEMDESC_SIZE != sizeof(efi_memory_desc_t)) { 437 memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
439 printk(KERN_WARNING PFX "Warning! Kernel-defined memdesc doesn't " 438
440 "match the one from EFI!\n");
441 }
442#if EFI_DEBUG 439#if EFI_DEBUG
443 print_efi_memmap(); 440 print_efi_memmap();
444#endif 441#endif
445} 442}
446 443
444static inline void __init check_range_for_systab(efi_memory_desc_t *md)
445{
446 if (((unsigned long)md->phys_addr <= (unsigned long)efi_phys.systab) &&
447 ((unsigned long)efi_phys.systab < md->phys_addr +
448 ((unsigned long)md->num_pages << EFI_PAGE_SHIFT))) {
449 unsigned long addr;
450
451 addr = md->virt_addr - md->phys_addr +
452 (unsigned long)efi_phys.systab;
453 efi.systab = (efi_system_table_t *)addr;
454 }
455}
456
447/* 457/*
448 * This function will switch the EFI runtime services to virtual mode. 458 * This function will switch the EFI runtime services to virtual mode.
449 * Essentially, look through the EFI memmap and map every region that 459 * Essentially, look through the EFI memmap and map every region that
@@ -457,43 +467,32 @@ void __init efi_enter_virtual_mode(void)
457{ 467{
458 efi_memory_desc_t *md; 468 efi_memory_desc_t *md;
459 efi_status_t status; 469 efi_status_t status;
460 int i; 470 void *p;
461 471
462 efi.systab = NULL; 472 efi.systab = NULL;
463 473
464 for (i = 0; i < memmap.nr_map; i++) { 474 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
465 md = &memmap.map[i]; 475 md = p;
466 476
467 if (md->attribute & EFI_MEMORY_RUNTIME) { 477 if (!(md->attribute & EFI_MEMORY_RUNTIME))
468 md->virt_addr = 478 continue;
469 (unsigned long)ioremap(md->phys_addr,
470 md->num_pages << EFI_PAGE_SHIFT);
471 if (!(unsigned long)md->virt_addr) {
472 printk(KERN_ERR PFX "ioremap of 0x%lX failed\n",
473 (unsigned long)md->phys_addr);
474 }
475 479
476 if (((unsigned long)md->phys_addr <= 480 md->virt_addr = (unsigned long)ioremap(md->phys_addr,
477 (unsigned long)efi_phys.systab) && 481 md->num_pages << EFI_PAGE_SHIFT);
478 ((unsigned long)efi_phys.systab < 482 if (!(unsigned long)md->virt_addr) {
479 md->phys_addr + 483 printk(KERN_ERR PFX "ioremap of 0x%lX failed\n",
480 ((unsigned long)md->num_pages << 484 (unsigned long)md->phys_addr);
481 EFI_PAGE_SHIFT))) {
482 unsigned long addr;
483
484 addr = md->virt_addr - md->phys_addr +
485 (unsigned long)efi_phys.systab;
486 efi.systab = (efi_system_table_t *)addr;
487 }
488 } 485 }
486 /* update the virtual address of the EFI system table */
487 check_range_for_systab(md);
489 } 488 }
490 489
491 if (!efi.systab) 490 if (!efi.systab)
492 BUG(); 491 BUG();
493 492
494 status = phys_efi_set_virtual_address_map( 493 status = phys_efi_set_virtual_address_map(
495 sizeof(efi_memory_desc_t) * memmap.nr_map, 494 memmap.desc_size * memmap.nr_map,
496 sizeof(efi_memory_desc_t), 495 memmap.desc_size,
497 memmap.desc_version, 496 memmap.desc_version,
498 memmap.phys_map); 497 memmap.phys_map);
499 498
@@ -533,10 +532,10 @@ efi_initialize_iomem_resources(struct resource *code_resource,
533{ 532{
534 struct resource *res; 533 struct resource *res;
535 efi_memory_desc_t *md; 534 efi_memory_desc_t *md;
536 int i; 535 void *p;
537 536
538 for (i = 0; i < memmap.nr_map; i++) { 537 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
539 md = &memmap.map[i]; 538 md = p;
540 539
541 if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) > 540 if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >
542 0x100000000ULL) 541 0x100000000ULL)
@@ -613,10 +612,10 @@ efi_initialize_iomem_resources(struct resource *code_resource,
613u32 efi_mem_type(unsigned long phys_addr) 612u32 efi_mem_type(unsigned long phys_addr)
614{ 613{
615 efi_memory_desc_t *md; 614 efi_memory_desc_t *md;
616 int i; 615 void *p;
617 616
618 for (i = 0; i < memmap.nr_map; i++) { 617 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
619 md = &memmap.map[i]; 618 md = p;
620 if ((md->phys_addr <= phys_addr) && (phys_addr < 619 if ((md->phys_addr <= phys_addr) && (phys_addr <
621 (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) )) 620 (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
622 return md->type; 621 return md->type;
@@ -627,10 +626,10 @@ u32 efi_mem_type(unsigned long phys_addr)
627u64 efi_mem_attributes(unsigned long phys_addr) 626u64 efi_mem_attributes(unsigned long phys_addr)
628{ 627{
629 efi_memory_desc_t *md; 628 efi_memory_desc_t *md;
630 int i; 629 void *p;
631 630
632 for (i = 0; i < memmap.nr_map; i++) { 631 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
633 md = &memmap.map[i]; 632 md = p;
634 if ((md->phys_addr <= phys_addr) && (phys_addr < 633 if ((md->phys_addr <= phys_addr) && (phys_addr <
635 (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) )) 634 (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
636 return md->attribute; 635 return md->attribute;
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index af4de58cab54..9adbf710ec8d 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -370,12 +370,16 @@ static void __init limit_regions(unsigned long long size)
370 int i; 370 int i;
371 371
372 if (efi_enabled) { 372 if (efi_enabled) {
373 for (i = 0; i < memmap.nr_map; i++) { 373 efi_memory_desc_t *md;
374 current_addr = memmap.map[i].phys_addr + 374 void *p;
375 (memmap.map[i].num_pages << 12); 375
376 if (memmap.map[i].type == EFI_CONVENTIONAL_MEMORY) { 376 for (p = memmap.map, i = 0; p < memmap.map_end;
377 p += memmap.desc_size, i++) {
378 md = p;
379 current_addr = md->phys_addr + (md->num_pages << 12);
380 if (md->type == EFI_CONVENTIONAL_MEMORY) {
377 if (current_addr >= size) { 381 if (current_addr >= size) {
378 memmap.map[i].num_pages -= 382 md->num_pages -=
379 (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT); 383 (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT);
380 memmap.nr_map = i + 1; 384 memmap.nr_map = i + 1;
381 return; 385 return;
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 12216b52e28b..d8b23ab76533 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -198,9 +198,10 @@ int page_is_ram(unsigned long pagenr)
198 198
199 if (efi_enabled) { 199 if (efi_enabled) {
200 efi_memory_desc_t *md; 200 efi_memory_desc_t *md;
201 void *p;
201 202
202 for (i = 0; i < memmap.nr_map; i++) { 203 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
203 md = &memmap.map[i]; 204 md = p;
204 if (!is_available_memory(md)) 205 if (!is_available_memory(md))
205 continue; 206 continue;
206 addr = (md->phys_addr+PAGE_SIZE-1) >> PAGE_SHIFT; 207 addr = (md->phys_addr+PAGE_SIZE-1) >> PAGE_SHIFT;
diff --git a/include/asm-i386/setup.h b/include/asm-i386/setup.h
index 7a32184d54bf..826a8ca50ac8 100644
--- a/include/asm-i386/setup.h
+++ b/include/asm-i386/setup.h
@@ -44,7 +44,7 @@ extern unsigned char boot_params[PARAM_SIZE];
44#define EFI_SYSTAB ((efi_system_table_t *) *((unsigned long *)(PARAM+0x1c4))) 44#define EFI_SYSTAB ((efi_system_table_t *) *((unsigned long *)(PARAM+0x1c4)))
45#define EFI_MEMDESC_SIZE (*((unsigned long *) (PARAM+0x1c8))) 45#define EFI_MEMDESC_SIZE (*((unsigned long *) (PARAM+0x1c8)))
46#define EFI_MEMDESC_VERSION (*((unsigned long *) (PARAM+0x1cc))) 46#define EFI_MEMDESC_VERSION (*((unsigned long *) (PARAM+0x1cc)))
47#define EFI_MEMMAP ((efi_memory_desc_t *) *((unsigned long *)(PARAM+0x1d0))) 47#define EFI_MEMMAP ((void *) *((unsigned long *)(PARAM+0x1d0)))
48#define EFI_MEMMAP_SIZE (*((unsigned long *) (PARAM+0x1d4))) 48#define EFI_MEMMAP_SIZE (*((unsigned long *) (PARAM+0x1d4)))
49#define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2)) 49#define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2))
50#define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8)) 50#define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8))
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 73781ec165b4..c7c5dd316182 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -91,11 +91,6 @@ typedef struct {
91 91
92#define EFI_PAGE_SHIFT 12 92#define EFI_PAGE_SHIFT 12
93 93
94/*
95 * For current x86 implementations of EFI, there is
96 * additional padding in the mem descriptors. This is not
97 * the case in ia64. Need to have this fixed in the f/w.
98 */
99typedef struct { 94typedef struct {
100 u32 type; 95 u32 type;
101 u32 pad; 96 u32 pad;
@@ -103,9 +98,6 @@ typedef struct {
103 u64 virt_addr; 98 u64 virt_addr;
104 u64 num_pages; 99 u64 num_pages;
105 u64 attribute; 100 u64 attribute;
106#if defined (__i386__)
107 u64 pad1;
108#endif
109} efi_memory_desc_t; 101} efi_memory_desc_t;
110 102
111typedef int (*efi_freemem_callback_t) (unsigned long start, unsigned long end, void *arg); 103typedef int (*efi_freemem_callback_t) (unsigned long start, unsigned long end, void *arg);
@@ -240,10 +232,12 @@ typedef struct {
240} efi_system_table_t; 232} efi_system_table_t;
241 233
242struct efi_memory_map { 234struct efi_memory_map {
243 efi_memory_desc_t *phys_map; 235 void *phys_map;
244 efi_memory_desc_t *map; 236 void *map;
237 void *map_end;
245 int nr_map; 238 int nr_map;
246 unsigned long desc_version; 239 unsigned long desc_version;
240 unsigned long desc_size;
247}; 241};
248 242
249/* 243/*