diff options
Diffstat (limited to 'cmd/efidebug.c')
| -rw-r--r-- | cmd/efidebug.c | 129 | 
1 files changed, 92 insertions, 37 deletions
| diff --git a/cmd/efidebug.c b/cmd/efidebug.c index e978e74aad9..1a191eb9994 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -653,38 +653,80 @@ static int do_efi_show_tables(struct cmd_tbl *cmdtp, int flag,  }  /** - * create_initrd_dp() - create a special device for our Boot### option + * enum efi_lo_dp_part - part of device path in load option + */ +enum efi_lo_dp_part { +	/** @EFI_LO_DP_PART_BINARY: binary */ +	EFI_LO_DP_PART_BINARY, +	/** @EFI_LO_DP_PART_INITRD: initial RAM disk */ +	EFI_LO_DP_PART_INITRD, +	/** @EFI_LP_DP_PART_FDT: device-tree */ +	EFI_LP_DP_PART_FDT, +}; + +/** + * create_lo_dp() - create a special device path for our Boot### option   *   * @dev:	device   * @part:	disk partition   * @file:	filename   * @shortform:	create short form device path + * @type:	part of device path to be created   * Return:	pointer to the device path or ERR_PTR   */  static -struct efi_device_path *create_initrd_dp(const char *dev, const char *part, -					 const char *file, int shortform) +struct efi_device_path *create_lo_dp_part(const char *dev, const char *part, +					  const char *file, bool shortform, +					  enum efi_lo_dp_part type)  {  	struct efi_device_path *tmp_dp = NULL, *tmp_fp = NULL, *short_fp = NULL; -	struct efi_device_path *initrd_dp = NULL; +	struct efi_device_path *dp = NULL; +	const struct efi_device_path *dp_prefix;  	efi_status_t ret; -	const struct efi_initrd_dp id_dp = { +	const struct efi_lo_dp_prefix fdt_dp = {  		.vendor = {  			{  			DEVICE_PATH_TYPE_MEDIA_DEVICE,  			DEVICE_PATH_SUB_TYPE_VENDOR_PATH, -			sizeof(id_dp.vendor), +			sizeof(fdt_dp.vendor), +			}, +			EFI_FDT_GUID, +		}, +		.end = { +			DEVICE_PATH_TYPE_END, +			DEVICE_PATH_SUB_TYPE_END, +			sizeof(fdt_dp.end), +		} +	}; +	const struct efi_lo_dp_prefix initrd_dp = { +		.vendor = { +			{ +			DEVICE_PATH_TYPE_MEDIA_DEVICE, +			DEVICE_PATH_SUB_TYPE_VENDOR_PATH, +			sizeof(initrd_dp.vendor),  			},  			EFI_INITRD_MEDIA_GUID,  		},  		.end = {  			DEVICE_PATH_TYPE_END,  			DEVICE_PATH_SUB_TYPE_END, -			sizeof(id_dp.end), +			sizeof(initrd_dp.end),  		}  	}; +	switch (type) { +	case EFI_LO_DP_PART_INITRD: +		dp_prefix = &initrd_dp.vendor.dp; +		break; +	case EFI_LP_DP_PART_FDT: +		dp_prefix = &fdt_dp.vendor.dp; +		break; +	default: +		dp_prefix = NULL; +		break; +	} +  	ret = efi_dp_from_name(dev, part, file, &tmp_dp, &tmp_fp);  	if (ret != EFI_SUCCESS) {  		printf("Cannot create device path for \"%s %s\"\n", part, file); @@ -695,13 +737,12 @@ struct efi_device_path *create_initrd_dp(const char *dev, const char *part,  	if (!short_fp)  		short_fp = tmp_fp; -	initrd_dp = efi_dp_concat((const struct efi_device_path *)&id_dp, -				  short_fp, false); +	dp = efi_dp_concat(dp_prefix, short_fp, 0);  out:  	efi_free_pool(tmp_dp);  	efi_free_pool(tmp_fp); -	return initrd_dp; +	return dp;  }  /** @@ -792,9 +833,8 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,  	efi_guid_t guid;  	u16 *label;  	struct efi_device_path *file_path = NULL; -	struct efi_device_path *fp_free = NULL; -	struct efi_device_path *final_fp = NULL;  	struct efi_device_path *initrd_dp = NULL; +	struct efi_device_path *fdt_dp = NULL;  	struct efi_load_option lo;  	void *data = NULL;  	efi_uintn_t size; @@ -842,22 +882,31 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,  			lo.label = label; /* label will be changed below */  			/* file path */ -			ret = efi_dp_from_name(argv[3], argv[4], argv[5], -					       NULL, &fp_free); -			if (ret != EFI_SUCCESS) { -				printf("Cannot create device path for \"%s %s\"\n", -				       argv[3], argv[4]); +			file_path = create_lo_dp_part(argv[3], argv[4], argv[5], +						      shortform, +						      EFI_LO_DP_PART_BINARY); +			argc -= 5; +			argv += 5; +			break; +		case 'd': +			shortform = 1; +			fallthrough; +		case 'D': +			if (argc < 3 || fdt_dp) { +				r = CMD_RET_USAGE; +				goto out; +			} + +			fdt_dp = create_lo_dp_part(argv[1], argv[2], argv[3], +						   shortform, +						   EFI_LP_DP_PART_FDT); +			if (!fdt_dp) { +				printf("Cannot add a device-tree\n");  				r = CMD_RET_FAILURE;  				goto out;  			} -			if (shortform) -				file_path = efi_dp_shorten(fp_free); -			if (!file_path) -				file_path = fp_free; -			fp_size += efi_dp_size(file_path) + -				sizeof(struct efi_device_path); -			argc -= 5; -			argv += 5; +			argc -= 3; +			argv += 3;  			break;  		case 'i':  			shortform = 1; @@ -868,8 +917,9 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,  				goto out;  			} -			initrd_dp = create_initrd_dp(argv[1], argv[2], argv[3], -						     shortform); +			initrd_dp = create_lo_dp_part(argv[1], argv[2], argv[3], +						      shortform, +						      EFI_LO_DP_PART_INITRD);  			if (!initrd_dp) {  				printf("Cannot add an initrd\n");  				r = CMD_RET_FAILURE; @@ -877,8 +927,6 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,  			}  			argc -= 3;  			argv += 3; -			fp_size += efi_dp_size(initrd_dp) + -				sizeof(struct efi_device_path);  			break;  		case 's':  			if (argc < 1 || lo.optional_data) { @@ -896,7 +944,6 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,  						     &file_path, &fp_size);  				if (r != CMD_RET_SUCCESS)  					goto out; -				fp_free = file_path;  				argc -= 3;  				argv += 3;  			} else{ @@ -916,14 +963,14 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,  		goto out;  	} -	final_fp = efi_dp_concat(file_path, initrd_dp, true); -	if (!final_fp) { +	ret = efi_load_option_dp_join(&file_path, &fp_size, initrd_dp, fdt_dp); +	if (ret != EFI_SUCCESS) {  		printf("Cannot create final device path\n");  		r = CMD_RET_FAILURE;  		goto out;  	} -	lo.file_path = final_fp; +	lo.file_path = file_path;  	lo.file_path_length = fp_size;  	size = efi_serialize_load_option(&lo, (u8 **)&data); @@ -944,9 +991,9 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,  out:  	free(data); -	efi_free_pool(final_fp);  	efi_free_pool(initrd_dp); -	efi_free_pool(fp_free); +	efi_free_pool(fdt_dp); +	efi_free_pool(file_path);  	free(lo.label);  	return r; @@ -1008,7 +1055,8 @@ static int do_efi_boot_rm(struct cmd_tbl *cmdtp, int flag,   */  static void show_efi_boot_opt_data(u16 *varname16, void *data, size_t *size)  { -	struct efi_device_path *initrd_path = NULL; +	struct efi_device_path *fdt_path; +	struct efi_device_path *initrd_path;  	struct efi_load_option lo;  	efi_status_t ret; @@ -1037,6 +1085,12 @@ static void show_efi_boot_opt_data(u16 *varname16, void *data, size_t *size)  		efi_free_pool(initrd_path);  	} +	fdt_path = efi_dp_from_lo(&lo, &efi_guid_fdt); +	if (fdt_path) { +		printf("  device-tree path: %pD\n", fdt_path); +		efi_free_pool(fdt_path); +	} +  	printf("  data:\n");  	print_hex_dump("    ", DUMP_PREFIX_OFFSET, 16, 1,  		       lo.optional_data, *size, true); @@ -1564,8 +1618,9 @@ U_BOOT_LONGHELP(efidebug,  	"\n"  	"efidebug boot add - set UEFI BootXXXX variable\n"  	"  -b|-B <bootid> <label> <interface> <devnum>[:<part>] <file path>\n" +	"  -d|-D <interface> <devnum>[:<part>] <device-tree file path>\n"  	"  -i|-I <interface> <devnum>[:<part>] <initrd file path>\n" -	"  (-b, -i for short form device path)\n" +	"  (-b, -d, -i for short form device path)\n"  #if (IS_ENABLED(CONFIG_EFI_HTTP_BOOT))  	"  -u <bootid> <label> <uri>\n"  #endif | 
