diff options
author | Ingo Molnar <mingo@kernel.org> | 2012-04-14 07:18:27 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-04-14 07:19:04 -0400 |
commit | 6ac1ef482d7ae0c690f1640bf6eb818ff9a2d91e (patch) | |
tree | 021cc9f6b477146fcebe6f3be4752abfa2ba18a9 /arch/x86/platform/efi | |
parent | 682968e0c425c60f0dde37977e5beb2b12ddc4cc (diff) | |
parent | a385ec4f11bdcf81af094c03e2444ee9b7fad2e5 (diff) |
Merge branch 'perf/core' into perf/uprobes
Merge in latest upstream (and the latest perf development tree),
to prepare for tooling changes, and also to pick up v3.4 MM
changes that the uprobes code needs to take care of.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/platform/efi')
-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); |