Re: [PATCH v9 04/11] efi_loader: capsule: support firmware update
Heinrich, On Wed, Nov 25, 2020 at 02:00:22AM +0100, Heinrich Schuchardt wrote: > On 11/17/20 1:27 AM, AKASHI Takahiro wrote: > > A capsule tagged with the guid, EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID, > > is handled as a firmware update object. > > What efi_update_capsule() basically does is to load any firmware management > > protocol (or fmp) drivers contained in a capsule, find out an appropriate > > fmp driver and then invoke its set_image() interface against each binary > > in a capsule. > > In this commit, however, loading drivers is not supported. > > > > The result of applying a capsule is set to be stored in "Capsule" > > variable, but its implementation is deferred to a fmp driver. > > > > Signed-off-by: AKASHI Takahiro > > --- > > include/efi_api.h| 129 +++ > > include/efi_loader.h | 2 + > > lib/efi_loader/Kconfig | 8 ++ > > lib/efi_loader/efi_capsule.c | 238 ++- > > lib/efi_loader/efi_setup.c | 4 + > > 5 files changed, 380 insertions(+), 1 deletion(-) > > > > diff --git a/include/efi_api.h b/include/efi_api.h > > index 7a2a087c60ed..966bc6e590bf 100644 > > --- a/include/efi_api.h > > +++ b/include/efi_api.h > > @@ -217,6 +217,9 @@ enum efi_reset_type { > > #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x0002 > > #define CAPSULE_FLAGS_INITIATE_RESET 0x0004 > > > > +#define CAPSULE_SUPPORT_AUTHENTICATION 0x0001 > > +#define CAPSULE_SUPPORT_DEPENDENCY 0x0002 > > + > > #define EFI_CAPSULE_REPORT_GUID \ > > EFI_GUID(0x39b68c46, 0xf7fb, 0x441b, 0xb6, 0xec, \ > > 0x16, 0xb0, 0xf6, 0x98, 0x21, 0xf3) > > @@ -225,6 +228,10 @@ enum efi_reset_type { > > EFI_GUID(0xde9f0ec, 0x88b6, 0x428f, 0x97, 0x7a, \ > > 0x25, 0x8f, 0x1d, 0xe, 0x5e, 0x72) > > > > +#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID \ > > + EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ > > +0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) > > + > > struct efi_capsule_header { > > efi_guid_t capsule_guid; > > u32 header_size; > > @@ -253,6 +260,33 @@ struct efi_memory_range_capsule { > > struct efi_memory_range memory_ranges[]; > > } __packed; > > > > +struct efi_firmware_management_capsule_header { > > + u32 version; > > + u16 embedded_driver_count; > > + u16 payload_item_count; > > + u64 item_offset_list[]; > > +} __packed; > > + > > +struct efi_firmware_management_capsule_image_header { > > + u32 version; > > + efi_guid_t update_image_type_id; > > + u8 update_image_index; > > + u8 reserved[3]; > > + u32 update_image_size; > > + u32 update_vendor_code_size; > > + u64 update_hardware_instance; > > + u64 image_capsule_support; > > +} __packed; > > + > > +struct efi_capsule_result_variable_fmp { > > + u16 version; > > + u8 payload_index; > > + u8 update_image_index; > > + efi_guid_t update_image_type_id; > > + // u16 capsule_file_name[]; > > + // u16 capsule_target[]; > > +} __packed; > > + > > #define EFI_RT_SUPPORTED_GET_TIME 0x0001 > > #define EFI_RT_SUPPORTED_SET_TIME 0x0002 > > #define EFI_RT_SUPPORTED_GET_WAKEUP_TIME 0x0004 > > @@ -1808,4 +1842,99 @@ struct efi_signature_list { > > /*struct efi_signature_data signatures[...][signature_size]; */ > > } __attribute__((__packed__)); > > > > +/* > > + * Firmware management protocol > > + */ > > +#define EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID \ > > + EFI_GUID(0x86c77a67, 0x0b97, 0x4633, 0xa1, 0x87, \ > > +0x49, 0x10, 0x4d, 0x06, 0x85, 0xc7) > > + > > +#define IMAGE_ATTRIBUTE_IMAGE_UPDATABLE0x0001 > > +#define IMAGE_ATTRIBUTE_RESET_REQUIRED 0x0002 > > +#define IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED0x0004 > > +#define IMAGE_ATTRIBUTE_IN_USE 0x0008 > > +#define IMAGE_ATTRIBUTE_UEFI_IMAGE 0x0010 > > +#define IMAGE_ATTRIBUTE_DEPENDENCY 0x0020 > > + > > +#define IMAGE_COMPATIBILITY_CHECK_SUPPORTED0x0001 > > + > > +#define IMAGE_UPDATABLE_VALID 0x0001 > > +#define IMAGE_UPDATABLE_INVALID0x0002 > > +#define IMAGE_UPDATABLE_INVALID_TYPE 0x0004 > > +#define IMAGE_UPDATABLE_INVALID_OLLD 0x0008 > > +#define IMAGE_UPDATABLE_VALID_WITH_VENDOR_CODE 0x0010 > > + > > +#define PACKAGE_ATTRIBUTE_VERSION_UPDATABLE > > 0x0001 > > +#define PACKAGE_ATTRIBUTE_RESET_REQUIRED 0x0002 > > +#define PACKAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED 0x0004 > > + > > +#define EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION 4 > > + > > +typedef struct efi_firmware_image_dependencies { > > + u8 dependencies[0]; > > +} efi_firmware_image_dep_t; > > + >
Re: [PATCH v9 04/11] efi_loader: capsule: support firmware update
On 11/17/20 1:27 AM, AKASHI Takahiro wrote: A capsule tagged with the guid, EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID, is handled as a firmware update object. What efi_update_capsule() basically does is to load any firmware management protocol (or fmp) drivers contained in a capsule, find out an appropriate fmp driver and then invoke its set_image() interface against each binary in a capsule. In this commit, however, loading drivers is not supported. The result of applying a capsule is set to be stored in "Capsule" variable, but its implementation is deferred to a fmp driver. Signed-off-by: AKASHI Takahiro --- include/efi_api.h| 129 +++ include/efi_loader.h | 2 + lib/efi_loader/Kconfig | 8 ++ lib/efi_loader/efi_capsule.c | 238 ++- lib/efi_loader/efi_setup.c | 4 + 5 files changed, 380 insertions(+), 1 deletion(-) diff --git a/include/efi_api.h b/include/efi_api.h index 7a2a087c60ed..966bc6e590bf 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -217,6 +217,9 @@ enum efi_reset_type { #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x0002 #define CAPSULE_FLAGS_INITIATE_RESET 0x0004 +#define CAPSULE_SUPPORT_AUTHENTICATION 0x0001 +#define CAPSULE_SUPPORT_DEPENDENCY 0x0002 + #define EFI_CAPSULE_REPORT_GUID \ EFI_GUID(0x39b68c46, 0xf7fb, 0x441b, 0xb6, 0xec, \ 0x16, 0xb0, 0xf6, 0x98, 0x21, 0xf3) @@ -225,6 +228,10 @@ enum efi_reset_type { EFI_GUID(0xde9f0ec, 0x88b6, 0x428f, 0x97, 0x7a, \ 0x25, 0x8f, 0x1d, 0xe, 0x5e, 0x72) +#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID \ + EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ +0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) + struct efi_capsule_header { efi_guid_t capsule_guid; u32 header_size; @@ -253,6 +260,33 @@ struct efi_memory_range_capsule { struct efi_memory_range memory_ranges[]; } __packed; +struct efi_firmware_management_capsule_header { + u32 version; + u16 embedded_driver_count; + u16 payload_item_count; + u64 item_offset_list[]; +} __packed; + +struct efi_firmware_management_capsule_image_header { + u32 version; + efi_guid_t update_image_type_id; + u8 update_image_index; + u8 reserved[3]; + u32 update_image_size; + u32 update_vendor_code_size; + u64 update_hardware_instance; + u64 image_capsule_support; +} __packed; + +struct efi_capsule_result_variable_fmp { + u16 version; + u8 payload_index; + u8 update_image_index; + efi_guid_t update_image_type_id; + // u16 capsule_file_name[]; + // u16 capsule_target[]; +} __packed; + #define EFI_RT_SUPPORTED_GET_TIME 0x0001 #define EFI_RT_SUPPORTED_SET_TIME 0x0002 #define EFI_RT_SUPPORTED_GET_WAKEUP_TIME 0x0004 @@ -1808,4 +1842,99 @@ struct efi_signature_list { /*struct efi_signature_data signatures[...][signature_size]; */ } __attribute__((__packed__)); +/* + * Firmware management protocol + */ +#define EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID \ + EFI_GUID(0x86c77a67, 0x0b97, 0x4633, 0xa1, 0x87, \ +0x49, 0x10, 0x4d, 0x06, 0x85, 0xc7) + +#define IMAGE_ATTRIBUTE_IMAGE_UPDATABLE0x0001 +#define IMAGE_ATTRIBUTE_RESET_REQUIRED 0x0002 +#define IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED0x0004 +#define IMAGE_ATTRIBUTE_IN_USE 0x0008 +#define IMAGE_ATTRIBUTE_UEFI_IMAGE 0x0010 +#define IMAGE_ATTRIBUTE_DEPENDENCY 0x0020 + +#define IMAGE_COMPATIBILITY_CHECK_SUPPORTED0x0001 + +#define IMAGE_UPDATABLE_VALID 0x0001 +#define IMAGE_UPDATABLE_INVALID0x0002 +#define IMAGE_UPDATABLE_INVALID_TYPE 0x0004 +#define IMAGE_UPDATABLE_INVALID_OLLD 0x0008 +#define IMAGE_UPDATABLE_VALID_WITH_VENDOR_CODE 0x0010 + +#define PACKAGE_ATTRIBUTE_VERSION_UPDATABLE0x0001 +#define PACKAGE_ATTRIBUTE_RESET_REQUIRED 0x0002 +#define PACKAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED 0x0004 + +#define EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION 4 + +typedef struct efi_firmware_image_dependencies { + u8 dependencies[0]; +} efi_firmware_image_dep_t; + +struct efi_firmware_image_descriptor { + u8 image_index; + efi_guid_t image_type_id; + u64 image_id; + u16 *image_id_name; + u32 version; + u16 *version_name; + efi_uintn_t size; + u64 attributes_supported; + u64 attributes_setting; + u64 compatibilities; + u32 lowest_supported_image_version; + u32 last_attempt_version; + u32 last_attempt_status; +
Re: [PATCH v9 04/11] efi_loader: capsule: support firmware update
Sughosh, On Tue, Nov 24, 2020 at 01:07:53PM +0530, Sughosh Ganu wrote: > Takahiro, > > On Tue, 24 Nov 2020 at 11:21, AKASHI Takahiro > wrote: > > > Sughosh, > > > > On Sat, Nov 21, 2020 at 11:32:43PM +0530, Sughosh Ganu wrote: > > > hi Takahiro, > > > > > > On Tue, 17 Nov 2020 at 05:58, AKASHI Takahiro < > > takahiro.aka...@linaro.org> > > > wrote: > > > > > > > A capsule tagged with the guid, > > EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID, > > > > is handled as a firmware update object. > > > > What efi_update_capsule() basically does is to load any firmware > > management > > > > protocol (or fmp) drivers contained in a capsule, find out an > > appropriate > > > > fmp driver and then invoke its set_image() interface against each > > binary > > > > in a capsule. > > > > In this commit, however, loading drivers is not supported. > > > > > > > > The result of applying a capsule is set to be stored in "Capsule" > > > > variable, but its implementation is deferred to a fmp driver. > > > > > > > > Signed-off-by: AKASHI Takahiro > > > > --- > > > > include/efi_api.h| 129 +++ > > > > include/efi_loader.h | 2 + > > > > lib/efi_loader/Kconfig | 8 ++ > > > > lib/efi_loader/efi_capsule.c | 238 ++- > > > > lib/efi_loader/efi_setup.c | 4 + > > > > 5 files changed, 380 insertions(+), 1 deletion(-) > > > > > > > > diff --git a/include/efi_api.h b/include/efi_api.h > > > > index 7a2a087c60ed..966bc6e590bf 100644 > > > > --- a/include/efi_api.h > > > > +++ b/include/efi_api.h > > > > @@ -217,6 +217,9 @@ enum efi_reset_type { > > > > #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE0x0002 > > > > #define CAPSULE_FLAGS_INITIATE_RESET 0x0004 > > > > > > > > +#define CAPSULE_SUPPORT_AUTHENTICATION 0x0001 > > > > +#define CAPSULE_SUPPORT_DEPENDENCY 0x0002 > > > > + > > > > #define EFI_CAPSULE_REPORT_GUID \ > > > > EFI_GUID(0x39b68c46, 0xf7fb, 0x441b, 0xb6, 0xec, \ > > > > 0x16, 0xb0, 0xf6, 0x98, 0x21, 0xf3) > > > > @@ -225,6 +228,10 @@ enum efi_reset_type { > > > > EFI_GUID(0xde9f0ec, 0x88b6, 0x428f, 0x97, 0x7a, \ > > > > 0x25, 0x8f, 0x1d, 0xe, 0x5e, 0x72) > > > > > > > > +#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID \ > > > > + EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ > > > > +0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) > > > > + > > > > struct efi_capsule_header { > > > > efi_guid_t capsule_guid; > > > > u32 header_size; > > > > @@ -253,6 +260,33 @@ struct efi_memory_range_capsule { > > > > struct efi_memory_range memory_ranges[]; > > > > } __packed; > > > > > > > > +struct efi_firmware_management_capsule_header { > > > > + u32 version; > > > > + u16 embedded_driver_count; > > > > + u16 payload_item_count; > > > > + u64 item_offset_list[]; > > > > +} __packed; > > > > + > > > > +struct efi_firmware_management_capsule_image_header { > > > > + u32 version; > > > > + efi_guid_t update_image_type_id; > > > > + u8 update_image_index; > > > > + u8 reserved[3]; > > > > + u32 update_image_size; > > > > + u32 update_vendor_code_size; > > > > + u64 update_hardware_instance; > > > > + u64 image_capsule_support; > > > > +} __packed; > > > > + > > > > +struct efi_capsule_result_variable_fmp { > > > > + u16 version; > > > > + u8 payload_index; > > > > + u8 update_image_index; > > > > + efi_guid_t update_image_type_id; > > > > + // u16 capsule_file_name[]; > > > > + // u16 capsule_target[]; > > > > +} __packed; > > > > + > > > > > > > > > > > > > > > > > > > > +/** > > > > + * efi_capsule_update_firmware - update firmware from capsule > > > > + * @capsule_data: Capsule > > > > + * > > > > + * Update firmware, using a capsule, @capsule_data. Loading any FMP > > > > + * drivers embedded in a capsule is not supported. > > > > + * > > > > + * Return: status code > > > > + */ > > > > +static efi_status_t efi_capsule_update_firmware( > > > > + struct efi_capsule_header *capsule_data) > > > > +{ > > > > + struct efi_firmware_management_capsule_header *capsule; > > > > + struct efi_firmware_management_capsule_image_header *image; > > > > + size_t capsule_size; > > > > + void *image_binary, *vendor_code; > > > > + efi_handle_t *handles; > > > > + efi_uintn_t no_handles; > > > > + int item; > > > > + struct efi_firmware_management_protocol *fmp; > > > > + u16 *abort_reason; > > > > + efi_status_t ret = EFI_SUCCESS; > > > > + > > > > + /* sanity check */ > > > > + if (capsule_data->header_size < sizeof(*capsule) || > > > > + capsule_data->header_size >= > > capsule_data->capsule_image_size) > > > > + return EFI_INVALID_PARAMETER; > > > > + > > > > + capsule
Re: [PATCH v9 04/11] efi_loader: capsule: support firmware update
Takahiro, On Tue, 24 Nov 2020 at 11:21, AKASHI Takahiro wrote: > Sughosh, > > On Sat, Nov 21, 2020 at 11:32:43PM +0530, Sughosh Ganu wrote: > > hi Takahiro, > > > > On Tue, 17 Nov 2020 at 05:58, AKASHI Takahiro < > takahiro.aka...@linaro.org> > > wrote: > > > > > A capsule tagged with the guid, > EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID, > > > is handled as a firmware update object. > > > What efi_update_capsule() basically does is to load any firmware > management > > > protocol (or fmp) drivers contained in a capsule, find out an > appropriate > > > fmp driver and then invoke its set_image() interface against each > binary > > > in a capsule. > > > In this commit, however, loading drivers is not supported. > > > > > > The result of applying a capsule is set to be stored in "Capsule" > > > variable, but its implementation is deferred to a fmp driver. > > > > > > Signed-off-by: AKASHI Takahiro > > > --- > > > include/efi_api.h| 129 +++ > > > include/efi_loader.h | 2 + > > > lib/efi_loader/Kconfig | 8 ++ > > > lib/efi_loader/efi_capsule.c | 238 ++- > > > lib/efi_loader/efi_setup.c | 4 + > > > 5 files changed, 380 insertions(+), 1 deletion(-) > > > > > > diff --git a/include/efi_api.h b/include/efi_api.h > > > index 7a2a087c60ed..966bc6e590bf 100644 > > > --- a/include/efi_api.h > > > +++ b/include/efi_api.h > > > @@ -217,6 +217,9 @@ enum efi_reset_type { > > > #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE0x0002 > > > #define CAPSULE_FLAGS_INITIATE_RESET 0x0004 > > > > > > +#define CAPSULE_SUPPORT_AUTHENTICATION 0x0001 > > > +#define CAPSULE_SUPPORT_DEPENDENCY 0x0002 > > > + > > > #define EFI_CAPSULE_REPORT_GUID \ > > > EFI_GUID(0x39b68c46, 0xf7fb, 0x441b, 0xb6, 0xec, \ > > > 0x16, 0xb0, 0xf6, 0x98, 0x21, 0xf3) > > > @@ -225,6 +228,10 @@ enum efi_reset_type { > > > EFI_GUID(0xde9f0ec, 0x88b6, 0x428f, 0x97, 0x7a, \ > > > 0x25, 0x8f, 0x1d, 0xe, 0x5e, 0x72) > > > > > > +#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID \ > > > + EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ > > > +0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) > > > + > > > struct efi_capsule_header { > > > efi_guid_t capsule_guid; > > > u32 header_size; > > > @@ -253,6 +260,33 @@ struct efi_memory_range_capsule { > > > struct efi_memory_range memory_ranges[]; > > > } __packed; > > > > > > +struct efi_firmware_management_capsule_header { > > > + u32 version; > > > + u16 embedded_driver_count; > > > + u16 payload_item_count; > > > + u64 item_offset_list[]; > > > +} __packed; > > > + > > > +struct efi_firmware_management_capsule_image_header { > > > + u32 version; > > > + efi_guid_t update_image_type_id; > > > + u8 update_image_index; > > > + u8 reserved[3]; > > > + u32 update_image_size; > > > + u32 update_vendor_code_size; > > > + u64 update_hardware_instance; > > > + u64 image_capsule_support; > > > +} __packed; > > > + > > > +struct efi_capsule_result_variable_fmp { > > > + u16 version; > > > + u8 payload_index; > > > + u8 update_image_index; > > > + efi_guid_t update_image_type_id; > > > + // u16 capsule_file_name[]; > > > + // u16 capsule_target[]; > > > +} __packed; > > > + > > > > > > > > > > > > > > +/** > > > + * efi_capsule_update_firmware - update firmware from capsule > > > + * @capsule_data: Capsule > > > + * > > > + * Update firmware, using a capsule, @capsule_data. Loading any FMP > > > + * drivers embedded in a capsule is not supported. > > > + * > > > + * Return: status code > > > + */ > > > +static efi_status_t efi_capsule_update_firmware( > > > + struct efi_capsule_header *capsule_data) > > > +{ > > > + struct efi_firmware_management_capsule_header *capsule; > > > + struct efi_firmware_management_capsule_image_header *image; > > > + size_t capsule_size; > > > + void *image_binary, *vendor_code; > > > + efi_handle_t *handles; > > > + efi_uintn_t no_handles; > > > + int item; > > > + struct efi_firmware_management_protocol *fmp; > > > + u16 *abort_reason; > > > + efi_status_t ret = EFI_SUCCESS; > > > + > > > + /* sanity check */ > > > + if (capsule_data->header_size < sizeof(*capsule) || > > > + capsule_data->header_size >= > capsule_data->capsule_image_size) > > > + return EFI_INVALID_PARAMETER; > > > + > > > + capsule = (void *)capsule_data + capsule_data->header_size; > > > + capsule_size = capsule_data->capsule_image_size > > > + - capsule_data->header_size; > > > + > > > + if (capsule->version != 0x0001) > > > + return EFI_INVALID_PARAMETER; > > > + > > > + /* Drivers */ > > > +
Re: [PATCH v9 04/11] efi_loader: capsule: support firmware update
Sughosh, On Sat, Nov 21, 2020 at 11:32:43PM +0530, Sughosh Ganu wrote: > hi Takahiro, > > On Tue, 17 Nov 2020 at 05:58, AKASHI Takahiro > wrote: > > > A capsule tagged with the guid, EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID, > > is handled as a firmware update object. > > What efi_update_capsule() basically does is to load any firmware management > > protocol (or fmp) drivers contained in a capsule, find out an appropriate > > fmp driver and then invoke its set_image() interface against each binary > > in a capsule. > > In this commit, however, loading drivers is not supported. > > > > The result of applying a capsule is set to be stored in "Capsule" > > variable, but its implementation is deferred to a fmp driver. > > > > Signed-off-by: AKASHI Takahiro > > --- > > include/efi_api.h| 129 +++ > > include/efi_loader.h | 2 + > > lib/efi_loader/Kconfig | 8 ++ > > lib/efi_loader/efi_capsule.c | 238 ++- > > lib/efi_loader/efi_setup.c | 4 + > > 5 files changed, 380 insertions(+), 1 deletion(-) > > > > diff --git a/include/efi_api.h b/include/efi_api.h > > index 7a2a087c60ed..966bc6e590bf 100644 > > --- a/include/efi_api.h > > +++ b/include/efi_api.h > > @@ -217,6 +217,9 @@ enum efi_reset_type { > > #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE0x0002 > > #define CAPSULE_FLAGS_INITIATE_RESET 0x0004 > > > > +#define CAPSULE_SUPPORT_AUTHENTICATION 0x0001 > > +#define CAPSULE_SUPPORT_DEPENDENCY 0x0002 > > + > > #define EFI_CAPSULE_REPORT_GUID \ > > EFI_GUID(0x39b68c46, 0xf7fb, 0x441b, 0xb6, 0xec, \ > > 0x16, 0xb0, 0xf6, 0x98, 0x21, 0xf3) > > @@ -225,6 +228,10 @@ enum efi_reset_type { > > EFI_GUID(0xde9f0ec, 0x88b6, 0x428f, 0x97, 0x7a, \ > > 0x25, 0x8f, 0x1d, 0xe, 0x5e, 0x72) > > > > +#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID \ > > + EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ > > +0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) > > + > > struct efi_capsule_header { > > efi_guid_t capsule_guid; > > u32 header_size; > > @@ -253,6 +260,33 @@ struct efi_memory_range_capsule { > > struct efi_memory_range memory_ranges[]; > > } __packed; > > > > +struct efi_firmware_management_capsule_header { > > + u32 version; > > + u16 embedded_driver_count; > > + u16 payload_item_count; > > + u64 item_offset_list[]; > > +} __packed; > > + > > +struct efi_firmware_management_capsule_image_header { > > + u32 version; > > + efi_guid_t update_image_type_id; > > + u8 update_image_index; > > + u8 reserved[3]; > > + u32 update_image_size; > > + u32 update_vendor_code_size; > > + u64 update_hardware_instance; > > + u64 image_capsule_support; > > +} __packed; > > + > > +struct efi_capsule_result_variable_fmp { > > + u16 version; > > + u8 payload_index; > > + u8 update_image_index; > > + efi_guid_t update_image_type_id; > > + // u16 capsule_file_name[]; > > + // u16 capsule_target[]; > > +} __packed; > > + > > > > > > > > +/** > > + * efi_capsule_update_firmware - update firmware from capsule > > + * @capsule_data: Capsule > > + * > > + * Update firmware, using a capsule, @capsule_data. Loading any FMP > > + * drivers embedded in a capsule is not supported. > > + * > > + * Return: status code > > + */ > > +static efi_status_t efi_capsule_update_firmware( > > + struct efi_capsule_header *capsule_data) > > +{ > > + struct efi_firmware_management_capsule_header *capsule; > > + struct efi_firmware_management_capsule_image_header *image; > > + size_t capsule_size; > > + void *image_binary, *vendor_code; > > + efi_handle_t *handles; > > + efi_uintn_t no_handles; > > + int item; > > + struct efi_firmware_management_protocol *fmp; > > + u16 *abort_reason; > > + efi_status_t ret = EFI_SUCCESS; > > + > > + /* sanity check */ > > + if (capsule_data->header_size < sizeof(*capsule) || > > + capsule_data->header_size >= capsule_data->capsule_image_size) > > + return EFI_INVALID_PARAMETER; > > + > > + capsule = (void *)capsule_data + capsule_data->header_size; > > + capsule_size = capsule_data->capsule_image_size > > + - capsule_data->header_size; > > + > > + if (capsule->version != 0x0001) > > + return EFI_INVALID_PARAMETER; > > + > > + /* Drivers */ > > + /* TODO: support loading drivers */ > > + > > + handles = NULL; > > + ret = EFI_CALL(efi_locate_handle_buffer( > > + BY_PROTOCOL, > > + _guid_firmware_management_protocol, > > + NULL, _handles, (efi_handle_t **))); > > + if (ret != EFI_SUCCESS) > > +
Re: [PATCH v9 04/11] efi_loader: capsule: support firmware update
hi Takahiro, On Tue, 17 Nov 2020 at 05:58, AKASHI Takahiro wrote: > A capsule tagged with the guid, EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID, > is handled as a firmware update object. > What efi_update_capsule() basically does is to load any firmware management > protocol (or fmp) drivers contained in a capsule, find out an appropriate > fmp driver and then invoke its set_image() interface against each binary > in a capsule. > In this commit, however, loading drivers is not supported. > > The result of applying a capsule is set to be stored in "Capsule" > variable, but its implementation is deferred to a fmp driver. > > Signed-off-by: AKASHI Takahiro > --- > include/efi_api.h| 129 +++ > include/efi_loader.h | 2 + > lib/efi_loader/Kconfig | 8 ++ > lib/efi_loader/efi_capsule.c | 238 ++- > lib/efi_loader/efi_setup.c | 4 + > 5 files changed, 380 insertions(+), 1 deletion(-) > > diff --git a/include/efi_api.h b/include/efi_api.h > index 7a2a087c60ed..966bc6e590bf 100644 > --- a/include/efi_api.h > +++ b/include/efi_api.h > @@ -217,6 +217,9 @@ enum efi_reset_type { > #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE0x0002 > #define CAPSULE_FLAGS_INITIATE_RESET 0x0004 > > +#define CAPSULE_SUPPORT_AUTHENTICATION 0x0001 > +#define CAPSULE_SUPPORT_DEPENDENCY 0x0002 > + > #define EFI_CAPSULE_REPORT_GUID \ > EFI_GUID(0x39b68c46, 0xf7fb, 0x441b, 0xb6, 0xec, \ > 0x16, 0xb0, 0xf6, 0x98, 0x21, 0xf3) > @@ -225,6 +228,10 @@ enum efi_reset_type { > EFI_GUID(0xde9f0ec, 0x88b6, 0x428f, 0x97, 0x7a, \ > 0x25, 0x8f, 0x1d, 0xe, 0x5e, 0x72) > > +#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID \ > + EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ > +0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) > + > struct efi_capsule_header { > efi_guid_t capsule_guid; > u32 header_size; > @@ -253,6 +260,33 @@ struct efi_memory_range_capsule { > struct efi_memory_range memory_ranges[]; > } __packed; > > +struct efi_firmware_management_capsule_header { > + u32 version; > + u16 embedded_driver_count; > + u16 payload_item_count; > + u64 item_offset_list[]; > +} __packed; > + > +struct efi_firmware_management_capsule_image_header { > + u32 version; > + efi_guid_t update_image_type_id; > + u8 update_image_index; > + u8 reserved[3]; > + u32 update_image_size; > + u32 update_vendor_code_size; > + u64 update_hardware_instance; > + u64 image_capsule_support; > +} __packed; > + > +struct efi_capsule_result_variable_fmp { > + u16 version; > + u8 payload_index; > + u8 update_image_index; > + efi_guid_t update_image_type_id; > + // u16 capsule_file_name[]; > + // u16 capsule_target[]; > +} __packed; > + > > +/** > + * efi_capsule_update_firmware - update firmware from capsule > + * @capsule_data: Capsule > + * > + * Update firmware, using a capsule, @capsule_data. Loading any FMP > + * drivers embedded in a capsule is not supported. > + * > + * Return: status code > + */ > +static efi_status_t efi_capsule_update_firmware( > + struct efi_capsule_header *capsule_data) > +{ > + struct efi_firmware_management_capsule_header *capsule; > + struct efi_firmware_management_capsule_image_header *image; > + size_t capsule_size; > + void *image_binary, *vendor_code; > + efi_handle_t *handles; > + efi_uintn_t no_handles; > + int item; > + struct efi_firmware_management_protocol *fmp; > + u16 *abort_reason; > + efi_status_t ret = EFI_SUCCESS; > + > + /* sanity check */ > + if (capsule_data->header_size < sizeof(*capsule) || > + capsule_data->header_size >= capsule_data->capsule_image_size) > + return EFI_INVALID_PARAMETER; > + > + capsule = (void *)capsule_data + capsule_data->header_size; > + capsule_size = capsule_data->capsule_image_size > + - capsule_data->header_size; > + > + if (capsule->version != 0x0001) > + return EFI_INVALID_PARAMETER; > + > + /* Drivers */ > + /* TODO: support loading drivers */ > + > + handles = NULL; > + ret = EFI_CALL(efi_locate_handle_buffer( > + BY_PROTOCOL, > + _guid_firmware_management_protocol, > + NULL, _handles, (efi_handle_t **))); > + if (ret != EFI_SUCCESS) > + return EFI_UNSUPPORTED; > + > + /* Payload */ > + for (item = capsule->embedded_driver_count; > +item < capsule->embedded_driver_count > + + capsule->payload_item_count; item++) { > + /* sanity check */ > + if ((capsule->item_offset_list[item] + sizeof(*image) > +
[PATCH v9 04/11] efi_loader: capsule: support firmware update
A capsule tagged with the guid, EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID, is handled as a firmware update object. What efi_update_capsule() basically does is to load any firmware management protocol (or fmp) drivers contained in a capsule, find out an appropriate fmp driver and then invoke its set_image() interface against each binary in a capsule. In this commit, however, loading drivers is not supported. The result of applying a capsule is set to be stored in "Capsule" variable, but its implementation is deferred to a fmp driver. Signed-off-by: AKASHI Takahiro --- include/efi_api.h| 129 +++ include/efi_loader.h | 2 + lib/efi_loader/Kconfig | 8 ++ lib/efi_loader/efi_capsule.c | 238 ++- lib/efi_loader/efi_setup.c | 4 + 5 files changed, 380 insertions(+), 1 deletion(-) diff --git a/include/efi_api.h b/include/efi_api.h index 7a2a087c60ed..966bc6e590bf 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -217,6 +217,9 @@ enum efi_reset_type { #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE0x0002 #define CAPSULE_FLAGS_INITIATE_RESET 0x0004 +#define CAPSULE_SUPPORT_AUTHENTICATION 0x0001 +#define CAPSULE_SUPPORT_DEPENDENCY 0x0002 + #define EFI_CAPSULE_REPORT_GUID \ EFI_GUID(0x39b68c46, 0xf7fb, 0x441b, 0xb6, 0xec, \ 0x16, 0xb0, 0xf6, 0x98, 0x21, 0xf3) @@ -225,6 +228,10 @@ enum efi_reset_type { EFI_GUID(0xde9f0ec, 0x88b6, 0x428f, 0x97, 0x7a, \ 0x25, 0x8f, 0x1d, 0xe, 0x5e, 0x72) +#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID \ + EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ +0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) + struct efi_capsule_header { efi_guid_t capsule_guid; u32 header_size; @@ -253,6 +260,33 @@ struct efi_memory_range_capsule { struct efi_memory_range memory_ranges[]; } __packed; +struct efi_firmware_management_capsule_header { + u32 version; + u16 embedded_driver_count; + u16 payload_item_count; + u64 item_offset_list[]; +} __packed; + +struct efi_firmware_management_capsule_image_header { + u32 version; + efi_guid_t update_image_type_id; + u8 update_image_index; + u8 reserved[3]; + u32 update_image_size; + u32 update_vendor_code_size; + u64 update_hardware_instance; + u64 image_capsule_support; +} __packed; + +struct efi_capsule_result_variable_fmp { + u16 version; + u8 payload_index; + u8 update_image_index; + efi_guid_t update_image_type_id; + // u16 capsule_file_name[]; + // u16 capsule_target[]; +} __packed; + #define EFI_RT_SUPPORTED_GET_TIME 0x0001 #define EFI_RT_SUPPORTED_SET_TIME 0x0002 #define EFI_RT_SUPPORTED_GET_WAKEUP_TIME 0x0004 @@ -1808,4 +1842,99 @@ struct efi_signature_list { /* struct efi_signature_data signatures[...][signature_size]; */ } __attribute__((__packed__)); +/* + * Firmware management protocol + */ +#define EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID \ + EFI_GUID(0x86c77a67, 0x0b97, 0x4633, 0xa1, 0x87, \ +0x49, 0x10, 0x4d, 0x06, 0x85, 0xc7) + +#define IMAGE_ATTRIBUTE_IMAGE_UPDATABLE0x0001 +#define IMAGE_ATTRIBUTE_RESET_REQUIRED 0x0002 +#define IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED0x0004 +#define IMAGE_ATTRIBUTE_IN_USE 0x0008 +#define IMAGE_ATTRIBUTE_UEFI_IMAGE 0x0010 +#define IMAGE_ATTRIBUTE_DEPENDENCY 0x0020 + +#define IMAGE_COMPATIBILITY_CHECK_SUPPORTED0x0001 + +#define IMAGE_UPDATABLE_VALID 0x0001 +#define IMAGE_UPDATABLE_INVALID0x0002 +#define IMAGE_UPDATABLE_INVALID_TYPE 0x0004 +#define IMAGE_UPDATABLE_INVALID_OLLD 0x0008 +#define IMAGE_UPDATABLE_VALID_WITH_VENDOR_CODE 0x0010 + +#define PACKAGE_ATTRIBUTE_VERSION_UPDATABLE0x0001 +#define PACKAGE_ATTRIBUTE_RESET_REQUIRED 0x0002 +#define PACKAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED 0x0004 + +#define EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION 4 + +typedef struct efi_firmware_image_dependencies { + u8 dependencies[0]; +} efi_firmware_image_dep_t; + +struct efi_firmware_image_descriptor { + u8 image_index; + efi_guid_t image_type_id; + u64 image_id; + u16 *image_id_name; + u32 version; + u16 *version_name; + efi_uintn_t size; + u64 attributes_supported; + u64 attributes_setting; + u64 compatibilities; + u32 lowest_supported_image_version; + u32 last_attempt_version; + u32 last_attempt_status; + u64 hardware_instance; +