]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/firmware/efi/libstub/arm32-stub.c
efi: Replace GPL license boilerplate with SPDX headers
[linux.git] / drivers / firmware / efi / libstub / arm32-stub.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2013 Linaro Ltd;  <roy.franz@linaro.org>
4  */
5 #include <linux/efi.h>
6 #include <asm/efi.h>
7
8 #include "efistub.h"
9
10 efi_status_t check_platform_features(efi_system_table_t *sys_table_arg)
11 {
12         int block;
13
14         /* non-LPAE kernels can run anywhere */
15         if (!IS_ENABLED(CONFIG_ARM_LPAE))
16                 return EFI_SUCCESS;
17
18         /* LPAE kernels need compatible hardware */
19         block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0);
20         if (block < 5) {
21                 pr_efi_err(sys_table_arg, "This LPAE kernel is not supported by your CPU\n");
22                 return EFI_UNSUPPORTED;
23         }
24         return EFI_SUCCESS;
25 }
26
27 static efi_guid_t screen_info_guid = LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID;
28
29 struct screen_info *alloc_screen_info(efi_system_table_t *sys_table_arg)
30 {
31         struct screen_info *si;
32         efi_status_t status;
33
34         /*
35          * Unlike on arm64, where we can directly fill out the screen_info
36          * structure from the stub, we need to allocate a buffer to hold
37          * its contents while we hand over to the kernel proper from the
38          * decompressor.
39          */
40         status = efi_call_early(allocate_pool, EFI_RUNTIME_SERVICES_DATA,
41                                 sizeof(*si), (void **)&si);
42
43         if (status != EFI_SUCCESS)
44                 return NULL;
45
46         status = efi_call_early(install_configuration_table,
47                                 &screen_info_guid, si);
48         if (status == EFI_SUCCESS)
49                 return si;
50
51         efi_call_early(free_pool, si);
52         return NULL;
53 }
54
55 void free_screen_info(efi_system_table_t *sys_table_arg, struct screen_info *si)
56 {
57         if (!si)
58                 return;
59
60         efi_call_early(install_configuration_table, &screen_info_guid, NULL);
61         efi_call_early(free_pool, si);
62 }
63
64 static efi_status_t reserve_kernel_base(efi_system_table_t *sys_table_arg,
65                                         unsigned long dram_base,
66                                         unsigned long *reserve_addr,
67                                         unsigned long *reserve_size)
68 {
69         efi_physical_addr_t alloc_addr;
70         efi_memory_desc_t *memory_map;
71         unsigned long nr_pages, map_size, desc_size, buff_size;
72         efi_status_t status;
73         unsigned long l;
74
75         struct efi_boot_memmap map = {
76                 .map            = &memory_map,
77                 .map_size       = &map_size,
78                 .desc_size      = &desc_size,
79                 .desc_ver       = NULL,
80                 .key_ptr        = NULL,
81                 .buff_size      = &buff_size,
82         };
83
84         /*
85          * Reserve memory for the uncompressed kernel image. This is
86          * all that prevents any future allocations from conflicting
87          * with the kernel. Since we can't tell from the compressed
88          * image how much DRAM the kernel actually uses (due to BSS
89          * size uncertainty) we allocate the maximum possible size.
90          * Do this very early, as prints can cause memory allocations
91          * that may conflict with this.
92          */
93         alloc_addr = dram_base + MAX_UNCOMP_KERNEL_SIZE;
94         nr_pages = MAX_UNCOMP_KERNEL_SIZE / EFI_PAGE_SIZE;
95         status = efi_call_early(allocate_pages, EFI_ALLOCATE_MAX_ADDRESS,
96                                 EFI_BOOT_SERVICES_DATA, nr_pages, &alloc_addr);
97         if (status == EFI_SUCCESS) {
98                 if (alloc_addr == dram_base) {
99                         *reserve_addr = alloc_addr;
100                         *reserve_size = MAX_UNCOMP_KERNEL_SIZE;
101                         return EFI_SUCCESS;
102                 }
103                 /*
104                  * If we end up here, the allocation succeeded but starts below
105                  * dram_base. This can only occur if the real base of DRAM is
106                  * not a multiple of 128 MB, in which case dram_base will have
107                  * been rounded up. Since this implies that a part of the region
108                  * was already occupied, we need to fall through to the code
109                  * below to ensure that the existing allocations don't conflict.
110                  * For this reason, we use EFI_BOOT_SERVICES_DATA above and not
111                  * EFI_LOADER_DATA, which we wouldn't able to distinguish from
112                  * allocations that we want to disallow.
113                  */
114         }
115
116         /*
117          * If the allocation above failed, we may still be able to proceed:
118          * if the only allocations in the region are of types that will be
119          * released to the OS after ExitBootServices(), the decompressor can
120          * safely overwrite them.
121          */
122         status = efi_get_memory_map(sys_table_arg, &map);
123         if (status != EFI_SUCCESS) {
124                 pr_efi_err(sys_table_arg,
125                            "reserve_kernel_base(): Unable to retrieve memory map.\n");
126                 return status;
127         }
128
129         for (l = 0; l < map_size; l += desc_size) {
130                 efi_memory_desc_t *desc;
131                 u64 start, end;
132
133                 desc = (void *)memory_map + l;
134                 start = desc->phys_addr;
135                 end = start + desc->num_pages * EFI_PAGE_SIZE;
136
137                 /* Skip if entry does not intersect with region */
138                 if (start >= dram_base + MAX_UNCOMP_KERNEL_SIZE ||
139                     end <= dram_base)
140                         continue;
141
142                 switch (desc->type) {
143                 case EFI_BOOT_SERVICES_CODE:
144                 case EFI_BOOT_SERVICES_DATA:
145                         /* Ignore types that are released to the OS anyway */
146                         continue;
147
148                 case EFI_CONVENTIONAL_MEMORY:
149                         /*
150                          * Reserve the intersection between this entry and the
151                          * region.
152                          */
153                         start = max(start, (u64)dram_base);
154                         end = min(end, (u64)dram_base + MAX_UNCOMP_KERNEL_SIZE);
155
156                         status = efi_call_early(allocate_pages,
157                                                 EFI_ALLOCATE_ADDRESS,
158                                                 EFI_LOADER_DATA,
159                                                 (end - start) / EFI_PAGE_SIZE,
160                                                 &start);
161                         if (status != EFI_SUCCESS) {
162                                 pr_efi_err(sys_table_arg,
163                                         "reserve_kernel_base(): alloc failed.\n");
164                                 goto out;
165                         }
166                         break;
167
168                 case EFI_LOADER_CODE:
169                 case EFI_LOADER_DATA:
170                         /*
171                          * These regions may be released and reallocated for
172                          * another purpose (including EFI_RUNTIME_SERVICE_DATA)
173                          * at any time during the execution of the OS loader,
174                          * so we cannot consider them as safe.
175                          */
176                 default:
177                         /*
178                          * Treat any other allocation in the region as unsafe */
179                         status = EFI_OUT_OF_RESOURCES;
180                         goto out;
181                 }
182         }
183
184         status = EFI_SUCCESS;
185 out:
186         efi_call_early(free_pool, memory_map);
187         return status;
188 }
189
190 efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
191                                  unsigned long *image_addr,
192                                  unsigned long *image_size,
193                                  unsigned long *reserve_addr,
194                                  unsigned long *reserve_size,
195                                  unsigned long dram_base,
196                                  efi_loaded_image_t *image)
197 {
198         efi_status_t status;
199
200         /*
201          * Verify that the DRAM base address is compatible with the ARM
202          * boot protocol, which determines the base of DRAM by masking
203          * off the low 27 bits of the address at which the zImage is
204          * loaded. These assumptions are made by the decompressor,
205          * before any memory map is available.
206          */
207         dram_base = round_up(dram_base, SZ_128M);
208
209         status = reserve_kernel_base(sys_table, dram_base, reserve_addr,
210                                      reserve_size);
211         if (status != EFI_SUCCESS) {
212                 pr_efi_err(sys_table, "Unable to allocate memory for uncompressed kernel.\n");
213                 return status;
214         }
215
216         /*
217          * Relocate the zImage, so that it appears in the lowest 128 MB
218          * memory window.
219          */
220         *image_size = image->image_size;
221         status = efi_relocate_kernel(sys_table, image_addr, *image_size,
222                                      *image_size,
223                                      dram_base + MAX_UNCOMP_KERNEL_SIZE, 0);
224         if (status != EFI_SUCCESS) {
225                 pr_efi_err(sys_table, "Failed to relocate kernel.\n");
226                 efi_free(sys_table, *reserve_size, *reserve_addr);
227                 *reserve_size = 0;
228                 return status;
229         }
230
231         /*
232          * Check to see if we were able to allocate memory low enough
233          * in memory. The kernel determines the base of DRAM from the
234          * address at which the zImage is loaded.
235          */
236         if (*image_addr + *image_size > dram_base + ZIMAGE_OFFSET_LIMIT) {
237                 pr_efi_err(sys_table, "Failed to relocate kernel, no low memory available.\n");
238                 efi_free(sys_table, *reserve_size, *reserve_addr);
239                 *reserve_size = 0;
240                 efi_free(sys_table, *image_size, *image_addr);
241                 *image_size = 0;
242                 return EFI_LOAD_ERROR;
243         }
244         return EFI_SUCCESS;
245 }