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 | 177 ++++++++++++++++++++++++++--
 1 file changed, 168 insertions(+), 9 deletions(-)

diff --git a/debian/patches/acpi-init-files.diff 
b/debian/patches/acpi-init-files.diff
index f817cba..c3f752a 100644
--- a/debian/patches/acpi-init-files.diff
+++ b/debian/patches/acpi-init-files.diff
@@ -1,8 +1,6 @@
-Index: libacpica/acpi_init.c
-===================================================================
 --- /dev/null
-+++ libacpica/acpi_init.c
-@@ -0,0 +1,1050 @@
++++ b/acpi_init.c
+@@ -0,0 +1,1213 @@
 +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
 +#include <acpi/acpi.h>
 +
@@ -29,6 +27,12 @@ Index: libacpica/acpi_init.c
 +#include <hurd.h>
 +#include <pciaccess.h>
 +#include <hurd/irqhelp.h>
++#ifdef __x86_64__
++#include <mach/host_info.h>
++#endif /* __x86_64__ */
++
++/* libacpica uses 0 as an 'invalid' address. */
++#define ACPI_INVALID_PHYSADDR 0
 +
 +#define ACPI_MAX_TABLES 128
 +
@@ -171,12 +175,169 @@ Index: libacpica/acpi_init.c
 +  return AE_OK;
 +}
 +
++#ifdef __x86_64__
++static error_t
++acpi_mach_efi_root (acpi_physical_address *pa)
++{
++  mach_msg_type_number_t size = HOST_EFI_SYSTAB_COUNT;
++  host_efi_systab_data_t systab;
++
++  if (host_info (mach_host_self (), HOST_EFI_SYSTAB,
++               (host_info_t) &systab, &size)
++      || systab == HOST_NO_UEFI)
++    return ENODEV;
++
++  *pa = systab;
++
++  return 0;
++}
++
++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
++
++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));
++
++  if (result != ACPI_INVALID_PHYSADDR)
++    {
++      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)
++      {
++        result = ACPI_INVALID_PHYSADDR;
++      }
++      else
++      {
++        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_physical_address pa;
++  acpi_physical_address pa = ACPI_INVALID_PHYSADDR;
++
++#ifdef __x86_64__
++  uint64_t rsdp = acpi_root_pointer_from_efi ();
++
++  if (rsdp != ACPI_INVALID_PHYSADDR)
++    pa = rsdp;
++#endif /* __x86_64__ */
++
++  if (pa == ACPI_INVALID_PHYSADDR)
++    acpi_find_root_pointer(&pa);
 +
-+  acpi_find_root_pointer(&pa);
 +  return pa;
 +}
 +
@@ -1053,10 +1214,8 @@ Index: libacpica/acpi_init.c
 +die:
 +  acpi_os_printf("OUCH!\n");
 +}
-Index: libacpica/include/acpi/acpi_init.h
-===================================================================
 --- /dev/null
-+++ libacpica/include/acpi/acpi_init.h
++++ b/include/acpi/acpi_init.h
 @@ -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