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