Re: [PATCH v9 04/11] efi_loader: capsule: support firmware update

2020-11-24 Thread AKASHI Takahiro
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

2020-11-24 Thread Heinrich Schuchardt

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

2020-11-24 Thread AKASHI Takahiro
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

2020-11-23 Thread Sughosh Ganu
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

2020-11-23 Thread AKASHI Takahiro
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

2020-11-21 Thread Sughosh Ganu
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

2020-11-16 Thread AKASHI Takahiro
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;
+