56b3b84fd3bd4d2a2f1553a0d0e46410ec345f61
[linux-2.6-microblaze.git] / drivers / firmware / efi / libstub / efi-stub-helper.c
1 // SPDX-License-Identifier: GPL-2.0
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
8  */
9
10 #include <stdarg.h>
11
12 #include <linux/efi.h>
13 #include <linux/kernel.h>
14 #include <asm/efi.h>
15
16 #include "efistub.h"
17
18 bool efi_nochunk;
19 bool efi_nokaslr;
20 bool efi_noinitrd;
21 bool efi_quiet;
22 bool efi_novamap;
23
24 static bool efi_nosoftreserve;
25 static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA);
26
27 bool __pure __efi_soft_reserve_enabled(void)
28 {
29         return !efi_nosoftreserve;
30 }
31
32 void efi_char16_puts(efi_char16_t *str)
33 {
34         efi_call_proto(efi_table_attr(efi_system_table, con_out),
35                        output_string, str);
36 }
37
38 void efi_puts(const char *str)
39 {
40         efi_char16_t buf[128];
41         size_t pos = 0, lim = ARRAY_SIZE(buf);
42
43         while (*str) {
44                 if (*str == '\n')
45                         buf[pos++] = L'\r';
46                 /* Cast to unsigned char to avoid sign-extension */
47                 buf[pos++] = (unsigned char)(*str++);
48                 if (*str == '\0' || pos >= lim - 2) {
49                         buf[pos] = L'\0';
50                         efi_char16_puts(buf);
51                         pos = 0;
52                 }
53         }
54 }
55
56 int efi_printk(const char *fmt, ...)
57 {
58         char printf_buf[256];
59         va_list args;
60         int printed;
61
62         va_start(args, fmt);
63         printed = vsprintf(printf_buf, fmt, args);
64         va_end(args);
65
66         efi_puts(printf_buf);
67
68         return printed;
69 }
70
71 /*
72  * Parse the ASCII string 'cmdline' for EFI options, denoted by the efi=
73  * option, e.g. efi=nochunk.
74  *
75  * It should be noted that efi= is parsed in two very different
76  * environments, first in the early boot environment of the EFI boot
77  * stub, and subsequently during the kernel boot.
78  */
79 efi_status_t efi_parse_options(char const *cmdline)
80 {
81         size_t len = strlen(cmdline) + 1;
82         efi_status_t status;
83         char *str, *buf;
84
85         status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, len, (void **)&buf);
86         if (status != EFI_SUCCESS)
87                 return status;
88
89         str = skip_spaces(memcpy(buf, cmdline, len));
90
91         while (*str) {
92                 char *param, *val;
93
94                 str = next_arg(str, &param, &val);
95
96                 if (!strcmp(param, "nokaslr")) {
97                         efi_nokaslr = true;
98                 } else if (!strcmp(param, "quiet")) {
99                         efi_quiet = true;
100                 } else if (!strcmp(param, "noinitrd")) {
101                         efi_noinitrd = true;
102                 } else if (!strcmp(param, "efi") && val) {
103                         efi_nochunk = parse_option_str(val, "nochunk");
104                         efi_novamap = parse_option_str(val, "novamap");
105
106                         efi_nosoftreserve = IS_ENABLED(CONFIG_EFI_SOFT_RESERVE) &&
107                                             parse_option_str(val, "nosoftreserve");
108
109                         if (parse_option_str(val, "disable_early_pci_dma"))
110                                 efi_disable_pci_dma = true;
111                         if (parse_option_str(val, "no_disable_early_pci_dma"))
112                                 efi_disable_pci_dma = false;
113                 } else if (!strcmp(param, "video") &&
114                            val && strstarts(val, "efifb:")) {
115                         efi_parse_option_graphics(val + strlen("efifb:"));
116                 }
117         }
118         efi_bs_call(free_pool, buf);
119         return EFI_SUCCESS;
120 }
121
122 /*
123  * Get the number of UTF-8 bytes corresponding to an UTF-16 character.
124  * This overestimates for surrogates, but that is okay.
125  */
126 static int efi_utf8_bytes(u16 c)
127 {
128         return 1 + (c >= 0x80) + (c >= 0x800);
129 }
130
131 /*
132  * Convert an UTF-16 string, not necessarily null terminated, to UTF-8.
133  */
134 static u8 *efi_utf16_to_utf8(u8 *dst, const u16 *src, int n)
135 {
136         unsigned int c;
137
138         while (n--) {
139                 c = *src++;
140                 if (n && c >= 0xd800 && c <= 0xdbff &&
141                     *src >= 0xdc00 && *src <= 0xdfff) {
142                         c = 0x10000 + ((c & 0x3ff) << 10) + (*src & 0x3ff);
143                         src++;
144                         n--;
145                 }
146                 if (c >= 0xd800 && c <= 0xdfff)
147                         c = 0xfffd; /* Unmatched surrogate */
148                 if (c < 0x80) {
149                         *dst++ = c;
150                         continue;
151                 }
152                 if (c < 0x800) {
153                         *dst++ = 0xc0 + (c >> 6);
154                         goto t1;
155                 }
156                 if (c < 0x10000) {
157                         *dst++ = 0xe0 + (c >> 12);
158                         goto t2;
159                 }
160                 *dst++ = 0xf0 + (c >> 18);
161                 *dst++ = 0x80 + ((c >> 12) & 0x3f);
162         t2:
163                 *dst++ = 0x80 + ((c >> 6) & 0x3f);
164         t1:
165                 *dst++ = 0x80 + (c & 0x3f);
166         }
167
168         return dst;
169 }
170
171 /*
172  * Convert the unicode UEFI command line to ASCII to pass to kernel.
173  * Size of memory allocated return in *cmd_line_len.
174  * Returns NULL on error.
175  */
176 char *efi_convert_cmdline(efi_loaded_image_t *image,
177                           int *cmd_line_len, unsigned long max_addr)
178 {
179         const u16 *s2;
180         u8 *s1 = NULL;
181         unsigned long cmdline_addr = 0;
182         int load_options_chars = efi_table_attr(image, load_options_size) / 2;
183         const u16 *options = efi_table_attr(image, load_options);
184         int options_bytes = 0;  /* UTF-8 bytes */
185         int options_chars = 0;  /* UTF-16 chars */
186         efi_status_t status;
187         u16 zero = 0;
188
189         if (options) {
190                 s2 = options;
191                 while (*s2 && *s2 != '\n'
192                        && options_chars < load_options_chars) {
193                         options_bytes += efi_utf8_bytes(*s2++);
194                         options_chars++;
195                 }
196         }
197
198         if (!options_chars) {
199                 /* No command line options, so return empty string*/
200                 options = &zero;
201         }
202
203         options_bytes++;        /* NUL termination */
204
205         status = efi_allocate_pages(options_bytes, &cmdline_addr, max_addr);
206         if (status != EFI_SUCCESS)
207                 return NULL;
208
209         s1 = (u8 *)cmdline_addr;
210         s2 = (const u16 *)options;
211
212         s1 = efi_utf16_to_utf8(s1, s2, options_chars);
213         *s1 = '\0';
214
215         *cmd_line_len = options_bytes;
216         return (char *)cmdline_addr;
217 }
218
219 /*
220  * Handle calling ExitBootServices according to the requirements set out by the
221  * spec.  Obtains the current memory map, and returns that info after calling
222  * ExitBootServices.  The client must specify a function to perform any
223  * processing of the memory map data prior to ExitBootServices.  A client
224  * specific structure may be passed to the function via priv.  The client
225  * function may be called multiple times.
226  */
227 efi_status_t efi_exit_boot_services(void *handle,
228                                     struct efi_boot_memmap *map,
229                                     void *priv,
230                                     efi_exit_boot_map_processing priv_func)
231 {
232         efi_status_t status;
233
234         status = efi_get_memory_map(map);
235
236         if (status != EFI_SUCCESS)
237                 goto fail;
238
239         status = priv_func(map, priv);
240         if (status != EFI_SUCCESS)
241                 goto free_map;
242
243         if (efi_disable_pci_dma)
244                 efi_pci_disable_bridge_busmaster();
245
246         status = efi_bs_call(exit_boot_services, handle, *map->key_ptr);
247
248         if (status == EFI_INVALID_PARAMETER) {
249                 /*
250                  * The memory map changed between efi_get_memory_map() and
251                  * exit_boot_services().  Per the UEFI Spec v2.6, Section 6.4:
252                  * EFI_BOOT_SERVICES.ExitBootServices we need to get the
253                  * updated map, and try again.  The spec implies one retry
254                  * should be sufficent, which is confirmed against the EDK2
255                  * implementation.  Per the spec, we can only invoke
256                  * get_memory_map() and exit_boot_services() - we cannot alloc
257                  * so efi_get_memory_map() cannot be used, and we must reuse
258                  * the buffer.  For all practical purposes, the headroom in the
259                  * buffer should account for any changes in the map so the call
260                  * to get_memory_map() is expected to succeed here.
261                  */
262                 *map->map_size = *map->buff_size;
263                 status = efi_bs_call(get_memory_map,
264                                      map->map_size,
265                                      *map->map,
266                                      map->key_ptr,
267                                      map->desc_size,
268                                      map->desc_ver);
269
270                 /* exit_boot_services() was called, thus cannot free */
271                 if (status != EFI_SUCCESS)
272                         goto fail;
273
274                 status = priv_func(map, priv);
275                 /* exit_boot_services() was called, thus cannot free */
276                 if (status != EFI_SUCCESS)
277                         goto fail;
278
279                 status = efi_bs_call(exit_boot_services, handle, *map->key_ptr);
280         }
281
282         /* exit_boot_services() was called, thus cannot free */
283         if (status != EFI_SUCCESS)
284                 goto fail;
285
286         return EFI_SUCCESS;
287
288 free_map:
289         efi_bs_call(free_pool, *map->map);
290 fail:
291         return status;
292 }
293
294 void *get_efi_config_table(efi_guid_t guid)
295 {
296         unsigned long tables = efi_table_attr(efi_system_table, tables);
297         int nr_tables = efi_table_attr(efi_system_table, nr_tables);
298         int i;
299
300         for (i = 0; i < nr_tables; i++) {
301                 efi_config_table_t *t = (void *)tables;
302
303                 if (efi_guidcmp(t->guid, guid) == 0)
304                         return efi_table_attr(t, table);
305
306                 tables += efi_is_native() ? sizeof(efi_config_table_t)
307                                           : sizeof(efi_config_table_32_t);
308         }
309         return NULL;
310 }
311
312 /*
313  * The LINUX_EFI_INITRD_MEDIA_GUID vendor media device path below provides a way
314  * for the firmware or bootloader to expose the initrd data directly to the stub
315  * via the trivial LoadFile2 protocol, which is defined in the UEFI spec, and is
316  * very easy to implement. It is a simple Linux initrd specific conduit between
317  * kernel and firmware, allowing us to put the EFI stub (being part of the
318  * kernel) in charge of where and when to load the initrd, while leaving it up
319  * to the firmware to decide whether it needs to expose its filesystem hierarchy
320  * via EFI protocols.
321  */
322 static const struct {
323         struct efi_vendor_dev_path      vendor;
324         struct efi_generic_dev_path     end;
325 } __packed initrd_dev_path = {
326         {
327                 {
328                         EFI_DEV_MEDIA,
329                         EFI_DEV_MEDIA_VENDOR,
330                         sizeof(struct efi_vendor_dev_path),
331                 },
332                 LINUX_EFI_INITRD_MEDIA_GUID
333         }, {
334                 EFI_DEV_END_PATH,
335                 EFI_DEV_END_ENTIRE,
336                 sizeof(struct efi_generic_dev_path)
337         }
338 };
339
340 /**
341  * efi_load_initrd_dev_path - load the initrd from the Linux initrd device path
342  * @load_addr:  pointer to store the address where the initrd was loaded
343  * @load_size:  pointer to store the size of the loaded initrd
344  * @max:        upper limit for the initrd memory allocation
345  * @return:     %EFI_SUCCESS if the initrd was loaded successfully, in which
346  *              case @load_addr and @load_size are assigned accordingly
347  *              %EFI_NOT_FOUND if no LoadFile2 protocol exists on the initrd
348  *              device path
349  *              %EFI_INVALID_PARAMETER if load_addr == NULL or load_size == NULL
350  *              %EFI_OUT_OF_RESOURCES if memory allocation failed
351  *              %EFI_LOAD_ERROR in all other cases
352  */
353 static
354 efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr,
355                                       unsigned long *load_size,
356                                       unsigned long max)
357 {
358         efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
359         efi_device_path_protocol_t *dp;
360         efi_load_file2_protocol_t *lf2;
361         unsigned long initrd_addr;
362         unsigned long initrd_size;
363         efi_handle_t handle;
364         efi_status_t status;
365
366         dp = (efi_device_path_protocol_t *)&initrd_dev_path;
367         status = efi_bs_call(locate_device_path, &lf2_proto_guid, &dp, &handle);
368         if (status != EFI_SUCCESS)
369                 return status;
370
371         status = efi_bs_call(handle_protocol, handle, &lf2_proto_guid,
372                              (void **)&lf2);
373         if (status != EFI_SUCCESS)
374                 return status;
375
376         status = efi_call_proto(lf2, load_file, dp, false, &initrd_size, NULL);
377         if (status != EFI_BUFFER_TOO_SMALL)
378                 return EFI_LOAD_ERROR;
379
380         status = efi_allocate_pages(initrd_size, &initrd_addr, max);
381         if (status != EFI_SUCCESS)
382                 return status;
383
384         status = efi_call_proto(lf2, load_file, dp, false, &initrd_size,
385                                 (void *)initrd_addr);
386         if (status != EFI_SUCCESS) {
387                 efi_free(initrd_size, initrd_addr);
388                 return EFI_LOAD_ERROR;
389         }
390
391         *load_addr = initrd_addr;
392         *load_size = initrd_size;
393         return EFI_SUCCESS;
394 }
395
396 static
397 efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image,
398                                      unsigned long *load_addr,
399                                      unsigned long *load_size,
400                                      unsigned long soft_limit,
401                                      unsigned long hard_limit)
402 {
403         if (!IS_ENABLED(CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER) ||
404             (IS_ENABLED(CONFIG_X86) && (!efi_is_native() || image == NULL))) {
405                 *load_addr = *load_size = 0;
406                 return EFI_SUCCESS;
407         }
408
409         return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2,
410                                     soft_limit, hard_limit,
411                                     load_addr, load_size);
412 }
413
414 efi_status_t efi_load_initrd(efi_loaded_image_t *image,
415                              unsigned long *load_addr,
416                              unsigned long *load_size,
417                              unsigned long soft_limit,
418                              unsigned long hard_limit)
419 {
420         efi_status_t status;
421
422         if (!load_addr || !load_size)
423                 return EFI_INVALID_PARAMETER;
424
425         status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit);
426         if (status == EFI_SUCCESS) {
427                 efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
428         } else if (status == EFI_NOT_FOUND) {
429                 status = efi_load_initrd_cmdline(image, load_addr, load_size,
430                                                  soft_limit, hard_limit);
431                 if (status == EFI_SUCCESS && *load_size > 0)
432                         efi_info("Loaded initrd from command line option\n");
433         }
434
435         return status;
436 }