The RSDP cannot be found by searching the traditional BIOS memory
locations. Try instead to acquire the EFI System table physical
address from Mach and search its configuration table for the RSDP.
---
 debian/patches/acpi-init-files.diff | 184 ++++++++++++++++++++++++++--
 1 file changed, 177 insertions(+), 7 deletions(-)

diff --git a/debian/patches/acpi-init-files.diff 
b/debian/patches/acpi-init-files.diff
index f817cba..dd60e62 100644
--- a/debian/patches/acpi-init-files.diff
+++ b/debian/patches/acpi-init-files.diff
@@ -1,8 +1,8 @@
 Index: libacpica/acpi_init.c
 ===================================================================
---- /dev/null
-+++ libacpica/acpi_init.c
-@@ -0,0 +1,1050 @@
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ libacpica/acpi_init.c      2026-10-07 14:01:17.575992634 +0100
+@@ -0,0 +1,1220 @@
 +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
 +#include <acpi/acpi.h>
 +
@@ -171,12 +171,182 @@ Index: libacpica/acpi_init.c
 +  return AE_OK;
 +}
 +
++#ifdef __x86_64__
++
++#include <device/efi_status.h>
++
++static error_t
++acpi_mach_efi_root (acpi_physical_address *pa)
++{
++  mach_port_t devices = MACH_PORT_NULL;
++  mach_port_t efi_device;
++
++  error_t err = get_privileged_ports (NULL, &devices);
++  if (err)
++    return err;
++
++  if (devices == MACH_PORT_NULL)
++    return ENODEV;
++
++  err = device_open (devices, D_READ, "efi", &efi_device);
++  mach_port_deallocate (mach_task_self (), devices);
++
++  if (!err)
++    {
++      uint64_t mpa;
++
++      mach_msg_type_number_t cnt = MACH_EFI_GET_SYSROOT_COUNT;
++      err = device_get_status (efi_device, MACH_EFI_GET_SYSROOT,
++                             (dev_status_t)&mpa, &cnt);
++
++      if (!err)
++      *pa = mpa;
++
++      device_close (efi_device);
++    }
++
++  return err;
++}
++
++struct efi_table_header
++{
++  uint64_t signature;
++  uint32_t revision;
++  uint32_t size;
++  uint32_t crc32;
++  uint32_t reserved;
++};
++
++typedef uint64_t efi_pa_t;
++typedef uint64_t efi_handle_t;
++typedef uint8_t  efi_guid_t[16];
++
++struct efi_system_table64
++{
++  struct efi_table_header hdr;
++
++  efi_pa_t     fw_vendor_pa;
++  uint32_t     fw_revision;
++  uint32_t     pad1;
++  efi_handle_t con_in_handle;
++  efi_pa_t     con_in;
++  efi_handle_t con_out_handle;
++  efi_pa_t     con_out;
++  efi_handle_t stderr_handle;
++  efi_pa_t     stderr;
++  efi_pa_t     runtime;
++  efi_pa_t     boottime;
++  uint32_t     nr_tables;
++  uint32_t     pad2;
++  efi_pa_t     tables;
++};
++
++struct efi_config_table64
++{
++  efi_guid_t guid;
++  efi_pa_t   table;
++};
++
++static const efi_guid_t acpi0_table_guid = {
++  0x30, 0x2d, 0x9d, 0xeb,
++  0x88, 0x2d,
++  0xd3, 0x11,
++  0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d
++};
++
++static const efi_guid_t acpi2_table_guid = {
++  0x71, 0xe8, 0x68, 0x88,
++  0xf1, 0xe4,
++  0xd3, 0x11,
++  0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81
++};
++
++#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249ULL
++
++/* libacpica uses 0 as an 'invalid' address. */
++#define ACPI_INVALID_PHYSADDR 0
++
++static uint64_t
++acpi_root_pointer_from_efi (void)
++{
++  uint64_t result = ACPI_INVALID_PHYSADDR;
++  uint64_t efi_system;
++
++  if (acpi_mach_efi_root (&efi_system))
++    return result;
++
++  struct efi_system_table64 *efi_ptr = (struct efi_system_table64 *)
++    acpi_os_map_memory (efi_system, sizeof(struct efi_system_table64));
++
++  if (efi_ptr == MAP_FAILED)
++    return result;
++
++  if (efi_ptr->hdr.signature == EFI_SYSTEM_TABLE_SIGNATURE
++      && efi_ptr->nr_tables > 0)
++    {
++      const acpi_size ct_sz = (sizeof (struct efi_system_table64) * 
efi_ptr->nr_tables);
++      struct efi_config_table64 *config_tables =
++      (struct efi_config_table64 *)acpi_os_map_memory (efi_ptr->tables, 
ct_sz);
++
++      if (config_tables != MAP_FAILED)
++      {
++        for (unsigned int i = 0; i < efi_ptr->nr_tables; i++)
++          {
++            if (memcmp (&config_tables->guid,
++                        &acpi2_table_guid,
++                        sizeof(efi_guid_t)) == 0)
++              {
++                result = config_tables->table;
++                /* Higher versions are preferred. */
++                break;
++              }
++            else if (memcmp (&config_tables->guid,
++                             &acpi0_table_guid,
++                             sizeof(efi_guid_t)) == 0)
++              result = config_tables->table;
++
++            config_tables++;
++          }
++
++        acpi_os_unmap_memory (config_tables, ct_sz);
++      }
++    }
++
++  acpi_os_unmap_memory (efi_ptr, sizeof(struct efi_system_table64));
++
++  struct acpi_rsdp_common *rsdp_ptr = (struct acpi_rsdp_common *)
++    acpi_os_map_memory (result, sizeof(struct acpi_rsdp_common));
++
++  if (rsdp_ptr != MAP_FAILED)
++    {
++      if (memcmp (rsdp_ptr->signature,
++                ACPI_SIG_RSDP,
++                sizeof(rsdp_ptr->signature)))
++      result = ACPI_INVALID_PHYSADDR;
++
++      acpi_os_unmap_memory (rsdp_ptr, sizeof(struct acpi_rsdp_common));
++    }
++
++  return result;
++}
++
++#endif /* __x86_64__ */
++
 +acpi_physical_address
-+acpi_os_get_root_pointer(void)
++acpi_os_get_root_pointer (void)
 +{
 +  acpi_physical_address pa;
 +
-+  acpi_find_root_pointer(&pa);
++  if (acpi_find_root_pointer (&pa) != AE_OK)
++    {
++#ifdef __x86_64__
++      uint64_t rsdp = acpi_root_pointer_from_efi ();
++
++      if (rsdp != ACPI_INVALID_PHYSADDR)
++      pa = rsdp;
++#endif /* __x86_64__ */
++    }
++
 +  return pa;
 +}
 +
@@ -1055,8 +1225,8 @@ Index: libacpica/acpi_init.c
 +}
 Index: libacpica/include/acpi/acpi_init.h
 ===================================================================
---- /dev/null
-+++ libacpica/include/acpi/acpi_init.h
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ libacpica/include/acpi/acpi_init.h 2026-10-07 14:00:35.904489055 +0100
 @@ -0,0 +1,11 @@
 +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
 +#ifndef ACPI_INIT_H_
-- 
2.47.3


Reply via email to