[PATCH 3/4] efi_loader: install DXE services table
Heinrich Schuchardt
heinrich.schuchardt at canonical.com
Tue Jan 7 18:19:07 CET 2025
On 07.01.25 14:30, Ilias Apalodimas wrote:
> On Thu, 2 Jan 2025 at 20:11, Heinrich Schuchardt
> <heinrich.schuchardt at canonical.com> wrote:
>>
>> The debug version of the UEFI shell requires a DXE services table to exist.
>>
>> Implement the table and let all DXE functions return EFI_UNSUPPORTED.
>>
>> Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
>> ---
>> include/efi_dxe.h | 54 ++++++++++++
>> include/efi_loader.h | 7 ++
>> lib/efi_loader/Kconfig | 7 ++
>> lib/efi_loader/Makefile | 1 +
>> lib/efi_loader/efi_dxe.c | 176 +++++++++++++++++++++++++++++++++++++
>> lib/efi_loader/efi_setup.c | 6 ++
>> 6 files changed, 251 insertions(+)
>> create mode 100644 include/efi_dxe.h
>> create mode 100644 lib/efi_loader/efi_dxe.c
>>
>> diff --git a/include/efi_dxe.h b/include/efi_dxe.h
>> new file mode 100644
>> index 00000000000..5623189de0c
>> --- /dev/null
>> +++ b/include/efi_dxe.h
>> @@ -0,0 +1,54 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * DXE services table
>> + *
>> + * Copyright (c) 2025 Heinrich Schuchardt
>> + */
>> +
>> +#ifndef _EFI_DXE_H
>> +#define _EFI_DXE_H 1
>> +
>> +#include <efi.h>
>> +
>> +/**
>> + * define DXE_SERVICES_SIGNATURE - DXE services signature ('DXE_SERV')
>> + */
>> +#define DXE_SERVICES_SIGNATURE 0x565245535f455844
>> +/**
>> + * define DXE_SERVICES_REVISION - DXE services revision (1.8)
>> + */
>> +#define DXE_SERVICES_REVISION 0x00010050
>> +
>> +/**
>> + * define EFI_DXE_SERVICES_TABLE_GUID - GUID of the EFI DXE services table
>> + */
>> +#define EFI_DXE_SERVICES_TABLE_GUID \
>> + EFI_GUID(0x5ad34ba, 0x6f02, 0x4214, \
>> + 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9)
>> +
>> +struct efi_dxe_services {
>> + struct efi_table_hdr hdr;
>> +
>> + efi_status_t (EFIAPI *add_memory_space)(void);
>> + efi_status_t (EFIAPI *allocate_memory_space)(void);
>> + efi_status_t (EFIAPI *free_memory_space)(void);
>> + efi_status_t (EFIAPI *remove_memory_space)(void);
>> + efi_status_t (EFIAPI *get_memory_space_descriptor)(void);
>> + efi_status_t (EFIAPI *set_memory_space_attributes)(void);
>> + efi_status_t (EFIAPI *get_memory_space_map)(void);
>> + efi_status_t (EFIAPI *add_io_space)(void);
>> + efi_status_t (EFIAPI *allocate_io_space)(void);
>> + efi_status_t (EFIAPI *free_io_space)(void);
>> + efi_status_t (EFIAPI *remove_io_space)(void);
>> + efi_status_t (EFIAPI *get_io_space_descriptor)(void);
>> + efi_status_t (EFIAPI *get_io_space_map)(void);
>> + efi_status_t (EFIAPI *dispatch)(void);
>> + efi_status_t (EFIAPI *schedule)(void);
>> + efi_status_t (EFIAPI *trust)(void);
>> + efi_status_t (EFIAPI *process_firmware_volume)(void);
>> + efi_status_t (EFIAPI *set_memory_space_capabilities)(void);
>> +};
>> +
>> +extern efi_guid_t efi_dxe_services_table_guid;
>> +
>> +#endif /* _EFI_DXE_H */
>> diff --git a/include/efi_loader.h b/include/efi_loader.h
>> index c1258098217..d474866184f 100644
>> --- a/include/efi_loader.h
>> +++ b/include/efi_loader.h
>> @@ -663,6 +663,13 @@ efi_status_t efi_smbios_register(void);
>> */
>> efi_status_t efi_hob_list_register(void);
>>
>> +/**
>> + * efi_dxe_services_register() - install DXE services table
>> + *
>> + * Return: status code
>> + */
>> +efi_status_t efi_dxe_services_register(void);
>> +
>> struct efi_simple_file_system_protocol *
>> efi_fs_from_path(struct efi_device_path *fp);
>>
>> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
>> index ec38a0ea352..ed3470508ff 100644
>> --- a/lib/efi_loader/Kconfig
>> +++ b/lib/efi_loader/Kconfig
>> @@ -384,6 +384,13 @@ config EFI_DT_FIXUP
>> The EFI device-tree fix-up protocol provides a function to let the
>> firmware apply fix-ups. This may be used by boot loaders.
>>
>> +config EFI_DXE
>> + bool 'DXE services table'
>> + default y
>> + help
>> + Install the DXE services table. The debug version of the UEFI shell
>> + requires it.
>> +
>> config EFI_LOADER_HII
>> bool "HII protocols"
>> default y
>> diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
>> index 195ed8667fe..4f250f21811 100644
>> --- a/lib/efi_loader/Makefile
>> +++ b/lib/efi_loader/Makefile
>> @@ -33,6 +33,7 @@ obj-y += efi_console.o
>> obj-y += efi_device_path.o
>> obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o
>> obj-$(CONFIG_EFI_DEVICE_PATH_UTIL) += efi_device_path_utilities.o
>> +obj-$(CONFIG_EFI_DXE) += efi_dxe.o
>> obj-y += efi_dt_fixup.o
>> obj-y += efi_fdt.o
>> obj-y += efi_file.o
>> diff --git a/lib/efi_loader/efi_dxe.c b/lib/efi_loader/efi_dxe.c
>> new file mode 100644
>> index 00000000000..f8920575b0c
>> --- /dev/null
>> +++ b/lib/efi_loader/efi_dxe.c
>> @@ -0,0 +1,176 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * DXE services table
>> + *
>> + * Copyright (c) 2025 Heinrich Schuchardt
>> + */
>> +
>> +#include <efi_dxe.h>
>> +#include <efi_loader.h>
>> +
>> +efi_guid_t efi_dxe_services_table_guid = EFI_DXE_SERVICES_TABLE_GUID;
>> +
>> +static efi_status_t EFIAPI add_memory_space(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI allocate_memory_space(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI free_memory_space(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI remove_memory_space(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI get_memory_space_descriptor(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI set_memory_space_attributes(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI get_memory_space_map(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI add_io_space(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI allocate_io_space(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI free_io_space(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI remove_io_space(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI get_io_space_descriptor(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI get_io_space_map(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI dispatch(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI schedule(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI trust(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI process_firmware_volume(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static efi_status_t EFIAPI set_memory_space_capabilities(void)
>> +{
>> + EFI_ENTRY();
>> +
>> + return EFI_EXIT(EFI_UNSUPPORTED);
>> +}
>> +
>> +static struct efi_dxe_services efi_dxe_services = {
>> + .hdr = {
>> + .signature = DXE_SERVICES_SIGNATURE,
>> + .revision = DXE_SERVICES_REVISION,
>> + .headersize = sizeof(struct efi_dxe_services),
>> + },
>> + .add_memory_space = add_memory_space,
>> + .allocate_memory_space = allocate_memory_space,
>> + .free_memory_space = free_memory_space,
>> + .remove_memory_space = remove_memory_space,
>> + .get_memory_space_descriptor = get_memory_space_descriptor,
>> + .set_memory_space_attributes = set_memory_space_attributes,
>> + .get_memory_space_map = get_memory_space_map,
>> + .add_io_space = add_io_space,
>> + .allocate_io_space = allocate_io_space,
>> + .free_io_space = free_io_space,
>> + .remove_io_space = remove_io_space,
>> + .get_io_space_descriptor = get_io_space_descriptor,
>> + .get_io_space_map = get_io_space_map,
>> + .dispatch = dispatch,
>> + .schedule = schedule,
>> + .trust = trust,
>> + .process_firmware_volume = process_firmware_volume,
>> + .set_memory_space_capabilities = set_memory_space_capabilities,
>
> Do we plan on ever implementing those? If not we could use a single
> function returning EFI_UNSUPPORTED instead of all of them for code
> size reasons
Currently I don't plan to implement these. But I wanted to be able to add
#define _DEBUG 1
to find out which of the functions is possibly used.
On x86 and sandbox I don't think our memory restrictions are very tight.
Best regards
Heinrich
>
> Cheers
> /Ilias
>> +};
>> +
>> +efi_status_t efi_dxe_services_register(void)
>> +{
>> + struct efi_dxe_services *dxe;
>> +
>> + dxe = efi_alloc(sizeof(struct efi_dxe_services));
>> + if (!dxe)
>> + return EFI_OUT_OF_RESOURCES;
>> +
>> + memcpy(dxe, &efi_dxe_services, sizeof(struct efi_dxe_services));
>> +
>> + return efi_install_configuration_table(&efi_dxe_services_table_guid, dxe);
>> +}
>> diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
>> index 393b690c3ee..796da5d5678 100644
>> --- a/lib/efi_loader/efi_setup.c
>> +++ b/lib/efi_loader/efi_setup.c
>> @@ -260,6 +260,12 @@ efi_status_t efi_init_obj_list(void)
>> if (ret != EFI_SUCCESS)
>> goto out;
>>
>> + if (IS_ENABLED(CONFIG_EFI_DXE)) {
>> + ret = efi_dxe_services_register();
>> + if (ret != EFI_SUCCESS)
>> + goto out;
>> + }
>> +
>> if (IS_ENABLED(CONFIG_EFI_ECPT)) {
>> ret = efi_ecpt_register();
>> if (ret != EFI_SUCCESS)
>> --
>> 2.47.1
>>
More information about the U-Boot
mailing list