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>
Acked-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
{
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)
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();
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");
} __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;
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,
+ uint64_t end_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);
}
#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.
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;