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