]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/firmware/efi/efi-stub-helper.c
x86/efi: Build our own EFI services pointer table
[karo-tx-linux.git] / drivers / firmware / efi / efi-stub-helper.c
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  */
12 #define EFI_READ_CHUNK_SIZE     (1024 * 1024)
13
14 struct file_info {
15         efi_file_handle_t *handle;
16         u64 size;
17 };
18
19 static void efi_printk(efi_system_table_t *sys_table_arg, char *str)
20 {
21         char *s8;
22
23         for (s8 = str; *s8; s8++) {
24                 efi_char16_t ch[2] = { 0 };
25
26                 ch[0] = *s8;
27                 if (*s8 == '\n') {
28                         efi_char16_t nl[2] = { '\r', 0 };
29                         efi_char16_printk(sys_table_arg, nl);
30                 }
31
32                 efi_char16_printk(sys_table_arg, ch);
33         }
34 }
35
36
37 static efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg,
38                                        efi_memory_desc_t **map,
39                                        unsigned long *map_size,
40                                        unsigned long *desc_size,
41                                        u32 *desc_ver,
42                                        unsigned long *key_ptr)
43 {
44         efi_memory_desc_t *m = NULL;
45         efi_status_t status;
46         unsigned long key;
47         u32 desc_version;
48
49         *map_size = sizeof(*m) * 32;
50 again:
51         /*
52          * Add an additional efi_memory_desc_t because we're doing an
53          * allocation which may be in a new descriptor region.
54          */
55         *map_size += sizeof(*m);
56         status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
57                                  *map_size, (void **)&m);
58         if (status != EFI_SUCCESS)
59                 goto fail;
60
61         *desc_size = 0;
62         key = 0;
63         status = efi_early->call(efi_early->get_memory_map, map_size, m,
64                                  &key, desc_size, &desc_version);
65         if (status == EFI_BUFFER_TOO_SMALL) {
66                 efi_early->call(efi_early->free_pool, m);
67                 goto again;
68         }
69
70         if (status != EFI_SUCCESS)
71                 efi_early->call(efi_early->free_pool, m);
72
73         if (key_ptr && status == EFI_SUCCESS)
74                 *key_ptr = key;
75         if (desc_ver && status == EFI_SUCCESS)
76                 *desc_ver = desc_version;
77
78 fail:
79         *map = m;
80         return status;
81 }
82
83 /*
84  * Allocate at the highest possible address that is not above 'max'.
85  */
86 static efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg,
87                                unsigned long size, unsigned long align,
88                                unsigned long *addr, unsigned long max)
89 {
90         unsigned long map_size, desc_size;
91         efi_memory_desc_t *map;
92         efi_status_t status;
93         unsigned long nr_pages;
94         u64 max_addr = 0;
95         int i;
96
97         status = efi_get_memory_map(sys_table_arg, &map, &map_size, &desc_size,
98                                     NULL, NULL);
99         if (status != EFI_SUCCESS)
100                 goto fail;
101
102         /*
103          * Enforce minimum alignment that EFI requires when requesting
104          * a specific address.  We are doing page-based allocations,
105          * so we must be aligned to a page.
106          */
107         if (align < EFI_PAGE_SIZE)
108                 align = EFI_PAGE_SIZE;
109
110         nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
111 again:
112         for (i = 0; i < map_size / desc_size; i++) {
113                 efi_memory_desc_t *desc;
114                 unsigned long m = (unsigned long)map;
115                 u64 start, end;
116
117                 desc = (efi_memory_desc_t *)(m + (i * desc_size));
118                 if (desc->type != EFI_CONVENTIONAL_MEMORY)
119                         continue;
120
121                 if (desc->num_pages < nr_pages)
122                         continue;
123
124                 start = desc->phys_addr;
125                 end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
126
127                 if ((start + size) > end || (start + size) > max)
128                         continue;
129
130                 if (end - size > max)
131                         end = max;
132
133                 if (round_down(end - size, align) < start)
134                         continue;
135
136                 start = round_down(end - size, align);
137
138                 /*
139                  * Don't allocate at 0x0. It will confuse code that
140                  * checks pointers against NULL.
141                  */
142                 if (start == 0x0)
143                         continue;
144
145                 if (start > max_addr)
146                         max_addr = start;
147         }
148
149         if (!max_addr)
150                 status = EFI_NOT_FOUND;
151         else {
152                 status = efi_early->call(efi_early->allocate_pages,
153                                          EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
154                                          nr_pages, &max_addr);
155                 if (status != EFI_SUCCESS) {
156                         max = max_addr;
157                         max_addr = 0;
158                         goto again;
159                 }
160
161                 *addr = max_addr;
162         }
163
164         efi_early->call(efi_early->free_pool, map);
165 fail:
166         return status;
167 }
168
169 /*
170  * Allocate at the lowest possible address.
171  */
172 static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
173                               unsigned long size, unsigned long align,
174                               unsigned long *addr)
175 {
176         unsigned long map_size, desc_size;
177         efi_memory_desc_t *map;
178         efi_status_t status;
179         unsigned long nr_pages;
180         int i;
181
182         status = efi_get_memory_map(sys_table_arg, &map, &map_size, &desc_size,
183                                     NULL, NULL);
184         if (status != EFI_SUCCESS)
185                 goto fail;
186
187         /*
188          * Enforce minimum alignment that EFI requires when requesting
189          * a specific address.  We are doing page-based allocations,
190          * so we must be aligned to a page.
191          */
192         if (align < EFI_PAGE_SIZE)
193                 align = EFI_PAGE_SIZE;
194
195         nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
196         for (i = 0; i < map_size / desc_size; i++) {
197                 efi_memory_desc_t *desc;
198                 unsigned long m = (unsigned long)map;
199                 u64 start, end;
200
201                 desc = (efi_memory_desc_t *)(m + (i * desc_size));
202
203                 if (desc->type != EFI_CONVENTIONAL_MEMORY)
204                         continue;
205
206                 if (desc->num_pages < nr_pages)
207                         continue;
208
209                 start = desc->phys_addr;
210                 end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
211
212                 /*
213                  * Don't allocate at 0x0. It will confuse code that
214                  * checks pointers against NULL. Skip the first 8
215                  * bytes so we start at a nice even number.
216                  */
217                 if (start == 0x0)
218                         start += 8;
219
220                 start = round_up(start, align);
221                 if ((start + size) > end)
222                         continue;
223
224                 status = efi_early->call(efi_early->allocate_pages,
225                                          EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
226                                          nr_pages, &start);
227                 if (status == EFI_SUCCESS) {
228                         *addr = start;
229                         break;
230                 }
231         }
232
233         if (i == map_size / desc_size)
234                 status = EFI_NOT_FOUND;
235
236         efi_early->call(efi_early->free_pool, map);
237 fail:
238         return status;
239 }
240
241 static void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
242                      unsigned long addr)
243 {
244         unsigned long nr_pages;
245
246         if (!size)
247                 return;
248
249         nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
250         efi_early->call(efi_early->free_pages, addr, nr_pages);
251 }
252
253
254 /*
255  * Check the cmdline for a LILO-style file= arguments.
256  *
257  * We only support loading a file from the same filesystem as
258  * the kernel image.
259  */
260 static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
261                                          efi_loaded_image_t *image,
262                                          char *cmd_line, char *option_string,
263                                          unsigned long max_addr,
264                                          unsigned long *load_addr,
265                                          unsigned long *load_size)
266 {
267         struct file_info *files;
268         unsigned long file_addr;
269         u64 file_size_total;
270         efi_file_handle_t *fh;
271         efi_status_t status;
272         int nr_files;
273         char *str;
274         int i, j, k;
275
276         file_addr = 0;
277         file_size_total = 0;
278
279         str = cmd_line;
280
281         j = 0;                  /* See close_handles */
282
283         if (!load_addr || !load_size)
284                 return EFI_INVALID_PARAMETER;
285
286         *load_addr = 0;
287         *load_size = 0;
288
289         if (!str || !*str)
290                 return EFI_SUCCESS;
291
292         for (nr_files = 0; *str; nr_files++) {
293                 str = strstr(str, option_string);
294                 if (!str)
295                         break;
296
297                 str += strlen(option_string);
298
299                 /* Skip any leading slashes */
300                 while (*str == '/' || *str == '\\')
301                         str++;
302
303                 while (*str && *str != ' ' && *str != '\n')
304                         str++;
305         }
306
307         if (!nr_files)
308                 return EFI_SUCCESS;
309
310         status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
311                                  nr_files * sizeof(*files), (void **)&files);
312         if (status != EFI_SUCCESS) {
313                 efi_printk(sys_table_arg, "Failed to alloc mem for file handle list\n");
314                 goto fail;
315         }
316
317         str = cmd_line;
318         for (i = 0; i < nr_files; i++) {
319                 struct file_info *file;
320                 efi_char16_t filename_16[256];
321                 efi_char16_t *p;
322
323                 str = strstr(str, option_string);
324                 if (!str)
325                         break;
326
327                 str += strlen(option_string);
328
329                 file = &files[i];
330                 p = filename_16;
331
332                 /* Skip any leading slashes */
333                 while (*str == '/' || *str == '\\')
334                         str++;
335
336                 while (*str && *str != ' ' && *str != '\n') {
337                         if ((u8 *)p >= (u8 *)filename_16 + sizeof(filename_16))
338                                 break;
339
340                         if (*str == '/') {
341                                 *p++ = '\\';
342                                 str++;
343                         } else {
344                                 *p++ = *str++;
345                         }
346                 }
347
348                 *p = '\0';
349
350                 /* Only open the volume once. */
351                 if (!i) {
352                         status = efi_open_volume(sys_table_arg, image,
353                                                  (void **)&fh);
354                         if (status != EFI_SUCCESS)
355                                 goto free_files;
356                 }
357
358                 status = efi_file_size(sys_table_arg, fh, filename_16,
359                                        (void **)&file->handle, &file->size);
360                 if (status != EFI_SUCCESS)
361                         goto close_handles;
362
363                 file_size_total += file->size;
364         }
365
366         if (file_size_total) {
367                 unsigned long addr;
368
369                 /*
370                  * Multiple files need to be at consecutive addresses in memory,
371                  * so allocate enough memory for all the files.  This is used
372                  * for loading multiple files.
373                  */
374                 status = efi_high_alloc(sys_table_arg, file_size_total, 0x1000,
375                                     &file_addr, max_addr);
376                 if (status != EFI_SUCCESS) {
377                         efi_printk(sys_table_arg, "Failed to alloc highmem for files\n");
378                         goto close_handles;
379                 }
380
381                 /* We've run out of free low memory. */
382                 if (file_addr > max_addr) {
383                         efi_printk(sys_table_arg, "We've run out of free low memory\n");
384                         status = EFI_INVALID_PARAMETER;
385                         goto free_file_total;
386                 }
387
388                 addr = file_addr;
389                 for (j = 0; j < nr_files; j++) {
390                         unsigned long size;
391
392                         size = files[j].size;
393                         while (size) {
394                                 unsigned long chunksize;
395                                 if (size > EFI_READ_CHUNK_SIZE)
396                                         chunksize = EFI_READ_CHUNK_SIZE;
397                                 else
398                                         chunksize = size;
399
400                                 status = efi_file_read(fh, files[j].handle,
401                                                        &chunksize,
402                                                        (void *)addr);
403                                 if (status != EFI_SUCCESS) {
404                                         efi_printk(sys_table_arg, "Failed to read file\n");
405                                         goto free_file_total;
406                                 }
407                                 addr += chunksize;
408                                 size -= chunksize;
409                         }
410
411                         efi_file_close(fh, files[j].handle);
412                 }
413
414         }
415
416         efi_early->call(efi_early->free_pool, files);
417
418         *load_addr = file_addr;
419         *load_size = file_size_total;
420
421         return status;
422
423 free_file_total:
424         efi_free(sys_table_arg, file_size_total, file_addr);
425
426 close_handles:
427         for (k = j; k < i; k++)
428                 efi_file_close(fh, files[k].handle);
429 free_files:
430         efi_early->call(efi_early->free_pool, files);
431 fail:
432         *load_addr = 0;
433         *load_size = 0;
434
435         return status;
436 }
437 /*
438  * Relocate a kernel image, either compressed or uncompressed.
439  * In the ARM64 case, all kernel images are currently
440  * uncompressed, and as such when we relocate it we need to
441  * allocate additional space for the BSS segment. Any low
442  * memory that this function should avoid needs to be
443  * unavailable in the EFI memory map, as if the preferred
444  * address is not available the lowest available address will
445  * be used.
446  */
447 static efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
448                                         unsigned long *image_addr,
449                                         unsigned long image_size,
450                                         unsigned long alloc_size,
451                                         unsigned long preferred_addr,
452                                         unsigned long alignment)
453 {
454         unsigned long cur_image_addr;
455         unsigned long new_addr = 0;
456         efi_status_t status;
457         unsigned long nr_pages;
458         efi_physical_addr_t efi_addr = preferred_addr;
459
460         if (!image_addr || !image_size || !alloc_size)
461                 return EFI_INVALID_PARAMETER;
462         if (alloc_size < image_size)
463                 return EFI_INVALID_PARAMETER;
464
465         cur_image_addr = *image_addr;
466
467         /*
468          * The EFI firmware loader could have placed the kernel image
469          * anywhere in memory, but the kernel has restrictions on the
470          * max physical address it can run at.  Some architectures
471          * also have a prefered address, so first try to relocate
472          * to the preferred address.  If that fails, allocate as low
473          * as possible while respecting the required alignment.
474          */
475         nr_pages = round_up(alloc_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
476         status = efi_early->call(efi_early->allocate_pages,
477                                  EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
478                                  nr_pages, &efi_addr);
479         new_addr = efi_addr;
480         /*
481          * If preferred address allocation failed allocate as low as
482          * possible.
483          */
484         if (status != EFI_SUCCESS) {
485                 status = efi_low_alloc(sys_table_arg, alloc_size, alignment,
486                                        &new_addr);
487         }
488         if (status != EFI_SUCCESS) {
489                 efi_printk(sys_table_arg, "ERROR: Failed to allocate usable memory for kernel.\n");
490                 return status;
491         }
492
493         /*
494          * We know source/dest won't overlap since both memory ranges
495          * have been allocated by UEFI, so we can safely use memcpy.
496          */
497         memcpy((void *)new_addr, (void *)cur_image_addr, image_size);
498
499         /* Return the new address of the relocated image. */
500         *image_addr = new_addr;
501
502         return status;
503 }
504
505 /*
506  * Convert the unicode UEFI command line to ASCII to pass to kernel.
507  * Size of memory allocated return in *cmd_line_len.
508  * Returns NULL on error.
509  */
510 static char *efi_convert_cmdline_to_ascii(efi_system_table_t *sys_table_arg,
511                                       efi_loaded_image_t *image,
512                                       int *cmd_line_len)
513 {
514         u16 *s2;
515         u8 *s1 = NULL;
516         unsigned long cmdline_addr = 0;
517         int load_options_size = image->load_options_size / 2; /* ASCII */
518         void *options = image->load_options;
519         int options_size = 0;
520         efi_status_t status;
521         int i;
522         u16 zero = 0;
523
524         if (options) {
525                 s2 = options;
526                 while (*s2 && *s2 != '\n' && options_size < load_options_size) {
527                         s2++;
528                         options_size++;
529                 }
530         }
531
532         if (options_size == 0) {
533                 /* No command line options, so return empty string*/
534                 options_size = 1;
535                 options = &zero;
536         }
537
538         options_size++;  /* NUL termination */
539 #ifdef CONFIG_ARM
540         /*
541          * For ARM, allocate at a high address to avoid reserved
542          * regions at low addresses that we don't know the specfics of
543          * at the time we are processing the command line.
544          */
545         status = efi_high_alloc(sys_table_arg, options_size, 0,
546                             &cmdline_addr, 0xfffff000);
547 #else
548         status = efi_low_alloc(sys_table_arg, options_size, 0,
549                             &cmdline_addr);
550 #endif
551         if (status != EFI_SUCCESS)
552                 return NULL;
553
554         s1 = (u8 *)cmdline_addr;
555         s2 = (u16 *)options;
556
557         for (i = 0; i < options_size - 1; i++)
558                 *s1++ = *s2++;
559
560         *s1 = '\0';
561
562         *cmd_line_len = options_size;
563         return (char *)cmdline_addr;
564 }