[PATCH 3/4] efi_loader: install DXE services table

Heinrich Schuchardt heinrich.schuchardt at canonical.com
Thu Jan 2 19:11:32 CET 2025


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