efi/x86: Move UEFI Runtime Services wrappers to generic code
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Thu, 26 Jun 2014 10:09:05 +0000 (12:09 +0200)
committerMatt Fleming <matt.fleming@intel.com>
Mon, 7 Jul 2014 19:12:53 +0000 (20:12 +0100)
In order for other archs (such as arm64) to be able to reuse the virtual
mode function call wrappers, move them to drivers/firmware/efi/runtime-wrappers.c.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
arch/x86/Kconfig
arch/x86/platform/efi/efi.c
drivers/firmware/efi/Kconfig
drivers/firmware/efi/Makefile
drivers/firmware/efi/runtime-wrappers.c [new file with mode: 0644]
include/linux/efi.h

index fcefdda..801ed36 100644 (file)
@@ -1522,6 +1522,7 @@ config EFI
        bool "EFI runtime service support"
        depends on ACPI
        select UCS2_STRING
+       select EFI_RUNTIME_WRAPPERS
        ---help---
          This enables the kernel to use EFI runtime services that are
          available (such as the EFI variable services).
index f852443..135812b 100644 (file)
@@ -88,130 +88,6 @@ static int __init setup_add_efi_memmap(char *arg)
 }
 early_param("add_efi_memmap", setup_add_efi_memmap);
 
-static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
-{
-       unsigned long flags;
-       efi_status_t status;
-
-       spin_lock_irqsave(&rtc_lock, flags);
-       status = efi_call_virt(get_time, tm, tc);
-       spin_unlock_irqrestore(&rtc_lock, flags);
-       return status;
-}
-
-static efi_status_t virt_efi_set_time(efi_time_t *tm)
-{
-       unsigned long flags;
-       efi_status_t status;
-
-       spin_lock_irqsave(&rtc_lock, flags);
-       status = efi_call_virt(set_time, tm);
-       spin_unlock_irqrestore(&rtc_lock, flags);
-       return status;
-}
-
-static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
-                                            efi_bool_t *pending,
-                                            efi_time_t *tm)
-{
-       unsigned long flags;
-       efi_status_t status;
-
-       spin_lock_irqsave(&rtc_lock, flags);
-       status = efi_call_virt(get_wakeup_time, enabled, pending, tm);
-       spin_unlock_irqrestore(&rtc_lock, flags);
-       return status;
-}
-
-static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
-{
-       unsigned long flags;
-       efi_status_t status;
-
-       spin_lock_irqsave(&rtc_lock, flags);
-       status = efi_call_virt(set_wakeup_time, enabled, tm);
-       spin_unlock_irqrestore(&rtc_lock, flags);
-       return status;
-}
-
-static efi_status_t virt_efi_get_variable(efi_char16_t *name,
-                                         efi_guid_t *vendor,
-                                         u32 *attr,
-                                         unsigned long *data_size,
-                                         void *data)
-{
-       return efi_call_virt(get_variable,
-                            name, vendor, attr,
-                            data_size, data);
-}
-
-static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
-                                              efi_char16_t *name,
-                                              efi_guid_t *vendor)
-{
-       return efi_call_virt(get_next_variable,
-                            name_size, name, vendor);
-}
-
-static efi_status_t virt_efi_set_variable(efi_char16_t *name,
-                                         efi_guid_t *vendor,
-                                         u32 attr,
-                                         unsigned long data_size,
-                                         void *data)
-{
-       return efi_call_virt(set_variable,
-                            name, vendor, attr,
-                            data_size, data);
-}
-
-static efi_status_t virt_efi_query_variable_info(u32 attr,
-                                                u64 *storage_space,
-                                                u64 *remaining_space,
-                                                u64 *max_variable_size)
-{
-       if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
-               return EFI_UNSUPPORTED;
-
-       return efi_call_virt(query_variable_info, attr, storage_space,
-                            remaining_space, max_variable_size);
-}
-
-static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
-{
-       return efi_call_virt(get_next_high_mono_count, count);
-}
-
-static void virt_efi_reset_system(int reset_type,
-                                 efi_status_t status,
-                                 unsigned long data_size,
-                                 efi_char16_t *data)
-{
-       __efi_call_virt(reset_system, reset_type, status,
-                       data_size, data);
-}
-
-static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
-                                           unsigned long count,
-                                           unsigned long sg_list)
-{
-       if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
-               return EFI_UNSUPPORTED;
-
-       return efi_call_virt(update_capsule, capsules, count, sg_list);
-}
-
-static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
-                                               unsigned long count,
-                                               u64 *max_size,
-                                               int *reset_type)
-{
-       if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
-               return EFI_UNSUPPORTED;
-
-       return efi_call_virt(query_capsule_caps, capsules, count, max_size,
-                            reset_type);
-}
-
 static efi_status_t __init phys_efi_set_virtual_address_map(
        unsigned long memory_map_size,
        unsigned long descriptor_size,
@@ -721,22 +597,6 @@ void __init old_map_region(efi_memory_desc_t *md)
                       (unsigned long long)md->phys_addr);
 }
 
-static void native_runtime_setup(void)
-{
-       efi.get_time = virt_efi_get_time;
-       efi.set_time = virt_efi_set_time;
-       efi.get_wakeup_time = virt_efi_get_wakeup_time;
-       efi.set_wakeup_time = virt_efi_set_wakeup_time;
-       efi.get_variable = virt_efi_get_variable;
-       efi.get_next_variable = virt_efi_get_next_variable;
-       efi.set_variable = virt_efi_set_variable;
-       efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
-       efi.reset_system = virt_efi_reset_system;
-       efi.query_variable_info = virt_efi_query_variable_info;
-       efi.update_capsule = virt_efi_update_capsule;
-       efi.query_capsule_caps = virt_efi_query_capsule_caps;
-}
-
 /* Merge contiguous regions of the same type and attribute */
 static void __init efi_merge_regions(void)
 {
@@ -923,7 +783,7 @@ static void __init kexec_enter_virtual_mode(void)
         */
        efi.runtime_version = efi_systab.hdr.revision;
 
-       native_runtime_setup();
+       efi_native_runtime_setup();
 
        efi.set_virtual_address_map = NULL;
 
@@ -1012,7 +872,7 @@ static void __init __efi_enter_virtual_mode(void)
        efi.runtime_version = efi_systab.hdr.revision;
 
        if (efi_is_native())
-               native_runtime_setup();
+               efi_native_runtime_setup();
        else
                efi_thunk_runtime_setup();
 
index d420ae2..588dc47 100644 (file)
@@ -54,6 +54,9 @@ config EFI_PARAMS_FROM_FDT
          the EFI runtime support gets system table address, memory
           map address, and other parameters from the device tree.
 
+config EFI_RUNTIME_WRAPPERS
+       bool
+
 endmenu
 
 config UEFI_CPER
index 9553496..e109653 100644 (file)
@@ -6,3 +6,4 @@ obj-$(CONFIG_EFI_VARS)                  += efivars.o
 obj-$(CONFIG_EFI_VARS_PSTORE)          += efi-pstore.o
 obj-$(CONFIG_UEFI_CPER)                        += cper.o
 obj-$(CONFIG_EFI_RUNTIME_MAP)          += runtime-map.o
+obj-$(CONFIG_EFI_RUNTIME_WRAPPERS)     += runtime-wrappers.o
diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c
new file mode 100644 (file)
index 0000000..10daa4b
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * runtime-wrappers.c - Runtime Services function call wrappers
+ *
+ * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ *
+ * Split off from arch/x86/platform/efi/efi.c
+ *
+ * Copyright (C) 1999 VA Linux Systems
+ * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
+ * Copyright (C) 1999-2002 Hewlett-Packard Co.
+ * Copyright (C) 2005-2008 Intel Co.
+ * Copyright (C) 2013 SuSE Labs
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/efi.h>
+#include <linux/spinlock.h>             /* spinlock_t */
+#include <asm/efi.h>
+
+/*
+ * As per commit ef68c8f87ed1 ("x86: Serialize EFI time accesses on rtc_lock"),
+ * the EFI specification requires that callers of the time related runtime
+ * functions serialize with other CMOS accesses in the kernel, as the EFI time
+ * functions may choose to also use the legacy CMOS RTC.
+ */
+__weak DEFINE_SPINLOCK(rtc_lock);
+
+static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
+{
+       unsigned long flags;
+       efi_status_t status;
+
+       spin_lock_irqsave(&rtc_lock, flags);
+       status = efi_call_virt(get_time, tm, tc);
+       spin_unlock_irqrestore(&rtc_lock, flags);
+       return status;
+}
+
+static efi_status_t virt_efi_set_time(efi_time_t *tm)
+{
+       unsigned long flags;
+       efi_status_t status;
+
+       spin_lock_irqsave(&rtc_lock, flags);
+       status = efi_call_virt(set_time, tm);
+       spin_unlock_irqrestore(&rtc_lock, flags);
+       return status;
+}
+
+static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
+                                            efi_bool_t *pending,
+                                            efi_time_t *tm)
+{
+       unsigned long flags;
+       efi_status_t status;
+
+       spin_lock_irqsave(&rtc_lock, flags);
+       status = efi_call_virt(get_wakeup_time, enabled, pending, tm);
+       spin_unlock_irqrestore(&rtc_lock, flags);
+       return status;
+}
+
+static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
+{
+       unsigned long flags;
+       efi_status_t status;
+
+       spin_lock_irqsave(&rtc_lock, flags);
+       status = efi_call_virt(set_wakeup_time, enabled, tm);
+       spin_unlock_irqrestore(&rtc_lock, flags);
+       return status;
+}
+
+static efi_status_t virt_efi_get_variable(efi_char16_t *name,
+                                         efi_guid_t *vendor,
+                                         u32 *attr,
+                                         unsigned long *data_size,
+                                         void *data)
+{
+       return efi_call_virt(get_variable, name, vendor, attr, data_size, data);
+}
+
+static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
+                                              efi_char16_t *name,
+                                              efi_guid_t *vendor)
+{
+       return efi_call_virt(get_next_variable, name_size, name, vendor);
+}
+
+static efi_status_t virt_efi_set_variable(efi_char16_t *name,
+                                         efi_guid_t *vendor,
+                                         u32 attr,
+                                         unsigned long data_size,
+                                         void *data)
+{
+       return efi_call_virt(set_variable, name, vendor, attr, data_size, data);
+}
+
+static efi_status_t virt_efi_query_variable_info(u32 attr,
+                                                u64 *storage_space,
+                                                u64 *remaining_space,
+                                                u64 *max_variable_size)
+{
+       if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+               return EFI_UNSUPPORTED;
+
+       return efi_call_virt(query_variable_info, attr, storage_space,
+                            remaining_space, max_variable_size);
+}
+
+static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
+{
+       return efi_call_virt(get_next_high_mono_count, count);
+}
+
+static void virt_efi_reset_system(int reset_type,
+                                 efi_status_t status,
+                                 unsigned long data_size,
+                                 efi_char16_t *data)
+{
+       __efi_call_virt(reset_system, reset_type, status, data_size, data);
+}
+
+static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
+                                           unsigned long count,
+                                           unsigned long sg_list)
+{
+       if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+               return EFI_UNSUPPORTED;
+
+       return efi_call_virt(update_capsule, capsules, count, sg_list);
+}
+
+static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
+                                               unsigned long count,
+                                               u64 *max_size,
+                                               int *reset_type)
+{
+       if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+               return EFI_UNSUPPORTED;
+
+       return efi_call_virt(query_capsule_caps, capsules, count, max_size,
+                            reset_type);
+}
+
+void efi_native_runtime_setup(void)
+{
+       efi.get_time = virt_efi_get_time;
+       efi.set_time = virt_efi_set_time;
+       efi.get_wakeup_time = virt_efi_get_wakeup_time;
+       efi.set_wakeup_time = virt_efi_set_wakeup_time;
+       efi.get_variable = virt_efi_get_variable;
+       efi.get_next_variable = virt_efi_get_next_variable;
+       efi.set_variable = virt_efi_set_variable;
+       efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
+       efi.reset_system = virt_efi_reset_system;
+       efi.query_variable_info = virt_efi_query_variable_info;
+       efi.update_capsule = virt_efi_update_capsule;
+       efi.query_capsule_caps = virt_efi_query_capsule_caps;
+}
index 41bbf8b..0ceb816 100644 (file)
@@ -521,6 +521,8 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules,
                                              int *reset_type);
 typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long size);
 
+void efi_native_runtime_setup(void);
+
 /*
  *  EFI Configuration Table and GUID definitions
  */