Merge branch 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[~shefty/rdma-dev.git] / arch / x86 / platform / efi / efi.c
index 35682489f6d6672025b349d5c0126a3a0611d719..77cf0090c0a3ef7890ea24d4e5e47d1d68e0b024 100644 (file)
@@ -51,9 +51,6 @@
 
 #define EFI_DEBUG      1
 
-int efi_enabled;
-EXPORT_SYMBOL(efi_enabled);
-
 struct efi __read_mostly efi = {
        .mps        = EFI_INVALID_TABLE_ADDR,
        .acpi       = EFI_INVALID_TABLE_ADDR,
@@ -69,19 +66,28 @@ EXPORT_SYMBOL(efi);
 
 struct efi_memory_map memmap;
 
-bool efi_64bit;
-
 static struct efi efi_phys __initdata;
 static efi_system_table_t efi_systab __initdata;
 
 static inline bool efi_is_native(void)
 {
-       return IS_ENABLED(CONFIG_X86_64) == efi_64bit;
+       return IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT);
+}
+
+unsigned long x86_efi_facility;
+
+/*
+ * Returns 1 if 'facility' is enabled, 0 otherwise.
+ */
+int efi_enabled(int facility)
+{
+       return test_bit(facility, &x86_efi_facility) != 0;
 }
+EXPORT_SYMBOL(efi_enabled);
 
 static int __init setup_noefi(char *arg)
 {
-       efi_enabled = 0;
+       clear_bit(EFI_BOOT, &x86_efi_facility);
        return 0;
 }
 early_param("noefi", setup_noefi);
@@ -426,6 +432,7 @@ void __init efi_reserve_boot_services(void)
 
 void __init efi_unmap_memmap(void)
 {
+       clear_bit(EFI_MEMMAP, &x86_efi_facility);
        if (memmap.map) {
                early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
                memmap.map = NULL;
@@ -460,7 +467,7 @@ void __init efi_free_boot_services(void)
 
 static int __init efi_systab_init(void *phys)
 {
-       if (efi_64bit) {
+       if (efi_enabled(EFI_64BIT)) {
                efi_system_table_64_t *systab64;
                u64 tmp = 0;
 
@@ -552,7 +559,7 @@ static int __init efi_config_init(u64 tables, int nr_tables)
        void *config_tables, *tablep;
        int i, sz;
 
-       if (efi_64bit)
+       if (efi_enabled(EFI_64BIT))
                sz = sizeof(efi_config_table_64_t);
        else
                sz = sizeof(efi_config_table_32_t);
@@ -572,7 +579,7 @@ static int __init efi_config_init(u64 tables, int nr_tables)
                efi_guid_t guid;
                unsigned long table;
 
-               if (efi_64bit) {
+               if (efi_enabled(EFI_64BIT)) {
                        u64 table64;
                        guid = ((efi_config_table_64_t *)tablep)->guid;
                        table64 = ((efi_config_table_64_t *)tablep)->table;
@@ -684,7 +691,6 @@ void __init efi_init(void)
        if (boot_params.efi_info.efi_systab_hi ||
            boot_params.efi_info.efi_memmap_hi) {
                pr_info("Table located above 4GB, disabling EFI.\n");
-               efi_enabled = 0;
                return;
        }
        efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab;
@@ -694,10 +700,10 @@ void __init efi_init(void)
                          ((__u64)boot_params.efi_info.efi_systab_hi<<32));
 #endif
 
-       if (efi_systab_init(efi_phys.systab)) {
-               efi_enabled = 0;
+       if (efi_systab_init(efi_phys.systab))
                return;
-       }
+
+       set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility);
 
        /*
         * Show what we know for posterity
@@ -715,10 +721,10 @@ void __init efi_init(void)
                efi.systab->hdr.revision >> 16,
                efi.systab->hdr.revision & 0xffff, vendor);
 
-       if (efi_config_init(efi.systab->tables, efi.systab->nr_tables)) {
-               efi_enabled = 0;
+       if (efi_config_init(efi.systab->tables, efi.systab->nr_tables))
                return;
-       }
+
+       set_bit(EFI_CONFIG_TABLES, &x86_efi_facility);
 
        /*
         * Note: We currently don't support runtime services on an EFI
@@ -727,15 +733,17 @@ void __init efi_init(void)
 
        if (!efi_is_native())
                pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n");
-       else if (efi_runtime_init()) {
-               efi_enabled = 0;
-               return;
+       else {
+               if (efi_runtime_init())
+                       return;
+               set_bit(EFI_RUNTIME_SERVICES, &x86_efi_facility);
        }
 
-       if (efi_memmap_init()) {
-               efi_enabled = 0;
+       if (efi_memmap_init())
                return;
-       }
+
+       set_bit(EFI_MEMMAP, &x86_efi_facility);
+
 #ifdef CONFIG_X86_32
        if (efi_is_native()) {
                x86_platform.get_wallclock = efi_get_time;
@@ -969,6 +977,9 @@ u32 efi_mem_type(unsigned long phys_addr)
        efi_memory_desc_t *md;
        void *p;
 
+       if (!efi_enabled(EFI_MEMMAP))
+               return 0;
+
        for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
                md = p;
                if ((md->phys_addr <= phys_addr) &&