]> Git Repo - linux.git/blame - drivers/firmware/efi/libstub/efi-stub-helper.c
efi/libstub: Avoid protocol wrapper for file I/O routines
[linux.git] / drivers / firmware / efi / libstub / efi-stub-helper.c
CommitLineData
4febfb8d 1// SPDX-License-Identifier: GPL-2.0
7721da4c
RF
2/*
3 * Helper functions used by the EFI stub on multiple
4 * architectures. This should be #included by the EFI stub
5 * implementation files.
6 *
7 * Copyright 2011 Intel Corporation; author Matt Fleming
7721da4c 8 */
7721da4c 9
bd669475
AB
10#include <linux/efi.h>
11#include <asm/efi.h>
12
13#include "efistub.h"
9bb40191 14
5a17dae4
MF
15/*
16 * Some firmware implementations have problems reading files in one go.
17 * A read chunk size of 1MB seems to work for most platforms.
18 *
19 * Unfortunately, reading files in chunks triggers *other* bugs on some
20 * platforms, so we provide a way to disable this workaround, which can
21 * be done by passing "efi=nochunk" on the EFI boot stub command line.
22 *
23 * If you experience issues with initrd images being corrupt it's worth
24 * trying efi=nochunk, but chunking is enabled by default because there
25 * are far more machines that require the workaround than those that
26 * break with it enabled.
27 */
bd669475 28#define EFI_READ_CHUNK_SIZE (1024 * 1024)
9bb40191 29
5a17dae4
MF
30static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE;
31
60f38de7 32static int __section(.data) __nokaslr;
eeff7d63 33static int __section(.data) __quiet;
4e46c2a9 34static int __section(.data) __novamap;
b617c526 35static bool __section(.data) efi_nosoftreserve;
60f38de7
AB
36
37int __pure nokaslr(void)
38{
39 return __nokaslr;
40}
eeff7d63
AB
41int __pure is_quiet(void)
42{
43 return __quiet;
44}
4e46c2a9
AB
45int __pure novamap(void)
46{
47 return __novamap;
48}
b617c526
DW
49bool __pure __efi_soft_reserve_enabled(void)
50{
51 return !efi_nosoftreserve;
52}
60f38de7 53
dadb57ab
JH
54#define EFI_MMAP_NR_SLACK_SLOTS 8
55
36f8961c 56struct file_info {
7721da4c
RF
57 efi_file_handle_t *handle;
58 u64 size;
59};
60
bd669475 61void efi_printk(efi_system_table_t *sys_table_arg, char *str)
7721da4c
RF
62{
63 char *s8;
64
65 for (s8 = str; *s8; s8++) {
66 efi_char16_t ch[2] = { 0 };
67
68 ch[0] = *s8;
69 if (*s8 == '\n') {
70 efi_char16_t nl[2] = { '\r', 0 };
876dc36a 71 efi_char16_printk(sys_table_arg, nl);
7721da4c
RF
72 }
73
876dc36a 74 efi_char16_printk(sys_table_arg, ch);
7721da4c
RF
75 }
76}
77
dadb57ab
JH
78static inline bool mmap_has_headroom(unsigned long buff_size,
79 unsigned long map_size,
80 unsigned long desc_size)
81{
82 unsigned long slack = buff_size - map_size;
83
84 return slack / desc_size >= EFI_MMAP_NR_SLACK_SLOTS;
85}
86
bd669475 87efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg,
dadb57ab 88 struct efi_boot_memmap *map)
7721da4c
RF
89{
90 efi_memory_desc_t *m = NULL;
91 efi_status_t status;
92 unsigned long key;
93 u32 desc_version;
94
dadb57ab
JH
95 *map->desc_size = sizeof(*m);
96 *map->map_size = *map->desc_size * 32;
97 *map->buff_size = *map->map_size;
43a9f696 98again:
204b0a1a 99 status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
dadb57ab 100 *map->map_size, (void **)&m);
7721da4c
RF
101 if (status != EFI_SUCCESS)
102 goto fail;
103
dadb57ab 104 *map->desc_size = 0;
43a9f696 105 key = 0;
dadb57ab
JH
106 status = efi_call_early(get_memory_map, map->map_size, m,
107 &key, map->desc_size, &desc_version);
108 if (status == EFI_BUFFER_TOO_SMALL ||
109 !mmap_has_headroom(*map->buff_size, *map->map_size,
110 *map->desc_size)) {
204b0a1a 111 efi_call_early(free_pool, m);
dadb57ab
JH
112 /*
113 * Make sure there is some entries of headroom so that the
114 * buffer can be reused for a new map after allocations are
115 * no longer permitted. Its unlikely that the map will grow to
116 * exceed this headroom once we are ready to trigger
117 * ExitBootServices()
118 */
119 *map->map_size += *map->desc_size * EFI_MMAP_NR_SLACK_SLOTS;
120 *map->buff_size = *map->map_size;
43a9f696 121 goto again;
7721da4c
RF
122 }
123
124 if (status != EFI_SUCCESS)
204b0a1a 125 efi_call_early(free_pool, m);
54b52d87 126
dadb57ab
JH
127 if (map->key_ptr && status == EFI_SUCCESS)
128 *map->key_ptr = key;
129 if (map->desc_ver && status == EFI_SUCCESS)
130 *map->desc_ver = desc_version;
7721da4c
RF
131
132fail:
dadb57ab 133 *map->map = m;
7721da4c
RF
134 return status;
135}
136
9bb40191 137
ddeeefe2 138unsigned long get_dram_base(efi_system_table_t *sys_table_arg)
9bb40191
RF
139{
140 efi_status_t status;
dadb57ab 141 unsigned long map_size, buff_size;
9bb40191
RF
142 unsigned long membase = EFI_ERROR;
143 struct efi_memory_map map;
144 efi_memory_desc_t *md;
dadb57ab 145 struct efi_boot_memmap boot_map;
9bb40191 146
dadb57ab
JH
147 boot_map.map = (efi_memory_desc_t **)&map.map;
148 boot_map.map_size = &map_size;
149 boot_map.desc_size = &map.desc_size;
150 boot_map.desc_ver = NULL;
151 boot_map.key_ptr = NULL;
152 boot_map.buff_size = &buff_size;
153
154 status = efi_get_memory_map(sys_table_arg, &boot_map);
9bb40191
RF
155 if (status != EFI_SUCCESS)
156 return membase;
157
158 map.map_end = map.map + map_size;
159
78ce248f
MF
160 for_each_efi_memory_desc_in_map(&map, md) {
161 if (md->attribute & EFI_MEMORY_WB) {
9bb40191
RF
162 if (membase > md->phys_addr)
163 membase = md->phys_addr;
78ce248f
MF
164 }
165 }
9bb40191
RF
166
167 efi_call_early(free_pool, map.map);
168
169 return membase;
170}
171
7721da4c
RF
172/*
173 * Allocate at the highest possible address that is not above 'max'.
174 */
bd669475
AB
175efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg,
176 unsigned long size, unsigned long align,
177 unsigned long *addr, unsigned long max)
7721da4c 178{
dadb57ab 179 unsigned long map_size, desc_size, buff_size;
7721da4c
RF
180 efi_memory_desc_t *map;
181 efi_status_t status;
182 unsigned long nr_pages;
183 u64 max_addr = 0;
184 int i;
dadb57ab
JH
185 struct efi_boot_memmap boot_map;
186
187 boot_map.map = &map;
188 boot_map.map_size = &map_size;
189 boot_map.desc_size = &desc_size;
190 boot_map.desc_ver = NULL;
191 boot_map.key_ptr = NULL;
192 boot_map.buff_size = &buff_size;
7721da4c 193
dadb57ab 194 status = efi_get_memory_map(sys_table_arg, &boot_map);
7721da4c
RF
195 if (status != EFI_SUCCESS)
196 goto fail;
197
38dd9c02 198 /*
5b88a31c
RF
199 * Enforce minimum alignment that EFI or Linux requires when
200 * requesting a specific address. We are doing page-based (or
201 * larger) allocations, and both the address and size must meet
202 * alignment constraints.
38dd9c02 203 */
cf2b0f10
AB
204 if (align < EFI_ALLOC_ALIGN)
205 align = EFI_ALLOC_ALIGN;
38dd9c02 206
5b88a31c
RF
207 size = round_up(size, EFI_ALLOC_ALIGN);
208 nr_pages = size / EFI_PAGE_SIZE;
7721da4c
RF
209again:
210 for (i = 0; i < map_size / desc_size; i++) {
211 efi_memory_desc_t *desc;
212 unsigned long m = (unsigned long)map;
213 u64 start, end;
214
02e43c2d 215 desc = efi_early_memdesc_ptr(m, desc_size, i);
7721da4c
RF
216 if (desc->type != EFI_CONVENTIONAL_MEMORY)
217 continue;
218
b617c526
DW
219 if (efi_soft_reserve_enabled() &&
220 (desc->attribute & EFI_MEMORY_SP))
221 continue;
222
7721da4c
RF
223 if (desc->num_pages < nr_pages)
224 continue;
225
226 start = desc->phys_addr;
5b88a31c 227 end = start + desc->num_pages * EFI_PAGE_SIZE;
7721da4c 228
7ed620bb 229 if (end > max)
7721da4c
RF
230 end = max;
231
7ed620bb
YL
232 if ((start + size) > end)
233 continue;
234
7721da4c
RF
235 if (round_down(end - size, align) < start)
236 continue;
237
238 start = round_down(end - size, align);
239
240 /*
241 * Don't allocate at 0x0. It will confuse code that
242 * checks pointers against NULL.
243 */
244 if (start == 0x0)
245 continue;
246
247 if (start > max_addr)
248 max_addr = start;
249 }
250
251 if (!max_addr)
252 status = EFI_NOT_FOUND;
253 else {
204b0a1a
MF
254 status = efi_call_early(allocate_pages,
255 EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
256 nr_pages, &max_addr);
7721da4c
RF
257 if (status != EFI_SUCCESS) {
258 max = max_addr;
259 max_addr = 0;
260 goto again;
261 }
262
263 *addr = max_addr;
264 }
265
204b0a1a 266 efi_call_early(free_pool, map);
7721da4c
RF
267fail:
268 return status;
269}
270
271/*
220dd769 272 * Allocate at the lowest possible address that is not below 'min'.
7721da4c 273 */
220dd769
KS
274efi_status_t efi_low_alloc_above(efi_system_table_t *sys_table_arg,
275 unsigned long size, unsigned long align,
276 unsigned long *addr, unsigned long min)
7721da4c 277{
dadb57ab 278 unsigned long map_size, desc_size, buff_size;
7721da4c
RF
279 efi_memory_desc_t *map;
280 efi_status_t status;
281 unsigned long nr_pages;
282 int i;
dadb57ab
JH
283 struct efi_boot_memmap boot_map;
284
285 boot_map.map = &map;
286 boot_map.map_size = &map_size;
287 boot_map.desc_size = &desc_size;
288 boot_map.desc_ver = NULL;
289 boot_map.key_ptr = NULL;
290 boot_map.buff_size = &buff_size;
7721da4c 291
dadb57ab 292 status = efi_get_memory_map(sys_table_arg, &boot_map);
7721da4c
RF
293 if (status != EFI_SUCCESS)
294 goto fail;
295
38dd9c02 296 /*
5b88a31c
RF
297 * Enforce minimum alignment that EFI or Linux requires when
298 * requesting a specific address. We are doing page-based (or
299 * larger) allocations, and both the address and size must meet
300 * alignment constraints.
38dd9c02 301 */
cf2b0f10
AB
302 if (align < EFI_ALLOC_ALIGN)
303 align = EFI_ALLOC_ALIGN;
38dd9c02 304
5b88a31c
RF
305 size = round_up(size, EFI_ALLOC_ALIGN);
306 nr_pages = size / EFI_PAGE_SIZE;
7721da4c
RF
307 for (i = 0; i < map_size / desc_size; i++) {
308 efi_memory_desc_t *desc;
309 unsigned long m = (unsigned long)map;
310 u64 start, end;
311
02e43c2d 312 desc = efi_early_memdesc_ptr(m, desc_size, i);
7721da4c
RF
313
314 if (desc->type != EFI_CONVENTIONAL_MEMORY)
315 continue;
316
b617c526
DW
317 if (efi_soft_reserve_enabled() &&
318 (desc->attribute & EFI_MEMORY_SP))
319 continue;
320
7721da4c
RF
321 if (desc->num_pages < nr_pages)
322 continue;
323
324 start = desc->phys_addr;
5b88a31c 325 end = start + desc->num_pages * EFI_PAGE_SIZE;
7721da4c 326
220dd769
KS
327 if (start < min)
328 start = min;
7721da4c
RF
329
330 start = round_up(start, align);
331 if ((start + size) > end)
332 continue;
333
204b0a1a
MF
334 status = efi_call_early(allocate_pages,
335 EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
336 nr_pages, &start);
7721da4c
RF
337 if (status == EFI_SUCCESS) {
338 *addr = start;
339 break;
340 }
341 }
342
343 if (i == map_size / desc_size)
344 status = EFI_NOT_FOUND;
345
204b0a1a 346 efi_call_early(free_pool, map);
7721da4c
RF
347fail:
348 return status;
349}
350
bd669475
AB
351void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
352 unsigned long addr)
7721da4c
RF
353{
354 unsigned long nr_pages;
355
0e1cadb0
RF
356 if (!size)
357 return;
358
cf2b0f10 359 nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
204b0a1a 360 efi_call_early(free_pages, addr, nr_pages);
7721da4c
RF
361}
362
2bd79f30
LW
363static efi_status_t efi_file_size(efi_system_table_t *sys_table_arg, void *__fh,
364 efi_char16_t *filename_16, void **handle,
365 u64 *file_sz)
366{
367 efi_file_handle_t *h, *fh = __fh;
368 efi_file_info_t *info;
369 efi_status_t status;
370 efi_guid_t info_guid = EFI_FILE_INFO_ID;
371 unsigned long info_sz;
372
14e900c7 373 status = fh->open(fh, &h, filename_16, EFI_FILE_MODE_READ, 0);
2bd79f30
LW
374 if (status != EFI_SUCCESS) {
375 efi_printk(sys_table_arg, "Failed to open file: ");
376 efi_char16_printk(sys_table_arg, filename_16);
377 efi_printk(sys_table_arg, "\n");
378 return status;
379 }
380
381 *handle = h;
382
383 info_sz = 0;
14e900c7 384 status = h->get_info(h, &info_guid, &info_sz, NULL);
2bd79f30
LW
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
14e900c7 398 status = h->get_info(h, &info_guid, &info_sz, info);
2bd79f30
LW
399 if (status == EFI_BUFFER_TOO_SMALL) {
400 efi_call_early(free_pool, info);
401 goto grow;
402 }
403
404 *file_sz = info->file_size;
405 efi_call_early(free_pool, info);
406
407 if (status != EFI_SUCCESS)
408 efi_printk(sys_table_arg, "Failed to get initrd info\n");
409
410 return status;
411}
412
960a8d01
AB
413static efi_status_t efi_file_read(efi_file_handle_t *handle,
414 unsigned long *size, void *addr)
2bd79f30 415{
14e900c7 416 return handle->read(handle, size, addr);
2bd79f30
LW
417}
418
960a8d01 419static efi_status_t efi_file_close(efi_file_handle_t *handle)
2bd79f30 420{
14e900c7 421 return handle->close(handle);
2bd79f30
LW
422}
423
c4db9c1e
LW
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;
14e900c7 432 efi_handle_t handle = image->device_handle;
c4db9c1e
LW
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
14e900c7 441 status = io->open_volume(io, &fh);
c4db9c1e
LW
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
5a17dae4
MF
450/*
451 * Parse the ASCII string 'cmdline' for EFI options, denoted by the efi=
452 * option, e.g. efi=nochunk.
453 *
454 * It should be noted that efi= is parsed in two very different
455 * environments, first in the early boot environment of the EFI boot
456 * stub, and subsequently during the kernel boot.
457 */
60f38de7 458efi_status_t efi_parse_options(char const *cmdline)
5a17dae4
MF
459{
460 char *str;
461
60f38de7
AB
462 str = strstr(cmdline, "nokaslr");
463 if (str == cmdline || (str && str > cmdline && *(str - 1) == ' '))
464 __nokaslr = 1;
b3879a4d 465
eeff7d63
AB
466 str = strstr(cmdline, "quiet");
467 if (str == cmdline || (str && str > cmdline && *(str - 1) == ' '))
468 __quiet = 1;
469
5a17dae4
MF
470 /*
471 * If no EFI parameters were specified on the cmdline we've got
472 * nothing to do.
473 */
474 str = strstr(cmdline, "efi=");
475 if (!str)
476 return EFI_SUCCESS;
477
478 /* Skip ahead to first argument */
479 str += strlen("efi=");
480
481 /*
482 * Remember, because efi= is also used by the kernel we need to
483 * skip over arguments we don't understand.
484 */
4c3f14bb 485 while (*str && *str != ' ') {
5a17dae4
MF
486 if (!strncmp(str, "nochunk", 7)) {
487 str += strlen("nochunk");
488 __chunk_size = -1UL;
489 }
490
4e46c2a9
AB
491 if (!strncmp(str, "novamap", 7)) {
492 str += strlen("novamap");
493 __novamap = 1;
494 }
495
b617c526
DW
496 if (IS_ENABLED(CONFIG_EFI_SOFT_RESERVE) &&
497 !strncmp(str, "nosoftreserve", 7)) {
498 str += strlen("nosoftreserve");
499 efi_nosoftreserve = 1;
500 }
501
5a17dae4 502 /* Group words together, delimited by "," */
4c3f14bb 503 while (*str && *str != ' ' && *str != ',')
5a17dae4
MF
504 str++;
505
506 if (*str == ',')
507 str++;
508 }
509
510 return EFI_SUCCESS;
511}
7721da4c
RF
512
513/*
36f8961c 514 * Check the cmdline for a LILO-style file= arguments.
7721da4c 515 *
36f8961c
RF
516 * We only support loading a file from the same filesystem as
517 * the kernel image.
7721da4c 518 */
bd669475
AB
519efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
520 efi_loaded_image_t *image,
521 char *cmd_line, char *option_string,
522 unsigned long max_addr,
523 unsigned long *load_addr,
524 unsigned long *load_size)
7721da4c 525{
36f8961c
RF
526 struct file_info *files;
527 unsigned long file_addr;
36f8961c 528 u64 file_size_total;
9403e462 529 efi_file_handle_t *fh = NULL;
7721da4c 530 efi_status_t status;
36f8961c 531 int nr_files;
7721da4c
RF
532 char *str;
533 int i, j, k;
534
36f8961c
RF
535 file_addr = 0;
536 file_size_total = 0;
7721da4c 537
46f4582e 538 str = cmd_line;
7721da4c
RF
539
540 j = 0; /* See close_handles */
541
46f4582e
RF
542 if (!load_addr || !load_size)
543 return EFI_INVALID_PARAMETER;
544
545 *load_addr = 0;
546 *load_size = 0;
547
7721da4c
RF
548 if (!str || !*str)
549 return EFI_SUCCESS;
550
36f8961c 551 for (nr_files = 0; *str; nr_files++) {
46f4582e 552 str = strstr(str, option_string);
7721da4c
RF
553 if (!str)
554 break;
555
46f4582e 556 str += strlen(option_string);
7721da4c
RF
557
558 /* Skip any leading slashes */
559 while (*str == '/' || *str == '\\')
560 str++;
561
562 while (*str && *str != ' ' && *str != '\n')
563 str++;
564 }
565
36f8961c 566 if (!nr_files)
7721da4c
RF
567 return EFI_SUCCESS;
568
204b0a1a
MF
569 status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
570 nr_files * sizeof(*files), (void **)&files);
7721da4c 571 if (status != EFI_SUCCESS) {
f966ea02 572 pr_efi_err(sys_table_arg, "Failed to alloc mem for file handle list\n");
7721da4c
RF
573 goto fail;
574 }
575
46f4582e 576 str = cmd_line;
36f8961c
RF
577 for (i = 0; i < nr_files; i++) {
578 struct file_info *file;
7721da4c 579 efi_char16_t filename_16[256];
7721da4c 580 efi_char16_t *p;
7721da4c 581
46f4582e 582 str = strstr(str, option_string);
7721da4c
RF
583 if (!str)
584 break;
585
46f4582e 586 str += strlen(option_string);
7721da4c 587
36f8961c 588 file = &files[i];
7721da4c
RF
589 p = filename_16;
590
591 /* Skip any leading slashes */
592 while (*str == '/' || *str == '\\')
593 str++;
594
595 while (*str && *str != ' ' && *str != '\n') {
596 if ((u8 *)p >= (u8 *)filename_16 + sizeof(filename_16))
597 break;
598
599 if (*str == '/') {
600 *p++ = '\\';
4e283088 601 str++;
7721da4c
RF
602 } else {
603 *p++ = *str++;
604 }
605 }
606
607 *p = '\0';
608
609 /* Only open the volume once. */
610 if (!i) {
c4db9c1e 611 status = efi_open_volume(sys_table_arg, image, &fh);
54b52d87 612 if (status != EFI_SUCCESS)
36f8961c 613 goto free_files;
7721da4c
RF
614 }
615
54b52d87
MF
616 status = efi_file_size(sys_table_arg, fh, filename_16,
617 (void **)&file->handle, &file->size);
618 if (status != EFI_SUCCESS)
7721da4c 619 goto close_handles;
7721da4c 620
54b52d87 621 file_size_total += file->size;
7721da4c
RF
622 }
623
36f8961c 624 if (file_size_total) {
7721da4c
RF
625 unsigned long addr;
626
627 /*
36f8961c
RF
628 * Multiple files need to be at consecutive addresses in memory,
629 * so allocate enough memory for all the files. This is used
630 * for loading multiple files.
7721da4c 631 */
36f8961c
RF
632 status = efi_high_alloc(sys_table_arg, file_size_total, 0x1000,
633 &file_addr, max_addr);
7721da4c 634 if (status != EFI_SUCCESS) {
f966ea02 635 pr_efi_err(sys_table_arg, "Failed to alloc highmem for files\n");
7721da4c
RF
636 goto close_handles;
637 }
638
639 /* We've run out of free low memory. */
36f8961c 640 if (file_addr > max_addr) {
f966ea02 641 pr_efi_err(sys_table_arg, "We've run out of free low memory\n");
7721da4c 642 status = EFI_INVALID_PARAMETER;
36f8961c 643 goto free_file_total;
7721da4c
RF
644 }
645
36f8961c
RF
646 addr = file_addr;
647 for (j = 0; j < nr_files; j++) {
6a5fe770 648 unsigned long size;
7721da4c 649
36f8961c 650 size = files[j].size;
7721da4c 651 while (size) {
6a5fe770 652 unsigned long chunksize;
b3879a4d
AB
653
654 if (IS_ENABLED(CONFIG_X86) && size > __chunk_size)
5a17dae4 655 chunksize = __chunk_size;
7721da4c
RF
656 else
657 chunksize = size;
54b52d87 658
47514c99 659 status = efi_file_read(files[j].handle,
54b52d87
MF
660 &chunksize,
661 (void *)addr);
7721da4c 662 if (status != EFI_SUCCESS) {
f966ea02 663 pr_efi_err(sys_table_arg, "Failed to read file\n");
36f8961c 664 goto free_file_total;
7721da4c
RF
665 }
666 addr += chunksize;
667 size -= chunksize;
668 }
669
47514c99 670 efi_file_close(files[j].handle);
7721da4c
RF
671 }
672
673 }
674
204b0a1a 675 efi_call_early(free_pool, files);
7721da4c 676
36f8961c
RF
677 *load_addr = file_addr;
678 *load_size = file_size_total;
7721da4c
RF
679
680 return status;
681
36f8961c
RF
682free_file_total:
683 efi_free(sys_table_arg, file_size_total, file_addr);
7721da4c
RF
684
685close_handles:
686 for (k = j; k < i; k++)
47514c99 687 efi_file_close(files[k].handle);
36f8961c 688free_files:
204b0a1a 689 efi_call_early(free_pool, files);
7721da4c 690fail:
46f4582e
RF
691 *load_addr = 0;
692 *load_size = 0;
7721da4c
RF
693
694 return status;
695}
4a9f3a7c
RF
696/*
697 * Relocate a kernel image, either compressed or uncompressed.
698 * In the ARM64 case, all kernel images are currently
699 * uncompressed, and as such when we relocate it we need to
700 * allocate additional space for the BSS segment. Any low
701 * memory that this function should avoid needs to be
702 * unavailable in the EFI memory map, as if the preferred
703 * address is not available the lowest available address will
704 * be used.
705 */
bd669475
AB
706efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
707 unsigned long *image_addr,
708 unsigned long image_size,
709 unsigned long alloc_size,
710 unsigned long preferred_addr,
220dd769
KS
711 unsigned long alignment,
712 unsigned long min_addr)
c6866d72 713{
4a9f3a7c
RF
714 unsigned long cur_image_addr;
715 unsigned long new_addr = 0;
c6866d72 716 efi_status_t status;
4a9f3a7c
RF
717 unsigned long nr_pages;
718 efi_physical_addr_t efi_addr = preferred_addr;
719
720 if (!image_addr || !image_size || !alloc_size)
721 return EFI_INVALID_PARAMETER;
722 if (alloc_size < image_size)
723 return EFI_INVALID_PARAMETER;
724
725 cur_image_addr = *image_addr;
c6866d72
RF
726
727 /*
728 * The EFI firmware loader could have placed the kernel image
4a9f3a7c
RF
729 * anywhere in memory, but the kernel has restrictions on the
730 * max physical address it can run at. Some architectures
731 * also have a prefered address, so first try to relocate
732 * to the preferred address. If that fails, allocate as low
733 * as possible while respecting the required alignment.
c6866d72 734 */
cf2b0f10 735 nr_pages = round_up(alloc_size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
204b0a1a
MF
736 status = efi_call_early(allocate_pages,
737 EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
738 nr_pages, &efi_addr);
4a9f3a7c
RF
739 new_addr = efi_addr;
740 /*
741 * If preferred address allocation failed allocate as low as
742 * possible.
743 */
c6866d72 744 if (status != EFI_SUCCESS) {
220dd769
KS
745 status = efi_low_alloc_above(sys_table_arg, alloc_size,
746 alignment, &new_addr, min_addr);
4a9f3a7c
RF
747 }
748 if (status != EFI_SUCCESS) {
f966ea02 749 pr_efi_err(sys_table_arg, "Failed to allocate usable memory for kernel.\n");
4a9f3a7c 750 return status;
c6866d72
RF
751 }
752
4a9f3a7c
RF
753 /*
754 * We know source/dest won't overlap since both memory ranges
755 * have been allocated by UEFI, so we can safely use memcpy.
756 */
757 memcpy((void *)new_addr, (void *)cur_image_addr, image_size);
c6866d72 758
4a9f3a7c
RF
759 /* Return the new address of the relocated image. */
760 *image_addr = new_addr;
c6866d72
RF
761
762 return status;
763}
5fef3870 764
c625d1c2
PA
765/*
766 * Get the number of UTF-8 bytes corresponding to an UTF-16 character.
767 * This overestimates for surrogates, but that is okay.
768 */
769static int efi_utf8_bytes(u16 c)
770{
771 return 1 + (c >= 0x80) + (c >= 0x800);
772}
773
774/*
775 * Convert an UTF-16 string, not necessarily null terminated, to UTF-8.
776 */
777static u8 *efi_utf16_to_utf8(u8 *dst, const u16 *src, int n)
778{
779 unsigned int c;
780
781 while (n--) {
782 c = *src++;
783 if (n && c >= 0xd800 && c <= 0xdbff &&
784 *src >= 0xdc00 && *src <= 0xdfff) {
785 c = 0x10000 + ((c & 0x3ff) << 10) + (*src & 0x3ff);
786 src++;
787 n--;
788 }
789 if (c >= 0xd800 && c <= 0xdfff)
790 c = 0xfffd; /* Unmatched surrogate */
791 if (c < 0x80) {
792 *dst++ = c;
793 continue;
794 }
795 if (c < 0x800) {
796 *dst++ = 0xc0 + (c >> 6);
797 goto t1;
798 }
799 if (c < 0x10000) {
800 *dst++ = 0xe0 + (c >> 12);
801 goto t2;
802 }
803 *dst++ = 0xf0 + (c >> 18);
804 *dst++ = 0x80 + ((c >> 12) & 0x3f);
805 t2:
806 *dst++ = 0x80 + ((c >> 6) & 0x3f);
807 t1:
808 *dst++ = 0x80 + (c & 0x3f);
809 }
810
811 return dst;
812}
813
48fcb2d0
AB
814#ifndef MAX_CMDLINE_ADDRESS
815#define MAX_CMDLINE_ADDRESS ULONG_MAX
816#endif
817
5fef3870
RF
818/*
819 * Convert the unicode UEFI command line to ASCII to pass to kernel.
820 * Size of memory allocated return in *cmd_line_len.
821 * Returns NULL on error.
822 */
bd669475
AB
823char *efi_convert_cmdline(efi_system_table_t *sys_table_arg,
824 efi_loaded_image_t *image,
825 int *cmd_line_len)
5fef3870 826{
c625d1c2 827 const u16 *s2;
5fef3870
RF
828 u8 *s1 = NULL;
829 unsigned long cmdline_addr = 0;
c625d1c2
PA
830 int load_options_chars = image->load_options_size / 2; /* UTF-16 */
831 const u16 *options = image->load_options;
832 int options_bytes = 0; /* UTF-8 bytes */
833 int options_chars = 0; /* UTF-16 chars */
5fef3870 834 efi_status_t status;
5fef3870
RF
835 u16 zero = 0;
836
837 if (options) {
838 s2 = options;
c625d1c2
PA
839 while (*s2 && *s2 != '\n'
840 && options_chars < load_options_chars) {
841 options_bytes += efi_utf8_bytes(*s2++);
842 options_chars++;
5fef3870
RF
843 }
844 }
845
c625d1c2 846 if (!options_chars) {
5fef3870 847 /* No command line options, so return empty string*/
5fef3870
RF
848 options = &zero;
849 }
850
c625d1c2 851 options_bytes++; /* NUL termination */
9403e462 852
48fcb2d0
AB
853 status = efi_high_alloc(sys_table_arg, options_bytes, 0,
854 &cmdline_addr, MAX_CMDLINE_ADDRESS);
5fef3870
RF
855 if (status != EFI_SUCCESS)
856 return NULL;
857
858 s1 = (u8 *)cmdline_addr;
c625d1c2 859 s2 = (const u16 *)options;
5fef3870 860
c625d1c2 861 s1 = efi_utf16_to_utf8(s1, s2, options_chars);
5fef3870
RF
862 *s1 = '\0';
863
c625d1c2 864 *cmd_line_len = options_bytes;
5fef3870
RF
865 return (char *)cmdline_addr;
866}
fc07716b
JH
867
868/*
869 * Handle calling ExitBootServices according to the requirements set out by the
870 * spec. Obtains the current memory map, and returns that info after calling
871 * ExitBootServices. The client must specify a function to perform any
872 * processing of the memory map data prior to ExitBootServices. A client
873 * specific structure may be passed to the function via priv. The client
874 * function may be called multiple times.
875 */
876efi_status_t efi_exit_boot_services(efi_system_table_t *sys_table_arg,
877 void *handle,
878 struct efi_boot_memmap *map,
879 void *priv,
880 efi_exit_boot_map_processing priv_func)
881{
882 efi_status_t status;
883
884 status = efi_get_memory_map(sys_table_arg, map);
885
886 if (status != EFI_SUCCESS)
887 goto fail;
888
889 status = priv_func(sys_table_arg, map, priv);
890 if (status != EFI_SUCCESS)
891 goto free_map;
892
893 status = efi_call_early(exit_boot_services, handle, *map->key_ptr);
894
895 if (status == EFI_INVALID_PARAMETER) {
896 /*
897 * The memory map changed between efi_get_memory_map() and
898 * exit_boot_services(). Per the UEFI Spec v2.6, Section 6.4:
899 * EFI_BOOT_SERVICES.ExitBootServices we need to get the
900 * updated map, and try again. The spec implies one retry
901 * should be sufficent, which is confirmed against the EDK2
902 * implementation. Per the spec, we can only invoke
903 * get_memory_map() and exit_boot_services() - we cannot alloc
904 * so efi_get_memory_map() cannot be used, and we must reuse
905 * the buffer. For all practical purposes, the headroom in the
906 * buffer should account for any changes in the map so the call
907 * to get_memory_map() is expected to succeed here.
908 */
909 *map->map_size = *map->buff_size;
910 status = efi_call_early(get_memory_map,
911 map->map_size,
912 *map->map,
913 map->key_ptr,
914 map->desc_size,
915 map->desc_ver);
916
917 /* exit_boot_services() was called, thus cannot free */
918 if (status != EFI_SUCCESS)
919 goto fail;
920
921 status = priv_func(sys_table_arg, map, priv);
922 /* exit_boot_services() was called, thus cannot free */
923 if (status != EFI_SUCCESS)
924 goto fail;
925
926 status = efi_call_early(exit_boot_services, handle, *map->key_ptr);
927 }
928
929 /* exit_boot_services() was called, thus cannot free */
930 if (status != EFI_SUCCESS)
931 goto fail;
932
933 return EFI_SUCCESS;
934
935free_map:
936 efi_call_early(free_pool, *map->map);
937fail:
938 return status;
939}
82d736ac
MG
940
941void *get_efi_config_table(efi_system_table_t *sys_table, efi_guid_t guid)
942{
f958efe9
AB
943 unsigned long tables = efi_table_attr(efi_system_table, tables, sys_table);
944 int nr_tables = efi_table_attr(efi_system_table, nr_tables, sys_table);
945 int i;
946
947 for (i = 0; i < nr_tables; i++) {
948 efi_config_table_t *t = (void *)tables;
949
950 if (efi_guidcmp(t->guid, guid) == 0)
951 return efi_table_attr(efi_config_table, table, t);
952
953 tables += efi_is_native() ? sizeof(efi_config_table_t)
954 : sizeof(efi_config_table_32_t);
955 }
956 return NULL;
82d736ac 957}
This page took 0.489541 seconds and 4 git commands to generate.