Replace dev-mem patch with a more robust version; the new one precludes

acpidump from using /dev/mem on arm64 at all.

Signed-off-by: Al Stone <ahs3@redhat.com>
This commit is contained in:
Al Stone 2015-06-03 15:16:20 -06:00
parent 6ee8a7a79c
commit 067c49c33b
3 changed files with 792 additions and 138 deletions

View File

@ -1,6 +1,6 @@
Name: acpica-tools
Version: 20150515
Release: 1%{?dist}
Release: 2%{?dist}
Summary: ACPICA tools for the development and debug of ACPI tables
Group: Development/Languages
@ -33,7 +33,7 @@ Patch6: OPT_LDFLAGS.patch
Patch7: int-format.patch
Patch8: f23-harden.patch
Patch9: acuuid.patch
Patch10: dev-mem.patch
Patch10: nodevmem.patch
Patch11: arm-madt.patch
Patch12: segfault.patch
@ -96,7 +96,7 @@ gzip -dc %{SOURCE1} | tar -x --strip-components=1 -f -
%patch7 -p1 -b .int-format
%patch8 -p1 -b .f23-harden
%patch9 -p1 -b .acuuid
%patch10 -p1 -b .dev-mem
%patch10 -p1 -b .nodevmem
%patch11 -p1 -b .arm-madt
%patch12 -p1 -b .segfault
@ -203,6 +203,12 @@ fi
%changelog
* Wed Jun 3 2015 Al Stone <ahs3@redhat.com> - 20150515-2
- Replace dev-mem patch with nodevmem; this is a much more robust version of
the functionality needed, and set up properly for arm64 -- the patch makes
it so that acpidump does not use /dev/mem at all on arm64 since it might
not contain the right data.
* Mon Jun 1 2015 Al Stone <ahs3@redhat.com> - 20150515-1
- Update to latest upstream. Closes BZ#122166
- Refresh patches

View File

@ -1,135 +0,0 @@
Subject: [RFC PATCH] Avoid all Linux /dev/mem accesses when -c is specified
From: Roy Franz <roy.franz@linaro.org>
Date: 05/15/2015 12:50 PM
To: linaro-uefi@lists.linaro.org, linaro-acpi@lists.linaro.org, graeme.gregory@linaro.org, al.stone@linaro.org
CC: Roy Franz <roy.franz@linaro.org>
Don't try to read the RSDP structure or RSDT/XSDT tables
from memory with the -c option. These are now provided
as files in /sysfs, and this allows acpidump to function
when /dev/mem is not available, which will be the case
for Aarch64 servers.
Signed-off-by: Roy Franz <roy.franz@linaro.org>
---
source/os_specific/service_layers/oslinuxtbl.c | 87 +++++++++++++-------------
1 file changed, 43 insertions(+), 44 deletions(-)
Index: acpica-unix/source/os_specific/service_layers/oslinuxtbl.c
===================================================================
--- acpica-unix.orig/source/os_specific/service_layers/oslinuxtbl.c
+++ acpica-unix/source/os_specific/service_layers/oslinuxtbl.c
@@ -686,70 +686,69 @@ OslTableInitialize (
return (AE_OK);
}
+ if (!Gbl_DumpCustomizedTables)
+ {
/* Get RSDP from memory */
- Status = OslLoadRsdp ();
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
+ Status = OslLoadRsdp ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
- /* Get XSDT from memory */
+ /* Get XSDT from memory */
- if (Gbl_Rsdp.Revision && !Gbl_DoNotDumpXsdt)
- {
- if (Gbl_Xsdt)
+ if (Gbl_Rsdp.Revision && !Gbl_DoNotDumpXsdt)
{
- free (Gbl_Xsdt);
- Gbl_Xsdt = NULL;
+ if (Gbl_Xsdt)
+ {
+ free (Gbl_Xsdt);
+ Gbl_Xsdt = NULL;
+ }
+
+ Gbl_Revision = 2;
+ Status = OslGetBiosTable (ACPI_SIG_XSDT, 0,
+ ACPI_CAST_PTR (ACPI_TABLE_HEADER *, &Gbl_Xsdt), &Address);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
}
- Gbl_Revision = 2;
- Status = OslGetBiosTable (ACPI_SIG_XSDT, 0,
- ACPI_CAST_PTR (ACPI_TABLE_HEADER *, &Gbl_Xsdt), &Address);
- if (ACPI_FAILURE (Status))
+ /* Get RSDT from memory */
+
+ if (Gbl_Rsdp.RsdtPhysicalAddress)
{
- return (Status);
+ if (Gbl_Rsdt)
+ {
+ free (Gbl_Rsdt);
+ Gbl_Rsdt = NULL;
+ }
+
+ Status = OslGetBiosTable (ACPI_SIG_RSDT, 0,
+ ACPI_CAST_PTR (ACPI_TABLE_HEADER *, &Gbl_Rsdt), &Address);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
}
- }
- /* Get RSDT from memory */
+ /* Get FADT from memory */
- if (Gbl_Rsdp.RsdtPhysicalAddress)
- {
- if (Gbl_Rsdt)
+ if (Gbl_Fadt)
{
- free (Gbl_Rsdt);
- Gbl_Rsdt = NULL;
+ free (Gbl_Fadt);
+ Gbl_Fadt = NULL;
}
- Status = OslGetBiosTable (ACPI_SIG_RSDT, 0,
- ACPI_CAST_PTR (ACPI_TABLE_HEADER *, &Gbl_Rsdt), &Address);
+ Status = OslGetBiosTable (ACPI_SIG_FADT, 0,
+ ACPI_CAST_PTR (ACPI_TABLE_HEADER *, &Gbl_Fadt), &Gbl_FadtAddress);
if (ACPI_FAILURE (Status))
{
return (Status);
}
- }
-
- /* Get FADT from memory */
-
- if (Gbl_Fadt)
- {
- free (Gbl_Fadt);
- Gbl_Fadt = NULL;
- }
- Status = OslGetBiosTable (ACPI_SIG_FADT, 0,
- ACPI_CAST_PTR (ACPI_TABLE_HEADER *, &Gbl_Fadt), &Gbl_FadtAddress);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
-
- if (!Gbl_DumpCustomizedTables)
- {
/* Add mandatory tables to global table list first */
-
Status = OslAddTableToList (ACPI_RSDP_NAME, 0);
if (ACPI_FAILURE (Status))
{

783
nodevmem.patch Normal file
View File

@ -0,0 +1,783 @@
diff -Naur acpica-unix2-20150515/generate/unix/acpidump/Makefile acpica-unix2-20150515.devmem/generate/unix/acpidump/Makefile
--- acpica-unix2-20150515/generate/unix/acpidump/Makefile 2015-05-15 17:49:17.000000000 -0600
+++ acpica-unix2-20150515.devmem/generate/unix/acpidump/Makefile 2015-06-02 15:00:31.813746336 -0600
@@ -67,10 +67,17 @@
OBJECTS += \
$(OBJDIR)/osbsdtbl.o
else
+
+ifeq ($(NO_DEV_MEM), true)
+OBJECTS += \
+ $(OBJDIR)/oslinuxtbl_nodevmem.o
+else
OBJECTS += \
$(OBJDIR)/oslinuxtbl.o
endif
+endif
+
#
# Flags specific to acpidump
#
diff -Naur acpica-unix2-20150515/generate/unix/Makefile.config acpica-unix2-20150515.devmem/generate/unix/Makefile.config
--- acpica-unix2-20150515/generate/unix/Makefile.config 2015-06-03 14:57:30.328724317 -0600
+++ acpica-unix2-20150515.devmem/generate/unix/Makefile.config 2015-06-02 15:03:53.727560100 -0600
@@ -49,6 +49,7 @@
LINKPROG = $(CC) $(OBJECTS) -o $(PROG) $(LDFLAGS) $(OPT_LDFLAGS)
PREFIX ?= /usr
INSTALLDIR = $(PREFIX)/bin
+UNAME_M := $(shell uname -m)
UNAME_S := $(shell uname -s)
#
@@ -70,6 +71,12 @@
HOST = _NetBSD
endif
+ifeq ($(UNAME_S), Linux)
+ifeq ($(UNAME_M), aarch64)
+NO_DEV_MEM ?= true
+endif
+endif
+
ifeq ($(HOST), _APPLE)
INSTALL = cp
INSTALLFLAGS ?= -f
diff -Naur acpica-unix2-20150515/source/os_specific/service_layers/oslinuxtbl_nodevmem.c acpica-unix2-20150515.devmem/source/os_specific/service_layers/oslinuxtbl_nodevmem.c
--- acpica-unix2-20150515/source/os_specific/service_layers/oslinuxtbl_nodevmem.c 1969-12-31 17:00:00.000000000 -0700
+++ acpica-unix2-20150515.devmem/source/os_specific/service_layers/oslinuxtbl_nodevmem.c 2015-06-02 16:14:38.088031027 -0600
@@ -0,0 +1,734 @@
+/******************************************************************************
+ *
+ * Module Name: oslinuxtbl_nodevmem - Linux OSL for obtaining ACPI tables
+ * that assumes you cannot use /dev/mem
+ *
+ *****************************************************************************/
+
+#include "acpidump.h"
+
+
+#define _COMPONENT ACPI_OS_SERVICES
+ ACPI_MODULE_NAME ("oslinuxtbl_nodevmem")
+
+
+#ifndef PATH_MAX
+#define PATH_MAX 256
+#endif
+
+
+/* List of information about obtained ACPI tables */
+
+typedef struct osl_table_info
+{
+ struct osl_table_info *Next;
+ UINT32 Instance;
+ char Signature[ACPI_NAME_SIZE];
+
+} OSL_TABLE_INFO;
+
+/* Local prototypes */
+
+static ACPI_STATUS
+OslTableInitialize (
+ void);
+
+static ACPI_STATUS
+OslTableNameFromFile (
+ char *Filename,
+ char *Signature,
+ UINT32 *Instance);
+
+static ACPI_STATUS
+OslAddTableToList (
+ char *Signature,
+ UINT32 Instance);
+
+static ACPI_STATUS
+OslReadTableFromFile (
+ char *Filename,
+ ACPI_SIZE FileOffset,
+ char *Signature,
+ ACPI_TABLE_HEADER **Table);
+
+static ACPI_STATUS
+OslListAcpiTables (
+ char *Directory);
+
+static ACPI_STATUS
+OslGetAcpiTable (
+ char *Pathname,
+ char *Signature,
+ UINT32 Instance,
+ ACPI_TABLE_HEADER **Table,
+ ACPI_PHYSICAL_ADDRESS *Address);
+
+static ACPI_STATUS
+OslGetLastStatus (
+ ACPI_STATUS DefaultStatus);
+
+
+/* File locations */
+
+#define DYNAMIC_TABLE_DIR "/sys/firmware/acpi/tables/dynamic"
+#define STATIC_TABLE_DIR "/sys/firmware/acpi/tables"
+
+/* Should we get dynamically loaded SSDTs from DYNAMIC_TABLE_DIR? */
+
+UINT8 Gbl_DumpDynamicTables = TRUE;
+
+/* Initialization flags */
+
+UINT8 Gbl_TableListInitialized = FALSE;
+
+/* Revision of RSD PTR */
+
+UINT8 Gbl_Revision = 0;
+
+OSL_TABLE_INFO *Gbl_TableListHead = NULL;
+UINT32 Gbl_TableCount = 0;
+
+
+/******************************************************************************
+ *
+ * FUNCTION: OslGetLastStatus
+ *
+ * PARAMETERS: DefaultStatus - Default error status to return
+ *
+ * RETURN: Status; Converted from errno.
+ *
+ * DESCRIPTION: Get last errno and conver it to ACPI_STATUS.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+OslGetLastStatus (
+ ACPI_STATUS DefaultStatus)
+{
+
+ switch (errno)
+ {
+ case EACCES:
+ case EPERM:
+
+ return (AE_ACCESS);
+
+ case ENOENT:
+
+ return (AE_NOT_FOUND);
+
+ case ENOMEM:
+
+ return (AE_NO_MEMORY);
+
+ default:
+
+ return (DefaultStatus);
+ }
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsGetTableByAddress
+ *
+ * PARAMETERS: Address - Physical address of the ACPI table
+ * Table - Where a pointer to the table is returned
+ *
+ * RETURN: Status; Table buffer is returned if AE_OK.
+ * AE_NOT_FOUND: A valid table was not found at the address
+ *
+ * DESCRIPTION: Get an ACPI table via a physical memory address.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsGetTableByAddress (
+ ACPI_PHYSICAL_ADDRESS Address,
+ ACPI_TABLE_HEADER **Table)
+{
+ /*
+ * If this source file is being used, there is no reliable access
+ * to /dev/mem on this system. Hence, we cannot retrieve a table
+ * by address at all and will always return AE_NOT_FOUND.
+ */
+
+ return AE_NOT_FOUND;
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsGetTableByName
+ *
+ * PARAMETERS: Signature - ACPI Signature for desired table. Must be
+ * a null terminated 4-character string.
+ * Instance - Multiple table support for SSDT/UEFI (0...n)
+ * Must be 0 for other tables.
+ * Table - Where a pointer to the table is returned
+ * Address - Where the table physical address is returned
+ *
+ * RETURN: Status; Table buffer and physical address returned if AE_OK.
+ * AE_LIMIT: Instance is beyond valid limit
+ * AE_NOT_FOUND: A table with the signature was not found
+ *
+ * NOTE: Assumes the input signature is uppercase.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsGetTableByName (
+ char *Signature,
+ UINT32 Instance,
+ ACPI_TABLE_HEADER **Table,
+ ACPI_PHYSICAL_ADDRESS *Address)
+{
+ ACPI_STATUS Status;
+
+
+ /* Get main ACPI tables from memory on first invocation of this function */
+
+ Status = OslTableInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Attempt to get the table from the static directory */
+
+ Status = OslGetAcpiTable (STATIC_TABLE_DIR, Signature,
+ Instance, Table, Address);
+
+ if (ACPI_FAILURE (Status) && Status == AE_LIMIT)
+ {
+ if (Gbl_DumpDynamicTables)
+ {
+ /* Attempt to get a dynamic table */
+
+ Status = OslGetAcpiTable (DYNAMIC_TABLE_DIR, Signature,
+ Instance, Table, Address);
+ }
+ }
+
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: OslAddTableToList
+ *
+ * PARAMETERS: Signature - Table signature
+ * Instance - Table instance
+ *
+ * RETURN: Status; Successfully added if AE_OK.
+ * AE_NO_MEMORY: Memory allocation error
+ *
+ * DESCRIPTION: Insert a table structure into OSL table list.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+OslAddTableToList (
+ char *Signature,
+ UINT32 Instance)
+{
+ OSL_TABLE_INFO *NewInfo;
+ OSL_TABLE_INFO *Next;
+ UINT32 NextInstance = 0;
+ BOOLEAN Found = FALSE;
+
+
+ NewInfo = calloc (1, sizeof (OSL_TABLE_INFO));
+ if (!NewInfo)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ ACPI_MOVE_NAME (NewInfo->Signature, Signature);
+
+ if (!Gbl_TableListHead)
+ {
+ Gbl_TableListHead = NewInfo;
+ }
+ else
+ {
+ Next = Gbl_TableListHead;
+ while (1)
+ {
+ if (ACPI_COMPARE_NAME (Next->Signature, Signature))
+ {
+ if (Next->Instance == Instance)
+ {
+ Found = TRUE;
+ }
+ if (Next->Instance >= NextInstance)
+ {
+ NextInstance = Next->Instance + 1;
+ }
+ }
+
+ if (!Next->Next)
+ {
+ break;
+ }
+ Next = Next->Next;
+ }
+ Next->Next = NewInfo;
+ }
+
+ if (Found)
+ {
+ if (Instance)
+ {
+ fprintf (stderr,
+ "%4.4s: Warning unmatched table instance %d, expected %d\n",
+ Signature, Instance, NextInstance);
+ }
+ Instance = NextInstance;
+ }
+
+ NewInfo->Instance = Instance;
+ Gbl_TableCount++;
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiOsGetTableByIndex
+ *
+ * PARAMETERS: Index - Which table to get
+ * Table - Where a pointer to the table is returned
+ * Instance - Where a pointer to the table instance no. is
+ * returned
+ * Address - Where the table physical address is returned
+ *
+ * RETURN: Status; Table buffer and physical address returned if AE_OK.
+ * AE_LIMIT: Index is beyond valid limit
+ *
+ * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns
+ * AE_LIMIT when an invalid index is reached. Index is not
+ * necessarily an index into the RSDT/XSDT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiOsGetTableByIndex (
+ UINT32 Index,
+ ACPI_TABLE_HEADER **Table,
+ UINT32 *Instance,
+ ACPI_PHYSICAL_ADDRESS *Address)
+{
+ OSL_TABLE_INFO *Info;
+ ACPI_STATUS Status;
+ UINT32 i;
+
+
+ /* Get main ACPI tables from memory on first invocation of this function */
+
+ Status = OslTableInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Validate Index */
+
+ if (Index >= Gbl_TableCount)
+ {
+ return (AE_LIMIT);
+ }
+
+ /* Point to the table list entry specified by the Index argument */
+
+ Info = Gbl_TableListHead;
+ for (i = 0; i < Index; i++)
+ {
+ Info = Info->Next;
+ }
+
+ /* Now we can just get the table via the signature */
+
+ Status = AcpiOsGetTableByName (Info->Signature, Info->Instance,
+ Table, Address);
+
+ if (ACPI_SUCCESS (Status))
+ {
+ *Instance = Info->Instance;
+ }
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: OslTableInitialize
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to
+ * local variables. Main ACPI tables include RSDT, FADT, RSDT,
+ * and/or XSDT.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+OslTableInitialize (
+ void)
+{
+ ACPI_STATUS Status;
+
+ if (Gbl_TableListInitialized)
+ {
+ return (AE_OK);
+ }
+
+ /* Add all tables found in the static directory */
+
+ Status = OslListAcpiTables (STATIC_TABLE_DIR);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (Gbl_DumpDynamicTables)
+ {
+ /* Add all dynamically loaded tables in the dynamic directory */
+
+ Status = OslListAcpiTables (DYNAMIC_TABLE_DIR);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ Gbl_TableListInitialized = TRUE;
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: OslListAcpiTables
+ *
+ * PARAMETERS: Directory - Directory that contains the tables
+ *
+ * RETURN: Status; Table list is initialized if AE_OK.
+ *
+ * DESCRIPTION: Add ACPI tables to the table list from a directory.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+OslListAcpiTables (
+ char *Directory)
+{
+ void *TableDir;
+ UINT32 Instance;
+ char TempName[ACPI_NAME_SIZE];
+ char *Filename;
+ ACPI_STATUS Status = AE_OK;
+
+
+ /* Open the requested directory */
+
+ TableDir = AcpiOsOpenDirectory (Directory, "*", REQUEST_FILE_ONLY);
+ if (!TableDir)
+ {
+ return (OslGetLastStatus (AE_NOT_FOUND));
+ }
+
+ /* Examine all entries in this directory */
+
+ while ((Filename = AcpiOsGetNextFilename (TableDir)))
+ {
+ /* Extract table name and instance number */
+
+ Status = OslTableNameFromFile (Filename, TempName, &Instance);
+
+ /* Ignore meaningless files */
+
+ if (ACPI_FAILURE (Status))
+ {
+ continue;
+ }
+
+ /* Add new info node to global table list */
+
+ Status = OslAddTableToList (TempName, Instance);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+ }
+
+ AcpiOsCloseDirectory (TableDir);
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: OslTableNameFromFile
+ *
+ * PARAMETERS: Filename - File that contains the desired table
+ * Signature - Pointer to 4-character buffer to store
+ * extracted table signature.
+ * Instance - Pointer to integer to store extracted
+ * table instance number.
+ *
+ * RETURN: Status; Table name is extracted if AE_OK.
+ *
+ * DESCRIPTION: Extract table signature and instance number from a table file
+ * name.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+OslTableNameFromFile (
+ char *Filename,
+ char *Signature,
+ UINT32 *Instance)
+{
+
+ /* Ignore meaningless files */
+
+ if (strlen (Filename) < ACPI_NAME_SIZE)
+ {
+ return (AE_BAD_SIGNATURE);
+ }
+
+ /* Extract instance number */
+
+ if (isdigit ((int) Filename[ACPI_NAME_SIZE]))
+ {
+ sscanf (&Filename[ACPI_NAME_SIZE], "%u", Instance);
+ }
+ else if (strlen (Filename) != ACPI_NAME_SIZE)
+ {
+ return (AE_BAD_SIGNATURE);
+ }
+ else
+ {
+ *Instance = 0;
+ }
+
+ /* Extract signature */
+
+ ACPI_MOVE_NAME (Signature, Filename);
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: OslReadTableFromFile
+ *
+ * PARAMETERS: Filename - File that contains the desired table
+ * FileOffset - Offset of the table in file
+ * Signature - Optional ACPI Signature for desired table.
+ * A null terminated 4-character string.
+ * Table - Where a pointer to the table is returned
+ *
+ * RETURN: Status; Table buffer is returned if AE_OK.
+ *
+ * DESCRIPTION: Read a ACPI table from a file.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+OslReadTableFromFile (
+ char *Filename,
+ ACPI_SIZE FileOffset,
+ char *Signature,
+ ACPI_TABLE_HEADER **Table)
+{
+ FILE *TableFile;
+ ACPI_TABLE_HEADER Header;
+ ACPI_TABLE_HEADER *LocalTable = NULL;
+ UINT32 TableLength;
+ INT32 Count;
+ ACPI_STATUS Status = AE_OK;
+
+
+ /* Open the file */
+
+ TableFile = fopen (Filename, "rb");
+ if (TableFile == NULL)
+ {
+ fprintf (stderr, "Could not open table file: %s\n", Filename);
+ return (OslGetLastStatus (AE_NOT_FOUND));
+ }
+
+ fseek (TableFile, FileOffset, SEEK_SET);
+
+ /* Read the Table header to get the table length */
+
+ Count = fread (&Header, 1, sizeof (ACPI_TABLE_HEADER), TableFile);
+ if (Count != sizeof (ACPI_TABLE_HEADER))
+ {
+ fprintf (stderr, "Could not read table header: %s\n", Filename);
+ Status = AE_BAD_HEADER;
+ goto Exit;
+ }
+
+ /* If signature is specified, it must match the table */
+
+ if (Signature)
+ {
+ if (ACPI_VALIDATE_RSDP_SIG (Signature))
+ {
+ if (!ACPI_VALIDATE_RSDP_SIG (Header.Signature)) {
+ fprintf (stderr, "Incorrect RSDP signature: found %8.8s\n",
+ Header.Signature);
+ Status = AE_BAD_SIGNATURE;
+ goto Exit;
+ }
+ }
+ else if (!ACPI_COMPARE_NAME (Signature, Header.Signature))
+ {
+ fprintf (stderr, "Incorrect signature: Expecting %4.4s, found %4.4s\n",
+ Signature, Header.Signature);
+ Status = AE_BAD_SIGNATURE;
+ goto Exit;
+ }
+ }
+
+ TableLength = ApGetTableLength (&Header);
+ if (TableLength == 0)
+ {
+ Status = AE_BAD_HEADER;
+ goto Exit;
+ }
+
+ /* Read the entire table into a local buffer */
+
+ LocalTable = calloc (1, TableLength);
+ if (!LocalTable)
+ {
+ fprintf (stderr,
+ "%4.4s: Could not allocate buffer for table of length %X\n",
+ Header.Signature, TableLength);
+ Status = AE_NO_MEMORY;
+ goto Exit;
+ }
+
+ fseek (TableFile, FileOffset, SEEK_SET);
+
+ Count = fread (LocalTable, 1, TableLength, TableFile);
+ if (Count != TableLength)
+ {
+ fprintf (stderr, "%4.4s: Could not read table content\n",
+ Header.Signature);
+ Status = AE_INVALID_TABLE_LENGTH;
+ goto Exit;
+ }
+
+ /* Validate checksum */
+
+ (void) ApIsValidChecksum (LocalTable);
+
+Exit:
+ fclose (TableFile);
+ *Table = LocalTable;
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: OslGetAcpiTable
+ *
+ * PARAMETERS: Pathname - Directory to find Linux ACPI table
+ * Signature - ACPI Signature for desired table. Must be
+ * a null terminated 4-character string.
+ * Instance - Multiple table support for SSDT/UEFI (0...n)
+ * Must be 0 for other tables.
+ * Table - Where a pointer to the table is returned
+ * Address - Where the table physical address is returned
+ *
+ * RETURN: Status; Table buffer is returned if AE_OK.
+ * AE_LIMIT: Instance is beyond valid limit
+ * AE_NOT_FOUND: A table with the signature was not found
+ *
+ * DESCRIPTION: Get an OS ACPI table.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+OslGetAcpiTable (
+ char *Pathname,
+ char *Signature,
+ UINT32 Instance,
+ ACPI_TABLE_HEADER **Table,
+ ACPI_PHYSICAL_ADDRESS *Address)
+{
+ void *TableDir;
+ UINT32 CurrentInstance = 0;
+ char TempName[ACPI_NAME_SIZE];
+ char TableFilename[PATH_MAX];
+ char *Filename;
+ ACPI_STATUS Status;
+
+
+ /* Open the directory for ACPI tables */
+
+ TableDir = AcpiOsOpenDirectory (Pathname, "*", REQUEST_FILE_ONLY);
+ if (!TableDir)
+ {
+ return (OslGetLastStatus (AE_NOT_FOUND));
+ }
+
+ /* Attempt to find the table in the directory */
+
+ while ((Filename = AcpiOsGetNextFilename (TableDir)))
+ {
+ /* Ignore meaningless files */
+
+ if (!ACPI_COMPARE_NAME (Filename, Signature))
+ {
+ continue;
+ }
+
+ /* Extract table name and instance number */
+
+ Status = OslTableNameFromFile (Filename, TempName, &CurrentInstance);
+
+ /* Ignore meaningless files */
+
+ if (ACPI_FAILURE (Status) || CurrentInstance != Instance)
+ {
+ continue;
+ }
+
+ /* Create the table pathname */
+
+ if (Instance != 0)
+ {
+ sprintf (TableFilename, "%s/%4.4s%d", Pathname, TempName, Instance);
+ }
+ else
+ {
+ sprintf (TableFilename, "%s/%4.4s", Pathname, TempName);
+ }
+ break;
+ }
+
+ AcpiOsCloseDirectory (TableDir);
+
+ if (!Filename)
+ {
+ return (AE_LIMIT);
+ }
+
+ /* There is no physical address saved for ACPI tables, use zero */
+
+ *Address = 0;
+ Status = OslReadTableFromFile (TableFilename, 0, NULL, Table);
+
+ return (Status);
+}