diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 20:03:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 20:03:14 -0400 |
commit | 227ad9bc070db2801a7f586b4d350dd1d8b82e03 (patch) | |
tree | fe5182ed4131e5f4c77eaedda6566e1b3ca082e0 | |
parent | 35b004cce1b0880876faecb8e0bd7cb2cb5a59d1 (diff) | |
parent | d80603c9d876efafd8b07469c891076de470e323 (diff) |
Merge branch 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
x86, efi: Properly pre-initialize table pointers
x86, efi: Add infrastructure for UEFI 2.0 runtime services
x86, efi: Fix argument types for SetVariable()
-rw-r--r-- | arch/x86/platform/efi/efi.c | 51 | ||||
-rw-r--r-- | include/linux/efi.h | 34 |
2 files changed, 82 insertions, 3 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index cfc588ce1155..3ae4128013e6 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -51,7 +51,17 @@ | |||
51 | int efi_enabled; | 51 | int efi_enabled; |
52 | EXPORT_SYMBOL(efi_enabled); | 52 | EXPORT_SYMBOL(efi_enabled); |
53 | 53 | ||
54 | struct efi efi; | 54 | struct efi __read_mostly efi = { |
55 | .mps = EFI_INVALID_TABLE_ADDR, | ||
56 | .acpi = EFI_INVALID_TABLE_ADDR, | ||
57 | .acpi20 = EFI_INVALID_TABLE_ADDR, | ||
58 | .smbios = EFI_INVALID_TABLE_ADDR, | ||
59 | .sal_systab = EFI_INVALID_TABLE_ADDR, | ||
60 | .boot_info = EFI_INVALID_TABLE_ADDR, | ||
61 | .hcdp = EFI_INVALID_TABLE_ADDR, | ||
62 | .uga = EFI_INVALID_TABLE_ADDR, | ||
63 | .uv_systab = EFI_INVALID_TABLE_ADDR, | ||
64 | }; | ||
55 | EXPORT_SYMBOL(efi); | 65 | EXPORT_SYMBOL(efi); |
56 | 66 | ||
57 | struct efi_memory_map memmap; | 67 | struct efi_memory_map memmap; |
@@ -146,7 +156,7 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size, | |||
146 | 156 | ||
147 | static efi_status_t virt_efi_set_variable(efi_char16_t *name, | 157 | static efi_status_t virt_efi_set_variable(efi_char16_t *name, |
148 | efi_guid_t *vendor, | 158 | efi_guid_t *vendor, |
149 | unsigned long attr, | 159 | u32 attr, |
150 | unsigned long data_size, | 160 | unsigned long data_size, |
151 | void *data) | 161 | void *data) |
152 | { | 162 | { |
@@ -155,6 +165,18 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name, | |||
155 | data_size, data); | 165 | data_size, data); |
156 | } | 166 | } |
157 | 167 | ||
168 | static efi_status_t virt_efi_query_variable_info(u32 attr, | ||
169 | u64 *storage_space, | ||
170 | u64 *remaining_space, | ||
171 | u64 *max_variable_size) | ||
172 | { | ||
173 | if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) | ||
174 | return EFI_UNSUPPORTED; | ||
175 | |||
176 | return efi_call_virt4(query_variable_info, attr, storage_space, | ||
177 | remaining_space, max_variable_size); | ||
178 | } | ||
179 | |||
158 | static efi_status_t virt_efi_get_next_high_mono_count(u32 *count) | 180 | static efi_status_t virt_efi_get_next_high_mono_count(u32 *count) |
159 | { | 181 | { |
160 | return efi_call_virt1(get_next_high_mono_count, count); | 182 | return efi_call_virt1(get_next_high_mono_count, count); |
@@ -169,6 +191,28 @@ static void virt_efi_reset_system(int reset_type, | |||
169 | data_size, data); | 191 | data_size, data); |
170 | } | 192 | } |
171 | 193 | ||
194 | static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules, | ||
195 | unsigned long count, | ||
196 | unsigned long sg_list) | ||
197 | { | ||
198 | if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) | ||
199 | return EFI_UNSUPPORTED; | ||
200 | |||
201 | return efi_call_virt3(update_capsule, capsules, count, sg_list); | ||
202 | } | ||
203 | |||
204 | static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules, | ||
205 | unsigned long count, | ||
206 | u64 *max_size, | ||
207 | int *reset_type) | ||
208 | { | ||
209 | if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) | ||
210 | return EFI_UNSUPPORTED; | ||
211 | |||
212 | return efi_call_virt4(query_capsule_caps, capsules, count, max_size, | ||
213 | reset_type); | ||
214 | } | ||
215 | |||
172 | static efi_status_t __init phys_efi_set_virtual_address_map( | 216 | static efi_status_t __init phys_efi_set_virtual_address_map( |
173 | unsigned long memory_map_size, | 217 | unsigned long memory_map_size, |
174 | unsigned long descriptor_size, | 218 | unsigned long descriptor_size, |
@@ -696,6 +740,9 @@ void __init efi_enter_virtual_mode(void) | |||
696 | efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; | 740 | efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; |
697 | efi.reset_system = virt_efi_reset_system; | 741 | efi.reset_system = virt_efi_reset_system; |
698 | efi.set_virtual_address_map = NULL; | 742 | efi.set_virtual_address_map = NULL; |
743 | efi.query_variable_info = virt_efi_query_variable_info; | ||
744 | efi.update_capsule = virt_efi_update_capsule; | ||
745 | efi.query_capsule_caps = virt_efi_query_capsule_caps; | ||
699 | if (__supported_pte_mask & _PAGE_NX) | 746 | if (__supported_pte_mask & _PAGE_NX) |
700 | runtime_code_page_mkexec(); | 747 | runtime_code_page_mkexec(); |
701 | early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); | 748 | early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); |
diff --git a/include/linux/efi.h b/include/linux/efi.h index e376270cd26e..ec2572693925 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h | |||
@@ -101,6 +101,13 @@ typedef struct { | |||
101 | u64 attribute; | 101 | u64 attribute; |
102 | } efi_memory_desc_t; | 102 | } efi_memory_desc_t; |
103 | 103 | ||
104 | typedef struct { | ||
105 | efi_guid_t guid; | ||
106 | u32 headersize; | ||
107 | u32 flags; | ||
108 | u32 imagesize; | ||
109 | } efi_capsule_header_t; | ||
110 | |||
104 | typedef int (*efi_freemem_callback_t) (u64 start, u64 end, void *arg); | 111 | typedef int (*efi_freemem_callback_t) (u64 start, u64 end, void *arg); |
105 | 112 | ||
106 | /* | 113 | /* |
@@ -156,6 +163,9 @@ typedef struct { | |||
156 | unsigned long set_variable; | 163 | unsigned long set_variable; |
157 | unsigned long get_next_high_mono_count; | 164 | unsigned long get_next_high_mono_count; |
158 | unsigned long reset_system; | 165 | unsigned long reset_system; |
166 | unsigned long update_capsule; | ||
167 | unsigned long query_capsule_caps; | ||
168 | unsigned long query_variable_info; | ||
159 | } efi_runtime_services_t; | 169 | } efi_runtime_services_t; |
160 | 170 | ||
161 | typedef efi_status_t efi_get_time_t (efi_time_t *tm, efi_time_cap_t *tc); | 171 | typedef efi_status_t efi_get_time_t (efi_time_t *tm, efi_time_cap_t *tc); |
@@ -168,7 +178,7 @@ typedef efi_status_t efi_get_variable_t (efi_char16_t *name, efi_guid_t *vendor, | |||
168 | typedef efi_status_t efi_get_next_variable_t (unsigned long *name_size, efi_char16_t *name, | 178 | typedef efi_status_t efi_get_next_variable_t (unsigned long *name_size, efi_char16_t *name, |
169 | efi_guid_t *vendor); | 179 | efi_guid_t *vendor); |
170 | typedef efi_status_t efi_set_variable_t (efi_char16_t *name, efi_guid_t *vendor, | 180 | typedef efi_status_t efi_set_variable_t (efi_char16_t *name, efi_guid_t *vendor, |
171 | unsigned long attr, unsigned long data_size, | 181 | u32 attr, unsigned long data_size, |
172 | void *data); | 182 | void *data); |
173 | typedef efi_status_t efi_get_next_high_mono_count_t (u32 *count); | 183 | typedef efi_status_t efi_get_next_high_mono_count_t (u32 *count); |
174 | typedef void efi_reset_system_t (int reset_type, efi_status_t status, | 184 | typedef void efi_reset_system_t (int reset_type, efi_status_t status, |
@@ -177,6 +187,17 @@ typedef efi_status_t efi_set_virtual_address_map_t (unsigned long memory_map_siz | |||
177 | unsigned long descriptor_size, | 187 | unsigned long descriptor_size, |
178 | u32 descriptor_version, | 188 | u32 descriptor_version, |
179 | efi_memory_desc_t *virtual_map); | 189 | efi_memory_desc_t *virtual_map); |
190 | typedef efi_status_t efi_query_variable_info_t(u32 attr, | ||
191 | u64 *storage_space, | ||
192 | u64 *remaining_space, | ||
193 | u64 *max_variable_size); | ||
194 | typedef efi_status_t efi_update_capsule_t(efi_capsule_header_t **capsules, | ||
195 | unsigned long count, | ||
196 | unsigned long sg_list); | ||
197 | typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules, | ||
198 | unsigned long count, | ||
199 | u64 *max_size, | ||
200 | int *reset_type); | ||
180 | 201 | ||
181 | /* | 202 | /* |
182 | * EFI Configuration Table and GUID definitions | 203 | * EFI Configuration Table and GUID definitions |
@@ -218,6 +239,13 @@ typedef struct { | |||
218 | 239 | ||
219 | #define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL) | 240 | #define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL) |
220 | 241 | ||
242 | #define EFI_2_30_SYSTEM_TABLE_REVISION ((2 << 16) | (30)) | ||
243 | #define EFI_2_20_SYSTEM_TABLE_REVISION ((2 << 16) | (20)) | ||
244 | #define EFI_2_10_SYSTEM_TABLE_REVISION ((2 << 16) | (10)) | ||
245 | #define EFI_2_00_SYSTEM_TABLE_REVISION ((2 << 16) | (00)) | ||
246 | #define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | (10)) | ||
247 | #define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | (02)) | ||
248 | |||
221 | typedef struct { | 249 | typedef struct { |
222 | efi_table_hdr_t hdr; | 250 | efi_table_hdr_t hdr; |
223 | unsigned long fw_vendor; /* physical addr of CHAR16 vendor string */ | 251 | unsigned long fw_vendor; /* physical addr of CHAR16 vendor string */ |
@@ -250,6 +278,7 @@ struct efi_memory_map { | |||
250 | */ | 278 | */ |
251 | extern struct efi { | 279 | extern struct efi { |
252 | efi_system_table_t *systab; /* EFI system table */ | 280 | efi_system_table_t *systab; /* EFI system table */ |
281 | unsigned int runtime_version; /* Runtime services version */ | ||
253 | unsigned long mps; /* MPS table */ | 282 | unsigned long mps; /* MPS table */ |
254 | unsigned long acpi; /* ACPI table (IA64 ext 0.71) */ | 283 | unsigned long acpi; /* ACPI table (IA64 ext 0.71) */ |
255 | unsigned long acpi20; /* ACPI table (ACPI 2.0) */ | 284 | unsigned long acpi20; /* ACPI table (ACPI 2.0) */ |
@@ -266,6 +295,9 @@ extern struct efi { | |||
266 | efi_get_variable_t *get_variable; | 295 | efi_get_variable_t *get_variable; |
267 | efi_get_next_variable_t *get_next_variable; | 296 | efi_get_next_variable_t *get_next_variable; |
268 | efi_set_variable_t *set_variable; | 297 | efi_set_variable_t *set_variable; |
298 | efi_query_variable_info_t *query_variable_info; | ||
299 | efi_update_capsule_t *update_capsule; | ||
300 | efi_query_capsule_caps_t *query_capsule_caps; | ||
269 | efi_get_next_high_mono_count_t *get_next_high_mono_count; | 301 | efi_get_next_high_mono_count_t *get_next_high_mono_count; |
270 | efi_reset_system_t *reset_system; | 302 | efi_reset_system_t *reset_system; |
271 | efi_set_virtual_address_map_t *set_virtual_address_map; | 303 | efi_set_virtual_address_map_t *set_virtual_address_map; |