diff options
Diffstat (limited to 'arch/x86/platform/efi/efi.c')
-rw-r--r-- | arch/x86/platform/efi/efi.c | 377 |
1 files changed, 270 insertions, 107 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 4cf9bd0a1653..92660edaa1e7 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -26,6 +26,8 @@ | |||
26 | * Skip non-WB memory and ignore empty memory ranges. | 26 | * Skip non-WB memory and ignore empty memory ranges. |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
30 | |||
29 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
30 | #include <linux/init.h> | 32 | #include <linux/init.h> |
31 | #include <linux/efi.h> | 33 | #include <linux/efi.h> |
@@ -47,7 +49,6 @@ | |||
47 | #include <asm/x86_init.h> | 49 | #include <asm/x86_init.h> |
48 | 50 | ||
49 | #define EFI_DEBUG 1 | 51 | #define EFI_DEBUG 1 |
50 | #define PFX "EFI: " | ||
51 | 52 | ||
52 | int efi_enabled; | 53 | int efi_enabled; |
53 | EXPORT_SYMBOL(efi_enabled); | 54 | EXPORT_SYMBOL(efi_enabled); |
@@ -67,6 +68,9 @@ EXPORT_SYMBOL(efi); | |||
67 | 68 | ||
68 | struct efi_memory_map memmap; | 69 | struct efi_memory_map memmap; |
69 | 70 | ||
71 | bool efi_64bit; | ||
72 | static bool efi_native; | ||
73 | |||
70 | static struct efi efi_phys __initdata; | 74 | static struct efi efi_phys __initdata; |
71 | static efi_system_table_t efi_systab __initdata; | 75 | static efi_system_table_t efi_systab __initdata; |
72 | 76 | ||
@@ -254,7 +258,7 @@ int efi_set_rtc_mmss(unsigned long nowtime) | |||
254 | 258 | ||
255 | status = efi.get_time(&eft, &cap); | 259 | status = efi.get_time(&eft, &cap); |
256 | if (status != EFI_SUCCESS) { | 260 | if (status != EFI_SUCCESS) { |
257 | printk(KERN_ERR "Oops: efitime: can't read time!\n"); | 261 | pr_err("Oops: efitime: can't read time!\n"); |
258 | return -1; | 262 | return -1; |
259 | } | 263 | } |
260 | 264 | ||
@@ -268,7 +272,7 @@ int efi_set_rtc_mmss(unsigned long nowtime) | |||
268 | 272 | ||
269 | status = efi.set_time(&eft); | 273 | status = efi.set_time(&eft); |
270 | if (status != EFI_SUCCESS) { | 274 | if (status != EFI_SUCCESS) { |
271 | printk(KERN_ERR "Oops: efitime: can't write time!\n"); | 275 | pr_err("Oops: efitime: can't write time!\n"); |
272 | return -1; | 276 | return -1; |
273 | } | 277 | } |
274 | return 0; | 278 | return 0; |
@@ -282,7 +286,7 @@ unsigned long efi_get_time(void) | |||
282 | 286 | ||
283 | status = efi.get_time(&eft, &cap); | 287 | status = efi.get_time(&eft, &cap); |
284 | if (status != EFI_SUCCESS) | 288 | if (status != EFI_SUCCESS) |
285 | printk(KERN_ERR "Oops: efitime: can't read time!\n"); | 289 | pr_err("Oops: efitime: can't read time!\n"); |
286 | 290 | ||
287 | return mktime(eft.year, eft.month, eft.day, eft.hour, | 291 | return mktime(eft.year, eft.month, eft.day, eft.hour, |
288 | eft.minute, eft.second); | 292 | eft.minute, eft.second); |
@@ -338,11 +342,16 @@ static void __init do_add_efi_memmap(void) | |||
338 | sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); | 342 | sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); |
339 | } | 343 | } |
340 | 344 | ||
341 | void __init efi_memblock_x86_reserve_range(void) | 345 | int __init efi_memblock_x86_reserve_range(void) |
342 | { | 346 | { |
343 | unsigned long pmap; | 347 | unsigned long pmap; |
344 | 348 | ||
345 | #ifdef CONFIG_X86_32 | 349 | #ifdef CONFIG_X86_32 |
350 | /* Can't handle data above 4GB at this time */ | ||
351 | if (boot_params.efi_info.efi_memmap_hi) { | ||
352 | pr_err("Memory map is above 4GB, disabling EFI.\n"); | ||
353 | return -EINVAL; | ||
354 | } | ||
346 | pmap = boot_params.efi_info.efi_memmap; | 355 | pmap = boot_params.efi_info.efi_memmap; |
347 | #else | 356 | #else |
348 | pmap = (boot_params.efi_info.efi_memmap | | 357 | pmap = (boot_params.efi_info.efi_memmap | |
@@ -354,6 +363,8 @@ void __init efi_memblock_x86_reserve_range(void) | |||
354 | memmap.desc_version = boot_params.efi_info.efi_memdesc_version; | 363 | memmap.desc_version = boot_params.efi_info.efi_memdesc_version; |
355 | memmap.desc_size = boot_params.efi_info.efi_memdesc_size; | 364 | memmap.desc_size = boot_params.efi_info.efi_memdesc_size; |
356 | memblock_reserve(pmap, memmap.nr_map * memmap.desc_size); | 365 | memblock_reserve(pmap, memmap.nr_map * memmap.desc_size); |
366 | |||
367 | return 0; | ||
357 | } | 368 | } |
358 | 369 | ||
359 | #if EFI_DEBUG | 370 | #if EFI_DEBUG |
@@ -367,7 +378,7 @@ static void __init print_efi_memmap(void) | |||
367 | p < memmap.map_end; | 378 | p < memmap.map_end; |
368 | p += memmap.desc_size, i++) { | 379 | p += memmap.desc_size, i++) { |
369 | md = p; | 380 | md = p; |
370 | printk(KERN_INFO PFX "mem%02u: type=%u, attr=0x%llx, " | 381 | pr_info("mem%02u: type=%u, attr=0x%llx, " |
371 | "range=[0x%016llx-0x%016llx) (%lluMB)\n", | 382 | "range=[0x%016llx-0x%016llx) (%lluMB)\n", |
372 | i, md->type, md->attribute, md->phys_addr, | 383 | i, md->type, md->attribute, md->phys_addr, |
373 | md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), | 384 | md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), |
@@ -400,7 +411,7 @@ void __init efi_reserve_boot_services(void) | |||
400 | memblock_is_region_reserved(start, size)) { | 411 | memblock_is_region_reserved(start, size)) { |
401 | /* Could not reserve, skip it */ | 412 | /* Could not reserve, skip it */ |
402 | md->num_pages = 0; | 413 | md->num_pages = 0; |
403 | memblock_dbg(PFX "Could not reserve boot range " | 414 | memblock_dbg("Could not reserve boot range " |
404 | "[0x%010llx-0x%010llx]\n", | 415 | "[0x%010llx-0x%010llx]\n", |
405 | start, start+size-1); | 416 | start, start+size-1); |
406 | } else | 417 | } else |
@@ -429,103 +440,172 @@ static void __init efi_free_boot_services(void) | |||
429 | } | 440 | } |
430 | } | 441 | } |
431 | 442 | ||
432 | void __init efi_init(void) | 443 | static int __init efi_systab_init(void *phys) |
433 | { | 444 | { |
434 | efi_config_table_t *config_tables; | 445 | if (efi_64bit) { |
435 | efi_runtime_services_t *runtime; | 446 | efi_system_table_64_t *systab64; |
436 | efi_char16_t *c16; | 447 | u64 tmp = 0; |
437 | char vendor[100] = "unknown"; | 448 | |
438 | int i = 0; | 449 | systab64 = early_ioremap((unsigned long)phys, |
439 | void *tmp; | 450 | sizeof(*systab64)); |
451 | if (systab64 == NULL) { | ||
452 | pr_err("Couldn't map the system table!\n"); | ||
453 | return -ENOMEM; | ||
454 | } | ||
440 | 455 | ||
456 | efi_systab.hdr = systab64->hdr; | ||
457 | efi_systab.fw_vendor = systab64->fw_vendor; | ||
458 | tmp |= systab64->fw_vendor; | ||
459 | efi_systab.fw_revision = systab64->fw_revision; | ||
460 | efi_systab.con_in_handle = systab64->con_in_handle; | ||
461 | tmp |= systab64->con_in_handle; | ||
462 | efi_systab.con_in = systab64->con_in; | ||
463 | tmp |= systab64->con_in; | ||
464 | efi_systab.con_out_handle = systab64->con_out_handle; | ||
465 | tmp |= systab64->con_out_handle; | ||
466 | efi_systab.con_out = systab64->con_out; | ||
467 | tmp |= systab64->con_out; | ||
468 | efi_systab.stderr_handle = systab64->stderr_handle; | ||
469 | tmp |= systab64->stderr_handle; | ||
470 | efi_systab.stderr = systab64->stderr; | ||
471 | tmp |= systab64->stderr; | ||
472 | efi_systab.runtime = (void *)(unsigned long)systab64->runtime; | ||
473 | tmp |= systab64->runtime; | ||
474 | efi_systab.boottime = (void *)(unsigned long)systab64->boottime; | ||
475 | tmp |= systab64->boottime; | ||
476 | efi_systab.nr_tables = systab64->nr_tables; | ||
477 | efi_systab.tables = systab64->tables; | ||
478 | tmp |= systab64->tables; | ||
479 | |||
480 | early_iounmap(systab64, sizeof(*systab64)); | ||
441 | #ifdef CONFIG_X86_32 | 481 | #ifdef CONFIG_X86_32 |
442 | efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab; | 482 | if (tmp >> 32) { |
443 | #else | 483 | pr_err("EFI data located above 4GB, disabling EFI.\n"); |
444 | efi_phys.systab = (efi_system_table_t *) | 484 | return -EINVAL; |
445 | (boot_params.efi_info.efi_systab | | 485 | } |
446 | ((__u64)boot_params.efi_info.efi_systab_hi<<32)); | ||
447 | #endif | 486 | #endif |
487 | } else { | ||
488 | efi_system_table_32_t *systab32; | ||
489 | |||
490 | systab32 = early_ioremap((unsigned long)phys, | ||
491 | sizeof(*systab32)); | ||
492 | if (systab32 == NULL) { | ||
493 | pr_err("Couldn't map the system table!\n"); | ||
494 | return -ENOMEM; | ||
495 | } | ||
496 | |||
497 | efi_systab.hdr = systab32->hdr; | ||
498 | efi_systab.fw_vendor = systab32->fw_vendor; | ||
499 | efi_systab.fw_revision = systab32->fw_revision; | ||
500 | efi_systab.con_in_handle = systab32->con_in_handle; | ||
501 | efi_systab.con_in = systab32->con_in; | ||
502 | efi_systab.con_out_handle = systab32->con_out_handle; | ||
503 | efi_systab.con_out = systab32->con_out; | ||
504 | efi_systab.stderr_handle = systab32->stderr_handle; | ||
505 | efi_systab.stderr = systab32->stderr; | ||
506 | efi_systab.runtime = (void *)(unsigned long)systab32->runtime; | ||
507 | efi_systab.boottime = (void *)(unsigned long)systab32->boottime; | ||
508 | efi_systab.nr_tables = systab32->nr_tables; | ||
509 | efi_systab.tables = systab32->tables; | ||
510 | |||
511 | early_iounmap(systab32, sizeof(*systab32)); | ||
512 | } | ||
448 | 513 | ||
449 | efi.systab = early_ioremap((unsigned long)efi_phys.systab, | ||
450 | sizeof(efi_system_table_t)); | ||
451 | if (efi.systab == NULL) | ||
452 | printk(KERN_ERR "Couldn't map the EFI system table!\n"); | ||
453 | memcpy(&efi_systab, efi.systab, sizeof(efi_system_table_t)); | ||
454 | early_iounmap(efi.systab, sizeof(efi_system_table_t)); | ||
455 | efi.systab = &efi_systab; | 514 | efi.systab = &efi_systab; |
456 | 515 | ||
457 | /* | 516 | /* |
458 | * Verify the EFI Table | 517 | * Verify the EFI Table |
459 | */ | 518 | */ |
460 | if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) | 519 | if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) { |
461 | printk(KERN_ERR "EFI system table signature incorrect!\n"); | 520 | pr_err("System table signature incorrect!\n"); |
521 | return -EINVAL; | ||
522 | } | ||
462 | if ((efi.systab->hdr.revision >> 16) == 0) | 523 | if ((efi.systab->hdr.revision >> 16) == 0) |
463 | printk(KERN_ERR "Warning: EFI system table version " | 524 | pr_err("Warning: System table version " |
464 | "%d.%02d, expected 1.00 or greater!\n", | 525 | "%d.%02d, expected 1.00 or greater!\n", |
465 | efi.systab->hdr.revision >> 16, | 526 | efi.systab->hdr.revision >> 16, |
466 | efi.systab->hdr.revision & 0xffff); | 527 | efi.systab->hdr.revision & 0xffff); |
467 | 528 | ||
468 | /* | 529 | return 0; |
469 | * Show what we know for posterity | 530 | } |
470 | */ | ||
471 | c16 = tmp = early_ioremap(efi.systab->fw_vendor, 2); | ||
472 | if (c16) { | ||
473 | for (i = 0; i < sizeof(vendor) - 1 && *c16; ++i) | ||
474 | vendor[i] = *c16++; | ||
475 | vendor[i] = '\0'; | ||
476 | } else | ||
477 | printk(KERN_ERR PFX "Could not map the firmware vendor!\n"); | ||
478 | early_iounmap(tmp, 2); | ||
479 | 531 | ||
480 | printk(KERN_INFO "EFI v%u.%.02u by %s\n", | 532 | static int __init efi_config_init(u64 tables, int nr_tables) |
481 | efi.systab->hdr.revision >> 16, | 533 | { |
482 | efi.systab->hdr.revision & 0xffff, vendor); | 534 | void *config_tables, *tablep; |
535 | int i, sz; | ||
536 | |||
537 | if (efi_64bit) | ||
538 | sz = sizeof(efi_config_table_64_t); | ||
539 | else | ||
540 | sz = sizeof(efi_config_table_32_t); | ||
483 | 541 | ||
484 | /* | 542 | /* |
485 | * Let's see what config tables the firmware passed to us. | 543 | * Let's see what config tables the firmware passed to us. |
486 | */ | 544 | */ |
487 | config_tables = early_ioremap( | 545 | config_tables = early_ioremap(tables, nr_tables * sz); |
488 | efi.systab->tables, | 546 | if (config_tables == NULL) { |
489 | efi.systab->nr_tables * sizeof(efi_config_table_t)); | 547 | pr_err("Could not map Configuration table!\n"); |
490 | if (config_tables == NULL) | 548 | return -ENOMEM; |
491 | printk(KERN_ERR "Could not map EFI Configuration Table!\n"); | 549 | } |
492 | 550 | ||
493 | printk(KERN_INFO); | 551 | tablep = config_tables; |
552 | pr_info(""); | ||
494 | for (i = 0; i < efi.systab->nr_tables; i++) { | 553 | for (i = 0; i < efi.systab->nr_tables; i++) { |
495 | if (!efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID)) { | 554 | efi_guid_t guid; |
496 | efi.mps = config_tables[i].table; | 555 | unsigned long table; |
497 | printk(" MPS=0x%lx ", config_tables[i].table); | 556 | |
498 | } else if (!efi_guidcmp(config_tables[i].guid, | 557 | if (efi_64bit) { |
499 | ACPI_20_TABLE_GUID)) { | 558 | u64 table64; |
500 | efi.acpi20 = config_tables[i].table; | 559 | guid = ((efi_config_table_64_t *)tablep)->guid; |
501 | printk(" ACPI 2.0=0x%lx ", config_tables[i].table); | 560 | table64 = ((efi_config_table_64_t *)tablep)->table; |
502 | } else if (!efi_guidcmp(config_tables[i].guid, | 561 | table = table64; |
503 | ACPI_TABLE_GUID)) { | 562 | #ifdef CONFIG_X86_32 |
504 | efi.acpi = config_tables[i].table; | 563 | if (table64 >> 32) { |
505 | printk(" ACPI=0x%lx ", config_tables[i].table); | 564 | pr_cont("\n"); |
506 | } else if (!efi_guidcmp(config_tables[i].guid, | 565 | pr_err("Table located above 4GB, disabling EFI.\n"); |
507 | SMBIOS_TABLE_GUID)) { | 566 | early_iounmap(config_tables, |
508 | efi.smbios = config_tables[i].table; | 567 | efi.systab->nr_tables * sz); |
509 | printk(" SMBIOS=0x%lx ", config_tables[i].table); | 568 | return -EINVAL; |
569 | } | ||
570 | #endif | ||
571 | } else { | ||
572 | guid = ((efi_config_table_32_t *)tablep)->guid; | ||
573 | table = ((efi_config_table_32_t *)tablep)->table; | ||
574 | } | ||
575 | if (!efi_guidcmp(guid, MPS_TABLE_GUID)) { | ||
576 | efi.mps = table; | ||
577 | pr_cont(" MPS=0x%lx ", table); | ||
578 | } else if (!efi_guidcmp(guid, ACPI_20_TABLE_GUID)) { | ||
579 | efi.acpi20 = table; | ||
580 | pr_cont(" ACPI 2.0=0x%lx ", table); | ||
581 | } else if (!efi_guidcmp(guid, ACPI_TABLE_GUID)) { | ||
582 | efi.acpi = table; | ||
583 | pr_cont(" ACPI=0x%lx ", table); | ||
584 | } else if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID)) { | ||
585 | efi.smbios = table; | ||
586 | pr_cont(" SMBIOS=0x%lx ", table); | ||
510 | #ifdef CONFIG_X86_UV | 587 | #ifdef CONFIG_X86_UV |
511 | } else if (!efi_guidcmp(config_tables[i].guid, | 588 | } else if (!efi_guidcmp(guid, UV_SYSTEM_TABLE_GUID)) { |
512 | UV_SYSTEM_TABLE_GUID)) { | 589 | efi.uv_systab = table; |
513 | efi.uv_systab = config_tables[i].table; | 590 | pr_cont(" UVsystab=0x%lx ", table); |
514 | printk(" UVsystab=0x%lx ", config_tables[i].table); | ||
515 | #endif | 591 | #endif |
516 | } else if (!efi_guidcmp(config_tables[i].guid, | 592 | } else if (!efi_guidcmp(guid, HCDP_TABLE_GUID)) { |
517 | HCDP_TABLE_GUID)) { | 593 | efi.hcdp = table; |
518 | efi.hcdp = config_tables[i].table; | 594 | pr_cont(" HCDP=0x%lx ", table); |
519 | printk(" HCDP=0x%lx ", config_tables[i].table); | 595 | } else if (!efi_guidcmp(guid, UGA_IO_PROTOCOL_GUID)) { |
520 | } else if (!efi_guidcmp(config_tables[i].guid, | 596 | efi.uga = table; |
521 | UGA_IO_PROTOCOL_GUID)) { | 597 | pr_cont(" UGA=0x%lx ", table); |
522 | efi.uga = config_tables[i].table; | ||
523 | printk(" UGA=0x%lx ", config_tables[i].table); | ||
524 | } | 598 | } |
599 | tablep += sz; | ||
525 | } | 600 | } |
526 | printk("\n"); | 601 | pr_cont("\n"); |
527 | early_iounmap(config_tables, | 602 | early_iounmap(config_tables, efi.systab->nr_tables * sz); |
528 | efi.systab->nr_tables * sizeof(efi_config_table_t)); | 603 | return 0; |
604 | } | ||
605 | |||
606 | static int __init efi_runtime_init(void) | ||
607 | { | ||
608 | efi_runtime_services_t *runtime; | ||
529 | 609 | ||
530 | /* | 610 | /* |
531 | * Check out the runtime services table. We need to map | 611 | * Check out the runtime services table. We need to map |
@@ -535,43 +615,116 @@ void __init efi_init(void) | |||
535 | */ | 615 | */ |
536 | runtime = early_ioremap((unsigned long)efi.systab->runtime, | 616 | runtime = early_ioremap((unsigned long)efi.systab->runtime, |
537 | sizeof(efi_runtime_services_t)); | 617 | sizeof(efi_runtime_services_t)); |
538 | if (runtime != NULL) { | 618 | if (!runtime) { |
539 | /* | 619 | pr_err("Could not map the runtime service table!\n"); |
540 | * We will only need *early* access to the following | 620 | return -ENOMEM; |
541 | * two EFI runtime services before set_virtual_address_map | 621 | } |
542 | * is invoked. | 622 | /* |
543 | */ | 623 | * We will only need *early* access to the following |
544 | efi_phys.get_time = (efi_get_time_t *)runtime->get_time; | 624 | * two EFI runtime services before set_virtual_address_map |
545 | efi_phys.set_virtual_address_map = | 625 | * is invoked. |
546 | (efi_set_virtual_address_map_t *) | 626 | */ |
547 | runtime->set_virtual_address_map; | 627 | efi_phys.get_time = (efi_get_time_t *)runtime->get_time; |
548 | /* | 628 | efi_phys.set_virtual_address_map = |
549 | * Make efi_get_time can be called before entering | 629 | (efi_set_virtual_address_map_t *) |
550 | * virtual mode. | 630 | runtime->set_virtual_address_map; |
551 | */ | 631 | /* |
552 | efi.get_time = phys_efi_get_time; | 632 | * Make efi_get_time can be called before entering |
553 | } else | 633 | * virtual mode. |
554 | printk(KERN_ERR "Could not map the EFI runtime service " | 634 | */ |
555 | "table!\n"); | 635 | efi.get_time = phys_efi_get_time; |
556 | early_iounmap(runtime, sizeof(efi_runtime_services_t)); | 636 | early_iounmap(runtime, sizeof(efi_runtime_services_t)); |
557 | 637 | ||
638 | return 0; | ||
639 | } | ||
640 | |||
641 | static int __init efi_memmap_init(void) | ||
642 | { | ||
558 | /* Map the EFI memory map */ | 643 | /* Map the EFI memory map */ |
559 | memmap.map = early_ioremap((unsigned long)memmap.phys_map, | 644 | memmap.map = early_ioremap((unsigned long)memmap.phys_map, |
560 | memmap.nr_map * memmap.desc_size); | 645 | memmap.nr_map * memmap.desc_size); |
561 | if (memmap.map == NULL) | 646 | if (memmap.map == NULL) { |
562 | printk(KERN_ERR "Could not map the EFI memory map!\n"); | 647 | pr_err("Could not map the memory map!\n"); |
648 | return -ENOMEM; | ||
649 | } | ||
563 | memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size); | 650 | memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size); |
564 | 651 | ||
565 | if (memmap.desc_size != sizeof(efi_memory_desc_t)) | ||
566 | printk(KERN_WARNING | ||
567 | "Kernel-defined memdesc doesn't match the one from EFI!\n"); | ||
568 | |||
569 | if (add_efi_memmap) | 652 | if (add_efi_memmap) |
570 | do_add_efi_memmap(); | 653 | do_add_efi_memmap(); |
571 | 654 | ||
655 | return 0; | ||
656 | } | ||
657 | |||
658 | void __init efi_init(void) | ||
659 | { | ||
660 | efi_char16_t *c16; | ||
661 | char vendor[100] = "unknown"; | ||
662 | int i = 0; | ||
663 | void *tmp; | ||
664 | |||
665 | #ifdef CONFIG_X86_32 | ||
666 | if (boot_params.efi_info.efi_systab_hi || | ||
667 | boot_params.efi_info.efi_memmap_hi) { | ||
668 | pr_info("Table located above 4GB, disabling EFI.\n"); | ||
669 | efi_enabled = 0; | ||
670 | return; | ||
671 | } | ||
672 | efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab; | ||
673 | efi_native = !efi_64bit; | ||
674 | #else | ||
675 | efi_phys.systab = (efi_system_table_t *) | ||
676 | (boot_params.efi_info.efi_systab | | ||
677 | ((__u64)boot_params.efi_info.efi_systab_hi<<32)); | ||
678 | efi_native = efi_64bit; | ||
679 | #endif | ||
680 | |||
681 | if (efi_systab_init(efi_phys.systab)) { | ||
682 | efi_enabled = 0; | ||
683 | return; | ||
684 | } | ||
685 | |||
686 | /* | ||
687 | * Show what we know for posterity | ||
688 | */ | ||
689 | c16 = tmp = early_ioremap(efi.systab->fw_vendor, 2); | ||
690 | if (c16) { | ||
691 | for (i = 0; i < sizeof(vendor) - 1 && *c16; ++i) | ||
692 | vendor[i] = *c16++; | ||
693 | vendor[i] = '\0'; | ||
694 | } else | ||
695 | pr_err("Could not map the firmware vendor!\n"); | ||
696 | early_iounmap(tmp, 2); | ||
697 | |||
698 | pr_info("EFI v%u.%.02u by %s\n", | ||
699 | efi.systab->hdr.revision >> 16, | ||
700 | efi.systab->hdr.revision & 0xffff, vendor); | ||
701 | |||
702 | if (efi_config_init(efi.systab->tables, efi.systab->nr_tables)) { | ||
703 | efi_enabled = 0; | ||
704 | return; | ||
705 | } | ||
706 | |||
707 | /* | ||
708 | * Note: We currently don't support runtime services on an EFI | ||
709 | * that doesn't match the kernel 32/64-bit mode. | ||
710 | */ | ||
711 | |||
712 | if (!efi_native) | ||
713 | pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); | ||
714 | else if (efi_runtime_init()) { | ||
715 | efi_enabled = 0; | ||
716 | return; | ||
717 | } | ||
718 | |||
719 | if (efi_memmap_init()) { | ||
720 | efi_enabled = 0; | ||
721 | return; | ||
722 | } | ||
572 | #ifdef CONFIG_X86_32 | 723 | #ifdef CONFIG_X86_32 |
573 | x86_platform.get_wallclock = efi_get_time; | 724 | if (efi_native) { |
574 | x86_platform.set_wallclock = efi_set_rtc_mmss; | 725 | x86_platform.get_wallclock = efi_get_time; |
726 | x86_platform.set_wallclock = efi_set_rtc_mmss; | ||
727 | } | ||
575 | #endif | 728 | #endif |
576 | 729 | ||
577 | #if EFI_DEBUG | 730 | #if EFI_DEBUG |
@@ -629,6 +782,14 @@ void __init efi_enter_virtual_mode(void) | |||
629 | 782 | ||
630 | efi.systab = NULL; | 783 | efi.systab = NULL; |
631 | 784 | ||
785 | /* | ||
786 | * We don't do virtual mode, since we don't do runtime services, on | ||
787 | * non-native EFI | ||
788 | */ | ||
789 | |||
790 | if (!efi_native) | ||
791 | goto out; | ||
792 | |||
632 | /* Merge contiguous regions of the same type and attribute */ | 793 | /* Merge contiguous regions of the same type and attribute */ |
633 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | 794 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
634 | u64 prev_size; | 795 | u64 prev_size; |
@@ -677,7 +838,7 @@ void __init efi_enter_virtual_mode(void) | |||
677 | md->virt_addr = (u64) (unsigned long) va; | 838 | md->virt_addr = (u64) (unsigned long) va; |
678 | 839 | ||
679 | if (!va) { | 840 | if (!va) { |
680 | printk(KERN_ERR PFX "ioremap of 0x%llX failed!\n", | 841 | pr_err("ioremap of 0x%llX failed!\n", |
681 | (unsigned long long)md->phys_addr); | 842 | (unsigned long long)md->phys_addr); |
682 | continue; | 843 | continue; |
683 | } | 844 | } |
@@ -711,8 +872,8 @@ void __init efi_enter_virtual_mode(void) | |||
711 | (efi_memory_desc_t *)__pa(new_memmap)); | 872 | (efi_memory_desc_t *)__pa(new_memmap)); |
712 | 873 | ||
713 | if (status != EFI_SUCCESS) { | 874 | if (status != EFI_SUCCESS) { |
714 | printk(KERN_ALERT "Unable to switch EFI into virtual mode " | 875 | pr_alert("Unable to switch EFI into virtual mode " |
715 | "(status=%lx)!\n", status); | 876 | "(status=%lx)!\n", status); |
716 | panic("EFI call to SetVirtualAddressMap() failed!"); | 877 | panic("EFI call to SetVirtualAddressMap() failed!"); |
717 | } | 878 | } |
718 | 879 | ||
@@ -744,6 +905,8 @@ void __init efi_enter_virtual_mode(void) | |||
744 | efi.query_capsule_caps = virt_efi_query_capsule_caps; | 905 | efi.query_capsule_caps = virt_efi_query_capsule_caps; |
745 | if (__supported_pte_mask & _PAGE_NX) | 906 | if (__supported_pte_mask & _PAGE_NX) |
746 | runtime_code_page_mkexec(); | 907 | runtime_code_page_mkexec(); |
908 | |||
909 | out: | ||
747 | early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); | 910 | early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); |
748 | memmap.map = NULL; | 911 | memmap.map = NULL; |
749 | kfree(new_memmap); | 912 | kfree(new_memmap); |