hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/drivers/firmware/efi/libstub/fdt.c
....@@ -1,13 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * FDT related 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 2013 Linaro Limited; author Roy Franz
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
1310 #include <linux/efi.h>
....@@ -19,21 +16,18 @@
1916 #define EFI_DT_ADDR_CELLS_DEFAULT 2
2017 #define EFI_DT_SIZE_CELLS_DEFAULT 2
2118
22
-static void fdt_update_cell_size(efi_system_table_t *sys_table, void *fdt)
19
+static void fdt_update_cell_size(void *fdt)
2320 {
2421 int offset;
2522
2623 offset = fdt_path_offset(fdt, "/");
2724 /* Set the #address-cells and #size-cells values for an empty tree */
2825
29
- fdt_setprop_u32(fdt, offset, "#address-cells",
30
- EFI_DT_ADDR_CELLS_DEFAULT);
31
-
32
- fdt_setprop_u32(fdt, offset, "#size-cells", EFI_DT_SIZE_CELLS_DEFAULT);
26
+ fdt_setprop_u32(fdt, offset, "#address-cells", EFI_DT_ADDR_CELLS_DEFAULT);
27
+ fdt_setprop_u32(fdt, offset, "#size-cells", EFI_DT_SIZE_CELLS_DEFAULT);
3328 }
3429
35
-static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
36
- unsigned long orig_fdt_size,
30
+static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
3731 void *fdt, int new_fdt_size, char *cmdline_ptr,
3832 u64 initrd_addr, u64 initrd_size)
3933 {
....@@ -42,18 +36,18 @@
4236 u32 fdt_val32;
4337 u64 fdt_val64;
4438
45
- /* Do some checks on provided FDT, if it exists*/
39
+ /* Do some checks on provided FDT, if it exists: */
4640 if (orig_fdt) {
4741 if (fdt_check_header(orig_fdt)) {
48
- pr_efi_err(sys_table, "Device Tree header not valid!\n");
42
+ efi_err("Device Tree header not valid!\n");
4943 return EFI_LOAD_ERROR;
5044 }
5145 /*
5246 * We don't get the size of the FDT if we get if from a
53
- * configuration table.
47
+ * configuration table:
5448 */
5549 if (orig_fdt_size && fdt_totalsize(orig_fdt) > orig_fdt_size) {
56
- pr_efi_err(sys_table, "Truncated device tree! foo!\n");
50
+ efi_err("Truncated device tree! foo!\n");
5751 return EFI_LOAD_ERROR;
5852 }
5953 }
....@@ -64,10 +58,10 @@
6458 status = fdt_create_empty_tree(fdt, new_fdt_size);
6559 if (status == 0) {
6660 /*
67
- * Any failure from the following function is non
68
- * critical
61
+ * Any failure from the following function is
62
+ * non-critical:
6963 */
70
- fdt_update_cell_size(sys_table, fdt);
64
+ fdt_update_cell_size(fdt);
7165 }
7266 }
7367
....@@ -86,12 +80,13 @@
8680 if (node < 0) {
8781 node = fdt_add_subnode(fdt, 0, "chosen");
8882 if (node < 0) {
89
- status = node; /* node is error code when negative */
83
+ /* 'node' is an error code when negative: */
84
+ status = node;
9085 goto fdt_set_fail;
9186 }
9287 }
9388
94
- if ((cmdline_ptr != NULL) && (strlen(cmdline_ptr) > 0)) {
89
+ if (cmdline_ptr != NULL && strlen(cmdline_ptr) > 0) {
9590 status = fdt_setprop(fdt, node, "bootargs", cmdline_ptr,
9691 strlen(cmdline_ptr) + 1);
9792 if (status)
....@@ -103,63 +98,57 @@
10398 u64 initrd_image_end;
10499 u64 initrd_image_start = cpu_to_fdt64(initrd_addr);
105100
106
- status = fdt_setprop(fdt, node, "linux,initrd-start",
107
- &initrd_image_start, sizeof(u64));
101
+ status = fdt_setprop_var(fdt, node, "linux,initrd-start", initrd_image_start);
108102 if (status)
109103 goto fdt_set_fail;
104
+
110105 initrd_image_end = cpu_to_fdt64(initrd_addr + initrd_size);
111
- status = fdt_setprop(fdt, node, "linux,initrd-end",
112
- &initrd_image_end, sizeof(u64));
106
+ status = fdt_setprop_var(fdt, node, "linux,initrd-end", initrd_image_end);
113107 if (status)
114108 goto fdt_set_fail;
115109 }
116110
117111 /* Add FDT entries for EFI runtime services in chosen node. */
118112 node = fdt_subnode_offset(fdt, 0, "chosen");
119
- fdt_val64 = cpu_to_fdt64((u64)(unsigned long)sys_table);
120
- status = fdt_setprop(fdt, node, "linux,uefi-system-table",
121
- &fdt_val64, sizeof(fdt_val64));
113
+ fdt_val64 = cpu_to_fdt64((u64)(unsigned long)efi_system_table);
114
+
115
+ status = fdt_setprop_var(fdt, node, "linux,uefi-system-table", fdt_val64);
122116 if (status)
123117 goto fdt_set_fail;
124118
125119 fdt_val64 = U64_MAX; /* placeholder */
126
- status = fdt_setprop(fdt, node, "linux,uefi-mmap-start",
127
- &fdt_val64, sizeof(fdt_val64));
120
+
121
+ status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-start", fdt_val64);
128122 if (status)
129123 goto fdt_set_fail;
130124
131125 fdt_val32 = U32_MAX; /* placeholder */
132
- status = fdt_setprop(fdt, node, "linux,uefi-mmap-size",
133
- &fdt_val32, sizeof(fdt_val32));
126
+
127
+ status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-size", fdt_val32);
134128 if (status)
135129 goto fdt_set_fail;
136130
137
- status = fdt_setprop(fdt, node, "linux,uefi-mmap-desc-size",
138
- &fdt_val32, sizeof(fdt_val32));
131
+ status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-desc-size", fdt_val32);
139132 if (status)
140133 goto fdt_set_fail;
141134
142
- status = fdt_setprop(fdt, node, "linux,uefi-mmap-desc-ver",
143
- &fdt_val32, sizeof(fdt_val32));
135
+ status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-desc-ver", fdt_val32);
144136 if (status)
145137 goto fdt_set_fail;
146138
147
- if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
139
+ if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && !efi_nokaslr) {
148140 efi_status_t efi_status;
149141
150
- efi_status = efi_get_random_bytes(sys_table, sizeof(fdt_val64),
142
+ efi_status = efi_get_random_bytes(sizeof(fdt_val64),
151143 (u8 *)&fdt_val64);
152144 if (efi_status == EFI_SUCCESS) {
153
- status = fdt_setprop(fdt, node, "kaslr-seed",
154
- &fdt_val64, sizeof(fdt_val64));
145
+ status = fdt_setprop_var(fdt, node, "kaslr-seed", fdt_val64);
155146 if (status)
156147 goto fdt_set_fail;
157
- } else if (efi_status != EFI_NOT_FOUND) {
158
- return efi_status;
159148 }
160149 }
161150
162
- /* shrink the FDT back to its minimum size */
151
+ /* Shrink the FDT back to its minimum size: */
163152 fdt_pack(fdt);
164153
165154 return EFI_SUCCESS;
....@@ -182,44 +171,39 @@
182171 return EFI_LOAD_ERROR;
183172
184173 fdt_val64 = cpu_to_fdt64((unsigned long)*map->map);
185
- err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-start",
186
- &fdt_val64, sizeof(fdt_val64));
174
+
175
+ err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-start", fdt_val64);
187176 if (err)
188177 return EFI_LOAD_ERROR;
189178
190179 fdt_val32 = cpu_to_fdt32(*map->map_size);
191
- err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-size",
192
- &fdt_val32, sizeof(fdt_val32));
180
+
181
+ err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-size", fdt_val32);
193182 if (err)
194183 return EFI_LOAD_ERROR;
195184
196185 fdt_val32 = cpu_to_fdt32(*map->desc_size);
197
- err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-desc-size",
198
- &fdt_val32, sizeof(fdt_val32));
186
+
187
+ err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-desc-size", fdt_val32);
199188 if (err)
200189 return EFI_LOAD_ERROR;
201190
202191 fdt_val32 = cpu_to_fdt32(*map->desc_ver);
203
- err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-desc-ver",
204
- &fdt_val32, sizeof(fdt_val32));
192
+
193
+ err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-desc-ver", fdt_val32);
205194 if (err)
206195 return EFI_LOAD_ERROR;
207196
208197 return EFI_SUCCESS;
209198 }
210199
211
-#ifndef EFI_FDT_ALIGN
212
-#define EFI_FDT_ALIGN EFI_PAGE_SIZE
213
-#endif
214
-
215200 struct exit_boot_struct {
216
- efi_memory_desc_t *runtime_map;
217
- int *runtime_entry_count;
218
- void *new_fdt_addr;
201
+ efi_memory_desc_t *runtime_map;
202
+ int *runtime_entry_count;
203
+ void *new_fdt_addr;
219204 };
220205
221
-static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg,
222
- struct efi_boot_memmap *map,
206
+static efi_status_t exit_boot_func(struct efi_boot_memmap *map,
223207 void *priv)
224208 {
225209 struct exit_boot_struct *p = priv;
....@@ -235,7 +219,7 @@
235219 }
236220
237221 #ifndef MAX_FDT_SIZE
238
-#define MAX_FDT_SIZE SZ_2M
222
+# define MAX_FDT_SIZE SZ_2M
239223 #endif
240224
241225 /*
....@@ -252,8 +236,7 @@
252236 * with the final memory map in it.
253237 */
254238
255
-efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
256
- void *handle,
239
+efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
257240 unsigned long *new_fdt_addr,
258241 unsigned long max_addr,
259242 u64 initrd_addr, u64 initrd_size,
....@@ -266,16 +249,16 @@
266249 unsigned long mmap_key;
267250 efi_memory_desc_t *memory_map, *runtime_map;
268251 efi_status_t status;
269
- int runtime_entry_count = 0;
252
+ int runtime_entry_count;
270253 struct efi_boot_memmap map;
271254 struct exit_boot_struct priv;
272255
273
- map.map = &runtime_map;
274
- map.map_size = &map_size;
275
- map.desc_size = &desc_size;
276
- map.desc_ver = &desc_ver;
277
- map.key_ptr = &mmap_key;
278
- map.buff_size = &buff_size;
256
+ map.map = &runtime_map;
257
+ map.map_size = &map_size;
258
+ map.desc_size = &desc_size;
259
+ map.desc_ver = &desc_ver;
260
+ map.key_ptr = &mmap_key;
261
+ map.buff_size = &buff_size;
279262
280263 /*
281264 * Get a copy of the current memory map that we will use to prepare
....@@ -283,55 +266,45 @@
283266 * subsequent allocations adding entries, since they could not affect
284267 * the number of EFI_MEMORY_RUNTIME regions.
285268 */
286
- status = efi_get_memory_map(sys_table, &map);
269
+ status = efi_get_memory_map(&map);
287270 if (status != EFI_SUCCESS) {
288
- pr_efi_err(sys_table, "Unable to retrieve UEFI memory map.\n");
271
+ efi_err("Unable to retrieve UEFI memory map.\n");
289272 return status;
290273 }
291274
292
- pr_efi(sys_table,
293
- "Exiting boot services and installing virtual address map...\n");
275
+ efi_info("Exiting boot services and installing virtual address map...\n");
294276
295277 map.map = &memory_map;
296
- status = efi_high_alloc(sys_table, MAX_FDT_SIZE, EFI_FDT_ALIGN,
297
- new_fdt_addr, max_addr);
278
+ status = efi_allocate_pages(MAX_FDT_SIZE, new_fdt_addr, max_addr);
298279 if (status != EFI_SUCCESS) {
299
- pr_efi_err(sys_table,
300
- "Unable to allocate memory for new device tree.\n");
280
+ efi_err("Unable to allocate memory for new device tree.\n");
301281 goto fail;
302282 }
303283
304
- /*
305
- * Now that we have done our final memory allocation (and free)
306
- * we can get the memory map key needed for exit_boot_services().
307
- */
308
- status = efi_get_memory_map(sys_table, &map);
309
- if (status != EFI_SUCCESS)
310
- goto fail_free_new_fdt;
311
-
312
- status = update_fdt(sys_table, (void *)fdt_addr, fdt_size,
284
+ status = update_fdt((void *)fdt_addr, fdt_size,
313285 (void *)*new_fdt_addr, MAX_FDT_SIZE, cmdline_ptr,
314286 initrd_addr, initrd_size);
315287
316288 if (status != EFI_SUCCESS) {
317
- pr_efi_err(sys_table, "Unable to construct new device tree.\n");
289
+ efi_err("Unable to construct new device tree.\n");
318290 goto fail_free_new_fdt;
319291 }
320292
321
- priv.runtime_map = runtime_map;
322
- priv.runtime_entry_count = &runtime_entry_count;
323
- priv.new_fdt_addr = (void *)*new_fdt_addr;
324
- status = efi_exit_boot_services(sys_table, handle, &map, &priv,
325
- exit_boot_func);
293
+ runtime_entry_count = 0;
294
+ priv.runtime_map = runtime_map;
295
+ priv.runtime_entry_count = &runtime_entry_count;
296
+ priv.new_fdt_addr = (void *)*new_fdt_addr;
297
+
298
+ status = efi_exit_boot_services(handle, &map, &priv, exit_boot_func);
326299
327300 if (status == EFI_SUCCESS) {
328301 efi_set_virtual_address_map_t *svam;
329302
330
- if (novamap())
303
+ if (efi_novamap)
331304 return EFI_SUCCESS;
332305
333306 /* Install the new virtual address map */
334
- svam = sys_table->runtime->set_virtual_address_map;
307
+ svam = efi_system_table->runtime->set_virtual_address_map;
335308 status = svam(runtime_entry_count * desc_size, desc_size,
336309 desc_ver, runtime_map);
337310
....@@ -359,36 +332,30 @@
359332 return EFI_SUCCESS;
360333 }
361334
362
- pr_efi_err(sys_table, "Exit boot services failed.\n");
335
+ efi_err("Exit boot services failed.\n");
363336
364337 fail_free_new_fdt:
365
- efi_free(sys_table, MAX_FDT_SIZE, *new_fdt_addr);
338
+ efi_free(MAX_FDT_SIZE, *new_fdt_addr);
366339
367340 fail:
368
- sys_table->boottime->free_pool(runtime_map);
341
+ efi_system_table->boottime->free_pool(runtime_map);
342
+
369343 return EFI_LOAD_ERROR;
370344 }
371345
372
-void *get_fdt(efi_system_table_t *sys_table, unsigned long *fdt_size)
346
+void *get_fdt(unsigned long *fdt_size)
373347 {
374
- efi_guid_t fdt_guid = DEVICE_TREE_GUID;
375
- efi_config_table_t *tables;
376348 void *fdt;
377
- int i;
378349
379
- tables = (efi_config_table_t *) sys_table->tables;
380
- fdt = NULL;
350
+ fdt = get_efi_config_table(DEVICE_TREE_GUID);
381351
382
- for (i = 0; i < sys_table->nr_tables; i++)
383
- if (efi_guidcmp(tables[i].guid, fdt_guid) == 0) {
384
- fdt = (void *) tables[i].table;
385
- if (fdt_check_header(fdt) != 0) {
386
- pr_efi_err(sys_table, "Invalid header detected on UEFI supplied FDT, ignoring ...\n");
387
- return NULL;
388
- }
389
- *fdt_size = fdt_totalsize(fdt);
390
- break;
391
- }
352
+ if (!fdt)
353
+ return NULL;
392354
355
+ if (fdt_check_header(fdt) != 0) {
356
+ efi_err("Invalid header detected on UEFI supplied FDT, ignoring ...\n");
357
+ return NULL;
358
+ }
359
+ *fdt_size = fdt_totalsize(fdt);
393360 return fdt;
394361 }