hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/firmware/efi/libstub/efi-stub-helper.c
....@@ -1,888 +1,457 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Helper functions used by the EFI stub on multiple
34 * architectures. This should be #included by the EFI stub
45 * implementation files.
56 *
67 * 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
- *
118 */
129
10
+#include <stdarg.h>
11
+
12
+#include <linux/ctype.h>
1313 #include <linux/efi.h>
14
+#include <linux/kernel.h>
15
+#include <linux/printk.h> /* For CONSOLE_LOGLEVEL_* */
1416 #include <asm/efi.h>
17
+#include <asm/setup.h>
1518
1619 #include "efistub.h"
1720
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.
21
+bool efi_nochunk;
22
+bool efi_nokaslr = !IS_ENABLED(CONFIG_RANDOMIZE_BASE);
23
+bool efi_noinitrd;
24
+int efi_loglevel = CONSOLE_LOGLEVEL_DEFAULT;
25
+bool efi_novamap;
26
+
27
+static bool efi_nosoftreserve;
28
+static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA);
29
+
30
+bool __pure __efi_soft_reserve_enabled(void)
31
+{
32
+ return !efi_nosoftreserve;
33
+}
34
+
35
+/**
36
+ * efi_char16_puts() - Write a UCS-2 encoded string to the console
37
+ * @str: UCS-2 encoded string
3038 */
31
-#define EFI_READ_CHUNK_SIZE (1024 * 1024)
32
-
33
-static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE;
34
-
35
-static int __section(.data) __nokaslr;
36
-static int __section(.data) __quiet;
37
-static int __section(.data) __novamap;
38
-
39
-int __pure nokaslr(void)
39
+void efi_char16_puts(efi_char16_t *str)
4040 {
41
- return __nokaslr;
42
-}
43
-int __pure is_quiet(void)
44
-{
45
- return __quiet;
46
-}
47
-int __pure novamap(void)
48
-{
49
- return __novamap;
41
+ efi_call_proto(efi_table_attr(efi_system_table, con_out),
42
+ output_string, str);
5043 }
5144
52
-#define EFI_MMAP_NR_SLACK_SLOTS 8
53
-
54
-struct file_info {
55
- efi_file_handle_t *handle;
56
- u64 size;
57
-};
58
-
59
-void efi_printk(efi_system_table_t *sys_table_arg, char *str)
45
+static
46
+u32 utf8_to_utf32(const u8 **s8)
6047 {
61
- char *s8;
48
+ u32 c32;
49
+ u8 c0, cx;
50
+ size_t clen, i;
6251
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
-
76
-static 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
-
85
-efi_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;
96
-again:
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
- * Make sure there is some entries of headroom so that the
112
- * buffer can be reused for a new map after allocations are
113
- * no longer permitted. Its unlikely that the map will grow to
114
- * exceed this headroom once we are ready to trigger
115
- * ExitBootServices()
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
-
130
-fail:
131
- *map->map = m;
132
- return status;
133
-}
134
-
135
-
136
-unsigned 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
- * Allocate at the highest possible address that is not above 'max'.
172
- */
173
-efi_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 = &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
-
52
+ c0 = cx = *(*s8)++;
19653 /*
197
- * Enforce minimum alignment that EFI or Linux requires when
198
- * requesting a specific address. We are doing page-based (or
199
- * larger) allocations, and both the address and size must meet
200
- * alignment constraints.
54
+ * The position of the most-significant 0 bit gives us the length of
55
+ * a multi-octet encoding.
20156 */
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;
207
-again:
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 (desc->num_pages < nr_pages)
218
- continue;
219
-
220
- start = desc->phys_addr;
221
- end = start + desc->num_pages * EFI_PAGE_SIZE;
222
-
223
- if (end > max)
224
- end = max;
225
-
226
- if ((start + size) > end)
227
- continue;
228
-
229
- if (round_down(end - size, align) < start)
230
- continue;
231
-
232
- start = round_down(end - size, align);
233
-
234
- /*
235
- * Don't allocate at 0x0. It will confuse code that
236
- * checks pointers against NULL.
237
- */
238
- if (start == 0x0)
239
- continue;
240
-
241
- if (start > max_addr)
242
- max_addr = start;
243
- }
244
-
245
- if (!max_addr)
246
- status = EFI_NOT_FOUND;
247
- else {
248
- status = efi_call_early(allocate_pages,
249
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
250
- nr_pages, &max_addr);
251
- if (status != EFI_SUCCESS) {
252
- max = max_addr;
253
- max_addr = 0;
254
- goto again;
255
- }
256
-
257
- *addr = max_addr;
258
- }
259
-
260
- efi_call_early(free_pool, map);
261
-fail:
262
- return status;
263
-}
264
-
265
-/*
266
- * Allocate at the lowest possible address.
267
- */
268
-efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
269
- unsigned long size, unsigned long align,
270
- unsigned long *addr)
271
-{
272
- unsigned long map_size, desc_size, buff_size;
273
- efi_memory_desc_t *map;
274
- efi_status_t status;
275
- unsigned long nr_pages;
276
- int i;
277
- struct efi_boot_memmap boot_map;
278
-
279
- boot_map.map = &map;
280
- boot_map.map_size = &map_size;
281
- boot_map.desc_size = &desc_size;
282
- boot_map.desc_ver = NULL;
283
- boot_map.key_ptr = NULL;
284
- boot_map.buff_size = &buff_size;
285
-
286
- status = efi_get_memory_map(sys_table_arg, &boot_map);
287
- if (status != EFI_SUCCESS)
288
- goto fail;
289
-
57
+ for (clen = 0; cx & 0x80; ++clen)
58
+ cx <<= 1;
29059 /*
291
- * Enforce minimum alignment that EFI or Linux requires when
292
- * requesting a specific address. We are doing page-based (or
293
- * larger) allocations, and both the address and size must meet
294
- * alignment constraints.
60
+ * If the 0 bit is in position 8, this is a valid single-octet
61
+ * encoding. If the 0 bit is in position 7 or positions 1-3, the
62
+ * encoding is invalid.
63
+ * In either case, we just return the first octet.
29564 */
296
- if (align < EFI_ALLOC_ALIGN)
297
- align = EFI_ALLOC_ALIGN;
65
+ if (clen < 2 || clen > 4)
66
+ return c0;
67
+ /* Get the bits from the first octet. */
68
+ c32 = cx >> clen--;
69
+ for (i = 0; i < clen; ++i) {
70
+ /* Trailing octets must have 10 in most significant bits. */
71
+ cx = (*s8)[i] ^ 0x80;
72
+ if (cx & 0xc0)
73
+ return c0;
74
+ c32 = (c32 << 6) | cx;
75
+ }
76
+ /*
77
+ * Check for validity:
78
+ * - The character must be in the Unicode range.
79
+ * - It must not be a surrogate.
80
+ * - It must be encoded using the correct number of octets.
81
+ */
82
+ if (c32 > 0x10ffff ||
83
+ (c32 & 0xf800) == 0xd800 ||
84
+ clen != (c32 >= 0x80) + (c32 >= 0x800) + (c32 >= 0x10000))
85
+ return c0;
86
+ *s8 += clen;
87
+ return c32;
88
+}
29889
299
- size = round_up(size, EFI_ALLOC_ALIGN);
300
- nr_pages = size / EFI_PAGE_SIZE;
301
- for (i = 0; i < map_size / desc_size; i++) {
302
- efi_memory_desc_t *desc;
303
- unsigned long m = (unsigned long)map;
304
- u64 start, end;
90
+/**
91
+ * efi_puts() - Write a UTF-8 encoded string to the console
92
+ * @str: UTF-8 encoded string
93
+ */
94
+void efi_puts(const char *str)
95
+{
96
+ efi_char16_t buf[128];
97
+ size_t pos = 0, lim = ARRAY_SIZE(buf);
98
+ const u8 *s8 = (const u8 *)str;
99
+ u32 c32;
305100
306
- desc = efi_early_memdesc_ptr(m, desc_size, i);
307
-
308
- if (desc->type != EFI_CONVENTIONAL_MEMORY)
309
- continue;
310
-
311
- if (desc->num_pages < nr_pages)
312
- continue;
313
-
314
- start = desc->phys_addr;
315
- end = start + desc->num_pages * EFI_PAGE_SIZE;
316
-
317
- /*
318
- * Don't allocate at 0x0. It will confuse code that
319
- * checks pointers against NULL. Skip the first 8
320
- * bytes so we start at a nice even number.
321
- */
322
- if (start == 0x0)
323
- start += 8;
324
-
325
- start = round_up(start, align);
326
- if ((start + size) > end)
327
- continue;
328
-
329
- status = efi_call_early(allocate_pages,
330
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
331
- nr_pages, &start);
332
- if (status == EFI_SUCCESS) {
333
- *addr = start;
334
- break;
101
+ while (*s8) {
102
+ if (*s8 == '\n')
103
+ buf[pos++] = L'\r';
104
+ c32 = utf8_to_utf32(&s8);
105
+ if (c32 < 0x10000) {
106
+ /* Characters in plane 0 use a single word. */
107
+ buf[pos++] = c32;
108
+ } else {
109
+ /*
110
+ * Characters in other planes encode into a surrogate
111
+ * pair.
112
+ */
113
+ buf[pos++] = (0xd800 - (0x10000 >> 10)) + (c32 >> 10);
114
+ buf[pos++] = 0xdc00 + (c32 & 0x3ff);
115
+ }
116
+ if (*s8 == '\0' || pos >= lim - 2) {
117
+ buf[pos] = L'\0';
118
+ efi_char16_puts(buf);
119
+ pos = 0;
335120 }
336121 }
337
-
338
- if (i == map_size / desc_size)
339
- status = EFI_NOT_FOUND;
340
-
341
- efi_call_early(free_pool, map);
342
-fail:
343
- return status;
344122 }
345123
346
-void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
347
- unsigned long addr)
124
+/**
125
+ * efi_printk() - Print a kernel message
126
+ * @fmt: format string
127
+ *
128
+ * The first letter of the format string is used to determine the logging level
129
+ * of the message. If the level is less then the current EFI logging level, the
130
+ * message is suppressed. The message will be truncated to 255 bytes.
131
+ *
132
+ * Return: number of printed characters
133
+ */
134
+int efi_printk(const char *fmt, ...)
348135 {
349
- unsigned long nr_pages;
136
+ char printf_buf[256];
137
+ va_list args;
138
+ int printed;
139
+ int loglevel = printk_get_level(fmt);
350140
351
- if (!size)
352
- return;
353
-
354
- nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
355
- efi_call_early(free_pages, addr, nr_pages);
356
-}
357
-
358
-static efi_status_t efi_file_size(efi_system_table_t *sys_table_arg, void *__fh,
359
- efi_char16_t *filename_16, void **handle,
360
- u64 *file_sz)
361
-{
362
- efi_file_handle_t *h, *fh = __fh;
363
- efi_file_info_t *info;
364
- efi_status_t status;
365
- efi_guid_t info_guid = EFI_FILE_INFO_ID;
366
- unsigned long info_sz;
367
-
368
- status = efi_call_proto(efi_file_handle, open, fh, &h, filename_16,
369
- EFI_FILE_MODE_READ, (u64)0);
370
- if (status != EFI_SUCCESS) {
371
- efi_printk(sys_table_arg, "Failed to open file: ");
372
- efi_char16_printk(sys_table_arg, filename_16);
373
- efi_printk(sys_table_arg, "\n");
374
- return status;
141
+ switch (loglevel) {
142
+ case '0' ... '9':
143
+ loglevel -= '0';
144
+ break;
145
+ default:
146
+ /*
147
+ * Use loglevel -1 for cases where we just want to print to
148
+ * the screen.
149
+ */
150
+ loglevel = -1;
151
+ break;
375152 }
376153
377
- *handle = h;
154
+ if (loglevel >= efi_loglevel)
155
+ return 0;
378156
379
- info_sz = 0;
380
- status = efi_call_proto(efi_file_handle, get_info, h, &info_guid,
381
- &info_sz, NULL);
382
- if (status != EFI_BUFFER_TOO_SMALL) {
383
- efi_printk(sys_table_arg, "Failed to get file info size\n");
384
- return status;
157
+ if (loglevel >= 0)
158
+ efi_puts("EFI stub: ");
159
+
160
+ fmt = printk_skip_level(fmt);
161
+
162
+ va_start(args, fmt);
163
+ printed = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args);
164
+ va_end(args);
165
+
166
+ efi_puts(printf_buf);
167
+ if (printed >= sizeof(printf_buf)) {
168
+ efi_puts("[Message truncated]\n");
169
+ return -1;
385170 }
386171
387
-grow:
388
- status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
389
- info_sz, (void **)&info);
390
- if (status != EFI_SUCCESS) {
391
- efi_printk(sys_table_arg, "Failed to alloc mem for file info\n");
392
- return status;
393
- }
394
-
395
- status = efi_call_proto(efi_file_handle, get_info, h, &info_guid,
396
- &info_sz, info);
397
- if (status == EFI_BUFFER_TOO_SMALL) {
398
- efi_call_early(free_pool, info);
399
- goto grow;
400
- }
401
-
402
- *file_sz = info->file_size;
403
- efi_call_early(free_pool, info);
404
-
405
- if (status != EFI_SUCCESS)
406
- efi_printk(sys_table_arg, "Failed to get initrd info\n");
407
-
408
- return status;
172
+ return printed;
409173 }
410174
411
-static efi_status_t efi_file_read(void *handle, unsigned long *size, void *addr)
412
-{
413
- return efi_call_proto(efi_file_handle, read, handle, size, addr);
414
-}
415
-
416
-static efi_status_t efi_file_close(void *handle)
417
-{
418
- return efi_call_proto(efi_file_handle, close, handle);
419
-}
420
-
421
-static efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
422
- efi_loaded_image_t *image,
423
- efi_file_handle_t **__fh)
424
-{
425
- efi_file_io_interface_t *io;
426
- efi_file_handle_t *fh;
427
- efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
428
- efi_status_t status;
429
- void *handle = (void *)(unsigned long)efi_table_attr(efi_loaded_image,
430
- device_handle,
431
- image);
432
-
433
- status = efi_call_early(handle_protocol, handle,
434
- &fs_proto, (void **)&io);
435
- if (status != EFI_SUCCESS) {
436
- efi_printk(sys_table_arg, "Failed to handle fs_proto\n");
437
- return status;
438
- }
439
-
440
- status = efi_call_proto(efi_file_io_interface, open_volume, io, &fh);
441
- if (status != EFI_SUCCESS)
442
- efi_printk(sys_table_arg, "Failed to open volume\n");
443
- else
444
- *__fh = fh;
445
-
446
- return status;
447
-}
448
-
449
-/*
450
- * Parse the ASCII string 'cmdline' for EFI options, denoted by the efi=
175
+/**
176
+ * efi_parse_options() - Parse EFI command line options
177
+ * @cmdline: kernel command line
178
+ *
179
+ * Parse the ASCII string @cmdline for EFI options, denoted by the efi=
451180 * option, e.g. efi=nochunk.
452181 *
453182 * It should be noted that efi= is parsed in two very different
454183 * environments, first in the early boot environment of the EFI boot
455184 * stub, and subsequently during the kernel boot.
185
+ *
186
+ * Return: status code
456187 */
457188 efi_status_t efi_parse_options(char const *cmdline)
458189 {
459
- char *str;
190
+ size_t len;
191
+ efi_status_t status;
192
+ char *str, *buf;
460193
461
- str = strstr(cmdline, "nokaslr");
462
- if (str == cmdline || (str && str > cmdline && *(str - 1) == ' '))
463
- __nokaslr = 1;
464
-
465
- str = strstr(cmdline, "quiet");
466
- if (str == cmdline || (str && str > cmdline && *(str - 1) == ' '))
467
- __quiet = 1;
468
-
469
- /*
470
- * If no EFI parameters were specified on the cmdline we've got
471
- * nothing to do.
472
- */
473
- str = strstr(cmdline, "efi=");
474
- if (!str)
194
+ if (!cmdline)
475195 return EFI_SUCCESS;
476196
477
- /* Skip ahead to first argument */
478
- str += strlen("efi=");
197
+ len = strnlen(cmdline, COMMAND_LINE_SIZE - 1) + 1;
198
+ status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, len, (void **)&buf);
199
+ if (status != EFI_SUCCESS)
200
+ return status;
479201
480
- /*
481
- * Remember, because efi= is also used by the kernel we need to
482
- * skip over arguments we don't understand.
483
- */
484
- while (*str && *str != ' ') {
485
- if (!strncmp(str, "nochunk", 7)) {
486
- str += strlen("nochunk");
487
- __chunk_size = -1UL;
202
+ memcpy(buf, cmdline, len - 1);
203
+ buf[len - 1] = '\0';
204
+ str = skip_spaces(buf);
205
+
206
+ while (*str) {
207
+ char *param, *val;
208
+
209
+ str = next_arg(str, &param, &val);
210
+ if (!val && !strcmp(param, "--"))
211
+ break;
212
+
213
+ if (!strcmp(param, "nokaslr")) {
214
+ efi_nokaslr = true;
215
+ } else if (!strcmp(param, "quiet")) {
216
+ efi_loglevel = CONSOLE_LOGLEVEL_QUIET;
217
+ } else if (!strcmp(param, "noinitrd")) {
218
+ efi_noinitrd = true;
219
+ } else if (!strcmp(param, "efi") && val) {
220
+ efi_nochunk = parse_option_str(val, "nochunk");
221
+ efi_novamap = parse_option_str(val, "novamap");
222
+
223
+ efi_nosoftreserve = IS_ENABLED(CONFIG_EFI_SOFT_RESERVE) &&
224
+ parse_option_str(val, "nosoftreserve");
225
+
226
+ if (parse_option_str(val, "disable_early_pci_dma"))
227
+ efi_disable_pci_dma = true;
228
+ if (parse_option_str(val, "no_disable_early_pci_dma"))
229
+ efi_disable_pci_dma = false;
230
+ if (parse_option_str(val, "debug"))
231
+ efi_loglevel = CONSOLE_LOGLEVEL_DEBUG;
232
+ } else if (!strcmp(param, "video") &&
233
+ val && strstarts(val, "efifb:")) {
234
+ efi_parse_option_graphics(val + strlen("efifb:"));
488235 }
489
-
490
- if (!strncmp(str, "novamap", 7)) {
491
- str += strlen("novamap");
492
- __novamap = 1;
493
- }
494
-
495
- /* Group words together, delimited by "," */
496
- while (*str && *str != ' ' && *str != ',')
497
- str++;
498
-
499
- if (*str == ',')
500
- str++;
501236 }
502
-
237
+ efi_bs_call(free_pool, buf);
503238 return EFI_SUCCESS;
504239 }
505240
506241 /*
507
- * Check the cmdline for a LILO-style file= arguments.
242
+ * The EFI_LOAD_OPTION descriptor has the following layout:
243
+ * u32 Attributes;
244
+ * u16 FilePathListLength;
245
+ * u16 Description[];
246
+ * efi_device_path_protocol_t FilePathList[];
247
+ * u8 OptionalData[];
508248 *
509
- * We only support loading a file from the same filesystem as
510
- * the kernel image.
249
+ * This function validates and unpacks the variable-size data fields.
511250 */
512
-efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
513
- efi_loaded_image_t *image,
514
- char *cmd_line, char *option_string,
515
- unsigned long max_addr,
516
- unsigned long *load_addr,
517
- unsigned long *load_size)
251
+static
252
+bool efi_load_option_unpack(efi_load_option_unpacked_t *dest,
253
+ const efi_load_option_t *src, size_t size)
518254 {
519
- struct file_info *files;
520
- unsigned long file_addr;
521
- u64 file_size_total;
522
- efi_file_handle_t *fh = NULL;
523
- efi_status_t status;
524
- int nr_files;
525
- char *str;
526
- int i, j, k;
255
+ const void *pos;
256
+ u16 c;
257
+ efi_device_path_protocol_t header;
258
+ const efi_char16_t *description;
259
+ const efi_device_path_protocol_t *file_path_list;
527260
528
- file_addr = 0;
529
- file_size_total = 0;
261
+ if (size < offsetof(efi_load_option_t, variable_data))
262
+ return false;
263
+ pos = src->variable_data;
264
+ size -= offsetof(efi_load_option_t, variable_data);
530265
531
- str = cmd_line;
266
+ if ((src->attributes & ~EFI_LOAD_OPTION_MASK) != 0)
267
+ return false;
532268
533
- j = 0; /* See close_handles */
269
+ /* Scan description. */
270
+ description = pos;
271
+ do {
272
+ if (size < sizeof(c))
273
+ return false;
274
+ c = *(const u16 *)pos;
275
+ pos += sizeof(c);
276
+ size -= sizeof(c);
277
+ } while (c != L'\0');
534278
535
- if (!load_addr || !load_size)
536
- return EFI_INVALID_PARAMETER;
279
+ /* Scan file_path_list. */
280
+ file_path_list = pos;
281
+ do {
282
+ if (size < sizeof(header))
283
+ return false;
284
+ header = *(const efi_device_path_protocol_t *)pos;
285
+ if (header.length < sizeof(header))
286
+ return false;
287
+ if (size < header.length)
288
+ return false;
289
+ pos += header.length;
290
+ size -= header.length;
291
+ } while ((header.type != EFI_DEV_END_PATH && header.type != EFI_DEV_END_PATH2) ||
292
+ (header.sub_type != EFI_DEV_END_ENTIRE));
293
+ if (pos != (const void *)file_path_list + src->file_path_list_length)
294
+ return false;
537295
538
- *load_addr = 0;
539
- *load_size = 0;
296
+ dest->attributes = src->attributes;
297
+ dest->file_path_list_length = src->file_path_list_length;
298
+ dest->description = description;
299
+ dest->file_path_list = file_path_list;
300
+ dest->optional_data_size = size;
301
+ dest->optional_data = size ? pos : NULL;
540302
541
- if (!str || !*str)
542
- return EFI_SUCCESS;
543
-
544
- for (nr_files = 0; *str; nr_files++) {
545
- str = strstr(str, option_string);
546
- if (!str)
547
- break;
548
-
549
- str += strlen(option_string);
550
-
551
- /* Skip any leading slashes */
552
- while (*str == '/' || *str == '\\')
553
- str++;
554
-
555
- while (*str && *str != ' ' && *str != '\n')
556
- str++;
557
- }
558
-
559
- if (!nr_files)
560
- return EFI_SUCCESS;
561
-
562
- status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
563
- nr_files * sizeof(*files), (void **)&files);
564
- if (status != EFI_SUCCESS) {
565
- pr_efi_err(sys_table_arg, "Failed to alloc mem for file handle list\n");
566
- goto fail;
567
- }
568
-
569
- str = cmd_line;
570
- for (i = 0; i < nr_files; i++) {
571
- struct file_info *file;
572
- efi_char16_t filename_16[256];
573
- efi_char16_t *p;
574
-
575
- str = strstr(str, option_string);
576
- if (!str)
577
- break;
578
-
579
- str += strlen(option_string);
580
-
581
- file = &files[i];
582
- p = filename_16;
583
-
584
- /* Skip any leading slashes */
585
- while (*str == '/' || *str == '\\')
586
- str++;
587
-
588
- while (*str && *str != ' ' && *str != '\n') {
589
- if ((u8 *)p >= (u8 *)filename_16 + sizeof(filename_16))
590
- break;
591
-
592
- if (*str == '/') {
593
- *p++ = '\\';
594
- str++;
595
- } else {
596
- *p++ = *str++;
597
- }
598
- }
599
-
600
- *p = '\0';
601
-
602
- /* Only open the volume once. */
603
- if (!i) {
604
- status = efi_open_volume(sys_table_arg, image, &fh);
605
- if (status != EFI_SUCCESS)
606
- goto free_files;
607
- }
608
-
609
- status = efi_file_size(sys_table_arg, fh, filename_16,
610
- (void **)&file->handle, &file->size);
611
- if (status != EFI_SUCCESS)
612
- goto close_handles;
613
-
614
- file_size_total += file->size;
615
- }
616
-
617
- if (file_size_total) {
618
- unsigned long addr;
619
-
620
- /*
621
- * Multiple files need to be at consecutive addresses in memory,
622
- * so allocate enough memory for all the files. This is used
623
- * for loading multiple files.
624
- */
625
- status = efi_high_alloc(sys_table_arg, file_size_total, 0x1000,
626
- &file_addr, max_addr);
627
- if (status != EFI_SUCCESS) {
628
- pr_efi_err(sys_table_arg, "Failed to alloc highmem for files\n");
629
- goto close_handles;
630
- }
631
-
632
- /* We've run out of free low memory. */
633
- if (file_addr > max_addr) {
634
- pr_efi_err(sys_table_arg, "We've run out of free low memory\n");
635
- status = EFI_INVALID_PARAMETER;
636
- goto free_file_total;
637
- }
638
-
639
- addr = file_addr;
640
- for (j = 0; j < nr_files; j++) {
641
- unsigned long size;
642
-
643
- size = files[j].size;
644
- while (size) {
645
- unsigned long chunksize;
646
-
647
- if (IS_ENABLED(CONFIG_X86) && size > __chunk_size)
648
- chunksize = __chunk_size;
649
- else
650
- chunksize = size;
651
-
652
- status = efi_file_read(files[j].handle,
653
- &chunksize,
654
- (void *)addr);
655
- if (status != EFI_SUCCESS) {
656
- pr_efi_err(sys_table_arg, "Failed to read file\n");
657
- goto free_file_total;
658
- }
659
- addr += chunksize;
660
- size -= chunksize;
661
- }
662
-
663
- efi_file_close(files[j].handle);
664
- }
665
-
666
- }
667
-
668
- efi_call_early(free_pool, files);
669
-
670
- *load_addr = file_addr;
671
- *load_size = file_size_total;
672
-
673
- return status;
674
-
675
-free_file_total:
676
- efi_free(sys_table_arg, file_size_total, file_addr);
677
-
678
-close_handles:
679
- for (k = j; k < i; k++)
680
- efi_file_close(files[k].handle);
681
-free_files:
682
- efi_call_early(free_pool, files);
683
-fail:
684
- *load_addr = 0;
685
- *load_size = 0;
686
-
687
- return status;
688
-}
689
-/*
690
- * Relocate a kernel image, either compressed or uncompressed.
691
- * In the ARM64 case, all kernel images are currently
692
- * uncompressed, and as such when we relocate it we need to
693
- * allocate additional space for the BSS segment. Any low
694
- * memory that this function should avoid needs to be
695
- * unavailable in the EFI memory map, as if the preferred
696
- * address is not available the lowest available address will
697
- * be used.
698
- */
699
-efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
700
- unsigned long *image_addr,
701
- unsigned long image_size,
702
- unsigned long alloc_size,
703
- unsigned long preferred_addr,
704
- unsigned long alignment)
705
-{
706
- unsigned long cur_image_addr;
707
- unsigned long new_addr = 0;
708
- efi_status_t status;
709
- unsigned long nr_pages;
710
- efi_physical_addr_t efi_addr = preferred_addr;
711
-
712
- if (!image_addr || !image_size || !alloc_size)
713
- return EFI_INVALID_PARAMETER;
714
- if (alloc_size < image_size)
715
- return EFI_INVALID_PARAMETER;
716
-
717
- cur_image_addr = *image_addr;
718
-
719
- /*
720
- * The EFI firmware loader could have placed the kernel image
721
- * anywhere in memory, but the kernel has restrictions on the
722
- * max physical address it can run at. Some architectures
723
- * also have a prefered address, so first try to relocate
724
- * to the preferred address. If that fails, allocate as low
725
- * as possible while respecting the required alignment.
726
- */
727
- nr_pages = round_up(alloc_size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
728
- status = efi_call_early(allocate_pages,
729
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
730
- nr_pages, &efi_addr);
731
- new_addr = efi_addr;
732
- /*
733
- * If preferred address allocation failed allocate as low as
734
- * possible.
735
- */
736
- if (status != EFI_SUCCESS) {
737
- status = efi_low_alloc(sys_table_arg, alloc_size, alignment,
738
- &new_addr);
739
- }
740
- if (status != EFI_SUCCESS) {
741
- pr_efi_err(sys_table_arg, "Failed to allocate usable memory for kernel.\n");
742
- return status;
743
- }
744
-
745
- /*
746
- * We know source/dest won't overlap since both memory ranges
747
- * have been allocated by UEFI, so we can safely use memcpy.
748
- */
749
- memcpy((void *)new_addr, (void *)cur_image_addr, image_size);
750
-
751
- /* Return the new address of the relocated image. */
752
- *image_addr = new_addr;
753
-
754
- return status;
303
+ return true;
755304 }
756305
757306 /*
758
- * Get the number of UTF-8 bytes corresponding to an UTF-16 character.
759
- * This overestimates for surrogates, but that is okay.
307
+ * At least some versions of Dell firmware pass the entire contents of the
308
+ * Boot#### variable, i.e. the EFI_LOAD_OPTION descriptor, rather than just the
309
+ * OptionalData field.
310
+ *
311
+ * Detect this case and extract OptionalData.
760312 */
761
-static int efi_utf8_bytes(u16 c)
313
+void efi_apply_loadoptions_quirk(const void **load_options, int *load_options_size)
762314 {
763
- return 1 + (c >= 0x80) + (c >= 0x800);
315
+ const efi_load_option_t *load_option = *load_options;
316
+ efi_load_option_unpacked_t load_option_unpacked;
317
+
318
+ if (!IS_ENABLED(CONFIG_X86))
319
+ return;
320
+ if (!load_option)
321
+ return;
322
+ if (*load_options_size < sizeof(*load_option))
323
+ return;
324
+ if ((load_option->attributes & ~EFI_LOAD_OPTION_BOOT_MASK) != 0)
325
+ return;
326
+
327
+ if (!efi_load_option_unpack(&load_option_unpacked, load_option, *load_options_size))
328
+ return;
329
+
330
+ efi_warn_once(FW_BUG "LoadOptions is an EFI_LOAD_OPTION descriptor\n");
331
+ efi_warn_once(FW_BUG "Using OptionalData as a workaround\n");
332
+
333
+ *load_options = load_option_unpacked.optional_data;
334
+ *load_options_size = load_option_unpacked.optional_data_size;
764335 }
765
-
766
-/*
767
- * Convert an UTF-16 string, not necessarily null terminated, to UTF-8.
768
- */
769
-static u8 *efi_utf16_to_utf8(u8 *dst, const u16 *src, int n)
770
-{
771
- unsigned int c;
772
-
773
- while (n--) {
774
- c = *src++;
775
- if (n && c >= 0xd800 && c <= 0xdbff &&
776
- *src >= 0xdc00 && *src <= 0xdfff) {
777
- c = 0x10000 + ((c & 0x3ff) << 10) + (*src & 0x3ff);
778
- src++;
779
- n--;
780
- }
781
- if (c >= 0xd800 && c <= 0xdfff)
782
- c = 0xfffd; /* Unmatched surrogate */
783
- if (c < 0x80) {
784
- *dst++ = c;
785
- continue;
786
- }
787
- if (c < 0x800) {
788
- *dst++ = 0xc0 + (c >> 6);
789
- goto t1;
790
- }
791
- if (c < 0x10000) {
792
- *dst++ = 0xe0 + (c >> 12);
793
- goto t2;
794
- }
795
- *dst++ = 0xf0 + (c >> 18);
796
- *dst++ = 0x80 + ((c >> 12) & 0x3f);
797
- t2:
798
- *dst++ = 0x80 + ((c >> 6) & 0x3f);
799
- t1:
800
- *dst++ = 0x80 + (c & 0x3f);
801
- }
802
-
803
- return dst;
804
-}
805
-
806
-#ifndef MAX_CMDLINE_ADDRESS
807
-#define MAX_CMDLINE_ADDRESS ULONG_MAX
808
-#endif
809336
810337 /*
811338 * Convert the unicode UEFI command line to ASCII to pass to kernel.
812339 * Size of memory allocated return in *cmd_line_len.
813340 * Returns NULL on error.
814341 */
815
-char *efi_convert_cmdline(efi_system_table_t *sys_table_arg,
816
- efi_loaded_image_t *image,
817
- int *cmd_line_len)
342
+char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len)
818343 {
819344 const u16 *s2;
820
- u8 *s1 = NULL;
821345 unsigned long cmdline_addr = 0;
822
- int load_options_chars = image->load_options_size / 2; /* UTF-16 */
823
- const u16 *options = image->load_options;
824
- int options_bytes = 0; /* UTF-8 bytes */
825
- int options_chars = 0; /* UTF-16 chars */
346
+ int options_chars = efi_table_attr(image, load_options_size);
347
+ const u16 *options = efi_table_attr(image, load_options);
348
+ int options_bytes = 0, safe_options_bytes = 0; /* UTF-8 bytes */
349
+ bool in_quote = false;
826350 efi_status_t status;
827
- u16 zero = 0;
351
+
352
+ efi_apply_loadoptions_quirk((const void **)&options, &options_chars);
353
+ options_chars /= sizeof(*options);
828354
829355 if (options) {
830356 s2 = options;
831
- while (*s2 && *s2 != '\n'
832
- && options_chars < load_options_chars) {
833
- options_bytes += efi_utf8_bytes(*s2++);
834
- options_chars++;
835
- }
836
- }
357
+ while (options_bytes < COMMAND_LINE_SIZE && options_chars--) {
358
+ u16 c = *s2++;
837359
838
- if (!options_chars) {
839
- /* No command line options, so return empty string*/
840
- options = &zero;
360
+ if (c < 0x80) {
361
+ if (c == L'\0' || c == L'\n')
362
+ break;
363
+ if (c == L'"')
364
+ in_quote = !in_quote;
365
+ else if (!in_quote && isspace((char)c))
366
+ safe_options_bytes = options_bytes;
367
+
368
+ options_bytes++;
369
+ continue;
370
+ }
371
+
372
+ /*
373
+ * Get the number of UTF-8 bytes corresponding to a
374
+ * UTF-16 character.
375
+ * The first part handles everything in the BMP.
376
+ */
377
+ options_bytes += 2 + (c >= 0x800);
378
+ /*
379
+ * Add one more byte for valid surrogate pairs. Invalid
380
+ * surrogates will be replaced with 0xfffd and take up
381
+ * only 3 bytes.
382
+ */
383
+ if ((c & 0xfc00) == 0xd800) {
384
+ /*
385
+ * If the very last word is a high surrogate,
386
+ * we must ignore it since we can't access the
387
+ * low surrogate.
388
+ */
389
+ if (!options_chars) {
390
+ options_bytes -= 3;
391
+ } else if ((*s2 & 0xfc00) == 0xdc00) {
392
+ options_bytes++;
393
+ options_chars--;
394
+ s2++;
395
+ }
396
+ }
397
+ }
398
+ if (options_bytes >= COMMAND_LINE_SIZE) {
399
+ options_bytes = safe_options_bytes;
400
+ efi_err("Command line is too long: truncated to %d bytes\n",
401
+ options_bytes);
402
+ }
841403 }
842404
843405 options_bytes++; /* NUL termination */
844406
845
- status = efi_high_alloc(sys_table_arg, options_bytes, 0,
846
- &cmdline_addr, MAX_CMDLINE_ADDRESS);
407
+ status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, options_bytes,
408
+ (void **)&cmdline_addr);
847409 if (status != EFI_SUCCESS)
848410 return NULL;
849411
850
- s1 = (u8 *)cmdline_addr;
851
- s2 = (const u16 *)options;
852
-
853
- s1 = efi_utf16_to_utf8(s1, s2, options_chars);
854
- *s1 = '\0';
412
+ snprintf((char *)cmdline_addr, options_bytes, "%.*ls",
413
+ options_bytes - 1, options);
855414
856415 *cmd_line_len = options_bytes;
857416 return (char *)cmdline_addr;
858417 }
859418
860
-/*
419
+/**
420
+ * efi_exit_boot_services() - Exit boot services
421
+ * @handle: handle of the exiting image
422
+ * @map: pointer to receive the memory map
423
+ * @priv: argument to be passed to @priv_func
424
+ * @priv_func: function to process the memory map before exiting boot services
425
+ *
861426 * Handle calling ExitBootServices according to the requirements set out by the
862427 * spec. Obtains the current memory map, and returns that info after calling
863428 * ExitBootServices. The client must specify a function to perform any
864429 * processing of the memory map data prior to ExitBootServices. A client
865430 * specific structure may be passed to the function via priv. The client
866431 * function may be called multiple times.
432
+ *
433
+ * Return: status code
867434 */
868
-efi_status_t efi_exit_boot_services(efi_system_table_t *sys_table_arg,
869
- void *handle,
435
+efi_status_t efi_exit_boot_services(void *handle,
870436 struct efi_boot_memmap *map,
871437 void *priv,
872438 efi_exit_boot_map_processing priv_func)
873439 {
874440 efi_status_t status;
875441
876
- status = efi_get_memory_map(sys_table_arg, map);
442
+ status = efi_get_memory_map(map);
877443
878444 if (status != EFI_SUCCESS)
879445 goto fail;
880446
881
- status = priv_func(sys_table_arg, map, priv);
447
+ status = priv_func(map, priv);
882448 if (status != EFI_SUCCESS)
883449 goto free_map;
884450
885
- status = efi_call_early(exit_boot_services, handle, *map->key_ptr);
451
+ if (efi_disable_pci_dma)
452
+ efi_pci_disable_bridge_busmaster();
453
+
454
+ status = efi_bs_call(exit_boot_services, handle, *map->key_ptr);
886455
887456 if (status == EFI_INVALID_PARAMETER) {
888457 /*
....@@ -899,23 +468,23 @@
899468 * to get_memory_map() is expected to succeed here.
900469 */
901470 *map->map_size = *map->buff_size;
902
- status = efi_call_early(get_memory_map,
903
- map->map_size,
904
- *map->map,
905
- map->key_ptr,
906
- map->desc_size,
907
- map->desc_ver);
471
+ status = efi_bs_call(get_memory_map,
472
+ map->map_size,
473
+ *map->map,
474
+ map->key_ptr,
475
+ map->desc_size,
476
+ map->desc_ver);
908477
909478 /* exit_boot_services() was called, thus cannot free */
910479 if (status != EFI_SUCCESS)
911480 goto fail;
912481
913
- status = priv_func(sys_table_arg, map, priv);
482
+ status = priv_func(map, priv);
914483 /* exit_boot_services() was called, thus cannot free */
915484 if (status != EFI_SUCCESS)
916485 goto fail;
917486
918
- status = efi_call_early(exit_boot_services, handle, *map->key_ptr);
487
+ status = efi_bs_call(exit_boot_services, handle, *map->key_ptr);
919488 }
920489
921490 /* exit_boot_services() was called, thus cannot free */
....@@ -925,7 +494,211 @@
925494 return EFI_SUCCESS;
926495
927496 free_map:
928
- efi_call_early(free_pool, *map->map);
497
+ efi_bs_call(free_pool, *map->map);
929498 fail:
930499 return status;
931500 }
501
+
502
+/**
503
+ * get_efi_config_table() - retrieve UEFI configuration table
504
+ * @guid: GUID of the configuration table to be retrieved
505
+ * Return: pointer to the configuration table or NULL
506
+ */
507
+void *get_efi_config_table(efi_guid_t guid)
508
+{
509
+ unsigned long tables = efi_table_attr(efi_system_table, tables);
510
+ int nr_tables = efi_table_attr(efi_system_table, nr_tables);
511
+ int i;
512
+
513
+ for (i = 0; i < nr_tables; i++) {
514
+ efi_config_table_t *t = (void *)tables;
515
+
516
+ if (efi_guidcmp(t->guid, guid) == 0)
517
+ return efi_table_attr(t, table);
518
+
519
+ tables += efi_is_native() ? sizeof(efi_config_table_t)
520
+ : sizeof(efi_config_table_32_t);
521
+ }
522
+ return NULL;
523
+}
524
+
525
+/*
526
+ * The LINUX_EFI_INITRD_MEDIA_GUID vendor media device path below provides a way
527
+ * for the firmware or bootloader to expose the initrd data directly to the stub
528
+ * via the trivial LoadFile2 protocol, which is defined in the UEFI spec, and is
529
+ * very easy to implement. It is a simple Linux initrd specific conduit between
530
+ * kernel and firmware, allowing us to put the EFI stub (being part of the
531
+ * kernel) in charge of where and when to load the initrd, while leaving it up
532
+ * to the firmware to decide whether it needs to expose its filesystem hierarchy
533
+ * via EFI protocols.
534
+ */
535
+static const struct {
536
+ struct efi_vendor_dev_path vendor;
537
+ struct efi_generic_dev_path end;
538
+} __packed initrd_dev_path = {
539
+ {
540
+ {
541
+ EFI_DEV_MEDIA,
542
+ EFI_DEV_MEDIA_VENDOR,
543
+ sizeof(struct efi_vendor_dev_path),
544
+ },
545
+ LINUX_EFI_INITRD_MEDIA_GUID
546
+ }, {
547
+ EFI_DEV_END_PATH,
548
+ EFI_DEV_END_ENTIRE,
549
+ sizeof(struct efi_generic_dev_path)
550
+ }
551
+};
552
+
553
+/**
554
+ * efi_load_initrd_dev_path() - load the initrd from the Linux initrd device path
555
+ * @load_addr: pointer to store the address where the initrd was loaded
556
+ * @load_size: pointer to store the size of the loaded initrd
557
+ * @max: upper limit for the initrd memory allocation
558
+ *
559
+ * Return:
560
+ * * %EFI_SUCCESS if the initrd was loaded successfully, in which
561
+ * case @load_addr and @load_size are assigned accordingly
562
+ * * %EFI_NOT_FOUND if no LoadFile2 protocol exists on the initrd device path
563
+ * * %EFI_INVALID_PARAMETER if load_addr == NULL or load_size == NULL
564
+ * * %EFI_OUT_OF_RESOURCES if memory allocation failed
565
+ * * %EFI_LOAD_ERROR in all other cases
566
+ */
567
+static
568
+efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr,
569
+ unsigned long *load_size,
570
+ unsigned long max)
571
+{
572
+ efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
573
+ efi_device_path_protocol_t *dp;
574
+ efi_load_file2_protocol_t *lf2;
575
+ unsigned long initrd_addr;
576
+ unsigned long initrd_size;
577
+ efi_handle_t handle;
578
+ efi_status_t status;
579
+
580
+ dp = (efi_device_path_protocol_t *)&initrd_dev_path;
581
+ status = efi_bs_call(locate_device_path, &lf2_proto_guid, &dp, &handle);
582
+ if (status != EFI_SUCCESS)
583
+ return status;
584
+
585
+ status = efi_bs_call(handle_protocol, handle, &lf2_proto_guid,
586
+ (void **)&lf2);
587
+ if (status != EFI_SUCCESS)
588
+ return status;
589
+
590
+ status = efi_call_proto(lf2, load_file, dp, false, &initrd_size, NULL);
591
+ if (status != EFI_BUFFER_TOO_SMALL)
592
+ return EFI_LOAD_ERROR;
593
+
594
+ status = efi_allocate_pages(initrd_size, &initrd_addr, max);
595
+ if (status != EFI_SUCCESS)
596
+ return status;
597
+
598
+ status = efi_call_proto(lf2, load_file, dp, false, &initrd_size,
599
+ (void *)initrd_addr);
600
+ if (status != EFI_SUCCESS) {
601
+ efi_free(initrd_size, initrd_addr);
602
+ return EFI_LOAD_ERROR;
603
+ }
604
+
605
+ *load_addr = initrd_addr;
606
+ *load_size = initrd_size;
607
+ return EFI_SUCCESS;
608
+}
609
+
610
+static
611
+efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image,
612
+ unsigned long *load_addr,
613
+ unsigned long *load_size,
614
+ unsigned long soft_limit,
615
+ unsigned long hard_limit)
616
+{
617
+ if (!IS_ENABLED(CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER) ||
618
+ (IS_ENABLED(CONFIG_X86) && (!efi_is_native() || image == NULL))) {
619
+ *load_addr = *load_size = 0;
620
+ return EFI_SUCCESS;
621
+ }
622
+
623
+ return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2,
624
+ soft_limit, hard_limit,
625
+ load_addr, load_size);
626
+}
627
+
628
+/**
629
+ * efi_load_initrd() - Load initial RAM disk
630
+ * @image: EFI loaded image protocol
631
+ * @load_addr: pointer to loaded initrd
632
+ * @load_size: size of loaded initrd
633
+ * @soft_limit: preferred size of allocated memory for loading the initrd
634
+ * @hard_limit: minimum size of allocated memory
635
+ *
636
+ * Return: status code
637
+ */
638
+efi_status_t efi_load_initrd(efi_loaded_image_t *image,
639
+ unsigned long *load_addr,
640
+ unsigned long *load_size,
641
+ unsigned long soft_limit,
642
+ unsigned long hard_limit)
643
+{
644
+ efi_status_t status;
645
+
646
+ if (!load_addr || !load_size)
647
+ return EFI_INVALID_PARAMETER;
648
+
649
+ status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit);
650
+ if (status == EFI_SUCCESS) {
651
+ efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
652
+ } else if (status == EFI_NOT_FOUND) {
653
+ status = efi_load_initrd_cmdline(image, load_addr, load_size,
654
+ soft_limit, hard_limit);
655
+ if (status == EFI_SUCCESS && *load_size > 0)
656
+ efi_info("Loaded initrd from command line option\n");
657
+ }
658
+
659
+ return status;
660
+}
661
+
662
+/**
663
+ * efi_wait_for_key() - Wait for key stroke
664
+ * @usec: number of microseconds to wait for key stroke
665
+ * @key: key entered
666
+ *
667
+ * Wait for up to @usec microseconds for a key stroke.
668
+ *
669
+ * Return: status code, EFI_SUCCESS if key received
670
+ */
671
+efi_status_t efi_wait_for_key(unsigned long usec, efi_input_key_t *key)
672
+{
673
+ efi_event_t events[2], timer;
674
+ unsigned long index;
675
+ efi_simple_text_input_protocol_t *con_in;
676
+ efi_status_t status;
677
+
678
+ con_in = efi_table_attr(efi_system_table, con_in);
679
+ if (!con_in)
680
+ return EFI_UNSUPPORTED;
681
+ efi_set_event_at(events, 0, efi_table_attr(con_in, wait_for_key));
682
+
683
+ status = efi_bs_call(create_event, EFI_EVT_TIMER, 0, NULL, NULL, &timer);
684
+ if (status != EFI_SUCCESS)
685
+ return status;
686
+
687
+ status = efi_bs_call(set_timer, timer, EfiTimerRelative,
688
+ EFI_100NSEC_PER_USEC * usec);
689
+ if (status != EFI_SUCCESS)
690
+ return status;
691
+ efi_set_event_at(events, 1, timer);
692
+
693
+ status = efi_bs_call(wait_for_event, 2, events, &index);
694
+ if (status == EFI_SUCCESS) {
695
+ if (index == 0)
696
+ status = efi_call_proto(con_in, read_keystroke, key);
697
+ else
698
+ status = EFI_TIMEOUT;
699
+ }
700
+
701
+ efi_bs_call(close_event, timer);
702
+
703
+ return status;
704
+}