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


Reply via email to