Re: [PATCH 1/2 v4] efi: Add ESRT to the EFI system table
On 23.02.21 17:50, Jose Marinho wrote: > The ESRT is initialised during efi_init_objlist after > efi_initialize_system_table(). > > The ESRT is recreated from scratch at the following events: > - successful UpdateCapsule; > - FMP instance install. > > The code ensures that every ESRT entry has a unique fw_class value. > > Limitations: > - The ESRT is not updated when an FMP instance is uninstalled; > - the fields image_type and flags are currently set to UNKNOWN and 0 > respectively. The mapping between fw_class and the image_type/flags > fields is platform specific. A mapping function is lacking from the > current implementation but should be added in the future. > > Signed-off-by: Jose Marinho > > CC: Heinrich Schuchardt > CC: Sughosh Ganu > CC: AKASHI Takahiro > CC: Ilias Apalodimas > CC: Andre Przywara > CC: Alexander Graf > CC: n...@arm.com > > --- > cmd/efidebug.c | 4 + > include/efi_api.h| 21 ++ > include/efi_loader.h | 20 ++ > lib/efi_loader/Kconfig | 7 + > lib/efi_loader/Makefile | 1 + > lib/efi_loader/efi_capsule.c | 8 + > lib/efi_loader/efi_esrt.c| 518 +++ > lib/efi_loader/efi_setup.c | 6 + > 8 files changed, 585 insertions(+) > create mode 100644 lib/efi_loader/efi_esrt.c > > diff --git a/cmd/efidebug.c b/cmd/efidebug.c > index bbbcb0a546..a7dace2f80 100644 > --- a/cmd/efidebug.c > +++ b/cmd/efidebug.c > @@ -459,6 +459,10 @@ static const struct { > "Block IO", > EFI_BLOCK_IO_PROTOCOL_GUID, > }, > + { > + "EFI System Resource Table", > + EFI_SYSTEM_RESOURCE_TABLE_GUID, > + }, > { > "Simple File System", > EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, > diff --git a/include/efi_api.h b/include/efi_api.h > index 48e48a6263..fb53637419 100644 > --- a/include/efi_api.h > +++ b/include/efi_api.h > @@ -1722,6 +1722,23 @@ struct efi_load_file_protocol { >void *buffer); > }; > > +struct efi_system_resource_entry { > + efi_guid_t fw_class; > + u32 fw_type; > + u32 fw_version; > + u32 lowest_supported_fw_version; > + u32 capsule_flags; > + u32 last_attempt_version; > + u32 last_attempt_status; > +} __packed; > + > +struct efi_system_resource_table { > + u32 fw_resource_count; > + u32 fw_resource_count_max; > + u64 fw_resource_version; > + struct efi_system_resource_entry entries[]; > +} __packed; > + > /* Boot manager load options */ > #define LOAD_OPTION_ACTIVE 0x0001 > #define LOAD_OPTION_FORCE_RECONNECT 0x0002 > @@ -1740,6 +1757,10 @@ struct efi_load_file_protocol { > #define ESRT_FW_TYPE_DEVICEFIRMWARE 0x0002 > #define ESRT_FW_TYPE_UEFIDRIVER 0x0003 > > +#define EFI_SYSTEM_RESOURCE_TABLE_GUID\ > + EFI_GUID(0xb122a263, 0x3661, 0x4f68,\ > + 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80) > + > /* Last Attempt Status Values */ > #define LAST_ATTEMPT_STATUS_SUCCESS 0x > #define LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL 0x0001 > diff --git a/include/efi_loader.h b/include/efi_loader.h > index f470bbd636..c2720f2823 100644 > --- a/include/efi_loader.h > +++ b/include/efi_loader.h > @@ -214,6 +214,8 @@ extern const efi_guid_t efi_guid_rng_protocol; > extern const efi_guid_t efi_guid_capsule_report; > /* GUID of firmware management protocol */ > extern const efi_guid_t efi_guid_firmware_management_protocol; > +/* GUID for the ESRT */ > +extern const efi_guid_t efi_esrt_guid; > > extern unsigned int __efi_runtime_start, __efi_runtime_stop; > extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; > @@ -884,4 +886,22 @@ static inline efi_status_t efi_launch_capsules(void) > > #endif /* CONFIG_IS_ENABLED(EFI_LOADER) */ > > +/** > + * Install the ESRT system table. > + * > + * @return status code > + */ > +efi_status_t efi_esrt_register(void); > + > +/** > + * efi_esrt_populate() - Populates the ESRT entries from the FMP instances > + * present in the system. > + * If an ESRT already exists, the old ESRT is replaced in the system table. > + * The memory of the old ESRT is deallocated. > + * > + * Return: > + * - EFI_SUCCESS if the ESRT is correctly created > + * - error code otherwise. > + */ > +efi_status_t efi_esrt_populate(void); > #endif /* _EFI_LOADER_H */ > diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig > index e729f727df..a96014ce18 100644 > --- a/lib/efi_loader/Kconfig > +++ b/lib/efi_loader/Kconfig > @@ -347,4 +347,11 @@ config EFI_SECURE_BOOT > it is signed with a trusted key. To do that, you need to install, > at least, PK, KEK and db. > > +config EFI_ESRT > + bool "Enable the UEFI ESRT generation" > + depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT > + default y > + help > + Enabling this option creates the ESRT UEFI system table. > + > end
[PATCH 1/2 v4] efi: Add ESRT to the EFI system table
The ESRT is initialised during efi_init_objlist after efi_initialize_system_table(). The ESRT is recreated from scratch at the following events: - successful UpdateCapsule; - FMP instance install. The code ensures that every ESRT entry has a unique fw_class value. Limitations: - The ESRT is not updated when an FMP instance is uninstalled; - the fields image_type and flags are currently set to UNKNOWN and 0 respectively. The mapping between fw_class and the image_type/flags fields is platform specific. A mapping function is lacking from the current implementation but should be added in the future. Signed-off-by: Jose Marinho CC: Heinrich Schuchardt CC: Sughosh Ganu CC: AKASHI Takahiro CC: Ilias Apalodimas CC: Andre Przywara CC: Alexander Graf CC: n...@arm.com --- cmd/efidebug.c | 4 + include/efi_api.h| 21 ++ include/efi_loader.h | 20 ++ lib/efi_loader/Kconfig | 7 + lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_capsule.c | 8 + lib/efi_loader/efi_esrt.c| 518 +++ lib/efi_loader/efi_setup.c | 6 + 8 files changed, 585 insertions(+) create mode 100644 lib/efi_loader/efi_esrt.c diff --git a/cmd/efidebug.c b/cmd/efidebug.c index bbbcb0a546..a7dace2f80 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -459,6 +459,10 @@ static const struct { "Block IO", EFI_BLOCK_IO_PROTOCOL_GUID, }, + { + "EFI System Resource Table", + EFI_SYSTEM_RESOURCE_TABLE_GUID, + }, { "Simple File System", EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, diff --git a/include/efi_api.h b/include/efi_api.h index 48e48a6263..fb53637419 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -1722,6 +1722,23 @@ struct efi_load_file_protocol { void *buffer); }; +struct efi_system_resource_entry { + efi_guid_t fw_class; + u32 fw_type; + u32 fw_version; + u32 lowest_supported_fw_version; + u32 capsule_flags; + u32 last_attempt_version; + u32 last_attempt_status; +} __packed; + +struct efi_system_resource_table { + u32 fw_resource_count; + u32 fw_resource_count_max; + u64 fw_resource_version; + struct efi_system_resource_entry entries[]; +} __packed; + /* Boot manager load options */ #define LOAD_OPTION_ACTIVE 0x0001 #define LOAD_OPTION_FORCE_RECONNECT0x0002 @@ -1740,6 +1757,10 @@ struct efi_load_file_protocol { #define ESRT_FW_TYPE_DEVICEFIRMWARE0x0002 #define ESRT_FW_TYPE_UEFIDRIVER0x0003 +#define EFI_SYSTEM_RESOURCE_TABLE_GUID\ + EFI_GUID(0xb122a263, 0x3661, 0x4f68,\ + 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80) + /* Last Attempt Status Values */ #define LAST_ATTEMPT_STATUS_SUCCESS0x #define LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL 0x0001 diff --git a/include/efi_loader.h b/include/efi_loader.h index f470bbd636..c2720f2823 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -214,6 +214,8 @@ extern const efi_guid_t efi_guid_rng_protocol; extern const efi_guid_t efi_guid_capsule_report; /* GUID of firmware management protocol */ extern const efi_guid_t efi_guid_firmware_management_protocol; +/* GUID for the ESRT */ +extern const efi_guid_t efi_esrt_guid; extern unsigned int __efi_runtime_start, __efi_runtime_stop; extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; @@ -884,4 +886,22 @@ static inline efi_status_t efi_launch_capsules(void) #endif /* CONFIG_IS_ENABLED(EFI_LOADER) */ +/** + * Install the ESRT system table. + * + * @return status code + */ +efi_status_t efi_esrt_register(void); + +/** + * efi_esrt_populate() - Populates the ESRT entries from the FMP instances + * present in the system. + * If an ESRT already exists, the old ESRT is replaced in the system table. + * The memory of the old ESRT is deallocated. + * + * Return: + * - EFI_SUCCESS if the ESRT is correctly created + * - error code otherwise. + */ +efi_status_t efi_esrt_populate(void); #endif /* _EFI_LOADER_H */ diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index e729f727df..a96014ce18 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -347,4 +347,11 @@ config EFI_SECURE_BOOT it is signed with a trusted key. To do that, you need to install, at least, PK, KEK and db. +config EFI_ESRT + bool "Enable the UEFI ESRT generation" + depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT + default y + help + Enabling this option creates the ESRT UEFI system table. + endif diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 10b42e8847..9a8127846f 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -52,6 +52,7 @@ obj-y += efi_variable.o obj-$(CONFIG_EFI_VARIABLES_PRESEED) += ef