
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@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, +}; + +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)