[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