aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/Kconfig1
-rw-r--r--arch/x86/platform/efi/efi.c144
-rw-r--r--drivers/firmware/efi/Kconfig3
-rw-r--r--drivers/firmware/efi/Makefile1
-rw-r--r--drivers/firmware/efi/runtime-wrappers.c161
-rw-r--r--include/linux/efi.h2
6 files changed, 170 insertions, 142 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index fcefdda5136d..801ed36c2e49 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1522,6 +1522,7 @@ config EFI
1522 bool "EFI runtime service support" 1522 bool "EFI runtime service support"
1523 depends on ACPI 1523 depends on ACPI
1524 select UCS2_STRING 1524 select UCS2_STRING
1525 select EFI_RUNTIME_WRAPPERS
1525 ---help--- 1526 ---help---
1526 This enables the kernel to use EFI runtime services that are 1527 This enables the kernel to use EFI runtime services that are
1527 available (such as the EFI variable services). 1528 available (such as the EFI variable services).
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index f8524434bf65..135812b593cc 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -88,130 +88,6 @@ static int __init setup_add_efi_memmap(char *arg)
88} 88}
89early_param("add_efi_memmap", setup_add_efi_memmap); 89early_param("add_efi_memmap", setup_add_efi_memmap);
90 90
91static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
92{
93 unsigned long flags;
94 efi_status_t status;
95
96 spin_lock_irqsave(&rtc_lock, flags);
97 status = efi_call_virt(get_time, tm, tc);
98 spin_unlock_irqrestore(&rtc_lock, flags);
99 return status;
100}
101
102static efi_status_t virt_efi_set_time(efi_time_t *tm)
103{
104 unsigned long flags;
105 efi_status_t status;
106
107 spin_lock_irqsave(&rtc_lock, flags);
108 status = efi_call_virt(set_time, tm);
109 spin_unlock_irqrestore(&rtc_lock, flags);
110 return status;
111}
112
113static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
114 efi_bool_t *pending,
115 efi_time_t *tm)
116{
117 unsigned long flags;
118 efi_status_t status;
119
120 spin_lock_irqsave(&rtc_lock, flags);
121 status = efi_call_virt(get_wakeup_time, enabled, pending, tm);
122 spin_unlock_irqrestore(&rtc_lock, flags);
123 return status;
124}
125
126static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
127{
128 unsigned long flags;
129 efi_status_t status;
130
131 spin_lock_irqsave(&rtc_lock, flags);
132 status = efi_call_virt(set_wakeup_time, enabled, tm);
133 spin_unlock_irqrestore(&rtc_lock, flags);
134 return status;
135}
136
137static efi_status_t virt_efi_get_variable(efi_char16_t *name,
138 efi_guid_t *vendor,
139 u32 *attr,
140 unsigned long *data_size,
141 void *data)
142{
143 return efi_call_virt(get_variable,
144 name, vendor, attr,
145 data_size, data);
146}
147
148static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
149 efi_char16_t *name,
150 efi_guid_t *vendor)
151{
152 return efi_call_virt(get_next_variable,
153 name_size, name, vendor);
154}
155
156static efi_status_t virt_efi_set_variable(efi_char16_t *name,
157 efi_guid_t *vendor,
158 u32 attr,
159 unsigned long data_size,
160 void *data)
161{
162 return efi_call_virt(set_variable,
163 name, vendor, attr,
164 data_size, data);
165}
166
167static efi_status_t virt_efi_query_variable_info(u32 attr,
168 u64 *storage_space,
169 u64 *remaining_space,
170 u64 *max_variable_size)
171{
172 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
173 return EFI_UNSUPPORTED;
174
175 return efi_call_virt(query_variable_info, attr, storage_space,
176 remaining_space, max_variable_size);
177}
178
179static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
180{
181 return efi_call_virt(get_next_high_mono_count, count);
182}
183
184static void virt_efi_reset_system(int reset_type,
185 efi_status_t status,
186 unsigned long data_size,
187 efi_char16_t *data)
188{
189 __efi_call_virt(reset_system, reset_type, status,
190 data_size, data);
191}
192
193static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
194 unsigned long count,
195 unsigned long sg_list)
196{
197 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
198 return EFI_UNSUPPORTED;
199
200 return efi_call_virt(update_capsule, capsules, count, sg_list);
201}
202
203static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
204 unsigned long count,
205 u64 *max_size,
206 int *reset_type)
207{
208 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
209 return EFI_UNSUPPORTED;
210
211 return efi_call_virt(query_capsule_caps, capsules, count, max_size,
212 reset_type);
213}
214
215static efi_status_t __init phys_efi_set_virtual_address_map( 91static efi_status_t __init phys_efi_set_virtual_address_map(
216 unsigned long memory_map_size, 92 unsigned long memory_map_size,
217 unsigned long descriptor_size, 93 unsigned long descriptor_size,
@@ -721,22 +597,6 @@ void __init old_map_region(efi_memory_desc_t *md)
721 (unsigned long long)md->phys_addr); 597 (unsigned long long)md->phys_addr);
722} 598}
723 599
724static void native_runtime_setup(void)
725{
726 efi.get_time = virt_efi_get_time;
727 efi.set_time = virt_efi_set_time;
728 efi.get_wakeup_time = virt_efi_get_wakeup_time;
729 efi.set_wakeup_time = virt_efi_set_wakeup_time;
730 efi.get_variable = virt_efi_get_variable;
731 efi.get_next_variable = virt_efi_get_next_variable;
732 efi.set_variable = virt_efi_set_variable;
733 efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
734 efi.reset_system = virt_efi_reset_system;
735 efi.query_variable_info = virt_efi_query_variable_info;
736 efi.update_capsule = virt_efi_update_capsule;
737 efi.query_capsule_caps = virt_efi_query_capsule_caps;
738}
739
740/* Merge contiguous regions of the same type and attribute */ 600/* Merge contiguous regions of the same type and attribute */
741static void __init efi_merge_regions(void) 601static void __init efi_merge_regions(void)
742{ 602{
@@ -923,7 +783,7 @@ static void __init kexec_enter_virtual_mode(void)
923 */ 783 */
924 efi.runtime_version = efi_systab.hdr.revision; 784 efi.runtime_version = efi_systab.hdr.revision;
925 785
926 native_runtime_setup(); 786 efi_native_runtime_setup();
927 787
928 efi.set_virtual_address_map = NULL; 788 efi.set_virtual_address_map = NULL;
929 789
@@ -1012,7 +872,7 @@ static void __init __efi_enter_virtual_mode(void)
1012 efi.runtime_version = efi_systab.hdr.revision; 872 efi.runtime_version = efi_systab.hdr.revision;
1013 873
1014 if (efi_is_native()) 874 if (efi_is_native())
1015 native_runtime_setup(); 875 efi_native_runtime_setup();
1016 else 876 else
1017 efi_thunk_runtime_setup(); 877 efi_thunk_runtime_setup();
1018 878
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index d420ae2d3413..588dc47e7075 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -54,6 +54,9 @@ config EFI_PARAMS_FROM_FDT
54 the EFI runtime support gets system table address, memory 54 the EFI runtime support gets system table address, memory
55 map address, and other parameters from the device tree. 55 map address, and other parameters from the device tree.
56 56
57config EFI_RUNTIME_WRAPPERS
58 bool
59
57endmenu 60endmenu
58 61
59config UEFI_CPER 62config UEFI_CPER
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 9553496b0f43..e1096539eedb 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_EFI_VARS) += efivars.o
6obj-$(CONFIG_EFI_VARS_PSTORE) += efi-pstore.o 6obj-$(CONFIG_EFI_VARS_PSTORE) += efi-pstore.o
7obj-$(CONFIG_UEFI_CPER) += cper.o 7obj-$(CONFIG_UEFI_CPER) += cper.o
8obj-$(CONFIG_EFI_RUNTIME_MAP) += runtime-map.o 8obj-$(CONFIG_EFI_RUNTIME_MAP) += runtime-map.o
9obj-$(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
index 000000000000..10daa4bbb258
--- /dev/null
+++ b/drivers/firmware/efi/runtime-wrappers.c
@@ -0,0 +1,161 @@
1/*
2 * runtime-wrappers.c - Runtime Services function call wrappers
3 *
4 * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
5 *
6 * Split off from arch/x86/platform/efi/efi.c
7 *
8 * Copyright (C) 1999 VA Linux Systems
9 * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
10 * Copyright (C) 1999-2002 Hewlett-Packard Co.
11 * Copyright (C) 2005-2008 Intel Co.
12 * Copyright (C) 2013 SuSE Labs
13 *
14 * This file is released under the GPLv2.
15 */
16
17#include <linux/efi.h>
18#include <linux/spinlock.h> /* spinlock_t */
19#include <asm/efi.h>
20
21/*
22 * As per commit ef68c8f87ed1 ("x86: Serialize EFI time accesses on rtc_lock"),
23 * the EFI specification requires that callers of the time related runtime
24 * functions serialize with other CMOS accesses in the kernel, as the EFI time
25 * functions may choose to also use the legacy CMOS RTC.
26 */
27__weak DEFINE_SPINLOCK(rtc_lock);
28
29static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
30{
31 unsigned long flags;
32 efi_status_t status;
33
34 spin_lock_irqsave(&rtc_lock, flags);
35 status = efi_call_virt(get_time, tm, tc);
36 spin_unlock_irqrestore(&rtc_lock, flags);
37 return status;
38}
39
40static efi_status_t virt_efi_set_time(efi_time_t *tm)
41{
42 unsigned long flags;
43 efi_status_t status;
44
45 spin_lock_irqsave(&rtc_lock, flags);
46 status = efi_call_virt(set_time, tm);
47 spin_unlock_irqrestore(&rtc_lock, flags);
48 return status;
49}
50
51static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
52 efi_bool_t *pending,
53 efi_time_t *tm)
54{
55 unsigned long flags;
56 efi_status_t status;
57
58 spin_lock_irqsave(&rtc_lock, flags);
59 status = efi_call_virt(get_wakeup_time, enabled, pending, tm);
60 spin_unlock_irqrestore(&rtc_lock, flags);
61 return status;
62}
63
64static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
65{
66 unsigned long flags;
67 efi_status_t status;
68
69 spin_lock_irqsave(&rtc_lock, flags);
70 status = efi_call_virt(set_wakeup_time, enabled, tm);
71 spin_unlock_irqrestore(&rtc_lock, flags);
72 return status;
73}
74
75static efi_status_t virt_efi_get_variable(efi_char16_t *name,
76 efi_guid_t *vendor,
77 u32 *attr,
78 unsigned long *data_size,
79 void *data)
80{
81 return efi_call_virt(get_variable, name, vendor, attr, data_size, data);
82}
83
84static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
85 efi_char16_t *name,
86 efi_guid_t *vendor)
87{
88 return efi_call_virt(get_next_variable, name_size, name, vendor);
89}
90
91static efi_status_t virt_efi_set_variable(efi_char16_t *name,
92 efi_guid_t *vendor,
93 u32 attr,
94 unsigned long data_size,
95 void *data)
96{
97 return efi_call_virt(set_variable, name, vendor, attr, data_size, data);
98}
99
100static efi_status_t virt_efi_query_variable_info(u32 attr,
101 u64 *storage_space,
102 u64 *remaining_space,
103 u64 *max_variable_size)
104{
105 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
106 return EFI_UNSUPPORTED;
107
108 return efi_call_virt(query_variable_info, attr, storage_space,
109 remaining_space, max_variable_size);
110}
111
112static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
113{
114 return efi_call_virt(get_next_high_mono_count, count);
115}
116
117static void virt_efi_reset_system(int reset_type,
118 efi_status_t status,
119 unsigned long data_size,
120 efi_char16_t *data)
121{
122 __efi_call_virt(reset_system, reset_type, status, data_size, data);
123}
124
125static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
126 unsigned long count,
127 unsigned long sg_list)
128{
129 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
130 return EFI_UNSUPPORTED;
131
132 return efi_call_virt(update_capsule, capsules, count, sg_list);
133}
134
135static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
136 unsigned long count,
137 u64 *max_size,
138 int *reset_type)
139{
140 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
141 return EFI_UNSUPPORTED;
142
143 return efi_call_virt(query_capsule_caps, capsules, count, max_size,
144 reset_type);
145}
146
147void efi_native_runtime_setup(void)
148{
149 efi.get_time = virt_efi_get_time;
150 efi.set_time = virt_efi_set_time;
151 efi.get_wakeup_time = virt_efi_get_wakeup_time;
152 efi.set_wakeup_time = virt_efi_set_wakeup_time;
153 efi.get_variable = virt_efi_get_variable;
154 efi.get_next_variable = virt_efi_get_next_variable;
155 efi.set_variable = virt_efi_set_variable;
156 efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
157 efi.reset_system = virt_efi_reset_system;
158 efi.query_variable_info = virt_efi_query_variable_info;
159 efi.update_capsule = virt_efi_update_capsule;
160 efi.query_capsule_caps = virt_efi_query_capsule_caps;
161}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 41bbf8ba4ba8..0ceb816bdfc2 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -521,6 +521,8 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules,
521 int *reset_type); 521 int *reset_type);
522typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long size); 522typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long size);
523 523
524void efi_native_runtime_setup(void);
525
524/* 526/*
525 * EFI Configuration Table and GUID definitions 527 * EFI Configuration Table and GUID definitions
526 */ 528 */