
On 10/10/2017 02:23 PM, Rob Clark wrote:
When we don't have a real device/image path, such as 'bootefi hello', construct a mem-mapped device-path.
This fixes 'bootefi hello' after devicepath refactoring.
Fixes: 95c5553ea2 ("efi_loader: refactor boot device and loaded_image handling") Signed-off-by: Rob Clark robdclark@gmail.com
cmd/bootefi.c | 23 +++++++++++++++++++++++ include/efi_api.h | 8 ++++++++ include/efi_loader.h | 3 +++ lib/efi_loader/efi_device_path.c | 24 ++++++++++++++++++++++++ lib/efi_loader/efi_device_path_to_text.c | 9 +++++++++ 5 files changed, 67 insertions(+)
diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 24958ada46..18176a1266 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -128,6 +128,7 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt, { struct efi_loaded_image loaded_image_info = {}; struct efi_object loaded_image_info_obj = {};
struct efi_device_path *memdp = NULL; ulong ret;
ulong (*entry)(void *image_handle, struct efi_system_table *st)
@@ -136,6 +137,20 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt, const efi_guid_t fdt_guid = EFI_FDT_GUID; bootm_headers_t img = { 0 };
- /*
* Special case for efi payload not loaded from disk, such as
* 'bootefi hello' or for example payload loaded directly into
* memory via jtag/etc:
*/
- if (!device_path && !image_path) {
printf("WARNING: using memory device/image path, this may confuse some payloads!\n");
/* actual addresses filled in after efi_load_pe() */
memdp = efi_dp_from_mem(0, 0, 0);
device_path = image_path = memdp;
- } else {
assert(device_path && image_path);
- }
- /* Initialize and populate EFI object list */ if (!efi_obj_list_initalized) efi_init_obj_list();
@@ -182,6 +197,14 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt, goto exit; }
- if (memdp) {
struct efi_device_path_memory *mdp = (void *)memdp;
mdp->memory_type = loaded_image_info.image_code_type;
mdp->start_address = (uintptr_t)loaded_image_info.image_base;
mdp->end_address = mdp->start_address +
loaded_image_info.image_size;
- }
- /* we don't support much: */ env_set("efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported", "{ro,boot}(blob)0000000000000000");
diff --git a/include/efi_api.h b/include/efi_api.h index 9610d03d47..07b2af7020 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -299,8 +299,16 @@ struct efi_mac_addr { } __packed;
#define DEVICE_PATH_TYPE_HARDWARE_DEVICE 0x01 +# define DEVICE_PATH_SUB_TYPE_MEMORY 0x03 # define DEVICE_PATH_SUB_TYPE_VENDOR 0x04
+struct efi_device_path_memory {
- struct efi_device_path dp;
- u32 memory_type;
- u64 start_address;
- u64 end_address;
+} __packed;
- struct efi_device_path_vendor { struct efi_device_path dp; efi_guid_t guid;
diff --git a/include/efi_loader.h b/include/efi_loader.h index fa4e1cdb1c..db805e898f 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -269,6 +269,9 @@ struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part); struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part, const char *path); struct efi_device_path *efi_dp_from_eth(void); +struct efi_device_path *efi_dp_from_mem(uint32_t mem_type,
uint64_t start_address,
void efi_dp_split_file_path(struct efi_device_path *full_path, struct efi_device_path **device_path, struct efi_device_path **file_path);uint64_t end_address);
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index 5d5c3b3464..f6e368e029 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -538,6 +538,30 @@ struct efi_device_path *efi_dp_from_eth(void) } #endif
+/* Construct a device-path for memory-mapped image */ +struct efi_device_path *efi_dp_from_mem(uint32_t memory_type,
uint64_t start_address,
uint64_t end_address)
+{
- struct efi_device_path_memory *mdp;
- void *buf, *start;
- start = buf = dp_alloc(sizeof(*mdp) + sizeof(END));
- mdp = buf;
- mdp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
- mdp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MEMORY;
- mdp->dp.length = sizeof(*mdp);
- mdp->memory_type = memory_type;
- mdp->start_address = start_address;
- mdp->end_address = end_address;
- buf = &mdp[1];
- *((struct efi_device_path *)buf) = END;
- return start;
+}
- /*
- Helper to split a full device path (containing both device and file
- parts) into it's constituent parts.
diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c index 1a5ef3919b..62771338f0 100644 --- a/lib/efi_loader/efi_device_path_to_text.c +++ b/lib/efi_loader/efi_device_path_to_text.c @@ -24,6 +24,15 @@ static char *dp_unknown(char *s, struct efi_device_path *dp) static char *dp_hardware(char *s, struct efi_device_path *dp) { switch (dp->sub_type) {
- case DEVICE_PATH_SUB_TYPE_MEMORY: {
struct efi_device_path_memory *mdp =
(struct efi_device_path_memory *)dp;
s += sprintf(s, "/MemoryMapped(0x%x,0x%llx,0x%llx)",
mdp->memory_type,
mdp->start_address,
mdp->end_address);
break;
- } case DEVICE_PATH_SUB_TYPE_VENDOR: { struct efi_device_path_vendor *vdp = (struct efi_device_path_vendor *)dp;
Providing a dummmy device path for bootefi hello and bootefi selftest is reasonable.
Acked-by: Heinrich Schuchardt xypron.glpk@gmx.de