Blob Blame Raw
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);
+}