diff options
Diffstat (limited to 'arch/ia64/kernel/efi.c')
-rw-r--r-- | arch/ia64/kernel/efi.c | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 9990320b6f9a..12cfedce73b1 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c | |||
@@ -458,24 +458,33 @@ efi_init (void) | |||
458 | printk(KERN_INFO "EFI v%u.%.02u by %s:", | 458 | printk(KERN_INFO "EFI v%u.%.02u by %s:", |
459 | efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, vendor); | 459 | efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, vendor); |
460 | 460 | ||
461 | efi.mps = EFI_INVALID_TABLE_ADDR; | ||
462 | efi.acpi = EFI_INVALID_TABLE_ADDR; | ||
463 | efi.acpi20 = EFI_INVALID_TABLE_ADDR; | ||
464 | efi.smbios = EFI_INVALID_TABLE_ADDR; | ||
465 | efi.sal_systab = EFI_INVALID_TABLE_ADDR; | ||
466 | efi.boot_info = EFI_INVALID_TABLE_ADDR; | ||
467 | efi.hcdp = EFI_INVALID_TABLE_ADDR; | ||
468 | efi.uga = EFI_INVALID_TABLE_ADDR; | ||
469 | |||
461 | for (i = 0; i < (int) efi.systab->nr_tables; i++) { | 470 | for (i = 0; i < (int) efi.systab->nr_tables; i++) { |
462 | if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) { | 471 | if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) { |
463 | efi.mps = __va(config_tables[i].table); | 472 | efi.mps = config_tables[i].table; |
464 | printk(" MPS=0x%lx", config_tables[i].table); | 473 | printk(" MPS=0x%lx", config_tables[i].table); |
465 | } else if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) { | 474 | } else if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) { |
466 | efi.acpi20 = __va(config_tables[i].table); | 475 | efi.acpi20 = config_tables[i].table; |
467 | printk(" ACPI 2.0=0x%lx", config_tables[i].table); | 476 | printk(" ACPI 2.0=0x%lx", config_tables[i].table); |
468 | } else if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) { | 477 | } else if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) { |
469 | efi.acpi = __va(config_tables[i].table); | 478 | efi.acpi = config_tables[i].table; |
470 | printk(" ACPI=0x%lx", config_tables[i].table); | 479 | printk(" ACPI=0x%lx", config_tables[i].table); |
471 | } else if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) { | 480 | } else if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) { |
472 | efi.smbios = __va(config_tables[i].table); | 481 | efi.smbios = config_tables[i].table; |
473 | printk(" SMBIOS=0x%lx", config_tables[i].table); | 482 | printk(" SMBIOS=0x%lx", config_tables[i].table); |
474 | } else if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) == 0) { | 483 | } else if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) == 0) { |
475 | efi.sal_systab = __va(config_tables[i].table); | 484 | efi.sal_systab = config_tables[i].table; |
476 | printk(" SALsystab=0x%lx", config_tables[i].table); | 485 | printk(" SALsystab=0x%lx", config_tables[i].table); |
477 | } else if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) { | 486 | } else if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) { |
478 | efi.hcdp = __va(config_tables[i].table); | 487 | efi.hcdp = config_tables[i].table; |
479 | printk(" HCDP=0x%lx", config_tables[i].table); | 488 | printk(" HCDP=0x%lx", config_tables[i].table); |
480 | } | 489 | } |
481 | } | 490 | } |
@@ -677,27 +686,34 @@ EXPORT_SYMBOL(efi_mem_attributes); | |||
677 | /* | 686 | /* |
678 | * Determines whether the memory at phys_addr supports the desired | 687 | * Determines whether the memory at phys_addr supports the desired |
679 | * attribute (WB, UC, etc). If this returns 1, the caller can safely | 688 | * attribute (WB, UC, etc). If this returns 1, the caller can safely |
680 | * access *size bytes at phys_addr with the specified attribute. | 689 | * access size bytes at phys_addr with the specified attribute. |
681 | */ | 690 | */ |
682 | static int | 691 | int |
683 | efi_mem_attribute_range (unsigned long phys_addr, unsigned long *size, u64 attr) | 692 | efi_mem_attribute_range (unsigned long phys_addr, unsigned long size, u64 attr) |
684 | { | 693 | { |
694 | unsigned long end = phys_addr + size; | ||
685 | efi_memory_desc_t *md = efi_memory_descriptor(phys_addr); | 695 | efi_memory_desc_t *md = efi_memory_descriptor(phys_addr); |
686 | unsigned long md_end; | ||
687 | 696 | ||
688 | if (!md || (md->attribute & attr) != attr) | 697 | /* |
698 | * Some firmware doesn't report MMIO regions in the EFI memory | ||
699 | * map. The Intel BigSur (a.k.a. HP i2000) has this problem. | ||
700 | * On those platforms, we have to assume UC is valid everywhere. | ||
701 | */ | ||
702 | if (!md || (md->attribute & attr) != attr) { | ||
703 | if (attr == EFI_MEMORY_UC && !efi_memmap_has_mmio()) | ||
704 | return 1; | ||
689 | return 0; | 705 | return 0; |
706 | } | ||
690 | 707 | ||
691 | do { | 708 | do { |
692 | md_end = efi_md_end(md); | 709 | unsigned long md_end = efi_md_end(md); |
693 | if (phys_addr + *size <= md_end) | 710 | |
711 | if (end <= md_end) | ||
694 | return 1; | 712 | return 1; |
695 | 713 | ||
696 | md = efi_memory_descriptor(md_end); | 714 | md = efi_memory_descriptor(md_end); |
697 | if (!md || (md->attribute & attr) != attr) { | 715 | if (!md || (md->attribute & attr) != attr) |
698 | *size = md_end - phys_addr; | 716 | return 0; |
699 | return 1; | ||
700 | } | ||
701 | } while (md); | 717 | } while (md); |
702 | return 0; | 718 | return 0; |
703 | } | 719 | } |
@@ -708,7 +724,7 @@ efi_mem_attribute_range (unsigned long phys_addr, unsigned long *size, u64 attr) | |||
708 | * control access size. | 724 | * control access size. |
709 | */ | 725 | */ |
710 | int | 726 | int |
711 | valid_phys_addr_range (unsigned long phys_addr, unsigned long *size) | 727 | valid_phys_addr_range (unsigned long phys_addr, unsigned long size) |
712 | { | 728 | { |
713 | return efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_WB); | 729 | return efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_WB); |
714 | } | 730 | } |
@@ -723,7 +739,7 @@ valid_phys_addr_range (unsigned long phys_addr, unsigned long *size) | |||
723 | * because that doesn't appear in the boot-time EFI memory map. | 739 | * because that doesn't appear in the boot-time EFI memory map. |
724 | */ | 740 | */ |
725 | int | 741 | int |
726 | valid_mmap_phys_addr_range (unsigned long phys_addr, unsigned long *size) | 742 | valid_mmap_phys_addr_range (unsigned long phys_addr, unsigned long size) |
727 | { | 743 | { |
728 | if (efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_WB)) | 744 | if (efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_WB)) |
729 | return 1; | 745 | return 1; |
@@ -731,14 +747,6 @@ valid_mmap_phys_addr_range (unsigned long phys_addr, unsigned long *size) | |||
731 | if (efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_UC)) | 747 | if (efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_UC)) |
732 | return 1; | 748 | return 1; |
733 | 749 | ||
734 | /* | ||
735 | * Some firmware doesn't report MMIO regions in the EFI memory map. | ||
736 | * The Intel BigSur (a.k.a. HP i2000) has this problem. In this | ||
737 | * case, we can't use the EFI memory map to validate mmap requests. | ||
738 | */ | ||
739 | if (!efi_memmap_has_mmio()) | ||
740 | return 1; | ||
741 | |||
742 | return 0; | 750 | return 0; |
743 | } | 751 | } |
744 | 752 | ||