16
16
17
17
#include "efistub.h"
18
18
19
- efi_status_t update_fdt (efi_system_table_t * sys_table , void * orig_fdt ,
20
- unsigned long orig_fdt_size ,
21
- void * fdt , int new_fdt_size , char * cmdline_ptr ,
22
- u64 initrd_addr , u64 initrd_size ,
23
- efi_memory_desc_t * memory_map ,
24
- unsigned long map_size , unsigned long desc_size ,
25
- u32 desc_ver )
19
+ static efi_status_t update_fdt (efi_system_table_t * sys_table , void * orig_fdt ,
20
+ unsigned long orig_fdt_size ,
21
+ void * fdt , int new_fdt_size , char * cmdline_ptr ,
22
+ u64 initrd_addr , u64 initrd_size )
26
23
{
27
24
int node , num_rsv ;
28
25
int status ;
@@ -101,25 +98,23 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
101
98
if (status )
102
99
goto fdt_set_fail ;
103
100
104
- fdt_val64 = cpu_to_fdt64 (( u64 )( unsigned long ) memory_map );
101
+ fdt_val64 = U64_MAX ; /* placeholder */
105
102
status = fdt_setprop (fdt , node , "linux,uefi-mmap-start" ,
106
103
& fdt_val64 , sizeof (fdt_val64 ));
107
104
if (status )
108
105
goto fdt_set_fail ;
109
106
110
- fdt_val32 = cpu_to_fdt32 ( map_size );
107
+ fdt_val32 = U32_MAX ; /* placeholder */
111
108
status = fdt_setprop (fdt , node , "linux,uefi-mmap-size" ,
112
109
& fdt_val32 , sizeof (fdt_val32 ));
113
110
if (status )
114
111
goto fdt_set_fail ;
115
112
116
- fdt_val32 = cpu_to_fdt32 (desc_size );
117
113
status = fdt_setprop (fdt , node , "linux,uefi-mmap-desc-size" ,
118
114
& fdt_val32 , sizeof (fdt_val32 ));
119
115
if (status )
120
116
goto fdt_set_fail ;
121
117
122
- fdt_val32 = cpu_to_fdt32 (desc_ver );
123
118
status = fdt_setprop (fdt , node , "linux,uefi-mmap-desc-ver" ,
124
119
& fdt_val32 , sizeof (fdt_val32 ));
125
120
if (status )
@@ -148,6 +143,43 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
148
143
return EFI_LOAD_ERROR ;
149
144
}
150
145
146
+ static efi_status_t update_fdt_memmap (void * fdt , struct efi_boot_memmap * map )
147
+ {
148
+ int node = fdt_path_offset (fdt , "/chosen" );
149
+ u64 fdt_val64 ;
150
+ u32 fdt_val32 ;
151
+ int err ;
152
+
153
+ if (node < 0 )
154
+ return EFI_LOAD_ERROR ;
155
+
156
+ fdt_val64 = cpu_to_fdt64 ((unsigned long )* map -> map );
157
+ err = fdt_setprop_inplace (fdt , node , "linux,uefi-mmap-start" ,
158
+ & fdt_val64 , sizeof (fdt_val64 ));
159
+ if (err )
160
+ return EFI_LOAD_ERROR ;
161
+
162
+ fdt_val32 = cpu_to_fdt32 (* map -> map_size );
163
+ err = fdt_setprop_inplace (fdt , node , "linux,uefi-mmap-size" ,
164
+ & fdt_val32 , sizeof (fdt_val32 ));
165
+ if (err )
166
+ return EFI_LOAD_ERROR ;
167
+
168
+ fdt_val32 = cpu_to_fdt32 (* map -> desc_size );
169
+ err = fdt_setprop_inplace (fdt , node , "linux,uefi-mmap-desc-size" ,
170
+ & fdt_val32 , sizeof (fdt_val32 ));
171
+ if (err )
172
+ return EFI_LOAD_ERROR ;
173
+
174
+ fdt_val32 = cpu_to_fdt32 (* map -> desc_ver );
175
+ err = fdt_setprop_inplace (fdt , node , "linux,uefi-mmap-desc-ver" ,
176
+ & fdt_val32 , sizeof (fdt_val32 ));
177
+ if (err )
178
+ return EFI_LOAD_ERROR ;
179
+
180
+ return EFI_SUCCESS ;
181
+ }
182
+
151
183
#ifndef EFI_FDT_ALIGN
152
184
#define EFI_FDT_ALIGN EFI_PAGE_SIZE
153
185
#endif
@@ -243,20 +275,10 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
243
275
goto fail ;
244
276
}
245
277
246
- /*
247
- * Now that we have done our final memory allocation (and free)
248
- * we can get the memory map key needed for
249
- * exit_boot_services().
250
- */
251
- status = efi_get_memory_map (sys_table , & map );
252
- if (status != EFI_SUCCESS )
253
- goto fail_free_new_fdt ;
254
-
255
278
status = update_fdt (sys_table ,
256
279
(void * )fdt_addr , fdt_size ,
257
280
(void * )* new_fdt_addr , new_fdt_size ,
258
- cmdline_ptr , initrd_addr , initrd_size ,
259
- memory_map , map_size , desc_size , desc_ver );
281
+ cmdline_ptr , initrd_addr , initrd_size );
260
282
261
283
/* Succeeding the first time is the expected case. */
262
284
if (status == EFI_SUCCESS )
@@ -266,20 +288,16 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
266
288
/*
267
289
* We need to allocate more space for the new
268
290
* device tree, so free existing buffer that is
269
- * too small. Also free memory map, as we will need
270
- * to get new one that reflects the free/alloc we do
271
- * on the device tree buffer.
291
+ * too small.
272
292
*/
273
293
efi_free (sys_table , new_fdt_size , * new_fdt_addr );
274
- sys_table -> boottime -> free_pool (memory_map );
275
294
new_fdt_size += EFI_PAGE_SIZE ;
276
295
} else {
277
296
pr_efi_err (sys_table , "Unable to construct new device tree.\n" );
278
- goto fail_free_mmap ;
297
+ goto fail_free_new_fdt ;
279
298
}
280
299
}
281
300
282
- sys_table -> boottime -> free_pool (memory_map );
283
301
priv .runtime_map = runtime_map ;
284
302
priv .runtime_entry_count = & runtime_entry_count ;
285
303
status = efi_exit_boot_services (sys_table , handle , & map , & priv ,
@@ -288,6 +306,16 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
288
306
if (status == EFI_SUCCESS ) {
289
307
efi_set_virtual_address_map_t * svam ;
290
308
309
+ status = update_fdt_memmap ((void * )* new_fdt_addr , & map );
310
+ if (status != EFI_SUCCESS ) {
311
+ /*
312
+ * The kernel won't get far without the memory map, but
313
+ * may still be able to print something meaningful so
314
+ * return success here.
315
+ */
316
+ return EFI_SUCCESS ;
317
+ }
318
+
291
319
/* Install the new virtual address map */
292
320
svam = sys_table -> runtime -> set_virtual_address_map ;
293
321
status = svam (runtime_entry_count * desc_size , desc_size ,
@@ -319,9 +347,6 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
319
347
320
348
pr_efi_err (sys_table , "Exit boot services failed.\n" );
321
349
322
- fail_free_mmap :
323
- sys_table -> boottime -> free_pool (memory_map );
324
-
325
350
fail_free_new_fdt :
326
351
efi_free (sys_table , new_fdt_size , * new_fdt_addr );
327
352
0 commit comments