aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-11 20:48:30 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-11 20:48:30 -0500
commit69019d77c71472428a5d67ab8bb7cfa9145000d0 (patch)
tree370f038a801c5ceee5266bf95944a458bcc0bfbf /drivers/firmware
parent6df1e7f2e96721dfdbfd8a034e52bc81916f978c (diff)
parent88392e9dd5a524b8194f1045369c7d0eb16d9f32 (diff)
Merge branch 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 EFI changes from Ingo Molnar: "Main changes: - Add support for earlyprintk=efi which uses the EFI framebuffer. Very useful for debugging boot problems. - EFI stub support for large memory maps (more than 128 entries) - EFI ARM support - this was mostly done by generalizing x86 <-> ARM platform differences, such as by moving x86 EFI code into drivers/firmware/efi/ and sharing it with ARM. - Documentation updates - misc fixes" * 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (26 commits) x86/efi: Add EFI framebuffer earlyprintk support boot, efi: Remove redundant memset() x86/efi: Fix config_table_type array termination x86 efi: bugfix interrupt disabling sequence x86: EFI stub support for large memory maps efi: resolve warnings found on ARM compile efi: Fix types in EFI calls to match EFI function definitions. efi: Renames in handle_cmdline_files() to complete generalization. efi: Generalize handle_ramdisks() and rename to handle_cmdline_files(). efi: Allow efi_free() to be called with size of 0 efi: use efi_get_memory_map() to get final map for x86 efi: generalize efi_get_memory_map() efi: Rename __get_map() to efi_get_memory_map() efi: Move unicode to ASCII conversion to shared function. efi: Generalize relocate_kernel() for use by other architectures. efi: Move relocate_kernel() to shared file. efi: Enforce minimum alignment of 1 page on allocations. efi: Rename memory allocation/free functions efi: Add system table pointer argument to shared functions. efi: Move common EFI stub code from x86 arch code to common location ...
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/efi/efi-stub-helper.c636
-rw-r--r--drivers/firmware/efi/efi.c140
-rw-r--r--drivers/firmware/efi/efivars.c2
3 files changed, 777 insertions, 1 deletions
diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/efi-stub-helper.c
new file mode 100644
index 000000000000..b6bffbfd3be7
--- /dev/null
+++ b/drivers/firmware/efi/efi-stub-helper.c
@@ -0,0 +1,636 @@
1/*
2 * Helper functions used by the EFI stub on multiple
3 * architectures. This should be #included by the EFI stub
4 * implementation files.
5 *
6 * Copyright 2011 Intel Corporation; author Matt Fleming
7 *
8 * This file is part of the Linux kernel, and is made available
9 * under the terms of the GNU General Public License version 2.
10 *
11 */
12#define EFI_READ_CHUNK_SIZE (1024 * 1024)
13
14struct file_info {
15 efi_file_handle_t *handle;
16 u64 size;
17};
18
19
20
21
22static void efi_char16_printk(efi_system_table_t *sys_table_arg,
23 efi_char16_t *str)
24{
25 struct efi_simple_text_output_protocol *out;
26
27 out = (struct efi_simple_text_output_protocol *)sys_table_arg->con_out;
28 efi_call_phys2(out->output_string, out, str);
29}
30
31static void efi_printk(efi_system_table_t *sys_table_arg, char *str)
32{
33 char *s8;
34
35 for (s8 = str; *s8; s8++) {
36 efi_char16_t ch[2] = { 0 };
37
38 ch[0] = *s8;
39 if (*s8 == '\n') {
40 efi_char16_t nl[2] = { '\r', 0 };
41 efi_char16_printk(sys_table_arg, nl);
42 }
43
44 efi_char16_printk(sys_table_arg, ch);
45 }
46}
47
48
49static efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg,
50 efi_memory_desc_t **map,
51 unsigned long *map_size,
52 unsigned long *desc_size,
53 u32 *desc_ver,
54 unsigned long *key_ptr)
55{
56 efi_memory_desc_t *m = NULL;
57 efi_status_t status;
58 unsigned long key;
59 u32 desc_version;
60
61 *map_size = sizeof(*m) * 32;
62again:
63 /*
64 * Add an additional efi_memory_desc_t because we're doing an
65 * allocation which may be in a new descriptor region.
66 */
67 *map_size += sizeof(*m);
68 status = efi_call_phys3(sys_table_arg->boottime->allocate_pool,
69 EFI_LOADER_DATA, *map_size, (void **)&m);
70 if (status != EFI_SUCCESS)
71 goto fail;
72
73 status = efi_call_phys5(sys_table_arg->boottime->get_memory_map,
74 map_size, m, &key, desc_size, &desc_version);
75 if (status == EFI_BUFFER_TOO_SMALL) {
76 efi_call_phys1(sys_table_arg->boottime->free_pool, m);
77 goto again;
78 }
79
80 if (status != EFI_SUCCESS)
81 efi_call_phys1(sys_table_arg->boottime->free_pool, m);
82 if (key_ptr && status == EFI_SUCCESS)
83 *key_ptr = key;
84 if (desc_ver && status == EFI_SUCCESS)
85 *desc_ver = desc_version;
86
87fail:
88 *map = m;
89 return status;
90}
91
92/*
93 * Allocate at the highest possible address that is not above 'max'.
94 */
95static efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg,
96 unsigned long size, unsigned long align,
97 unsigned long *addr, unsigned long max)
98{
99 unsigned long map_size, desc_size;
100 efi_memory_desc_t *map;
101 efi_status_t status;
102 unsigned long nr_pages;
103 u64 max_addr = 0;
104 int i;
105
106 status = efi_get_memory_map(sys_table_arg, &map, &map_size, &desc_size,
107 NULL, NULL);
108 if (status != EFI_SUCCESS)
109 goto fail;
110
111 /*
112 * Enforce minimum alignment that EFI requires when requesting
113 * a specific address. We are doing page-based allocations,
114 * so we must be aligned to a page.
115 */
116 if (align < EFI_PAGE_SIZE)
117 align = EFI_PAGE_SIZE;
118
119 nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
120again:
121 for (i = 0; i < map_size / desc_size; i++) {
122 efi_memory_desc_t *desc;
123 unsigned long m = (unsigned long)map;
124 u64 start, end;
125
126 desc = (efi_memory_desc_t *)(m + (i * desc_size));
127 if (desc->type != EFI_CONVENTIONAL_MEMORY)
128 continue;
129
130 if (desc->num_pages < nr_pages)
131 continue;
132
133 start = desc->phys_addr;
134 end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
135
136 if ((start + size) > end || (start + size) > max)
137 continue;
138
139 if (end - size > max)
140 end = max;
141
142 if (round_down(end - size, align) < start)
143 continue;
144
145 start = round_down(end - size, align);
146
147 /*
148 * Don't allocate at 0x0. It will confuse code that
149 * checks pointers against NULL.
150 */
151 if (start == 0x0)
152 continue;
153
154 if (start > max_addr)
155 max_addr = start;
156 }
157
158 if (!max_addr)
159 status = EFI_NOT_FOUND;
160 else {
161 status = efi_call_phys4(sys_table_arg->boottime->allocate_pages,
162 EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
163 nr_pages, &max_addr);
164 if (status != EFI_SUCCESS) {
165 max = max_addr;
166 max_addr = 0;
167 goto again;
168 }
169
170 *addr = max_addr;
171 }
172
173 efi_call_phys1(sys_table_arg->boottime->free_pool, map);
174
175fail:
176 return status;
177}
178
179/*
180 * Allocate at the lowest possible address.
181 */
182static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
183 unsigned long size, unsigned long align,
184 unsigned long *addr)
185{
186 unsigned long map_size, desc_size;
187 efi_memory_desc_t *map;
188 efi_status_t status;
189 unsigned long nr_pages;
190 int i;
191
192 status = efi_get_memory_map(sys_table_arg, &map, &map_size, &desc_size,
193 NULL, NULL);
194 if (status != EFI_SUCCESS)
195 goto fail;
196
197 /*
198 * Enforce minimum alignment that EFI requires when requesting
199 * a specific address. We are doing page-based allocations,
200 * so we must be aligned to a page.
201 */
202 if (align < EFI_PAGE_SIZE)
203 align = EFI_PAGE_SIZE;
204
205 nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
206 for (i = 0; i < map_size / desc_size; i++) {
207 efi_memory_desc_t *desc;
208 unsigned long m = (unsigned long)map;
209 u64 start, end;
210
211 desc = (efi_memory_desc_t *)(m + (i * desc_size));
212
213 if (desc->type != EFI_CONVENTIONAL_MEMORY)
214 continue;
215
216 if (desc->num_pages < nr_pages)
217 continue;
218
219 start = desc->phys_addr;
220 end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
221
222 /*
223 * Don't allocate at 0x0. It will confuse code that
224 * checks pointers against NULL. Skip the first 8
225 * bytes so we start at a nice even number.
226 */
227 if (start == 0x0)
228 start += 8;
229
230 start = round_up(start, align);
231 if ((start + size) > end)
232 continue;
233
234 status = efi_call_phys4(sys_table_arg->boottime->allocate_pages,
235 EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
236 nr_pages, &start);
237 if (status == EFI_SUCCESS) {
238 *addr = start;
239 break;
240 }
241 }
242
243 if (i == map_size / desc_size)
244 status = EFI_NOT_FOUND;
245
246 efi_call_phys1(sys_table_arg->boottime->free_pool, map);
247fail:
248 return status;
249}
250
251static void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
252 unsigned long addr)
253{
254 unsigned long nr_pages;
255
256 if (!size)
257 return;
258
259 nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
260 efi_call_phys2(sys_table_arg->boottime->free_pages, addr, nr_pages);
261}
262
263
264/*
265 * Check the cmdline for a LILO-style file= arguments.
266 *
267 * We only support loading a file from the same filesystem as
268 * the kernel image.
269 */
270static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
271 efi_loaded_image_t *image,
272 char *cmd_line, char *option_string,
273 unsigned long max_addr,
274 unsigned long *load_addr,
275 unsigned long *load_size)
276{
277 struct file_info *files;
278 unsigned long file_addr;
279 efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
280 u64 file_size_total;
281 efi_file_io_interface_t *io;
282 efi_file_handle_t *fh;
283 efi_status_t status;
284 int nr_files;
285 char *str;
286 int i, j, k;
287
288 file_addr = 0;
289 file_size_total = 0;
290
291 str = cmd_line;
292
293 j = 0; /* See close_handles */
294
295 if (!load_addr || !load_size)
296 return EFI_INVALID_PARAMETER;
297
298 *load_addr = 0;
299 *load_size = 0;
300
301 if (!str || !*str)
302 return EFI_SUCCESS;
303
304 for (nr_files = 0; *str; nr_files++) {
305 str = strstr(str, option_string);
306 if (!str)
307 break;
308
309 str += strlen(option_string);
310
311 /* Skip any leading slashes */
312 while (*str == '/' || *str == '\\')
313 str++;
314
315 while (*str && *str != ' ' && *str != '\n')
316 str++;
317 }
318
319 if (!nr_files)
320 return EFI_SUCCESS;
321
322 status = efi_call_phys3(sys_table_arg->boottime->allocate_pool,
323 EFI_LOADER_DATA,
324 nr_files * sizeof(*files),
325 (void **)&files);
326 if (status != EFI_SUCCESS) {
327 efi_printk(sys_table_arg, "Failed to alloc mem for file handle list\n");
328 goto fail;
329 }
330
331 str = cmd_line;
332 for (i = 0; i < nr_files; i++) {
333 struct file_info *file;
334 efi_file_handle_t *h;
335 efi_file_info_t *info;
336 efi_char16_t filename_16[256];
337 unsigned long info_sz;
338 efi_guid_t info_guid = EFI_FILE_INFO_ID;
339 efi_char16_t *p;
340 u64 file_sz;
341
342 str = strstr(str, option_string);
343 if (!str)
344 break;
345
346 str += strlen(option_string);
347
348 file = &files[i];
349 p = filename_16;
350
351 /* Skip any leading slashes */
352 while (*str == '/' || *str == '\\')
353 str++;
354
355 while (*str && *str != ' ' && *str != '\n') {
356 if ((u8 *)p >= (u8 *)filename_16 + sizeof(filename_16))
357 break;
358
359 if (*str == '/') {
360 *p++ = '\\';
361 str++;
362 } else {
363 *p++ = *str++;
364 }
365 }
366
367 *p = '\0';
368
369 /* Only open the volume once. */
370 if (!i) {
371 efi_boot_services_t *boottime;
372
373 boottime = sys_table_arg->boottime;
374
375 status = efi_call_phys3(boottime->handle_protocol,
376 image->device_handle, &fs_proto,
377 (void **)&io);
378 if (status != EFI_SUCCESS) {
379 efi_printk(sys_table_arg, "Failed to handle fs_proto\n");
380 goto free_files;
381 }
382
383 status = efi_call_phys2(io->open_volume, io, &fh);
384 if (status != EFI_SUCCESS) {
385 efi_printk(sys_table_arg, "Failed to open volume\n");
386 goto free_files;
387 }
388 }
389
390 status = efi_call_phys5(fh->open, fh, &h, filename_16,
391 EFI_FILE_MODE_READ, (u64)0);
392 if (status != EFI_SUCCESS) {
393 efi_printk(sys_table_arg, "Failed to open file: ");
394 efi_char16_printk(sys_table_arg, filename_16);
395 efi_printk(sys_table_arg, "\n");
396 goto close_handles;
397 }
398
399 file->handle = h;
400
401 info_sz = 0;
402 status = efi_call_phys4(h->get_info, h, &info_guid,
403 &info_sz, NULL);
404 if (status != EFI_BUFFER_TOO_SMALL) {
405 efi_printk(sys_table_arg, "Failed to get file info size\n");
406 goto close_handles;
407 }
408
409grow:
410 status = efi_call_phys3(sys_table_arg->boottime->allocate_pool,
411 EFI_LOADER_DATA, info_sz,
412 (void **)&info);
413 if (status != EFI_SUCCESS) {
414 efi_printk(sys_table_arg, "Failed to alloc mem for file info\n");
415 goto close_handles;
416 }
417
418 status = efi_call_phys4(h->get_info, h, &info_guid,
419 &info_sz, info);
420 if (status == EFI_BUFFER_TOO_SMALL) {
421 efi_call_phys1(sys_table_arg->boottime->free_pool,
422 info);
423 goto grow;
424 }
425
426 file_sz = info->file_size;
427 efi_call_phys1(sys_table_arg->boottime->free_pool, info);
428
429 if (status != EFI_SUCCESS) {
430 efi_printk(sys_table_arg, "Failed to get file info\n");
431 goto close_handles;
432 }
433
434 file->size = file_sz;
435 file_size_total += file_sz;
436 }
437
438 if (file_size_total) {
439 unsigned long addr;
440
441 /*
442 * Multiple files need to be at consecutive addresses in memory,
443 * so allocate enough memory for all the files. This is used
444 * for loading multiple files.
445 */
446 status = efi_high_alloc(sys_table_arg, file_size_total, 0x1000,
447 &file_addr, max_addr);
448 if (status != EFI_SUCCESS) {
449 efi_printk(sys_table_arg, "Failed to alloc highmem for files\n");
450 goto close_handles;
451 }
452
453 /* We've run out of free low memory. */
454 if (file_addr > max_addr) {
455 efi_printk(sys_table_arg, "We've run out of free low memory\n");
456 status = EFI_INVALID_PARAMETER;
457 goto free_file_total;
458 }
459
460 addr = file_addr;
461 for (j = 0; j < nr_files; j++) {
462 unsigned long size;
463
464 size = files[j].size;
465 while (size) {
466 unsigned long chunksize;
467 if (size > EFI_READ_CHUNK_SIZE)
468 chunksize = EFI_READ_CHUNK_SIZE;
469 else
470 chunksize = size;
471 status = efi_call_phys3(fh->read,
472 files[j].handle,
473 &chunksize,
474 (void *)addr);
475 if (status != EFI_SUCCESS) {
476 efi_printk(sys_table_arg, "Failed to read file\n");
477 goto free_file_total;
478 }
479 addr += chunksize;
480 size -= chunksize;
481 }
482
483 efi_call_phys1(fh->close, files[j].handle);
484 }
485
486 }
487
488 efi_call_phys1(sys_table_arg->boottime->free_pool, files);
489
490 *load_addr = file_addr;
491 *load_size = file_size_total;
492
493 return status;
494
495free_file_total:
496 efi_free(sys_table_arg, file_size_total, file_addr);
497
498close_handles:
499 for (k = j; k < i; k++)
500 efi_call_phys1(fh->close, files[k].handle);
501free_files:
502 efi_call_phys1(sys_table_arg->boottime->free_pool, files);
503fail:
504 *load_addr = 0;
505 *load_size = 0;
506
507 return status;
508}
509/*
510 * Relocate a kernel image, either compressed or uncompressed.
511 * In the ARM64 case, all kernel images are currently
512 * uncompressed, and as such when we relocate it we need to
513 * allocate additional space for the BSS segment. Any low
514 * memory that this function should avoid needs to be
515 * unavailable in the EFI memory map, as if the preferred
516 * address is not available the lowest available address will
517 * be used.
518 */
519static efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
520 unsigned long *image_addr,
521 unsigned long image_size,
522 unsigned long alloc_size,
523 unsigned long preferred_addr,
524 unsigned long alignment)
525{
526 unsigned long cur_image_addr;
527 unsigned long new_addr = 0;
528 efi_status_t status;
529 unsigned long nr_pages;
530 efi_physical_addr_t efi_addr = preferred_addr;
531
532 if (!image_addr || !image_size || !alloc_size)
533 return EFI_INVALID_PARAMETER;
534 if (alloc_size < image_size)
535 return EFI_INVALID_PARAMETER;
536
537 cur_image_addr = *image_addr;
538
539 /*
540 * The EFI firmware loader could have placed the kernel image
541 * anywhere in memory, but the kernel has restrictions on the
542 * max physical address it can run at. Some architectures
543 * also have a prefered address, so first try to relocate
544 * to the preferred address. If that fails, allocate as low
545 * as possible while respecting the required alignment.
546 */
547 nr_pages = round_up(alloc_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
548 status = efi_call_phys4(sys_table_arg->boottime->allocate_pages,
549 EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
550 nr_pages, &efi_addr);
551 new_addr = efi_addr;
552 /*
553 * If preferred address allocation failed allocate as low as
554 * possible.
555 */
556 if (status != EFI_SUCCESS) {
557 status = efi_low_alloc(sys_table_arg, alloc_size, alignment,
558 &new_addr);
559 }
560 if (status != EFI_SUCCESS) {
561 efi_printk(sys_table_arg, "ERROR: Failed to allocate usable memory for kernel.\n");
562 return status;
563 }
564
565 /*
566 * We know source/dest won't overlap since both memory ranges
567 * have been allocated by UEFI, so we can safely use memcpy.
568 */
569 memcpy((void *)new_addr, (void *)cur_image_addr, image_size);
570
571 /* Return the new address of the relocated image. */
572 *image_addr = new_addr;
573
574 return status;
575}
576
577/*
578 * Convert the unicode UEFI command line to ASCII to pass to kernel.
579 * Size of memory allocated return in *cmd_line_len.
580 * Returns NULL on error.
581 */
582static char *efi_convert_cmdline_to_ascii(efi_system_table_t *sys_table_arg,
583 efi_loaded_image_t *image,
584 int *cmd_line_len)
585{
586 u16 *s2;
587 u8 *s1 = NULL;
588 unsigned long cmdline_addr = 0;
589 int load_options_size = image->load_options_size / 2; /* ASCII */
590 void *options = image->load_options;
591 int options_size = 0;
592 efi_status_t status;
593 int i;
594 u16 zero = 0;
595
596 if (options) {
597 s2 = options;
598 while (*s2 && *s2 != '\n' && options_size < load_options_size) {
599 s2++;
600 options_size++;
601 }
602 }
603
604 if (options_size == 0) {
605 /* No command line options, so return empty string*/
606 options_size = 1;
607 options = &zero;
608 }
609
610 options_size++; /* NUL termination */
611#ifdef CONFIG_ARM
612 /*
613 * For ARM, allocate at a high address to avoid reserved
614 * regions at low addresses that we don't know the specfics of
615 * at the time we are processing the command line.
616 */
617 status = efi_high_alloc(sys_table_arg, options_size, 0,
618 &cmdline_addr, 0xfffff000);
619#else
620 status = efi_low_alloc(sys_table_arg, options_size, 0,
621 &cmdline_addr);
622#endif
623 if (status != EFI_SUCCESS)
624 return NULL;
625
626 s1 = (u8 *)cmdline_addr;
627 s2 = (u16 *)options;
628
629 for (i = 0; i < options_size - 1; i++)
630 *s1++ = *s2++;
631
632 *s1 = '\0';
633
634 *cmd_line_len = options_size;
635 return (char *)cmdline_addr;
636}
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 5145fa344ad5..2e2fbdec0845 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -13,11 +13,27 @@
13 * This file is released under the GPLv2. 13 * This file is released under the GPLv2.
14 */ 14 */
15 15
16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17
16#include <linux/kobject.h> 18#include <linux/kobject.h>
17#include <linux/module.h> 19#include <linux/module.h>
18#include <linux/init.h> 20#include <linux/init.h>
19#include <linux/device.h> 21#include <linux/device.h>
20#include <linux/efi.h> 22#include <linux/efi.h>
23#include <linux/io.h>
24
25struct efi __read_mostly efi = {
26 .mps = EFI_INVALID_TABLE_ADDR,
27 .acpi = EFI_INVALID_TABLE_ADDR,
28 .acpi20 = EFI_INVALID_TABLE_ADDR,
29 .smbios = EFI_INVALID_TABLE_ADDR,
30 .sal_systab = EFI_INVALID_TABLE_ADDR,
31 .boot_info = EFI_INVALID_TABLE_ADDR,
32 .hcdp = EFI_INVALID_TABLE_ADDR,
33 .uga = EFI_INVALID_TABLE_ADDR,
34 .uv_systab = EFI_INVALID_TABLE_ADDR,
35};
36EXPORT_SYMBOL(efi);
21 37
22static struct kobject *efi_kobj; 38static struct kobject *efi_kobj;
23static struct kobject *efivars_kobj; 39static struct kobject *efivars_kobj;
@@ -132,3 +148,127 @@ err_put:
132} 148}
133 149
134subsys_initcall(efisubsys_init); 150subsys_initcall(efisubsys_init);
151
152
153/*
154 * We can't ioremap data in EFI boot services RAM, because we've already mapped
155 * it as RAM. So, look it up in the existing EFI memory map instead. Only
156 * callable after efi_enter_virtual_mode and before efi_free_boot_services.
157 */
158void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
159{
160 struct efi_memory_map *map;
161 void *p;
162 map = efi.memmap;
163 if (!map)
164 return NULL;
165 if (WARN_ON(!map->map))
166 return NULL;
167 for (p = map->map; p < map->map_end; p += map->desc_size) {
168 efi_memory_desc_t *md = p;
169 u64 size = md->num_pages << EFI_PAGE_SHIFT;
170 u64 end = md->phys_addr + size;
171 if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
172 md->type != EFI_BOOT_SERVICES_CODE &&
173 md->type != EFI_BOOT_SERVICES_DATA)
174 continue;
175 if (!md->virt_addr)
176 continue;
177 if (phys_addr >= md->phys_addr && phys_addr < end) {
178 phys_addr += md->virt_addr - md->phys_addr;
179 return (__force void __iomem *)(unsigned long)phys_addr;
180 }
181 }
182 return NULL;
183}
184
185static __initdata efi_config_table_type_t common_tables[] = {
186 {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
187 {ACPI_TABLE_GUID, "ACPI", &efi.acpi},
188 {HCDP_TABLE_GUID, "HCDP", &efi.hcdp},
189 {MPS_TABLE_GUID, "MPS", &efi.mps},
190 {SAL_SYSTEM_TABLE_GUID, "SALsystab", &efi.sal_systab},
191 {SMBIOS_TABLE_GUID, "SMBIOS", &efi.smbios},
192 {UGA_IO_PROTOCOL_GUID, "UGA", &efi.uga},
193 {NULL_GUID, NULL, 0},
194};
195
196static __init int match_config_table(efi_guid_t *guid,
197 unsigned long table,
198 efi_config_table_type_t *table_types)
199{
200 u8 str[EFI_VARIABLE_GUID_LEN + 1];
201 int i;
202
203 if (table_types) {
204 efi_guid_unparse(guid, str);
205
206 for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
207 efi_guid_unparse(&table_types[i].guid, str);
208
209 if (!efi_guidcmp(*guid, table_types[i].guid)) {
210 *(table_types[i].ptr) = table;
211 pr_cont(" %s=0x%lx ",
212 table_types[i].name, table);
213 return 1;
214 }
215 }
216 }
217
218 return 0;
219}
220
221int __init efi_config_init(efi_config_table_type_t *arch_tables)
222{
223 void *config_tables, *tablep;
224 int i, sz;
225
226 if (efi_enabled(EFI_64BIT))
227 sz = sizeof(efi_config_table_64_t);
228 else
229 sz = sizeof(efi_config_table_32_t);
230
231 /*
232 * Let's see what config tables the firmware passed to us.
233 */
234 config_tables = early_memremap(efi.systab->tables,
235 efi.systab->nr_tables * sz);
236 if (config_tables == NULL) {
237 pr_err("Could not map Configuration table!\n");
238 return -ENOMEM;
239 }
240
241 tablep = config_tables;
242 pr_info("");
243 for (i = 0; i < efi.systab->nr_tables; i++) {
244 efi_guid_t guid;
245 unsigned long table;
246
247 if (efi_enabled(EFI_64BIT)) {
248 u64 table64;
249 guid = ((efi_config_table_64_t *)tablep)->guid;
250 table64 = ((efi_config_table_64_t *)tablep)->table;
251 table = table64;
252#ifndef CONFIG_64BIT
253 if (table64 >> 32) {
254 pr_cont("\n");
255 pr_err("Table located above 4GB, disabling EFI.\n");
256 early_iounmap(config_tables,
257 efi.systab->nr_tables * sz);
258 return -EINVAL;
259 }
260#endif
261 } else {
262 guid = ((efi_config_table_32_t *)tablep)->guid;
263 table = ((efi_config_table_32_t *)tablep)->table;
264 }
265
266 if (!match_config_table(&guid, table, common_tables))
267 match_config_table(&guid, table, arch_tables);
268
269 tablep += sz;
270 }
271 pr_cont("\n");
272 early_iounmap(config_tables, efi.systab->nr_tables * sz);
273 return 0;
274}
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index 8a7432a4b413..933eb027d527 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -564,7 +564,7 @@ static int efivar_sysfs_destroy(struct efivar_entry *entry, void *data)
564 return 0; 564 return 0;
565} 565}
566 566
567void efivars_sysfs_exit(void) 567static void efivars_sysfs_exit(void)
568{ 568{
569 /* Remove all entries and destroy */ 569 /* Remove all entries and destroy */
570 __efivar_entry_iter(efivar_sysfs_destroy, &efivar_sysfs_list, NULL, NULL); 570 __efivar_entry_iter(efivar_sysfs_destroy, &efivar_sysfs_list, NULL, NULL);