1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/efi.h>
14#include <asm/efi.h>
15
16#include "efistub.h"
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31#define EFI_READ_CHUNK_SIZE (1024 * 1024)
32
33static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE;
34
35static int __section(.data) __nokaslr;
36static int __section(.data) __quiet;
37static bool __section(.data) efi_nosoftreserve;
38
39int __pure nokaslr(void)
40{
41 return __nokaslr;
42}
43int __pure is_quiet(void)
44{
45 return __quiet;
46}
47bool __pure __efi_soft_reserve_enabled(void)
48{
49 return !efi_nosoftreserve;
50}
51
52#define EFI_MMAP_NR_SLACK_SLOTS 8
53
54struct file_info {
55 efi_file_handle_t *handle;
56 u64 size;
57};
58
59void efi_printk(efi_system_table_t *sys_table_arg, char *str)
60{
61 char *s8;
62
63 for (s8 = str; *s8; s8++) {
64 efi_char16_t ch[2] = { 0 };
65
66 ch[0] = *s8;
67 if (*s8 == '\n') {
68 efi_char16_t nl[2] = { '\r', 0 };
69 efi_char16_printk(sys_table_arg, nl);
70 }
71
72 efi_char16_printk(sys_table_arg, ch);
73 }
74}
75
76static inline bool mmap_has_headroom(unsigned long buff_size,
77 unsigned long map_size,
78 unsigned long desc_size)
79{
80 unsigned long slack = buff_size - map_size;
81
82 return slack / desc_size >= EFI_MMAP_NR_SLACK_SLOTS;
83}
84
85efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg,
86 struct efi_boot_memmap *map)
87{
88 efi_memory_desc_t *m = NULL;
89 efi_status_t status;
90 unsigned long key;
91 u32 desc_version;
92
93 *map->desc_size = sizeof(*m);
94 *map->map_size = *map->desc_size * 32;
95 *map->buff_size = *map->map_size;
96again:
97 status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
98 *map->map_size, (void **)&m);
99 if (status != EFI_SUCCESS)
100 goto fail;
101
102 *map->desc_size = 0;
103 key = 0;
104 status = efi_call_early(get_memory_map, map->map_size, m,
105 &key, map->desc_size, &desc_version);
106 if (status == EFI_BUFFER_TOO_SMALL ||
107 !mmap_has_headroom(*map->buff_size, *map->map_size,
108 *map->desc_size)) {
109 efi_call_early(free_pool, m);
110
111
112
113
114
115
116
117 *map->map_size += *map->desc_size * EFI_MMAP_NR_SLACK_SLOTS;
118 *map->buff_size = *map->map_size;
119 goto again;
120 }
121
122 if (status != EFI_SUCCESS)
123 efi_call_early(free_pool, m);
124
125 if (map->key_ptr && status == EFI_SUCCESS)
126 *map->key_ptr = key;
127 if (map->desc_ver && status == EFI_SUCCESS)
128 *map->desc_ver = desc_version;
129
130fail:
131 *map->map = m;
132 return status;
133}
134
135
136unsigned long get_dram_base(efi_system_table_t *sys_table_arg)
137{
138 efi_status_t status;
139 unsigned long map_size, buff_size;
140 unsigned long membase = EFI_ERROR;
141 struct efi_memory_map map;
142 efi_memory_desc_t *md;
143 struct efi_boot_memmap boot_map;
144
145 boot_map.map = (efi_memory_desc_t **)&map.map;
146 boot_map.map_size = &map_size;
147 boot_map.desc_size = &map.desc_size;
148 boot_map.desc_ver = NULL;
149 boot_map.key_ptr = NULL;
150 boot_map.buff_size = &buff_size;
151
152 status = efi_get_memory_map(sys_table_arg, &boot_map);
153 if (status != EFI_SUCCESS)
154 return membase;
155
156 map.map_end = map.map + map_size;
157
158 for_each_efi_memory_desc_in_map(&map, md) {
159 if (md->attribute & EFI_MEMORY_WB) {
160 if (membase > md->phys_addr)
161 membase = md->phys_addr;
162 }
163 }
164
165 efi_call_early(free_pool, map.map);
166
167 return membase;
168}
169
170
171
172
173efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg,
174 unsigned long size, unsigned long align,
175 unsigned long *addr, unsigned long max)
176{
177 unsigned long map_size, desc_size, buff_size;
178 efi_memory_desc_t *map;
179 efi_status_t status;
180 unsigned long nr_pages;
181 u64 max_addr = 0;
182 int i;
183 struct efi_boot_memmap boot_map;
184
185 boot_map.map = ↦
186 boot_map.map_size = &map_size;
187 boot_map.desc_size = &desc_size;
188 boot_map.desc_ver = NULL;
189 boot_map.key_ptr = NULL;
190 boot_map.buff_size = &buff_size;
191
192 status = efi_get_memory_map(sys_table_arg, &boot_map);
193 if (status != EFI_SUCCESS)
194 goto fail;
195
196
197
198
199
200
201
202 if (align < EFI_ALLOC_ALIGN)
203 align = EFI_ALLOC_ALIGN;
204
205 size = round_up(size, EFI_ALLOC_ALIGN);
206 nr_pages = size / EFI_PAGE_SIZE;
207again:
208 for (i = 0; i < map_size / desc_size; i++) {
209 efi_memory_desc_t *desc;
210 unsigned long m = (unsigned long)map;
211 u64 start, end;
212
213 desc = efi_early_memdesc_ptr(m, desc_size, i);
214 if (desc->type != EFI_CONVENTIONAL_MEMORY)
215 continue;
216
217 if (efi_soft_reserve_enabled() &&
218 (desc->attribute & EFI_MEMORY_SP))
219 continue;
220
221 if (desc->num_pages < nr_pages)
222 continue;
223
224 start = desc->phys_addr;
225 end = start + desc->num_pages * EFI_PAGE_SIZE;
226
227 if (end > max)
228 end = max;
229
230 if ((start + size) > end)
231 continue;
232
233 if (round_down(end - size, align) < start)
234 continue;
235
236 start = round_down(end - size, align);
237
238
239
240
241
242 if (start == 0x0)
243 continue;
244
245 if (start > max_addr)
246 max_addr = start;
247 }
248
249 if (!max_addr)
250 status = EFI_NOT_FOUND;
251 else {
252 status = efi_call_early(allocate_pages,
253 EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
254 nr_pages, &max_addr);
255 if (status != EFI_SUCCESS) {
256 max = max_addr;
257 max_addr = 0;
258 goto again;
259 }
260
261 *addr = max_addr;
262 }
263
264 efi_call_early(free_pool, map);
265fail:
266 return status;
267}
268
269
270
271
272efi_status_t efi_low_alloc_above(efi_system_table_t *sys_table_arg,
273 unsigned long size, unsigned long align,
274 unsigned long *addr, unsigned long min)
275{
276 unsigned long map_size, desc_size, buff_size;
277 efi_memory_desc_t *map;
278 efi_status_t status;
279 unsigned long nr_pages;
280 int i;
281 struct efi_boot_memmap boot_map;
282
283 boot_map.map = ↦
284 boot_map.map_size = &map_size;
285 boot_map.desc_size = &desc_size;
286 boot_map.desc_ver = NULL;
287 boot_map.key_ptr = NULL;
288 boot_map.buff_size = &buff_size;
289
290 status = efi_get_memory_map(sys_table_arg, &boot_map);
291 if (status != EFI_SUCCESS)
292 goto fail;
293
294
295
296
297
298
299
300 if (align < EFI_ALLOC_ALIGN)
301 align = EFI_ALLOC_ALIGN;
302
303 size = round_up(size, EFI_ALLOC_ALIGN);
304 nr_pages = size / EFI_PAGE_SIZE;
305 for (i = 0; i < map_size / desc_size; i++) {
306 efi_memory_desc_t *desc;
307 unsigned long m = (unsigned long)map;
308 u64 start, end;
309
310 desc = efi_early_memdesc_ptr(m, desc_size, i);
311
312 if (desc->type != EFI_CONVENTIONAL_MEMORY)
313 continue;
314
315 if (efi_soft_reserve_enabled() &&
316 (desc->attribute & EFI_MEMORY_SP))
317 continue;
318
319 if (desc->num_pages < nr_pages)
320 continue;
321
322 start = desc->phys_addr;
323 end = start + desc->num_pages * EFI_PAGE_SIZE;
324
325 if (start < min)
326 start = min;
327
328 start = round_up(start, align);
329 if ((start + size) > end)
330 continue;
331
332 status = efi_call_early(allocate_pages,
333 EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
334 nr_pages, &start);
335 if (status == EFI_SUCCESS) {
336 *addr = start;
337 break;
338 }
339 }
340
341 if (i == map_size / desc_size)
342 status = EFI_NOT_FOUND;
343
344 efi_call_early(free_pool, map);
345fail:
346 return status;
347}
348
349void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
350 unsigned long addr)
351{
352 unsigned long nr_pages;
353
354 if (!size)
355 return;
356
357 nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
358 efi_call_early(free_pages, addr, nr_pages);
359}
360
361static efi_status_t efi_file_size(efi_system_table_t *sys_table_arg, void *__fh,
362 efi_char16_t *filename_16, void **handle,
363 u64 *file_sz)
364{
365 efi_file_handle_t *h, *fh = __fh;
366 efi_file_info_t *info;
367 efi_status_t status;
368 efi_guid_t info_guid = EFI_FILE_INFO_ID;
369 unsigned long info_sz;
370
371 status = efi_call_proto(efi_file_handle, open, fh, &h, filename_16,
372 EFI_FILE_MODE_READ, (u64)0);
373 if (status != EFI_SUCCESS) {
374 efi_printk(sys_table_arg, "Failed to open file: ");
375 efi_char16_printk(sys_table_arg, filename_16);
376 efi_printk(sys_table_arg, "\n");
377 return status;
378 }
379
380 *handle = h;
381
382 info_sz = 0;
383 status = efi_call_proto(efi_file_handle, get_info, h, &info_guid,
384 &info_sz, NULL);
385 if (status != EFI_BUFFER_TOO_SMALL) {
386 efi_printk(sys_table_arg, "Failed to get file info size\n");
387 return status;
388 }
389
390grow:
391 status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
392 info_sz, (void **)&info);
393 if (status != EFI_SUCCESS) {
394 efi_printk(sys_table_arg, "Failed to alloc mem for file info\n");
395 return status;
396 }
397
398 status = efi_call_proto(efi_file_handle, get_info, h, &info_guid,
399 &info_sz, info);
400 if (status == EFI_BUFFER_TOO_SMALL) {
401 efi_call_early(free_pool, info);
402 goto grow;
403 }
404
405 *file_sz = info->file_size;
406 efi_call_early(free_pool, info);
407
408 if (status != EFI_SUCCESS)
409 efi_printk(sys_table_arg, "Failed to get initrd info\n");
410
411 return status;
412}
413
414static efi_status_t efi_file_read(void *handle, unsigned long *size, void *addr)
415{
416 return efi_call_proto(efi_file_handle, read, handle, size, addr);
417}
418
419static efi_status_t efi_file_close(void *handle)
420{
421 return efi_call_proto(efi_file_handle, close, handle);
422}
423
424static efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
425 efi_loaded_image_t *image,
426 efi_file_handle_t **__fh)
427{
428 efi_file_io_interface_t *io;
429 efi_file_handle_t *fh;
430 efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
431 efi_status_t status;
432 void *handle = efi_table_attr(efi_loaded_image, device_handle, image);
433
434 status = efi_call_early(handle_protocol, handle,
435 &fs_proto, (void **)&io);
436 if (status != EFI_SUCCESS) {
437 efi_printk(sys_table_arg, "Failed to handle fs_proto\n");
438 return status;
439 }
440
441 status = efi_call_proto(efi_file_io_interface, open_volume, io, &fh);
442 if (status != EFI_SUCCESS)
443 efi_printk(sys_table_arg, "Failed to open volume\n");
444 else
445 *__fh = fh;
446
447 return status;
448}
449
450
451
452
453
454
455
456
457
458efi_status_t efi_parse_options(char const *cmdline)
459{
460 char *str;
461
462 str = strstr(cmdline, "nokaslr");
463 if (str == cmdline || (str && str > cmdline && *(str - 1) == ' '))
464 __nokaslr = 1;
465
466 str = strstr(cmdline, "quiet");
467 if (str == cmdline || (str && str > cmdline && *(str - 1) == ' '))
468 __quiet = 1;
469
470
471
472
473
474 str = strstr(cmdline, "efi=");
475 if (!str)
476 return EFI_SUCCESS;
477
478
479 str += strlen("efi=");
480
481
482
483
484
485 while (*str && *str != ' ') {
486 if (!strncmp(str, "nochunk", 7)) {
487 str += strlen("nochunk");
488 __chunk_size = -1UL;
489 }
490
491 if (IS_ENABLED(CONFIG_EFI_SOFT_RESERVE) &&
492 !strncmp(str, "nosoftreserve", 7)) {
493 str += strlen("nosoftreserve");
494 efi_nosoftreserve = 1;
495 }
496
497
498 while (*str && *str != ' ' && *str != ',')
499 str++;
500
501 if (*str == ',')
502 str++;
503 }
504
505 return EFI_SUCCESS;
506}
507
508
509
510
511
512
513
514efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
515 efi_loaded_image_t *image,
516 char *cmd_line, char *option_string,
517 unsigned long max_addr,
518 unsigned long *load_addr,
519 unsigned long *load_size)
520{
521 struct file_info *files;
522 unsigned long file_addr;
523 u64 file_size_total;
524 efi_file_handle_t *fh = NULL;
525 efi_status_t status;
526 int nr_files;
527 char *str;
528 int i, j, k;
529
530 file_addr = 0;
531 file_size_total = 0;
532
533 str = cmd_line;
534
535 j = 0;
536
537 if (!load_addr || !load_size)
538 return EFI_INVALID_PARAMETER;
539
540 *load_addr = 0;
541 *load_size = 0;
542
543 if (!str || !*str)
544 return EFI_SUCCESS;
545
546 for (nr_files = 0; *str; nr_files++) {
547 str = strstr(str, option_string);
548 if (!str)
549 break;
550
551 str += strlen(option_string);
552
553
554 while (*str == '/' || *str == '\\')
555 str++;
556
557 while (*str && *str != ' ' && *str != '\n')
558 str++;
559 }
560
561 if (!nr_files)
562 return EFI_SUCCESS;
563
564 status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
565 nr_files * sizeof(*files), (void **)&files);
566 if (status != EFI_SUCCESS) {
567 pr_efi_err(sys_table_arg, "Failed to alloc mem for file handle list\n");
568 goto fail;
569 }
570
571 str = cmd_line;
572 for (i = 0; i < nr_files; i++) {
573 struct file_info *file;
574 efi_char16_t filename_16[256];
575 efi_char16_t *p;
576
577 str = strstr(str, option_string);
578 if (!str)
579 break;
580
581 str += strlen(option_string);
582
583 file = &files[i];
584 p = filename_16;
585
586
587 while (*str == '/' || *str == '\\')
588 str++;
589
590 while (*str && *str != ' ' && *str != '\n') {
591 if ((u8 *)p >= (u8 *)filename_16 + sizeof(filename_16))
592 break;
593
594 if (*str == '/') {
595 *p++ = '\\';
596 str++;
597 } else {
598 *p++ = *str++;
599 }
600 }
601
602 *p = '\0';
603
604
605 if (!i) {
606 status = efi_open_volume(sys_table_arg, image, &fh);
607 if (status != EFI_SUCCESS)
608 goto free_files;
609 }
610
611 status = efi_file_size(sys_table_arg, fh, filename_16,
612 (void **)&file->handle, &file->size);
613 if (status != EFI_SUCCESS)
614 goto close_handles;
615
616 file_size_total += file->size;
617 }
618
619 if (file_size_total) {
620 unsigned long addr;
621
622
623
624
625
626
627 status = efi_high_alloc(sys_table_arg, file_size_total, 0x1000,
628 &file_addr, max_addr);
629 if (status != EFI_SUCCESS) {
630 pr_efi_err(sys_table_arg, "Failed to alloc highmem for files\n");
631 goto close_handles;
632 }
633
634
635 if (file_addr > max_addr) {
636 pr_efi_err(sys_table_arg, "We've run out of free low memory\n");
637 status = EFI_INVALID_PARAMETER;
638 goto free_file_total;
639 }
640
641 addr = file_addr;
642 for (j = 0; j < nr_files; j++) {
643 unsigned long size;
644
645 size = files[j].size;
646 while (size) {
647 unsigned long chunksize;
648
649 if (IS_ENABLED(CONFIG_X86) && size > __chunk_size)
650 chunksize = __chunk_size;
651 else
652 chunksize = size;
653
654 status = efi_file_read(files[j].handle,
655 &chunksize,
656 (void *)addr);
657 if (status != EFI_SUCCESS) {
658 pr_efi_err(sys_table_arg, "Failed to read file\n");
659 goto free_file_total;
660 }
661 addr += chunksize;
662 size -= chunksize;
663 }
664
665 efi_file_close(files[j].handle);
666 }
667
668 }
669
670 efi_call_early(free_pool, files);
671
672 *load_addr = file_addr;
673 *load_size = file_size_total;
674
675 return status;
676
677free_file_total:
678 efi_free(sys_table_arg, file_size_total, file_addr);
679
680close_handles:
681 for (k = j; k < i; k++)
682 efi_file_close(files[k].handle);
683free_files:
684 efi_call_early(free_pool, files);
685fail:
686 *load_addr = 0;
687 *load_size = 0;
688
689 return status;
690}
691
692
693
694
695
696
697
698
699
700
701efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
702 unsigned long *image_addr,
703 unsigned long image_size,
704 unsigned long alloc_size,
705 unsigned long preferred_addr,
706 unsigned long alignment,
707 unsigned long min_addr)
708{
709 unsigned long cur_image_addr;
710 unsigned long new_addr = 0;
711 efi_status_t status;
712 unsigned long nr_pages;
713 efi_physical_addr_t efi_addr = preferred_addr;
714
715 if (!image_addr || !image_size || !alloc_size)
716 return EFI_INVALID_PARAMETER;
717 if (alloc_size < image_size)
718 return EFI_INVALID_PARAMETER;
719
720 cur_image_addr = *image_addr;
721
722
723
724
725
726
727
728
729
730 nr_pages = round_up(alloc_size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
731 status = efi_call_early(allocate_pages,
732 EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
733 nr_pages, &efi_addr);
734 new_addr = efi_addr;
735
736
737
738
739 if (status != EFI_SUCCESS) {
740 status = efi_low_alloc_above(sys_table_arg, alloc_size,
741 alignment, &new_addr, min_addr);
742 }
743 if (status != EFI_SUCCESS) {
744 pr_efi_err(sys_table_arg, "Failed to allocate usable memory for kernel.\n");
745 return status;
746 }
747
748
749
750
751
752 memcpy((void *)new_addr, (void *)cur_image_addr, image_size);
753
754
755 *image_addr = new_addr;
756
757 return status;
758}
759
760
761
762
763
764static int efi_utf8_bytes(u16 c)
765{
766 return 1 + (c >= 0x80) + (c >= 0x800);
767}
768
769
770
771
772static u8 *efi_utf16_to_utf8(u8 *dst, const u16 *src, int n)
773{
774 unsigned int c;
775
776 while (n--) {
777 c = *src++;
778 if (n && c >= 0xd800 && c <= 0xdbff &&
779 *src >= 0xdc00 && *src <= 0xdfff) {
780 c = 0x10000 + ((c & 0x3ff) << 10) + (*src & 0x3ff);
781 src++;
782 n--;
783 }
784 if (c >= 0xd800 && c <= 0xdfff)
785 c = 0xfffd;
786 if (c < 0x80) {
787 *dst++ = c;
788 continue;
789 }
790 if (c < 0x800) {
791 *dst++ = 0xc0 + (c >> 6);
792 goto t1;
793 }
794 if (c < 0x10000) {
795 *dst++ = 0xe0 + (c >> 12);
796 goto t2;
797 }
798 *dst++ = 0xf0 + (c >> 18);
799 *dst++ = 0x80 + ((c >> 12) & 0x3f);
800 t2:
801 *dst++ = 0x80 + ((c >> 6) & 0x3f);
802 t1:
803 *dst++ = 0x80 + (c & 0x3f);
804 }
805
806 return dst;
807}
808
809#ifndef MAX_CMDLINE_ADDRESS
810#define MAX_CMDLINE_ADDRESS ULONG_MAX
811#endif
812
813
814
815
816
817
818char *efi_convert_cmdline(efi_system_table_t *sys_table_arg,
819 efi_loaded_image_t *image,
820 int *cmd_line_len)
821{
822 const u16 *s2;
823 u8 *s1 = NULL;
824 unsigned long cmdline_addr = 0;
825 int load_options_chars = image->load_options_size / 2;
826 const u16 *options = image->load_options;
827 int options_bytes = 0;
828 int options_chars = 0;
829 efi_status_t status;
830 u16 zero = 0;
831
832 if (options) {
833 s2 = options;
834 while (*s2 && *s2 != '\n'
835 && options_chars < load_options_chars) {
836 options_bytes += efi_utf8_bytes(*s2++);
837 options_chars++;
838 }
839 }
840
841 if (!options_chars) {
842
843 options = &zero;
844 }
845
846 options_bytes++;
847
848 status = efi_high_alloc(sys_table_arg, options_bytes, 0,
849 &cmdline_addr, MAX_CMDLINE_ADDRESS);
850 if (status != EFI_SUCCESS)
851 return NULL;
852
853 s1 = (u8 *)cmdline_addr;
854 s2 = (const u16 *)options;
855
856 s1 = efi_utf16_to_utf8(s1, s2, options_chars);
857 *s1 = '\0';
858
859 *cmd_line_len = options_bytes;
860 return (char *)cmdline_addr;
861}
862
863
864
865
866
867
868
869
870
871efi_status_t efi_exit_boot_services(efi_system_table_t *sys_table_arg,
872 void *handle,
873 struct efi_boot_memmap *map,
874 void *priv,
875 efi_exit_boot_map_processing priv_func)
876{
877 efi_status_t status;
878
879 status = efi_get_memory_map(sys_table_arg, map);
880
881 if (status != EFI_SUCCESS)
882 goto fail;
883
884 status = priv_func(sys_table_arg, map, priv);
885 if (status != EFI_SUCCESS)
886 goto free_map;
887
888 status = efi_call_early(exit_boot_services, handle, *map->key_ptr);
889
890 if (status == EFI_INVALID_PARAMETER) {
891
892
893
894
895
896
897
898
899
900
901
902
903
904 *map->map_size = *map->buff_size;
905 status = efi_call_early(get_memory_map,
906 map->map_size,
907 *map->map,
908 map->key_ptr,
909 map->desc_size,
910 map->desc_ver);
911
912
913 if (status != EFI_SUCCESS)
914 goto fail;
915
916 status = priv_func(sys_table_arg, map, priv);
917
918 if (status != EFI_SUCCESS)
919 goto fail;
920
921 status = efi_call_early(exit_boot_services, handle, *map->key_ptr);
922 }
923
924
925 if (status != EFI_SUCCESS)
926 goto fail;
927
928 return EFI_SUCCESS;
929
930free_map:
931 efi_call_early(free_pool, *map->map);
932fail:
933 return status;
934}
935
936void *get_efi_config_table(efi_system_table_t *sys_table, efi_guid_t guid)
937{
938 unsigned long tables = efi_table_attr(efi_system_table, tables, sys_table);
939 int nr_tables = efi_table_attr(efi_system_table, nr_tables, sys_table);
940 int i;
941
942 for (i = 0; i < nr_tables; i++) {
943 efi_config_table_t *t = (void *)tables;
944
945 if (efi_guidcmp(t->guid, guid) == 0)
946 return efi_table_attr(efi_config_table, table, t);
947
948 tables += efi_is_native() ? sizeof(efi_config_table_t)
949 : sizeof(efi_config_table_32_t);
950 }
951 return NULL;
952}
953