aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/efi.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/kernel/efi.c')
-rw-r--r--arch/ia64/kernel/efi.c62
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 */
682static int 691int
683efi_mem_attribute_range (unsigned long phys_addr, unsigned long *size, u64 attr) 692efi_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 */
710int 726int
711valid_phys_addr_range (unsigned long phys_addr, unsigned long *size) 727valid_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 */
725int 741int
726valid_mmap_phys_addr_range (unsigned long phys_addr, unsigned long *size) 742valid_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