@@ -22,97 +22,14 @@ DECLARE_GLOBAL_DATA_PTR;
2222
2323static uint8_t efi_obj_list_initalized ;
2424
25- /*
26- * When booting using the "bootefi" command, we don't know which
27- * physical device the file came from. So we create a pseudo-device
28- * called "bootefi" with the device path /bootefi.
29- *
30- * In addition to the originating device we also declare the file path
31- * of "bootefi" based loads to be /bootefi.
32- */
33- static struct efi_device_path_file_path bootefi_image_path [] = {
34- {
35- .dp .type = DEVICE_PATH_TYPE_MEDIA_DEVICE ,
36- .dp .sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH ,
37- .dp .length = sizeof (bootefi_image_path [0 ]),
38- .str = { 'b' ,'o' ,'o' ,'t' ,'e' ,'f' ,'i' },
39- }, {
40- .dp .type = DEVICE_PATH_TYPE_END ,
41- .dp .sub_type = DEVICE_PATH_SUB_TYPE_END ,
42- .dp .length = sizeof (bootefi_image_path [0 ]),
43- }
44- };
45-
46- static struct efi_device_path_file_path bootefi_device_path [] = {
47- {
48- .dp .type = DEVICE_PATH_TYPE_MEDIA_DEVICE ,
49- .dp .sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH ,
50- .dp .length = sizeof (bootefi_image_path [0 ]),
51- .str = { 'b' ,'o' ,'o' ,'t' ,'e' ,'f' ,'i' },
52- }, {
53- .dp .type = DEVICE_PATH_TYPE_END ,
54- .dp .sub_type = DEVICE_PATH_SUB_TYPE_END ,
55- .dp .length = sizeof (bootefi_image_path [0 ]),
56- }
57- };
58-
59- /* The EFI loaded_image interface for the image executed via "bootefi" */
60- static struct efi_loaded_image loaded_image_info = {
61- .device_handle = bootefi_device_path ,
62- .file_path = bootefi_image_path ,
63- };
64-
65- /* The EFI object struct for the image executed via "bootefi" */
66- static struct efi_object loaded_image_info_obj = {
67- .handle = & loaded_image_info ,
68- .protocols = {
69- {
70- /*
71- * When asking for the loaded_image interface, just
72- * return handle which points to loaded_image_info
73- */
74- .guid = & efi_guid_loaded_image ,
75- .protocol_interface = & loaded_image_info ,
76- },
77- {
78- /*
79- * When asking for the device path interface, return
80- * bootefi_device_path
81- */
82- .guid = & efi_guid_device_path ,
83- .protocol_interface = bootefi_device_path ,
84- },
85- {
86- .guid = & efi_guid_console_control ,
87- .protocol_interface = (void * ) & efi_console_control
88- },
89- {
90- .guid = & efi_guid_device_path_to_text_protocol ,
91- .protocol_interface = (void * ) & efi_device_path_to_text
92- },
93- },
94- };
95-
96- /* The EFI object struct for the device the "bootefi" image was loaded from */
97- static struct efi_object bootefi_device_obj = {
98- .handle = bootefi_device_path ,
99- .protocols = {
100- {
101- /* When asking for the device path interface, return
102- * bootefi_device_path */
103- .guid = & efi_guid_device_path ,
104- .protocol_interface = bootefi_device_path
105- }
106- },
107- };
25+ static struct efi_device_path * bootefi_image_path ;
26+ static struct efi_device_path * bootefi_device_path ;
10827
10928/* Initialize and populate EFI object list */
11029static void efi_init_obj_list (void )
11130{
11231 efi_obj_list_initalized = 1 ;
11332
114- list_add_tail (& loaded_image_info_obj .link , & efi_obj_list );
115- list_add_tail (& bootefi_device_obj .link , & efi_obj_list );
11633 efi_console_register ();
11734#ifdef CONFIG_PARTITIONS
11835 efi_disk_register ();
@@ -121,13 +38,7 @@ static void efi_init_obj_list(void)
12138 efi_gop_register ();
12239#endif
12340#ifdef CONFIG_NET
124- void * nethandle = loaded_image_info .device_handle ;
125- efi_net_register (& nethandle );
126-
127- if (!memcmp (bootefi_device_path [0 ].str , "N\0e\0t" , 6 ))
128- loaded_image_info .device_handle = nethandle ;
129- else
130- loaded_image_info .device_handle = bootefi_device_path ;
41+ efi_net_register ();
13142#endif
13243#ifdef CONFIG_GENERATE_SMBIOS_TABLE
13344 efi_smbios_register ();
@@ -210,14 +121,27 @@ static unsigned long efi_run_in_el2(asmlinkage ulong (*entry)(
210121 * Load an EFI payload into a newly allocated piece of memory, register all
211122 * EFI objects it would want to access and jump to it.
212123 */
213- static unsigned long do_bootefi_exec (void * efi , void * fdt )
124+ static unsigned long do_bootefi_exec (void * efi , void * fdt ,
125+ struct efi_device_path * device_path ,
126+ struct efi_device_path * image_path )
214127{
128+ struct efi_loaded_image loaded_image_info = {};
129+ struct efi_object loaded_image_info_obj = {};
130+ ulong ret ;
131+
215132 ulong (* entry )(void * image_handle , struct efi_system_table * st )
216133 asmlinkage ;
217134 ulong fdt_pages , fdt_size , fdt_start , fdt_end ;
218135 const efi_guid_t fdt_guid = EFI_FDT_GUID ;
219136 bootm_headers_t img = { 0 };
220137
138+ /* Initialize and populate EFI object list */
139+ if (!efi_obj_list_initalized )
140+ efi_init_obj_list ();
141+
142+ efi_setup_loaded_image (& loaded_image_info , & loaded_image_info_obj ,
143+ device_path , image_path );
144+
221145 /*
222146 * gd lives in a fixed register which may get clobbered while we execute
223147 * the payload. So save it here and restore it on every callback entry
@@ -252,18 +176,18 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt)
252176
253177 /* Load the EFI payload */
254178 entry = efi_load_pe (efi , & loaded_image_info );
255- if (!entry )
256- return - ENOENT ;
257-
258- /* Initialize and populate EFI object list */
259- if (!efi_obj_list_initalized )
260- efi_init_obj_list ();
179+ if (!entry ) {
180+ ret = - ENOENT ;
181+ goto exit ;
182+ }
261183
262184 /* Call our payload! */
263185 debug ("%s:%d Jumping to 0x%lx\n" , __func__ , __LINE__ , (long )entry );
264186
265187 if (setjmp (& loaded_image_info .exit_jmp )) {
266- return loaded_image_info .exit_status ;
188+ ret = loaded_image_info .exit_status ;
189+ EFI_EXIT (ret );
190+ goto exit ;
267191 }
268192
269193#ifdef CONFIG_ARM64
@@ -282,7 +206,13 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt)
282206 }
283207#endif
284208
285- return efi_do_enter (& loaded_image_info , & systab , entry );
209+ ret = efi_do_enter (& loaded_image_info , & systab , entry );
210+
211+ exit :
212+ /* image has returned, loaded-image obj goes *poof*: */
213+ list_del (& loaded_image_info_obj .link );
214+
215+ return ret ;
286216}
287217
288218
@@ -319,7 +249,8 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
319249 }
320250
321251 printf ("## Starting EFI application at %08lx ...\n" , addr );
322- r = do_bootefi_exec ((void * )addr , (void * )fdt_addr );
252+ r = do_bootefi_exec ((void * )addr , (void * )fdt_addr ,
253+ bootefi_device_path , bootefi_image_path );
323254 printf ("## Application terminated, r = %lu\n" ,
324255 r & ~EFI_ERROR_MASK );
325256
@@ -348,58 +279,44 @@ U_BOOT_CMD(
348279 bootefi_help_text
349280);
350281
351- void efi_set_bootdev (const char * dev , const char * devnr , const char * path )
282+ static int parse_partnum (const char * devnr )
352283{
353- __maybe_unused struct blk_desc * desc ;
354- char devname [32 ] = { 0 }; /* dp->str is u16[32] long */
355- char * colon , * s ;
356-
357- #if defined(CONFIG_BLK ) || CONFIG_IS_ENABLED (ISO_PARTITION )
358- desc = blk_get_dev (dev , simple_strtol (devnr , NULL , 10 ));
359- #endif
360-
361- #ifdef CONFIG_BLK
362- if (desc ) {
363- snprintf (devname , sizeof (devname ), "%s" , desc -> bdev -> name );
364- } else
365- #endif
366-
367- {
368- /* Assemble the condensed device name we use in efi_disk.c */
369- snprintf (devname , sizeof (devname ), "%s%s" , dev , devnr );
284+ const char * str = strchr (devnr , ':' );
285+ if (str ) {
286+ str ++ ;
287+ return simple_strtoul (str , NULL , 16 );
370288 }
289+ return 0 ;
290+ }
371291
372- colon = strchr (devname , ':' );
373-
374- #if CONFIG_IS_ENABLED (ISO_PARTITION )
375- /* For ISOs we create partition block devices */
376- if (desc && (desc -> type != DEV_TYPE_UNKNOWN ) &&
377- (desc -> part_type == PART_TYPE_ISO )) {
378- if (!colon )
379- snprintf (devname , sizeof (devname ), "%s:1" , devname );
292+ void efi_set_bootdev (const char * dev , const char * devnr , const char * path )
293+ {
294+ char filename [32 ] = { 0 }; /* dp->str is u16[32] long */
295+ char * s ;
380296
381- colon = NULL ;
382- }
383- #endif
297+ if ( strcmp ( dev , "Net" )) {
298+ struct blk_desc * desc ;
299+ int part ;
384300
385- if ( colon )
386- * colon = '\0' ;
301+ desc = blk_get_dev ( dev , simple_strtol ( devnr , NULL , 10 ));
302+ part = parse_partnum ( devnr ) ;
387303
388- /* Patch bootefi_device_path to the target device */
389- memset (bootefi_device_path [0 ].str , 0 , sizeof (bootefi_device_path [0 ].str ));
390- ascii2unicode (bootefi_device_path [0 ].str , devname );
304+ bootefi_device_path = efi_dp_from_part (desc , part );
305+ } else {
306+ #ifdef CONFIG_NET
307+ bootefi_device_path = efi_dp_from_eth ();
308+ #endif
309+ }
391310
392- /* Patch bootefi_image_path to the target file path */
393- memset (bootefi_image_path [0 ].str , 0 , sizeof (bootefi_image_path [0 ].str ));
394311 if (strcmp (dev , "Net" )) {
395312 /* Add leading / to fs paths, because they're absolute */
396- snprintf (devname , sizeof (devname ), "/%s" , path );
313+ snprintf (filename , sizeof (filename ), "/%s" , path );
397314 } else {
398- snprintf (devname , sizeof (devname ), "%s" , path );
315+ snprintf (filename , sizeof (filename ), "%s" , path );
399316 }
400317 /* DOS style file path: */
401- s = devname ;
318+ s = filename ;
402319 while ((s = strchr (s , '/' )))
403320 * s ++ = '\\' ;
404- ascii2unicode ( bootefi_image_path [ 0 ]. str , devname );
321+ bootefi_image_path = efi_dp_from_file ( NULL , 0 , filename );
405322}
0 commit comments