diff --git a/generate/unix/Makefile.common b/generate/unix/Makefile.common index a0e26bab2c..21f8786cbb 100644 --- a/generate/unix/Makefile.common +++ b/generate/unix/Makefile.common @@ -12,11 +12,11 @@ HARDWARE_NAME := $(shell uname -m) # Main rule will only generate versions that are appropriate for the running # OS, either 64-bit or 32-bit. # -all: ${PROGS} -${PROGS}: FORCE +all: $(PROGS) +$(PROGS): FORCE @cd $(BUILD_DIRECTORY_PATH)/$@; \ mkdir -p obj; \ - make || exit "$$?"; \ + $(MAKE) || exit "$$?"; \ if [ $(findstring 64,$(HARDWARE_NAME)) ]; then \ echo "64-bit version of $@:"; \ else \ @@ -30,12 +30,12 @@ ${PROGS}: FORCE # in the local bin directory # clean: FORCE - @for toolname in ${PROGS}; do \ + @for toolname in $(PROGS); do \ (cd $(BUILD_DIRECTORY_PATH)/$$toolname; \ if [ -d "obj" ] ; then \ echo "Removing $$toolname:"; \ pwd; \ - make clean; \ + $(MAKE) clean; \ rmdir obj; \ echo ""; \ fi; \ @@ -46,12 +46,12 @@ clean: FORCE # Very clean removes all executables and the local bin directory # veryclean: FORCE - @for toolname in ${PROGS}; do \ + @for toolname in $(PROGS); do \ (cd $(BUILD_DIRECTORY_PATH)/$$toolname; \ if [ -d "obj" ] ; then \ echo "Removing $$toolname:"; \ pwd; \ - make clean; \ + $(MAKE) clean; \ rmdir obj; \ echo ""; \ fi; \ @@ -68,10 +68,10 @@ veryclean: FORCE # Install all tools, either 32-bit or 64-bit as appropriate for the host OS # install: FORCE - @for toolname in ${PROGS}; do \ + @for toolname in $(PROGS); do \ (cd $(BUILD_DIRECTORY_PATH)/$$toolname; \ pwd; \ - make PROG=$$toolname install; \ + $(MAKE) PROG=$$toolname install; \ if [ $(findstring 64,$(HARDWARE_NAME)) ]; then \ echo "Installed 64-bit version of $$toolname"; \ else \ diff --git a/generate/unix/Makefile.config b/generate/unix/Makefile.config index 390a4643d6..be485ad611 100644 --- a/generate/unix/Makefile.config +++ b/generate/unix/Makefile.config @@ -155,7 +155,6 @@ CWARNINGFLAGS += \ -Waddress\ -Waggregate-return\ -Wchar-subscripts\ - -Wempty-body\ -Wmissing-declarations\ -Wmissing-field-initializers\ -Wnested-externs\ @@ -165,6 +164,12 @@ CWARNINGFLAGS += \ # # Additional gcc 4+ flags # +ifeq ($(HOST), _FreeBSD) +CWARNINGFLAGS += \ + -Wno-format-nonliteral +else +CWARNINGFLAGS += \ + -Wempty-body ifneq ($(HOST), _APPLE) CWARNINGFLAGS += \ -Wlogical-op\ @@ -172,6 +177,7 @@ CWARNINGFLAGS += \ -Wold-style-declaration\ -Wtype-limits endif +endif # # Extra warning flags (for possible future use) diff --git a/generate/unix/acpidump/Makefile b/generate/unix/acpidump/Makefile index d113bc7838..1e7b114235 100644 --- a/generate/unix/acpidump/Makefile +++ b/generate/unix/acpidump/Makefile @@ -38,8 +38,14 @@ OBJECTS = \ $(OBJDIR)/utmath.o\ $(OBJDIR)/utstring.o\ $(OBJDIR)/utxferror.o\ - $(OBJDIR)/oslinuxtbl.o\ $(OBJDIR)/getopt.o +ifeq ($(HOST), _FreeBSD) +OBJECTS += \ + $(OBJDIR)/osfreebsdtbl.o +else +OBJECTS += \ + $(OBJDIR)/oslinuxtbl.o +endif # # Flags specific to acpidump diff --git a/generate/unix/iasl/Makefile b/generate/unix/iasl/Makefile index 931620a741..e9520edf4e 100644 --- a/generate/unix/iasl/Makefile +++ b/generate/unix/iasl/Makefile @@ -238,22 +238,22 @@ include ../Makefile.rules # Parser and Lexer - intermediate C files # $(OBJDIR)/aslcompilerlex.c : $(ASL_COMPILER)/aslcompiler.l $(ASL_COMPILER)/aslsupport.l - ${LEX} ${LFLAGS} -PAslCompiler -o$@ $(ASL_COMPILER)/aslcompiler.l + $(LEX) $(LFLAGS) -PAslCompiler -o$@ $(ASL_COMPILER)/aslcompiler.l $(OBJDIR)/aslcompilerparse.c $(OBJDIR)/aslcompilerparse.h : $(ASL_COMPILER)/aslcompiler.y - ${YACC} ${YFLAGS} -pAslCompiler -o$@ $? + $(YACC) $(YFLAGS) -pAslCompiler -o$@ $? $(OBJDIR)/dtparserlex.c : $(ASL_COMPILER)/dtparser.l - ${LEX} ${LFLAGS} -PDtParser -o$@ $? + $(LEX) $(LFLAGS) -PDtParser -o$@ $? $(OBJDIR)/dtparserparse.c $(OBJDIR)/dtparserparse.h : $(ASL_COMPILER)/dtparser.y - ${YACC} ${YFLAGS} -pDtParser -o$@ $? + $(YACC) $(YFLAGS) -pDtParser -o$@ $? $(OBJDIR)/prparserlex.c : $(ASL_COMPILER)/prparser.l - ${LEX} ${LFLAGS} -PPrParser -o$@ $? + $(LEX) $(LFLAGS) -PPrParser -o$@ $? $(OBJDIR)/prparserparse.c $(OBJDIR)/prparserparse.h : $(ASL_COMPILER)/prparser.y - ${YACC} ${YFLAGS} -pPrParser -o$@ $? + $(YACC) $(YFLAGS) -pPrParser -o$@ $? # diff --git a/source/components/debugger/dbcmds.c b/source/components/debugger/dbcmds.c index 0e1c49bad9..54ddf1a3c6 100644 --- a/source/components/debugger/dbcmds.c +++ b/source/components/debugger/dbcmds.c @@ -177,13 +177,15 @@ AcpiDbConvertToNode ( char *InString) { ACPI_NAMESPACE_NODE *Node; + ACPI_SIZE Address; if ((*InString >= 0x30) && (*InString <= 0x39)) { /* Numeric argument, convert */ - Node = ACPI_TO_POINTER (ACPI_STRTOUL (InString, NULL, 16)); + Address = ACPI_STRTOUL (InString, NULL, 16); + Node = ACPI_TO_POINTER (Address); if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE))) { AcpiOsPrintf ("Address %p is invalid in this address space\n", diff --git a/source/components/debugger/dbdisply.c b/source/components/debugger/dbdisply.c index a42a954bd1..832647d8ef 100644 --- a/source/components/debugger/dbdisply.c +++ b/source/components/debugger/dbdisply.c @@ -211,9 +211,11 @@ AcpiDbGetPointer ( void *Target) { void *ObjPtr; + ACPI_SIZE Address; - ObjPtr = ACPI_TO_POINTER (ACPI_STRTOUL (Target, NULL, 16)); + Address = ACPI_STRTOUL (Target, NULL, 16); + ObjPtr = ACPI_TO_POINTER (Address); return (ObjPtr); } diff --git a/source/components/debugger/dbnames.c b/source/components/debugger/dbnames.c index bc37388833..9fbe539530 100644 --- a/source/components/debugger/dbnames.c +++ b/source/components/debugger/dbnames.c @@ -855,11 +855,13 @@ AcpiDbFindReferences ( char *ObjectArg) { ACPI_OPERAND_OBJECT *ObjDesc; + ACPI_SIZE Address; /* Convert string to object pointer */ - ObjDesc = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16)); + Address = ACPI_STRTOUL (ObjectArg, NULL, 16); + ObjDesc = ACPI_TO_POINTER (Address); /* Search all nodes in namespace */ diff --git a/source/components/executer/exdump.c b/source/components/executer/exdump.c index cb9383184f..af788e2439 100644 --- a/source/components/executer/exdump.c +++ b/source/components/executer/exdump.c @@ -429,6 +429,7 @@ AcpiExDumpObject ( { UINT8 *Target; char *Name; + const char *ReferenceName; UINT8 Count; @@ -513,8 +514,8 @@ AcpiExDumpObject ( case ACPI_EXD_REFERENCE: - AcpiExOutString ("Class Name", - ACPI_CAST_PTR (char, AcpiUtGetReferenceName (ObjDesc))); + ReferenceName = AcpiUtGetReferenceName (ObjDesc); + AcpiExOutString ("Class Name", ACPI_CAST_PTR (char, ReferenceName)); AcpiExDumpReferenceObj (ObjDesc); break; diff --git a/source/components/namespace/nsxfname.c b/source/components/namespace/nsxfname.c index 0fa88cdd14..530d94ad1d 100644 --- a/source/components/namespace/nsxfname.c +++ b/source/components/namespace/nsxfname.c @@ -249,6 +249,7 @@ AcpiGetName ( { ACPI_STATUS Status; ACPI_NAMESPACE_NODE *Node; + char *NodeName; /* Parameter validation */ @@ -299,7 +300,8 @@ AcpiGetName ( /* Just copy the ACPI name from the Node and zero terminate it */ - ACPI_MOVE_NAME (Buffer->Pointer, AcpiUtGetNodeName (Node)); + NodeName = AcpiUtGetNodeName (Node); + ACPI_MOVE_NAME (Buffer->Pointer, NodeName); ((char *) Buffer->Pointer) [ACPI_NAME_SIZE] = 0; Status = AE_OK; diff --git a/source/os_specific/service_layers/osfreebsdtbl.c b/source/os_specific/service_layers/osfreebsdtbl.c new file mode 100644 index 0000000000..2d59b566f1 --- /dev/null +++ b/source/os_specific/service_layers/osfreebsdtbl.c @@ -0,0 +1,1087 @@ +/****************************************************************************** + * + * Module Name: osfreebsdtbl - FreeBSD OSL for obtaining ACPI tables + * + *****************************************************************************/ + +/****************************************************************************** + * + * 1. Copyright Notice + * + * Some or all of this work - Copyright (c) 1999 - 2013, Intel Corp. + * All rights reserved. + * + * 2. License + * + * 2.1. This is your license from Intel Corp. under its intellectual property + * rights. You may have additional license terms from the party that provided + * you this software, covering your right to use that party's intellectual + * property rights. + * + * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a + * copy of the source code appearing in this file ("Covered Code") an + * irrevocable, perpetual, worldwide license under Intel's copyrights in the + * base code distributed originally by Intel ("Original Intel Code") to copy, + * make derivatives, distribute, use and display any portion of the Covered + * Code in any form, with the right to sublicense such rights; and + * + * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent + * license (with the right to sublicense), under only those claims of Intel + * patents that are infringed by the Original Intel Code, to make, use, sell, + * offer to sell, and import the Covered Code and derivative works thereof + * solely to the minimum extent necessary to exercise the above copyright + * license, and in no event shall the patent license extend to any additions + * to or modifications of the Original Intel Code. No other license or right + * is granted directly or by implication, estoppel or otherwise; + * + * The above copyright and patent license is granted only if the following + * conditions are met: + * + * 3. Conditions + * + * 3.1. Redistribution of Source with Rights to Further Distribute Source. + * Redistribution of source code of any substantial portion of the Covered + * Code or modification with rights to further distribute source must include + * the above Copyright Notice, the above License, this list of Conditions, + * and the following Disclaimer and Export Compliance provision. In addition, + * Licensee must cause all Covered Code to which Licensee contributes to + * contain a file documenting the changes Licensee made to create that Covered + * Code and the date of any change. Licensee must include in that file the + * documentation of any changes made by any predecessor Licensee. Licensee + * must include a prominent statement that the modification is derived, + * directly or indirectly, from Original Intel Code. + * + * 3.2. Redistribution of Source with no Rights to Further Distribute Source. + * Redistribution of source code of any substantial portion of the Covered + * Code or modification without rights to further distribute source must + * include the following Disclaimer and Export Compliance provision in the + * documentation and/or other materials provided with distribution. In + * addition, Licensee may not authorize further sublicense of source of any + * portion of the Covered Code, and must include terms to the effect that the + * license from Licensee to its licensee is limited to the intellectual + * property embodied in the software Licensee provides to its licensee, and + * not to intellectual property embodied in modifications its licensee may + * make. + * + * 3.3. Redistribution of Executable. Redistribution in executable form of any + * substantial portion of the Covered Code or modification must reproduce the + * above Copyright Notice, and the following Disclaimer and Export Compliance + * provision in the documentation and/or other materials provided with the + * distribution. + * + * 3.4. Intel retains all right, title, and interest in and to the Original + * Intel Code. + * + * 3.5. Neither the name Intel nor any other trademark owned or controlled by + * Intel shall be used in advertising or otherwise to promote the sale, use or + * other dealings in products derived from or relating to the Covered Code + * without prior written authorization from Intel. + * + * 4. Disclaimer and Export Compliance + * + * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED + * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE + * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, + * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY + * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A + * PARTICULAR PURPOSE. + * + * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES + * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR + * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, + * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY + * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL + * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS + * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY + * LIMITED REMEDY. + * + * 4.3. Licensee shall not export, either directly or indirectly, any of this + * software or system incorporating such software without first obtaining any + * required license or other approval from the U. S. Department of Commerce or + * any other agency or department of the United States Government. In the + * event Licensee exports any such software from the United States or + * re-exports any such software from a foreign destination, Licensee shall + * ensure that the distribution and export/re-export of the software is in + * compliance with all laws, regulations, orders, or other restrictions of the + * U.S. Export Administration Regulations. Licensee agrees that neither it nor + * any of its subsidiaries will export/re-export any technical data, process, + * software, or service, directly or indirectly, to any country for which the + * United States government or any agency thereof requires an export license, + * other governmental approval, or letter of assurance, without first obtaining + * such license, approval or letter. + * + *****************************************************************************/ + +#include "acpidump.h" + +#include +#include +#include +#include +#include + + +#define _COMPONENT ACPI_OS_SERVICES + ACPI_MODULE_NAME ("osfreebsdtbl") + + +/* Local prototypes */ + +static ACPI_STATUS +OslTableInitialize ( + void); + +static ACPI_STATUS +OslMapTable ( + ACPI_SIZE Address, + char *Signature, + ACPI_TABLE_HEADER **Table); + +static ACPI_STATUS +OslAddTablesToList ( + void); + +static ACPI_STATUS +OslGetTableViaRoot ( + char *Signature, + UINT32 Instance, + ACPI_TABLE_HEADER **Table, + ACPI_PHYSICAL_ADDRESS *Address); + + +/* File locations */ + +#define SYSTEM_MEMORY "/dev/mem" + +/* Hints for RSDP */ + +#define SYSTEM_KENV "hint.acpi.0.rsdp" +#define SYSTEM_SYSCTL "machdep.acpi_root" + +/* Initialization flags */ + +UINT8 Gbl_TableListInitialized = FALSE; +UINT8 Gbl_MainTableObtained = FALSE; + +/* Local copies of main ACPI tables */ + +ACPI_TABLE_RSDP Gbl_Rsdp; +ACPI_TABLE_FADT *Gbl_Fadt; +ACPI_TABLE_RSDT *Gbl_Rsdt; +ACPI_TABLE_XSDT *Gbl_Xsdt; + +/* Fadt address */ + +ACPI_PHYSICAL_ADDRESS Gbl_FadtAddress; + +/* Revision of RSD PTR */ + +UINT8 Gbl_Revision; + +/* List of information about obtained ACPI tables */ + +typedef struct table_info +{ + struct table_info *Next; + char Signature[4]; + UINT32 Instance; + ACPI_PHYSICAL_ADDRESS Address; + +} OSL_TABLE_INFO; + +OSL_TABLE_INFO *Gbl_TableListHead = NULL; + + +/****************************************************************************** + * + * 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) +{ + ACPI_TABLE_HEADER *MappedTable; + ACPI_TABLE_HEADER *LocalTable; + ACPI_STATUS Status; + + + /* Validate the input physical address to avoid program crash */ + + if (Address < ACPI_HI_RSDP_WINDOW_BASE) + { + fprintf (stderr, "Invalid table address: 0x%8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (Address)); + return (AE_BAD_ADDRESS); + } + + /* Map the table and validate it */ + + Status = OslMapTable (Address, NULL, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* Copy table to local buffer and return it */ + + LocalTable = calloc (1, MappedTable->Length); + if (!LocalTable) + { + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (LocalTable, MappedTable, MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + + *Table = LocalTable; + return (AE_OK); +} + + +/****************************************************************************** + * + * 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; + + + /* Instance is only valid for SSDT/UEFI tables */ + + if (Instance && + !ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT) && + !ACPI_COMPARE_NAME (Signature, ACPI_SIG_UEFI)) + { + return (AE_LIMIT); + } + + /* Initialize main tables */ + + Status = OslTableInitialize (); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* + * If one of the main ACPI tables was requested (RSDT/XSDT/FADT), + * simply return it immediately. + */ + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_XSDT)) + { + if (!Gbl_Revision) + { + return (AE_NOT_FOUND); + } + + *Address = Gbl_Rsdp.XsdtPhysicalAddress; + *Table = (ACPI_TABLE_HEADER *) Gbl_Xsdt; + return (AE_OK); + } + + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDT)) + { + if (!Gbl_Rsdp.RsdtPhysicalAddress) + { + return (AE_NOT_FOUND); + } + + *Address = Gbl_Rsdp.RsdtPhysicalAddress; + *Table = (ACPI_TABLE_HEADER *) Gbl_Rsdt; + return (AE_OK); + } + + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FADT)) + { + *Address = Gbl_FadtAddress; + *Table = (ACPI_TABLE_HEADER *) Gbl_Fadt; + return (AE_OK); + } + + /* Not a main ACPI table, attempt to extract it from the RSDT/XSDT */ + + Status = OslGetTableViaRoot (Signature, Instance, Table, Address); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiOsGetTableByIndex + * + * PARAMETERS: Index - Which table to get + * 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: 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, + ACPI_PHYSICAL_ADDRESS *Address) +{ + OSL_TABLE_INFO *Info; + ACPI_STATUS Status; + UINT32 i; + + + /* Initialize main tables */ + + Status = OslTableInitialize (); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* Add all tables to list */ + + Status = OslAddTablesToList (); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* Validate Index */ + + if (Index >= Gbl_TableListHead->Instance) + { + 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 address or name */ + + if (Info->Address) + { + Status = AcpiOsGetTableByAddress (Info->Address, Table); + if (ACPI_SUCCESS (Status)) + { + *Address = Info->Address; + } + } + else + { + Status = AcpiOsGetTableByName (Info->Signature, Info->Instance, + Table, Address); + } + return (Status); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiOsMapMemory + * + * PARAMETERS: Where - Physical address of memory to be mapped + * Length - How much memory to map + * + * RETURN: Pointer to mapped memory. Null on error. + * + * DESCRIPTION: Map physical memory into local address space. + * + *****************************************************************************/ + +void * +AcpiOsMapMemory ( + ACPI_PHYSICAL_ADDRESS Where, + ACPI_SIZE Length) +{ + UINT8 *MappedMemory; + ACPI_PHYSICAL_ADDRESS Offset; + int fd; + + + fd = open (SYSTEM_MEMORY, O_RDONLY); + if (fd < 0) + { + fprintf (stderr, "Cannot open %s\n", SYSTEM_MEMORY); + return (NULL); + } + + /* Align the offset to use mmap */ + + Offset = Where % PAGE_SIZE; + + /* Map the table header to get the length of the full table */ + + MappedMemory = mmap (NULL, (Length + Offset), PROT_READ, MAP_SHARED, + fd, (Where - Offset)); + close (fd); + + if (MappedMemory == MAP_FAILED) + { + return (NULL); + } + + return (ACPI_CAST8 (MappedMemory + Offset)); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiOsUnmapMemory + * + * PARAMETERS: Where - Logical address of memory to be unmapped + * Length - How much memory to unmap + * + * RETURN: None. + * + * DESCRIPTION: Delete a previously created mapping. Where and Length must + * correspond to a previous mapping exactly. + * + *****************************************************************************/ + +void +AcpiOsUnmapMemory ( + void *Where, + ACPI_SIZE Length) +{ + ACPI_PHYSICAL_ADDRESS Offset; + + + Offset = (ACPI_PHYSICAL_ADDRESS) Where % PAGE_SIZE; + munmap ((UINT8 *) Where - Offset, (Length + Offset)); +} + + +/****************************************************************************** + * + * FUNCTION: OslTableInitialize + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to + * local variables. Main ACPI tables include RSDP, FADT, RSDT, + * and/or XSDT. + * + *****************************************************************************/ + +static ACPI_STATUS +OslTableInitialize ( + void) +{ + char Buffer[32]; + ACPI_TABLE_HEADER *MappedTable; + UINT8 *TableAddress; + UINT8 *RsdpAddress; + ACPI_PHYSICAL_ADDRESS RsdpBase; + ACPI_SIZE RsdpSize; + ACPI_STATUS Status; + u_long Address = 0; + size_t Length = sizeof (Address); + + + /* Get main ACPI tables from memory on first invocation of this function */ + + if (Gbl_MainTableObtained) + { + return (AE_OK); + } + + /* Attempt to use kenv or sysctl to find RSD PTR record. */ + + if (kenv (KENV_GET, SYSTEM_KENV, Buffer, sizeof (Buffer)) > 0) + { + Address = ACPI_STRTOUL (Buffer, NULL, 0); + } + if (!Address) + { + if (sysctlbyname (SYSTEM_SYSCTL, &Address, &Length, NULL, 0) != 0) + { + Address = 0; + } + } + if (Address) + { + RsdpBase = Address; + RsdpSize = sizeof (Gbl_Rsdp); + } + else + { + RsdpBase = ACPI_HI_RSDP_WINDOW_BASE; + RsdpSize = ACPI_HI_RSDP_WINDOW_SIZE; + } + + /* Get RSDP from memory */ + + RsdpAddress = AcpiOsMapMemory (RsdpBase, RsdpSize); + if (!RsdpAddress) + { + return (AE_ERROR); + } + + /* Search low memory for the RSDP */ + + TableAddress = AcpiTbScanMemoryForRsdp (RsdpAddress, RsdpSize); + MappedTable = ACPI_CAST_PTR (ACPI_TABLE_HEADER, TableAddress); + if (!MappedTable) + { + AcpiOsUnmapMemory (RsdpAddress, RsdpSize); + return (AE_ERROR); + } + + ACPI_MEMCPY (&Gbl_Rsdp, MappedTable, sizeof (Gbl_Rsdp)); + AcpiOsUnmapMemory (RsdpAddress, RsdpSize); + + /* Get XSDT from memory */ + + if (Gbl_Rsdp.Revision) + { + Status = OslMapTable (Gbl_Rsdp.XsdtPhysicalAddress, + ACPI_SIG_XSDT, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Gbl_Revision = 2; + Gbl_Xsdt = calloc (1, MappedTable->Length); + if (!Gbl_Xsdt) + { + fprintf (stderr, + "XSDT: Could not allocate buffer for table of length %X\n", + MappedTable->Length); + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (Gbl_Xsdt, MappedTable, MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + } + + /* Get RSDT from memory */ + + if (Gbl_Rsdp.RsdtPhysicalAddress) + { + Status = OslMapTable (Gbl_Rsdp.RsdtPhysicalAddress, + ACPI_SIG_RSDT, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Gbl_Rsdt = calloc (1, MappedTable->Length); + if (!Gbl_Rsdt) + { + fprintf (stderr, + "RSDT: Could not allocate buffer for table of length %X\n", + MappedTable->Length); + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (Gbl_Rsdt, MappedTable, MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + } + + /* Get FADT from memory */ + + if (Gbl_Revision) + { + Gbl_FadtAddress = Gbl_Xsdt->TableOffsetEntry[0]; + } + else + { + Gbl_FadtAddress = Gbl_Rsdt->TableOffsetEntry[0]; + } + + if (!Gbl_FadtAddress) + { + fprintf(stderr, "FADT: Table could not be found\n"); + return (AE_ERROR); + } + + Status = OslMapTable (Gbl_FadtAddress, ACPI_SIG_FADT, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Gbl_Fadt = calloc (1, MappedTable->Length); + if (!Gbl_Fadt) + { + fprintf (stderr, + "FADT: Could not allocate buffer for table of length %X\n", + MappedTable->Length); + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (Gbl_Fadt, MappedTable, MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + Gbl_MainTableObtained = TRUE; + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: OslGetTableViaRoot + * + * PARAMETERS: Signature - ACPI Signature for common 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 + * + * DESCRIPTION: Get an ACPI table via the root table (RSDT/XSDT) + * + * NOTE: Assumes the input signature is uppercase. + * + *****************************************************************************/ + +static ACPI_STATUS +OslGetTableViaRoot ( + char *Signature, + UINT32 Instance, + ACPI_TABLE_HEADER **Table, + ACPI_PHYSICAL_ADDRESS *Address) +{ + ACPI_TABLE_HEADER *LocalTable = NULL; + ACPI_TABLE_HEADER *MappedTable = NULL; + UINT8 NumberOfTables; + UINT32 CurrentInstance = 0; + ACPI_PHYSICAL_ADDRESS TableAddress = 0; + ACPI_STATUS Status; + UINT32 i; + + + /* DSDT and FACS address must be extracted from the FADT */ + + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT) || + ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) + { + /* + * Get the appropriate address, either 32-bit or 64-bit. Be very + * careful about the FADT length and validate table addresses. + * Note: The 64-bit addresses have priority. + */ + if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT)) + { + if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XDSDT) && + Gbl_Fadt->XDsdt) + { + TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XDsdt; + } + else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_DSDT) && + Gbl_Fadt->Dsdt) + { + TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Dsdt; + } + } + else /* FACS */ + { + if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XFACS) && + Gbl_Fadt->XFacs) + { + TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XFacs; + } + else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_FACS) && + Gbl_Fadt->Facs) + { + TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Facs; + } + } + + if (!TableAddress) + { + fprintf (stderr, + "Could not find a valid address for %4.4s in the FADT\n", + Signature); + + return (AE_NOT_FOUND); + } + + /* Now we can get the requested table (DSDT or FACS) */ + + Status = OslMapTable (TableAddress, Signature, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + } + else /* Case for a normal ACPI table */ + { + if (Gbl_Revision) + { + NumberOfTables = + (Gbl_Xsdt->Header.Length - sizeof (Gbl_Xsdt->Header)) + / sizeof (Gbl_Xsdt->TableOffsetEntry[0]); + } + else /* Use RSDT if XSDT is not available */ + { + NumberOfTables = + (Gbl_Rsdt->Header.Length - sizeof (Gbl_Rsdt->Header)) + / sizeof (Gbl_Rsdt->TableOffsetEntry[0]); + } + + /* Search RSDT/XSDT for the requested table */ + + for (i = 0; i < NumberOfTables; i++) + { + if (Gbl_Revision) + { + TableAddress = Gbl_Xsdt->TableOffsetEntry[i]; + } + else + { + TableAddress = Gbl_Rsdt->TableOffsetEntry[i]; + } + + Status = OslMapTable (TableAddress, NULL, &MappedTable); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* Does this table match the requested signature? */ + + if (!ACPI_COMPARE_NAME (MappedTable->Signature, Signature)) + { + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + MappedTable = NULL; + continue; + } + + /* Match table instance (for SSDT/UEFI tables) */ + + if (CurrentInstance != Instance) + { + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + MappedTable = NULL; + CurrentInstance++; + continue; + } + + break; + } + } + + if (CurrentInstance != Instance) + { + return (AE_LIMIT); + } + + if (!MappedTable) + { + return (AE_NOT_FOUND); + } + + /* Copy table to local buffer and return it */ + + LocalTable = calloc (1, MappedTable->Length); + if (!LocalTable) + { + return (AE_NO_MEMORY); + } + + ACPI_MEMCPY (LocalTable, MappedTable, MappedTable->Length); + AcpiOsUnmapMemory (MappedTable, MappedTable->Length); + *Address = TableAddress; + + *Table = LocalTable; + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: OslAddTablesToList + * + * PARAMETERS: None + * + * RETURN: Status; Table list is initialized if AE_OK. + * + * DESCRIPTION: Add ACPI tables to the table list. + * + *****************************************************************************/ + +static ACPI_STATUS +OslAddTablesToList( + void) +{ + ACPI_PHYSICAL_ADDRESS TableAddress; + OSL_TABLE_INFO *Info = NULL; + OSL_TABLE_INFO *NewInfo; + ACPI_TABLE_HEADER *Table; + UINT8 Instance; + UINT8 NumberOfTables; + int i; + + + /* Initialize the table list on first invocation */ + + if (Gbl_TableListInitialized) + { + return (AE_OK); + } + + /* Add mandatory tables to global table list first */ + + for (i = 0; i < 4; i++) + { + NewInfo = calloc (1, sizeof (*NewInfo)); + if (!NewInfo) + { + return (AE_NO_MEMORY); + } + + switch (i) { + case 0: + + Gbl_TableListHead = Info = NewInfo; + continue; + + case 1: + + ACPI_MOVE_NAME (NewInfo->Signature, + Gbl_Revision ? ACPI_SIG_XSDT : ACPI_SIG_RSDT); + break; + + case 2: + + ACPI_MOVE_NAME (NewInfo->Signature, ACPI_SIG_FACS); + break; + + default: + + ACPI_MOVE_NAME (NewInfo->Signature, ACPI_SIG_DSDT); + + } + + Info->Next = NewInfo; + Info = NewInfo; + Gbl_TableListHead->Instance++; + } + + /* Add normal tables from RSDT/XSDT to global list */ + + if (Gbl_Revision) + { + NumberOfTables = + (Gbl_Xsdt->Header.Length - sizeof (Gbl_Xsdt->Header)) + / sizeof (Gbl_Xsdt->TableOffsetEntry[0]); + } + else + { + NumberOfTables = + (Gbl_Rsdt->Header.Length - sizeof (Gbl_Rsdt->Header)) + / sizeof (Gbl_Rsdt->TableOffsetEntry[0]); + } + + for (i = 0; i < NumberOfTables; i++) + { + if (Gbl_Revision) + { + TableAddress = Gbl_Xsdt->TableOffsetEntry[i]; + } + else + { + TableAddress = Gbl_Rsdt->TableOffsetEntry[i]; + } + + Table = AcpiOsMapMemory (TableAddress, sizeof (*Table)); + if (!Table) + { + return (AE_NO_MEMORY); + } + + Instance = 0; + NewInfo = Gbl_TableListHead; + while (NewInfo->Next != NULL) + { + NewInfo = NewInfo->Next; + if (ACPI_COMPARE_NAME (Table->Signature, NewInfo->Signature)) + { + Instance++; + } + } + + NewInfo = calloc (1, sizeof (*NewInfo)); + if (!NewInfo) + { + AcpiOsUnmapMemory (Table, sizeof (*Table)); + return (AE_NO_MEMORY); + } + + ACPI_MOVE_NAME (NewInfo->Signature, Table->Signature); + + AcpiOsUnmapMemory (Table, sizeof (*Table)); + + NewInfo->Instance = Instance; + NewInfo->Address = TableAddress; + Info->Next = NewInfo; + Info = NewInfo; + Gbl_TableListHead->Instance++; + } + + Gbl_TableListInitialized = TRUE; + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: OslMapTable + * + * PARAMETERS: Address - Address of the table in memory + * Signature - Optional ACPI Signature for desired table. + * Null terminated 4-character string. + * Table - Where a pointer to the mapped table is + * returned + * + * RETURN: Status; Mapped table is returned if AE_OK. + * + * DESCRIPTION: Map entire ACPI table into caller's address space. Also + * validates the table and checksum. + * + *****************************************************************************/ + +static ACPI_STATUS +OslMapTable ( + ACPI_SIZE Address, + char *Signature, + ACPI_TABLE_HEADER **Table) +{ + ACPI_TABLE_HEADER *MappedTable; + UINT32 Length; + + + /* Map the header so we can get the table length */ + + MappedTable = AcpiOsMapMemory (Address, sizeof (*MappedTable)); + if (!MappedTable) + { + fprintf (stderr, "Could not map table header at 0x%8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (Address)); + return (AE_BAD_ADDRESS); + } + + /* Check if table is valid */ + + if (!ApIsValidHeader (MappedTable)) + { + return (AE_BAD_HEADER); + } + + /* If specified, signature must match */ + + if (Signature && + !ACPI_COMPARE_NAME (Signature, MappedTable->Signature)) + { + return (AE_NOT_EXIST); + } + + /* Map the entire table */ + + Length = MappedTable->Length; + AcpiOsUnmapMemory (MappedTable, sizeof (*MappedTable)); + + MappedTable = AcpiOsMapMemory (Address, Length); + if (!MappedTable) + { + fprintf (stderr, "Could not map table at 0x%8.8X%8.8X length %8.8X\n", + ACPI_FORMAT_UINT64 (Address), Length); + return (AE_NO_MEMORY); + } + + *Table = MappedTable; + + /* Checksum for RSDP */ + + if (!ACPI_STRNCMP (MappedTable->Signature, ACPI_SIG_RSDP, + sizeof (ACPI_SIG_RSDP) - 1)) + { + /* Check the standard checksum */ + + if (AcpiTbChecksum ((UINT8 *) MappedTable, ACPI_RSDP_CHECKSUM_LENGTH)) + { + fprintf (stderr, "Warning: wrong checksum for RSDP\n"); + } + + /* Check extended checksum if table version >= 2 */ + + if (MappedTable->Revision) + { + if (AcpiTbChecksum ((UINT8 *) MappedTable, + ACPI_RSDP_XCHECKSUM_LENGTH)) + { + fprintf (stderr, "Warning: wrong checksum for RSDP\n"); + } + } + } + + /* FACS does not have a checksum */ + + if (ACPI_COMPARE_NAME (MappedTable->Signature, ACPI_SIG_FACS)) + { + return (AE_OK); + } + + /* Validate checksum for most tables */ + + if (AcpiTbChecksum (ACPI_CAST8 (MappedTable), Length)) + { + fprintf (stderr, "Warning: wrong checksum for %4.4s\n", + MappedTable->Signature); + } + + return (AE_OK); +}