This device allows privileged user processes to determine the physical
address of the EFI system table.
---
device/efi.c | 58 ++++++++++++++++++++++++++++++++++
device/efi.h | 30 ++++++++++++++++++
i386/i386/multiboot2_hdr_asm.h | 2 +-
i386/i386at/acpi_parse_apic.c | 9 ++++++
i386/i386at/conf.c | 12 +++++++
include/device/efi_status.h | 26 +++++++++++++++
x86_64/Makefrag.am | 6 ++++
7 files changed, 142 insertions(+), 1 deletion(-)
create mode 100644 device/efi.c
create mode 100644 device/efi.h
create mode 100644 include/device/efi_status.h
diff --git a/device/efi.c b/device/efi.c
new file mode 100644
index 00000000..0df77989
--- /dev/null
+++ b/device/efi.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2026 Free Software Foundation, Inc.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * THE FREE SOFTWARE FOUNDATIONALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. THE FREE SOFTWARE FOUNDATION DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ */
+
+#include <device/device_types.h>
+#include <device/efi.h>
+#include <device/efi_status.h>
+#include <mach/message.h>
+#include <string.h>
+
+uint64_t efi_root = MACH_EFI_INVALID_ADDR;
+
+io_return_t
+efi_getstat(
+ dev_t dev,
+ dev_flavor_t flavor,
+ dev_status_t data, /* pointer to OUT array */
+ mach_msg_type_number_t *count) /* OUT */
+{
+ io_return_t result = D_INVALID_OPERATION;
+
+ switch (flavor)
+ {
+#ifndef MACH_XEN
+ case MACH_EFI_GET_SYSROOT:
+ {
+ if (efi_root == MACH_EFI_INVALID_ADDR)
+ {
+ result = D_NO_SUCH_DEVICE;
+ }
+ else if (*count >= MACH_EFI_GET_SYSROOT_COUNT)
+ {
+ memcpy (data,
+ &efi_root,
+ MACH_EFI_GET_SYSROOT_COUNT * sizeof (int));
+
+ *count = MACH_EFI_GET_SYSROOT_COUNT;
+ result = D_SUCCESS;
+ }
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+
+ return result;
+}
diff --git a/device/efi.h b/device/efi.h
new file mode 100644
index 00000000..73095d33
--- /dev/null
+++ b/device/efi.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2026 Free Software Foundation
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * FSF ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. FSF DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ */
+
+#ifndef _DEVICE_EFI_H_
+#define _DEVICE_EFI_H_
+
+#include <device/conf.h>
+#include <mach/message.h>
+#include <sys/types.h>
+
+extern uint64_t efi_root;
+
+extern io_return_t
+efi_getstat(dev_t dev,
+ dev_flavor_t flavor,
+ dev_status_t data,
+ mach_msg_type_number_t *count);
+
+#endif /* _DEVICE_EFI_H_ */
diff --git a/i386/i386/multiboot2_hdr_asm.h b/i386/i386/multiboot2_hdr_asm.h
index 37ed8837..b2ecb21c 100644
--- a/i386/i386/multiboot2_hdr_asm.h
+++ b/i386/i386/multiboot2_hdr_asm.h
@@ -37,7 +37,7 @@ multiboot2_hdr:
.long MULTIBOOT2_TAG_TYPE_ELF_SECTIONS
.long MULTIBOOT2_TAG_TYPE_ACPI_OLD
.long MULTIBOOT2_TAG_TYPE_ACPI_NEW
- .long 0 /* alignment */
+ .long MULTIBOOT2_TAG_TYPE_EFI64
/* Align modules on page boundaries */
.short MULTIBOOT2_HEADER_TAG_MODULE_ALIGN
.short 0
diff --git a/i386/i386at/acpi_parse_apic.c b/i386/i386at/acpi_parse_apic.c
index b33b5324..94310f83 100644
--- a/i386/i386at/acpi_parse_apic.c
+++ b/i386/i386at/acpi_parse_apic.c
@@ -26,6 +26,10 @@
#include <mach/machine.h> /* machine_slot */
#include <mach/machine/multiboot2.h>
+#ifdef __x86_64__
+#include <device/efi.h>
+#endif
+
#include <kern/printf.h> /* printf */
#include <kern/debug.h>
#include <i386/vm_param.h> /* phystokv */
@@ -719,6 +723,11 @@ acpi_mb2_initialise (const struct multiboot2_raw_info *bi)
}
break;
+#ifdef __x86_64__
+ case MULTIBOOT2_TAG_TYPE_EFI64:
+ efi_root = ((const struct multiboot2_tag_efi64 *)tag)->pointer;
+ break;
+#endif
default:
break;
}
diff --git a/i386/i386at/conf.c b/i386/i386at/conf.c
index 9bdd8379..5990c58e 100644
--- a/i386/i386at/conf.c
+++ b/i386/i386at/conf.c
@@ -74,6 +74,11 @@
#include <i386at/mbinfo.h>
#define mbinfoname "mbinfo"
+#ifdef __x86_64__
+#include <device/efi.h>
+#define efiname "efi"
+#endif /* __x86_64__ */
+
/*
* List of devices - console must be at slot 0
*/
@@ -165,6 +170,13 @@ struct dev_ops dev_name_list[] =
nulldev_write,nulldev_getstat,nulldev_setstat,nomap,
nodev_async_in, nulldev_reset, nulldev_portdeath,0,
nodev_info },
+
+#ifdef __x86_64__
+ { efiname, nulldev_open, nulldev_close, nulldev_read,
+ nulldev_write, efi_getstat,nulldev_setstat,nomap,
+ nodev_async_in, nulldev_reset, nulldev_portdeath,0,
+ nodev_info },
+#endif /* __x86_64__ */
#endif /* MACH_HYP */
};
diff --git a/include/device/efi_status.h b/include/device/efi_status.h
new file mode 100644
index 00000000..edc198a2
--- /dev/null
+++ b/include/device/efi_status.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2026 Free Software Foundation
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * FSF ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. FSF DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ */
+
+#ifndef _DEVICE_EFI_STATUS_H_
+#define _DEVICE_EFI_STATUS_H_
+
+#define MACH_EFI_INVALID_ADDR __UINT64_MAX__
+
+/* Flavor for device_get_status */
+
+/* Returns (uint64_t) physical address of the EFI system table. */
+#define MACH_EFI_GET_SYSROOT 0
+#define MACH_EFI_GET_SYSROOT_COUNT (sizeof(uint64_t) / sizeof(int))
+
+#endif /* _DEVICE_EFI_STATUS_H_ */
diff --git a/x86_64/Makefrag.am b/x86_64/Makefrag.am
index c9d15ff1..d144cf88 100644
--- a/x86_64/Makefrag.am
+++ b/x86_64/Makefrag.am
@@ -90,6 +90,8 @@ endif
#
libkernel_a_SOURCES += \
+ device/efi.c \
+ device/efi.h \
i386/i386/percpu.h \
i386/i386/percpu.c \
x86_64/cswitch.S \
@@ -196,6 +198,10 @@ include_mach_x86_64_HEADERS = \
i386/include/mach/i386/vm_param.h \
i386/include/mach/i386/vm_types.h
+include_mach_x86_64devicedir = $(includedir)/device
+include_mach_x86_64device_HEADERS = \
+ include/device/efi_status.h
+
if enable_user32
include_mach_x86_64_HEADERS += i386/include/mach/i386/syscall_sw.h
else
--
2.47.3