# # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # Copyright 2020 Joyent, Inc. # Copyright 2016 RackTop Systems. # PROG= acpidump include ../../Makefile.cmd include ../../Makefile.ctf OBJS= apmain.o apdump.o apfiles.o getopt.o tbprint.o tbxfroot.o osillumostbl.o \ utascii.o utbuffer.o utdebug.o utexcep.o utmath.o utnonansi.o \ utxferror.o utglobal.o osunixdir.o osl.o osunixxf.o \ uthex.o utstrsuppt.o utstrtoul64.o SRCS = $(OBJS:.o=.c) VPATH = ../common:$(SRC)/common/acpica/utilities:$(SRC)/common/acpica/tables CERRWARN += -Wno-unused-function SMOFF = all_func_returns CPPFLAGS += -I$(SRC)/uts/intel/sys/acpi -DACPI_DUMP_APP CPPFLAGS += -DACPI_DATE=\"`$(ECHO) $(VERSION) | sed -e 's/ /_/g'`\" LDLIBS += -ldevinfo .KEEP_STATE: all: $(PROG) $(PROG): $(OBJS) $(LINK.c) -o $@ $(OBJS) $(LDLIBS) $(POST_PROCESS) install: all $(ROOTUSRSBINPROG) clean: $(RM) $(OBJS) $(PROG) lint: lint_SRCS include ../../Makefile.targ /****************************************************************************** * * Module Name: acpidump.h - Include file for AcpiDump utility * *****************************************************************************/ /****************************************************************************** * * 1. Copyright Notice * * Some or all of this work - Copyright (c) 1999 - 2018, 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. * ***************************************************************************** * * Alternatively, you may choose to be licensed under the terms of the * following license: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * substantially similar to the "NO WARRANTY" disclaimer below * ("Disclaimer") and any redistribution must be conditioned upon * including a substantially similar Disclaimer requirement for further * binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, you may choose to be licensed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * *****************************************************************************/ /* * Global variables. Defined in main.c only, externed in all other files */ #ifdef _DECLARE_GLOBALS #define EXTERN #define INIT_GLOBAL(a,b) a=b #else #define EXTERN extern #define INIT_GLOBAL(a,b) a #endif #include "acpi.h" #include "accommon.h" #include "actables.h" #include "acapps.h" /* Globals */ EXTERN BOOLEAN INIT_GLOBAL (Gbl_SummaryMode, FALSE); EXTERN BOOLEAN INIT_GLOBAL (Gbl_VerboseMode, FALSE); EXTERN BOOLEAN INIT_GLOBAL (Gbl_BinaryMode, FALSE); EXTERN BOOLEAN INIT_GLOBAL (Gbl_DumpCustomizedTables, TRUE); EXTERN BOOLEAN INIT_GLOBAL (Gbl_DoNotDumpXsdt, FALSE); EXTERN ACPI_FILE INIT_GLOBAL (Gbl_OutputFile, NULL); EXTERN char INIT_GLOBAL (*Gbl_OutputFilename, NULL); EXTERN UINT64 INIT_GLOBAL (Gbl_RsdpBase, 0); /* Action table used to defer requested options */ typedef struct ap_dump_action { char *Argument; UINT32 ToBeDone; } AP_DUMP_ACTION; #define AP_MAX_ACTIONS 32 #define AP_DUMP_ALL_TABLES 0 #define AP_DUMP_TABLE_BY_ADDRESS 1 #define AP_DUMP_TABLE_BY_NAME 2 #define AP_DUMP_TABLE_BY_FILE 3 #define AP_MAX_ACPI_FILES 256 /* Prevent infinite loops */ /* Minimum FADT sizes for various table addresses */ #define MIN_FADT_FOR_DSDT (ACPI_FADT_OFFSET (Dsdt) + sizeof (UINT32)) #define MIN_FADT_FOR_FACS (ACPI_FADT_OFFSET (Facs) + sizeof (UINT32)) #define MIN_FADT_FOR_XDSDT (ACPI_FADT_OFFSET (XDsdt) + sizeof (UINT64)) #define MIN_FADT_FOR_XFACS (ACPI_FADT_OFFSET (XFacs) + sizeof (UINT64)) /* * apdump - Table get/dump routines */ int ApDumpTableFromFile ( char *Pathname); int ApDumpTableByName ( char *Signature); int ApDumpTableByAddress ( char *AsciiAddress); int ApDumpAllTables ( void); BOOLEAN ApIsValidHeader ( ACPI_TABLE_HEADER *Table); BOOLEAN ApIsValidChecksum ( ACPI_TABLE_HEADER *Table); UINT32 ApGetTableLength ( ACPI_TABLE_HEADER *Table); /* * apfiles - File I/O utilities */ int ApOpenOutputFile ( char *Pathname); int ApWriteToBinaryFile ( ACPI_TABLE_HEADER *Table, UINT32 Instance); ACPI_TABLE_HEADER * ApGetTableFromFile ( char *Pathname, UINT32 *FileSize); /****************************************************************************** * * Module Name: apdump - Dump routines for ACPI tables (acpidump) * *****************************************************************************/ /****************************************************************************** * * 1. Copyright Notice * * Some or all of this work - Copyright (c) 1999 - 2018, 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. * ***************************************************************************** * * Alternatively, you may choose to be licensed under the terms of the * following license: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * substantially similar to the "NO WARRANTY" disclaimer below * ("Disclaimer") and any redistribution must be conditioned upon * including a substantially similar Disclaimer requirement for further * binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, you may choose to be licensed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * *****************************************************************************/ #include "acpidump.h" /* Local prototypes */ static int ApDumpTableBuffer ( ACPI_TABLE_HEADER *Table, UINT32 Instance, ACPI_PHYSICAL_ADDRESS Address); /****************************************************************************** * * FUNCTION: ApIsValidHeader * * PARAMETERS: Table - Pointer to table to be validated * * RETURN: TRUE if the header appears to be valid. FALSE otherwise * * DESCRIPTION: Check for a valid ACPI table header * ******************************************************************************/ BOOLEAN ApIsValidHeader ( ACPI_TABLE_HEADER *Table) { if (!ACPI_VALIDATE_RSDP_SIG (Table->Signature)) { /* Make sure signature is all ASCII and a valid ACPI name */ if (!AcpiUtValidNameseg (Table->Signature)) { fprintf (stderr, "Table signature (0x%8.8X) is invalid\n", *(UINT32 *) Table->Signature); return (FALSE); } /* Check for minimum table length */ if (Table->Length < sizeof (ACPI_TABLE_HEADER)) { fprintf (stderr, "Table length (0x%8.8X) is invalid\n", Table->Length); return (FALSE); } } return (TRUE); } /****************************************************************************** * * FUNCTION: ApIsValidChecksum * * PARAMETERS: Table - Pointer to table to be validated * * RETURN: TRUE if the checksum appears to be valid. FALSE otherwise. * * DESCRIPTION: Check for a valid ACPI table checksum. * ******************************************************************************/ BOOLEAN ApIsValidChecksum ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; ACPI_TABLE_RSDP *Rsdp; if (ACPI_VALIDATE_RSDP_SIG (Table->Signature)) { /* * Checksum for RSDP. * Note: Other checksums are computed during the table dump. */ Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table); Status = AcpiTbValidateRsdp (Rsdp); } else { Status = AcpiTbVerifyChecksum (Table, Table->Length); } if (ACPI_FAILURE (Status)) { fprintf (stderr, "%4.4s: Warning: wrong checksum in table\n", Table->Signature); } return (AE_OK); } /****************************************************************************** * * FUNCTION: ApGetTableLength * * PARAMETERS: Table - Pointer to the table * * RETURN: Table length * * DESCRIPTION: Obtain table length according to table signature. * ******************************************************************************/ UINT32 ApGetTableLength ( ACPI_TABLE_HEADER *Table) { ACPI_TABLE_RSDP *Rsdp; /* Check if table is valid */ if (!ApIsValidHeader (Table)) { return (0); } if (ACPI_VALIDATE_RSDP_SIG (Table->Signature)) { Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table); return (AcpiTbGetRsdpLength (Rsdp)); } /* Normal ACPI table */ return (Table->Length); } /****************************************************************************** * * FUNCTION: ApDumpTableBuffer * * PARAMETERS: Table - ACPI table to be dumped * Instance - ACPI table instance no. to be dumped * Address - Physical address of the table * * RETURN: None * * DESCRIPTION: Dump an ACPI table in standard ASCII hex format, with a * header that is compatible with the AcpiXtract utility. * ******************************************************************************/ static int ApDumpTableBuffer ( ACPI_TABLE_HEADER *Table, UINT32 Instance, ACPI_PHYSICAL_ADDRESS Address) { UINT32 TableLength; TableLength = ApGetTableLength (Table); /* Print only the header if requested */ if (Gbl_SummaryMode) { AcpiTbPrintTableHeader (Address, Table); return (0); } /* Dump to binary file if requested */ if (Gbl_BinaryMode) { return (ApWriteToBinaryFile (Table, Instance)); } /* * Dump the table with header for use with acpixtract utility. * Note: simplest to just always emit a 64-bit address. AcpiXtract * utility can handle this. */ fprintf (Gbl_OutputFile, "%4.4s @ 0x%8.8X%8.8X\n", Table->Signature, ACPI_FORMAT_UINT64 (Address)); AcpiUtDumpBufferToFile (Gbl_OutputFile, ACPI_CAST_PTR (UINT8, Table), TableLength, DB_BYTE_DISPLAY, 0); fprintf (Gbl_OutputFile, "\n"); return (0); } /****************************************************************************** * * FUNCTION: ApDumpAllTables * * PARAMETERS: None * * RETURN: Status * * DESCRIPTION: Get all tables from the RSDT/XSDT (or at least all of the * tables that we can possibly get). * ******************************************************************************/ int ApDumpAllTables ( void) { ACPI_TABLE_HEADER *Table; UINT32 Instance = 0; ACPI_PHYSICAL_ADDRESS Address; ACPI_STATUS Status; int TableStatus; UINT32 i; /* Get and dump all available ACPI tables */ for (i = 0; i < AP_MAX_ACPI_FILES; i++) { Status = AcpiOsGetTableByIndex (i, &Table, &Instance, &Address); if (ACPI_FAILURE (Status)) { /* AE_LIMIT means that no more tables are available */ if (Status == AE_LIMIT) { return (0); } else if (i == 0) { fprintf (stderr, "Could not get ACPI tables, %s\n", AcpiFormatException (Status)); return (-1); } else { fprintf (stderr, "Could not get ACPI table at index %u, %s\n", i, AcpiFormatException (Status)); continue; } } TableStatus = ApDumpTableBuffer (Table, Instance, Address); ACPI_FREE (Table); if (TableStatus) { break; } } /* Something seriously bad happened if the loop terminates here */ return (-1); } /****************************************************************************** * * FUNCTION: ApDumpTableByAddress * * PARAMETERS: AsciiAddress - Address for requested ACPI table * * RETURN: Status * * DESCRIPTION: Get an ACPI table via a physical address and dump it. * ******************************************************************************/ int ApDumpTableByAddress ( char *AsciiAddress) { ACPI_PHYSICAL_ADDRESS Address; ACPI_TABLE_HEADER *Table; ACPI_STATUS Status; int TableStatus; UINT64 LongAddress; /* Convert argument to an integer physical address */ Status = AcpiUtStrtoul64 (AsciiAddress, &LongAddress); if (ACPI_FAILURE (Status)) { fprintf (stderr, "%s: Could not convert to a physical address\n", AsciiAddress); return (-1); } Address = (ACPI_PHYSICAL_ADDRESS) LongAddress; Status = AcpiOsGetTableByAddress (Address, &Table); if (ACPI_FAILURE (Status)) { fprintf (stderr, "Could not get table at 0x%8.8X%8.8X, %s\n", ACPI_FORMAT_UINT64 (Address), AcpiFormatException (Status)); return (-1); } TableStatus = ApDumpTableBuffer (Table, 0, Address); ACPI_FREE (Table); return (TableStatus); } /****************************************************************************** * * FUNCTION: ApDumpTableByName * * PARAMETERS: Signature - Requested ACPI table signature * * RETURN: Status * * DESCRIPTION: Get an ACPI table via a signature and dump it. Handles * multiple tables with the same signature (SSDTs). * ******************************************************************************/ int ApDumpTableByName ( char *Signature) { char LocalSignature [ACPI_NAME_SIZE + 1]; UINT32 Instance; ACPI_TABLE_HEADER *Table; ACPI_PHYSICAL_ADDRESS Address; ACPI_STATUS Status; int TableStatus; if (strlen (Signature) != ACPI_NAME_SIZE) { fprintf (stderr, "Invalid table signature [%s]: must be exactly 4 characters\n", Signature); return (-1); } /* Table signatures are expected to be uppercase */ strcpy (LocalSignature, Signature); AcpiUtStrupr (LocalSignature); /* To be friendly, handle tables whose signatures do not match the name */ if (ACPI_COMPARE_NAME (LocalSignature, "FADT")) { strcpy (LocalSignature, ACPI_SIG_FADT); } else if (ACPI_COMPARE_NAME (LocalSignature, "MADT")) { strcpy (LocalSignature, ACPI_SIG_MADT); } /* Dump all instances of this signature (to handle multiple SSDTs) */ for (Instance = 0; Instance < AP_MAX_ACPI_FILES; Instance++) { Status = AcpiOsGetTableByName (LocalSignature, Instance, &Table, &Address); if (ACPI_FAILURE (Status)) { /* AE_LIMIT means that no more tables are available */ if (Status == AE_LIMIT) { return (0); } fprintf (stderr, "Could not get ACPI table with signature [%s], %s\n", LocalSignature, AcpiFormatException (Status)); return (-1); } TableStatus = ApDumpTableBuffer (Table, Instance, Address); ACPI_FREE (Table); if (TableStatus) { break; } } /* Something seriously bad happened if the loop terminates here */ return (-1); } /****************************************************************************** * * FUNCTION: ApDumpTableFromFile * * PARAMETERS: Pathname - File containing the binary ACPI table * * RETURN: Status * * DESCRIPTION: Dump an ACPI table from a binary file * ******************************************************************************/ int ApDumpTableFromFile ( char *Pathname) { ACPI_TABLE_HEADER *Table; UINT32 FileSize = 0; int TableStatus = -1; /* Get the entire ACPI table from the file */ Table = ApGetTableFromFile (Pathname, &FileSize); if (!Table) { return (-1); } if (!AcpiUtValidNameseg (Table->Signature)) { fprintf (stderr, "No valid ACPI signature was found in input file %s\n", Pathname); } /* File must be at least as long as the table length */ if (Table->Length > FileSize) { fprintf (stderr, "Table length (0x%X) is too large for input file (0x%X) %s\n", Table->Length, FileSize, Pathname); goto Exit; } if (Gbl_VerboseMode) { fprintf (stderr, "Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n", Pathname, Table->Signature, FileSize, FileSize); } TableStatus = ApDumpTableBuffer (Table, 0, 0); Exit: ACPI_FREE (Table); return (TableStatus); } /****************************************************************************** * * Module Name: apfiles - File-related functions for acpidump utility * *****************************************************************************/ /****************************************************************************** * * 1. Copyright Notice * * Some or all of this work - Copyright (c) 1999 - 2018, 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. * ***************************************************************************** * * Alternatively, you may choose to be licensed under the terms of the * following license: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * substantially similar to the "NO WARRANTY" disclaimer below * ("Disclaimer") and any redistribution must be conditioned upon * including a substantially similar Disclaimer requirement for further * binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, you may choose to be licensed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * *****************************************************************************/ #include "acpidump.h" /* Local prototypes */ static int ApIsExistingFile ( char *Pathname); /****************************************************************************** * * FUNCTION: ApIsExistingFile * * PARAMETERS: Pathname - Output filename * * RETURN: 0 on success * * DESCRIPTION: Query for file overwrite if it already exists. * ******************************************************************************/ static int ApIsExistingFile ( char *Pathname) { #if !defined(_GNU_EFI) && !defined(_EDK2_EFI) struct stat StatInfo; if (!stat (Pathname, &StatInfo)) { fprintf (stderr, "Target path already exists, overwrite? [y|n] "); if (getchar () != 'y') { return (-1); } } #endif return 0; } /****************************************************************************** * * FUNCTION: ApOpenOutputFile * * PARAMETERS: Pathname - Output filename * * RETURN: Open file handle * * DESCRIPTION: Open a text output file for acpidump. Checks if file already * exists. * ******************************************************************************/ int ApOpenOutputFile ( char *Pathname) { ACPI_FILE File; /* If file exists, prompt for overwrite */ if (ApIsExistingFile (Pathname) != 0) { return (-1); } /* Point stdout to the file */ File = fopen (Pathname, "w"); if (!File) { fprintf (stderr, "Could not open output file: %s\n", Pathname); return (-1); } /* Save the file and path */ Gbl_OutputFile = File; Gbl_OutputFilename = Pathname; return (0); } /****************************************************************************** * * FUNCTION: ApWriteToBinaryFile * * PARAMETERS: Table - ACPI table to be written * Instance - ACPI table instance no. to be written * * RETURN: Status * * DESCRIPTION: Write an ACPI table to a binary file. Builds the output * filename from the table signature. * ******************************************************************************/ int ApWriteToBinaryFile ( ACPI_TABLE_HEADER *Table, UINT32 Instance) { char Filename[ACPI_NAME_SIZE + 16]; char InstanceStr [16]; ACPI_FILE File; ACPI_SIZE Actual; UINT32 TableLength; /* Obtain table length */ TableLength = ApGetTableLength (Table); /* Construct lower-case filename from the table local signature */ if (ACPI_VALIDATE_RSDP_SIG (Table->Signature)) { ACPI_MOVE_NAME (Filename, ACPI_RSDP_NAME); } else { ACPI_MOVE_NAME (Filename, Table->Signature); } Filename[0] = (char) tolower ((int) Filename[0]); Filename[1] = (char) tolower ((int) Filename[1]); Filename[2] = (char) tolower ((int) Filename[2]); Filename[3] = (char) tolower ((int) Filename[3]); Filename[ACPI_NAME_SIZE] = 0; /* Handle multiple SSDTs - create different filenames for each */ if (Instance > 0) { snprintf (InstanceStr, sizeof (InstanceStr), "%u", Instance); strcat (Filename, InstanceStr); } strcat (Filename, FILE_SUFFIX_BINARY_TABLE); if (Gbl_VerboseMode) { fprintf (stderr, "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n", Table->Signature, Filename, Table->Length, Table->Length); } /* Open the file and dump the entire table in binary mode */ File = fopen (Filename, "wb"); if (!File) { fprintf (stderr, "Could not open output file: %s\n", Filename); return (-1); } Actual = fwrite (Table, 1, TableLength, File); if (Actual != TableLength) { fprintf (stderr, "Error writing binary output file: %s\n", Filename); fclose (File); return (-1); } fclose (File); return (0); } /****************************************************************************** * * FUNCTION: ApGetTableFromFile * * PARAMETERS: Pathname - File containing the binary ACPI table * OutFileSize - Where the file size is returned * * RETURN: Buffer containing the ACPI table. NULL on error. * * DESCRIPTION: Open a file and read it entirely into a new buffer * ******************************************************************************/ ACPI_TABLE_HEADER * ApGetTableFromFile ( char *Pathname, UINT32 *OutFileSize) { ACPI_TABLE_HEADER *Buffer = NULL; ACPI_FILE File; UINT32 FileSize; ACPI_SIZE Actual; /* Must use binary mode */ File = fopen (Pathname, "rb"); if (!File) { fprintf (stderr, "Could not open input file: %s\n", Pathname); return (NULL); } /* Need file size to allocate a buffer */ FileSize = CmGetFileSize (File); if (FileSize == ACPI_UINT32_MAX) { fprintf (stderr, "Could not get input file size: %s\n", Pathname); goto Cleanup; } /* Allocate a buffer for the entire file */ Buffer = ACPI_ALLOCATE_ZEROED (FileSize); if (!Buffer) { fprintf (stderr, "Could not allocate file buffer of size: %u\n", FileSize); goto Cleanup; } /* Read the entire file */ Actual = fread (Buffer, 1, FileSize, File); if (Actual != FileSize) { fprintf (stderr, "Could not read input file: %s\n", Pathname); ACPI_FREE (Buffer); Buffer = NULL; goto Cleanup; } *OutFileSize = FileSize; Cleanup: fclose (File); return (Buffer); } /****************************************************************************** * * Module Name: apmain - Main module for the acpidump utility * *****************************************************************************/ /****************************************************************************** * * 1. Copyright Notice * * Some or all of this work - Copyright (c) 1999 - 2018, 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. * ***************************************************************************** * * Alternatively, you may choose to be licensed under the terms of the * following license: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * substantially similar to the "NO WARRANTY" disclaimer below * ("Disclaimer") and any redistribution must be conditioned upon * including a substantially similar Disclaimer requirement for further * binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, you may choose to be licensed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * *****************************************************************************/ #define _DECLARE_GLOBALS #include "acpidump.h" /* * acpidump - A portable utility for obtaining system ACPI tables and dumping * them in an ASCII hex format suitable for binary extraction via acpixtract. * * Obtaining the system ACPI tables is an OS-specific operation. * * This utility can be ported to any host operating system by providing a * module containing system-specific versions of these interfaces: * * AcpiOsGetTableByAddress * AcpiOsGetTableByIndex * AcpiOsGetTableByName * * See the ACPICA Reference Guide for the exact definitions of these * interfaces. Also, see these ACPICA source code modules for example * implementations: * * source/os_specific/service_layers/oswintbl.c * source/os_specific/service_layers/oslinuxtbl.c */ /* Local prototypes */ static void ApDisplayUsage ( void); static int ApDoOptions ( int argc, char **argv); static int ApInsertAction ( char *Argument, UINT32 ToBeDone); /* Table for deferred actions from command line options */ AP_DUMP_ACTION ActionTable [AP_MAX_ACTIONS]; UINT32 CurrentAction = 0; #define AP_UTILITY_NAME "ACPI Binary Table Dump Utility" #define AP_SUPPORTED_OPTIONS "?a:bc:f:hn:o:r:sv^xz" /****************************************************************************** * * FUNCTION: ApDisplayUsage * * DESCRIPTION: Usage message for the AcpiDump utility * ******************************************************************************/ static void ApDisplayUsage ( void) { ACPI_USAGE_HEADER ("acpidump [options]"); ACPI_OPTION ("-b", "Dump tables to binary files"); ACPI_OPTION ("-h -?", "This help message"); ACPI_OPTION ("-o ", "Redirect output to file"); ACPI_OPTION ("-r
", "Dump tables from specified RSDP"); ACPI_OPTION ("-s", "Print table summaries only"); ACPI_OPTION ("-v", "Display version information"); ACPI_OPTION ("-vd", "Display build date and time"); ACPI_OPTION ("-z", "Verbose mode"); ACPI_USAGE_TEXT ("\nTable Options:\n"); ACPI_OPTION ("-a
", "Get table via a physical address"); ACPI_OPTION ("-c ", "Turning on/off customized table dumping"); ACPI_OPTION ("-f ", "Get table via a binary file"); ACPI_OPTION ("-n ", "Get table via a name/signature"); ACPI_OPTION ("-x", "Use RSDT instead of XSDT"); ACPI_USAGE_TEXT ( "\n" "Invocation without parameters dumps all available tables\n" "Multiple mixed instances of -a, -f, and -n are supported\n\n"); } /****************************************************************************** * * FUNCTION: ApInsertAction * * PARAMETERS: Argument - Pointer to the argument for this action * ToBeDone - What to do to process this action * * RETURN: Status * * DESCRIPTION: Add an action item to the action table * ******************************************************************************/ static int ApInsertAction ( char *Argument, UINT32 ToBeDone) { /* Insert action and check for table overflow */ ActionTable [CurrentAction].Argument = Argument; ActionTable [CurrentAction].ToBeDone = ToBeDone; CurrentAction++; if (CurrentAction > AP_MAX_ACTIONS) { fprintf (stderr, "Too many table options (max %u)\n", AP_MAX_ACTIONS); return (-1); } return (0); } /****************************************************************************** * * FUNCTION: ApDoOptions * * PARAMETERS: argc/argv - Standard argc/argv * * RETURN: Status * * DESCRIPTION: Command line option processing. The main actions for getting * and dumping tables are deferred via the action table. * *****************************************************************************/ static int ApDoOptions ( int argc, char **argv) { int j; ACPI_STATUS Status; /* Command line options */ while ((j = AcpiGetopt (argc, argv, AP_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch (j) { /* * Global options */ case 'b': /* Dump all input tables to binary files */ Gbl_BinaryMode = TRUE; continue; case 'c': /* Dump customized tables */ if (!strcmp (AcpiGbl_Optarg, "on")) { Gbl_DumpCustomizedTables = TRUE; } else if (!strcmp (AcpiGbl_Optarg, "off")) { Gbl_DumpCustomizedTables = FALSE; } else { fprintf (stderr, "%s: Cannot handle this switch, please use on|off\n", AcpiGbl_Optarg); return (-1); } continue; case 'h': case '?': ApDisplayUsage (); return (1); case 'o': /* Redirect output to a single file */ if (ApOpenOutputFile (AcpiGbl_Optarg)) { return (-1); } continue; case 'r': /* Dump tables from specified RSDP */ Status = AcpiUtStrtoul64 (AcpiGbl_Optarg, &Gbl_RsdpBase); if (ACPI_FAILURE (Status)) { fprintf (stderr, "%s: Could not convert to a physical address\n", AcpiGbl_Optarg); return (-1); } continue; case 's': /* Print table summaries only */ Gbl_SummaryMode = TRUE; continue; case 'x': /* Do not use XSDT */ if (!AcpiGbl_DoNotUseXsdt) { AcpiGbl_DoNotUseXsdt = TRUE; } else { Gbl_DoNotDumpXsdt = TRUE; } continue; case 'v': /* -v: (Version): signon already emitted, just exit */ switch (AcpiGbl_Optarg[0]) { case '^': /* -v: (Version) */ fprintf (stderr, ACPI_COMMON_SIGNON (AP_UTILITY_NAME)); return (1); case 'd': fprintf (stderr, ACPI_COMMON_SIGNON (AP_UTILITY_NAME)); printf (ACPI_COMMON_BUILD_TIME); return (1); default: printf ("Unknown option: -v%s\n", AcpiGbl_Optarg); return (-1); } break; case 'z': /* Verbose mode */ Gbl_VerboseMode = TRUE; fprintf (stderr, ACPI_COMMON_SIGNON (AP_UTILITY_NAME)); continue; /* * Table options */ case 'a': /* Get table by physical address */ if (ApInsertAction (AcpiGbl_Optarg, AP_DUMP_TABLE_BY_ADDRESS)) { return (-1); } break; case 'f': /* Get table from a file */ if (ApInsertAction (AcpiGbl_Optarg, AP_DUMP_TABLE_BY_FILE)) { return (-1); } break; case 'n': /* Get table by input name (signature) */ if (ApInsertAction (AcpiGbl_Optarg, AP_DUMP_TABLE_BY_NAME)) { return (-1); } break; default: ApDisplayUsage (); return (-1); } /* If there are no actions, this means "get/dump all tables" */ if (CurrentAction == 0) { if (ApInsertAction (NULL, AP_DUMP_ALL_TABLES)) { return (-1); } } return (0); } /****************************************************************************** * * FUNCTION: main * * PARAMETERS: argc/argv - Standard argc/argv * * RETURN: Status * * DESCRIPTION: C main function for acpidump utility * ******************************************************************************/ #if !defined(_GNU_EFI) && !defined(_EDK2_EFI) int ACPI_SYSTEM_XFACE main ( int argc, char *argv[]) #else int ACPI_SYSTEM_XFACE acpi_main ( int argc, char *argv[]) #endif { int Status = 0; AP_DUMP_ACTION *Action; UINT32 FileSize; UINT32 i; ACPI_DEBUG_INITIALIZE (); /* For debug version only */ AcpiOsInitialize (); Gbl_OutputFile = ACPI_FILE_OUT; AcpiGbl_IntegerByteWidth = 8; /* Process command line options */ Status = ApDoOptions (argc, argv); if (Status > 0) { return (0); } if (Status < 0) { return (Status); } /* Get/dump ACPI table(s) as requested */ for (i = 0; i < CurrentAction; i++) { Action = &ActionTable[i]; switch (Action->ToBeDone) { case AP_DUMP_ALL_TABLES: Status = ApDumpAllTables (); break; case AP_DUMP_TABLE_BY_ADDRESS: Status = ApDumpTableByAddress (Action->Argument); break; case AP_DUMP_TABLE_BY_NAME: Status = ApDumpTableByName (Action->Argument); break; case AP_DUMP_TABLE_BY_FILE: Status = ApDumpTableFromFile (Action->Argument); break; default: fprintf (stderr, "Internal error, invalid action: 0x%X\n", Action->ToBeDone); return (-1); } if (Status) { return (Status); } } if (Gbl_OutputFilename) { if (Gbl_VerboseMode) { /* Summary for the output file */ FileSize = CmGetFileSize (Gbl_OutputFile); fprintf (stderr, "Output file %s contains 0x%X (%u) bytes\n\n", Gbl_OutputFilename, FileSize, FileSize); } fclose (Gbl_OutputFile); } return (Status); } /* * * Module Name: osillumostbl - illumos OSL for obtaining ACPI tables * This file is derived from the Intel oslinuxtbl source file. * */ /* * Copyright (C) 2000 - 2016, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * substantially similar to the "NO WARRANTY" disclaimer below * ("Disclaimer") and any redistribution must be conditioned upon * including a substantially similar Disclaimer requirement for further * binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. */ /* * Copyright (c) 2018, Joyent, Inc. */ #include #include #include #include #include #include "acpidump.h" #define _COMPONENT ACPI_OS_SERVICES ACPI_MODULE_NAME("osillumostbl") /* 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 *, char *, UINT32 *); static ACPI_STATUS OslAddTableToList(char *); static ACPI_STATUS OslMapTable(ACPI_SIZE, char *, ACPI_TABLE_HEADER **); static void OslUnmapTable(ACPI_TABLE_HEADER *); static ACPI_STATUS OslLoadRsdp(void); static ACPI_STATUS OslListBiosTables(void); static ACPI_STATUS OslGetBiosTable(char *, UINT32, ACPI_TABLE_HEADER **, ACPI_PHYSICAL_ADDRESS *); static ACPI_STATUS OslGetLastStatus(ACPI_STATUS); static int pagesize; /* Initialization flags */ UINT8 Gbl_TableListInitialized = FALSE; /* Local copies of main ACPI tables */ ACPI_TABLE_RSDP Gbl_Rsdp; ACPI_TABLE_FADT *Gbl_Fadt = NULL; ACPI_TABLE_RSDT *Gbl_Rsdt = NULL; ACPI_TABLE_XSDT *Gbl_Xsdt = NULL; /* Table addresses */ ACPI_PHYSICAL_ADDRESS Gbl_FadtAddress = 0; ACPI_PHYSICAL_ADDRESS Gbl_RsdpAddress = 0; /* 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) { UINT32 TableLength; ACPI_TABLE_HEADER *MappedTable; ACPI_TABLE_HEADER *LocalTable = NULL; ACPI_STATUS Status = AE_OK; /* * Get main ACPI tables from memory on first invocation of this * function */ Status = OslTableInitialize(); if (ACPI_FAILURE(Status)) { return (Status); } /* 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 */ TableLength = ApGetTableLength(MappedTable); if (TableLength == 0) { Status = AE_BAD_HEADER; goto Exit; } LocalTable = calloc(1, TableLength); if (!LocalTable) { Status = AE_NO_MEMORY; goto Exit; } memcpy(LocalTable, MappedTable, TableLength); Exit: OslUnmapTable(MappedTable); *Table = LocalTable; return (Status); } /* * * 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 extract it from the RSDT/XSDT */ Status = OslGetBiosTable(Signature, Instance, Table, Address); return (Status); } /* * * FUNCTION: OslAddTableToList * * PARAMETERS: Signature - Table signature * * 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) { OSL_TABLE_INFO *NewInfo; OSL_TABLE_INFO *Next; UINT32 NextInstance = 0; UINT32 Instance = 0; BOOLEAN Found = FALSE; NewInfo = calloc(1, sizeof (OSL_TABLE_INFO)); if (NewInfo == NULL) { 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 == 0) { Found = TRUE; } if (Next->Instance >= NextInstance) { NextInstance = Next->Instance + 1; } } if (!Next->Next) { break; } Next = Next->Next; } Next->Next = NewInfo; } if (Found) { 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: OslLoadRsdp * * PARAMETERS: None * * RETURN: Status * * DESCRIPTION: Scan and load RSDP. * See the find_rsdp() function in usr/src/uts/i86pc/os/fakebop.c, which is how * the kernel finds the RSDP. That algorithm matches AcpiFindRootPointer(). * * If the system is not using BIOS, and ACPI information was passed to the * system from the boot loader, then the RSDP is recorded in the "acpi-root-tab" * property. * * The code here is derived from AcpiFindRootPointer, except that we will * try the "acpi-root-tab" property first. If the property does not exist or * we do not find the root, then we scan the EBDA. Finally, we will search * the BIOS and copy the table if found. */ static ACPI_STATUS OslLoadRsdp(void) { UINT8 *mapp = NULL; ACPI_TABLE_HEADER *tblp; ACPI_SIZE mapsize = sizeof (ACPI_TABLE_RSDP); ACPI_PHYSICAL_ADDRESS physaddr; di_node_t root; int64_t *val64; if ((root = di_init("/", DINFOPROP)) != DI_NODE_NIL) { if (di_prop_lookup_int64(DDI_DEV_T_ANY, root, "acpi-root-tab", &val64) == 1) { physaddr = (ACPI_PHYSICAL_ADDRESS)*val64; mapp = AcpiOsMapMemory(physaddr, mapsize); } di_fini(root); } if (mapp != NULL) { tblp = ACPI_CAST_PTR(ACPI_TABLE_HEADER, AcpiTbScanMemoryForRsdp(mapp, mapsize)); if (tblp != NULL) { physaddr += (ACPI_PHYSICAL_ADDRESS) ACPI_PTR_DIFF(tblp, mapp); Gbl_RsdpAddress = physaddr; memcpy(&Gbl_Rsdp, tblp, sizeof (ACPI_TABLE_RSDP)); AcpiOsUnmapMemory(mapp, mapsize); return (AE_OK); } AcpiOsUnmapMemory(mapp, mapsize); } /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ mapp = AcpiOsMapMemory((ACPI_PHYSICAL_ADDRESS)ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH); if (mapp == NULL) goto try_bios; ACPI_MOVE_16_TO_32(&physaddr, mapp); /* Convert segment part to physical address */ physaddr <<= 4; AcpiOsUnmapMemory(mapp, ACPI_EBDA_PTR_LENGTH); /* EBDA present? */ if (physaddr <= 0x400) goto try_bios; /* * 1b) Search EBDA paragraphs (EBDA is required to be a minimum of 1K * length) */ mapp = AcpiOsMapMemory(physaddr, ACPI_EBDA_WINDOW_SIZE); if (mapp == NULL) { (void) fprintf(stderr, "EBDA (0x%p) found, but is not " "mappable\n", physaddr); goto try_bios; } tblp = ACPI_CAST_PTR(ACPI_TABLE_HEADER, AcpiTbScanMemoryForRsdp(mapp, ACPI_EBDA_WINDOW_SIZE)); if (tblp != NULL) { physaddr += (ACPI_PHYSICAL_ADDRESS) ACPI_PTR_DIFF(tblp, mapp); Gbl_RsdpAddress = physaddr; memcpy(&Gbl_Rsdp, tblp, sizeof (ACPI_TABLE_RSDP)); AcpiOsUnmapMemory(mapp, ACPI_EBDA_WINDOW_SIZE); return (AE_OK); } AcpiOsUnmapMemory(mapp, ACPI_EBDA_WINDOW_SIZE); try_bios: /* Try to get RSDP from BIOS memory */ if (Gbl_RsdpBase != 0) { physaddr = Gbl_RsdpBase; mapsize = sizeof (ACPI_TABLE_RSDP); } else { physaddr = ACPI_HI_RSDP_WINDOW_BASE; mapsize = ACPI_HI_RSDP_WINDOW_SIZE; } mapp = AcpiOsMapMemory(physaddr, mapsize); if (mapp == NULL) return (OslGetLastStatus(AE_BAD_ADDRESS)); /* Search low memory for the RSDP */ tblp = ACPI_CAST_PTR(ACPI_TABLE_HEADER, AcpiTbScanMemoryForRsdp(mapp, mapsize)); if (tblp == NULL) { AcpiOsUnmapMemory(mapp, mapsize); return (AE_NOT_FOUND); } physaddr += (ACPI_PHYSICAL_ADDRESS) ACPI_PTR_DIFF(tblp, mapp); Gbl_RsdpAddress = physaddr; memcpy(&Gbl_Rsdp, tblp, sizeof (ACPI_TABLE_RSDP)); AcpiOsUnmapMemory(mapp, mapsize); return (AE_OK); } /* * * FUNCTION: OslCanUseXsdt * * PARAMETERS: None * * RETURN: TRUE if XSDT is allowed to be used. * * DESCRIPTION: This function collects logic that can be used to determine if * XSDT should be used instead of RSDT. * */ static BOOLEAN OslCanUseXsdt(void) { if (Gbl_Revision && !AcpiGbl_DoNotUseXsdt) { return (TRUE); } else { return (FALSE); } } /* * * 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; ACPI_PHYSICAL_ADDRESS Address; if (Gbl_TableListInitialized) { return (AE_OK); } /* Get RSDP from memory */ Status = OslLoadRsdp(); if (ACPI_FAILURE(Status)) { return (Status); } /* Get XSDT from memory */ if (Gbl_Rsdp.Revision && !Gbl_DoNotDumpXsdt) { 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); } } /* Get RSDT from memory */ if (Gbl_Rsdp.RsdtPhysicalAddress) { 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 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); } /* Add mandatory tables to global table list first */ Status = OslAddTableToList(ACPI_RSDP_NAME); if (ACPI_FAILURE(Status)) { return (Status); } Status = OslAddTableToList(ACPI_SIG_RSDT); if (ACPI_FAILURE(Status)) { return (Status); } if (Gbl_Revision == 2) { Status = OslAddTableToList(ACPI_SIG_XSDT); if (ACPI_FAILURE(Status)) { return (Status); } } Status = OslAddTableToList(ACPI_SIG_DSDT); if (ACPI_FAILURE(Status)) { return (Status); } Status = OslAddTableToList(ACPI_SIG_FACS); if (ACPI_FAILURE(Status)) { return (Status); } /* Add all tables found in the memory */ Status = OslListBiosTables(); if (ACPI_FAILURE(Status)) { return (Status); } Gbl_TableListInitialized = TRUE; return (AE_OK); } /* * * FUNCTION: OslListBiosTables * * PARAMETERS: None * * RETURN: Status; Table list is initialized if AE_OK. * * DESCRIPTION: Add ACPI tables to the table list from memory. */ static ACPI_STATUS OslListBiosTables(void) { ACPI_TABLE_HEADER *MappedTable = NULL; UINT8 *TableData; UINT32 NumberOfTables; UINT8 ItemSize; ACPI_PHYSICAL_ADDRESS TableAddress = 0; ACPI_STATUS Status = AE_OK; UINT32 i; if (OslCanUseXsdt()) { ItemSize = sizeof (UINT64); TableData = ACPI_CAST8(Gbl_Xsdt) + sizeof (ACPI_TABLE_HEADER); NumberOfTables = (UINT32) ((Gbl_Xsdt->Header.Length - sizeof (ACPI_TABLE_HEADER)) / ItemSize); } else { /* Use RSDT if XSDT is not available */ ItemSize = sizeof (UINT32); TableData = ACPI_CAST8(Gbl_Rsdt) + sizeof (ACPI_TABLE_HEADER); NumberOfTables = (UINT32) ((Gbl_Rsdt->Header.Length - sizeof (ACPI_TABLE_HEADER)) / ItemSize); } /* Search RSDT/XSDT for the requested table */ for (i = 0; i < NumberOfTables; ++i, TableData += ItemSize) { if (OslCanUseXsdt()) { TableAddress = (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST64(TableData)); } else { TableAddress = (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST32(TableData)); } /* Skip NULL entries in RSDT/XSDT */ if (TableAddress == 0) { continue; } Status = OslMapTable(TableAddress, NULL, &MappedTable); if (ACPI_FAILURE(Status)) { return (Status); } OslAddTableToList(MappedTable->Signature); OslUnmapTable(MappedTable); } return (AE_OK); } /* * * FUNCTION: OslGetBiosTable * * 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 a BIOS provided ACPI table * * NOTE: Assumes the input signature is uppercase. * */ static ACPI_STATUS OslGetBiosTable(char *Signature, UINT32 Instance, ACPI_TABLE_HEADER **Table, ACPI_PHYSICAL_ADDRESS *Address) { ACPI_TABLE_HEADER *LocalTable = NULL; ACPI_TABLE_HEADER *MappedTable = NULL; UINT8 *TableData; UINT8 NumberOfTables; UINT8 ItemSize; UINT32 CurrentInstance = 0; ACPI_PHYSICAL_ADDRESS TableAddress = 0; UINT32 TableLength = 0; ACPI_STATUS Status = AE_OK; UINT32 i; /* Handle special tables whose addresses are not in RSDT/XSDT */ if (ACPI_COMPARE_NAME(Signature, ACPI_RSDP_NAME) || ACPI_COMPARE_NAME(Signature, ACPI_SIG_RSDT) || ACPI_COMPARE_NAME(Signature, ACPI_SIG_XSDT) || ACPI_COMPARE_NAME(Signature, ACPI_SIG_DSDT) || ACPI_COMPARE_NAME(Signature, ACPI_SIG_FACS)) { if (Instance > 0) { return (AE_LIMIT); } /* * 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 if (ACPI_COMPARE_NAME(Signature, ACPI_SIG_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; } } else if (ACPI_COMPARE_NAME(Signature, ACPI_SIG_XSDT)) { if (!Gbl_Revision) { return (AE_BAD_SIGNATURE); } TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.XsdtPhysicalAddress; } else if (ACPI_COMPARE_NAME(Signature, ACPI_SIG_RSDT)) { TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.RsdtPhysicalAddress; } else { TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_RsdpAddress; Signature = ACPI_SIG_RSDP; } /* Now we can get the requested special table */ Status = OslMapTable(TableAddress, Signature, &MappedTable); if (ACPI_FAILURE(Status)) { return (Status); } TableLength = ApGetTableLength(MappedTable); } else { /* Case for a normal ACPI table */ if (OslCanUseXsdt()) { ItemSize = sizeof (UINT64); TableData = ACPI_CAST8(Gbl_Xsdt) + sizeof (ACPI_TABLE_HEADER); NumberOfTables = (UINT8) ((Gbl_Xsdt->Header.Length - sizeof (ACPI_TABLE_HEADER)) / ItemSize); } else { /* Use RSDT if XSDT is not available */ ItemSize = sizeof (UINT32); TableData = ACPI_CAST8(Gbl_Rsdt) + sizeof (ACPI_TABLE_HEADER); NumberOfTables = (UINT8) ((Gbl_Rsdt->Header.Length - sizeof (ACPI_TABLE_HEADER)) / ItemSize); } /* Search RSDT/XSDT for the requested table */ for (i = 0; i < NumberOfTables; ++i, TableData += ItemSize) { if (OslCanUseXsdt()) { TableAddress = (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST64(TableData)); } else { TableAddress = (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST32(TableData)); } /* Skip NULL entries in RSDT/XSDT */ if (TableAddress == 0) { continue; } Status = OslMapTable(TableAddress, NULL, &MappedTable); if (ACPI_FAILURE(Status)) { return (Status); } TableLength = MappedTable->Length; /* Does this table match the requested signature? */ if (!ACPI_COMPARE_NAME(MappedTable->Signature, Signature)) { OslUnmapTable(MappedTable); MappedTable = NULL; continue; } /* Match table instance (for SSDT/UEFI tables) */ if (CurrentInstance != Instance) { OslUnmapTable(MappedTable); MappedTable = NULL; CurrentInstance++; continue; } break; } } if (MappedTable == NULL) { return (AE_LIMIT); } if (TableLength == 0) { Status = AE_BAD_HEADER; goto Exit; } /* Copy table to local buffer and return it */ LocalTable = calloc(1, TableLength); if (LocalTable == NULL) { Status = AE_NO_MEMORY; goto Exit; } memcpy(LocalTable, MappedTable, TableLength); *Address = TableAddress; *Table = LocalTable; Exit: OslUnmapTable(MappedTable); return (Status); } /* * * 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. * AE_NOT_FOUND: A valid table was not found at the address * * DESCRIPTION: Map entire ACPI table into caller's address space. * */ static ACPI_STATUS OslMapTable(ACPI_SIZE Address, char *Signature, ACPI_TABLE_HEADER **Table) { ACPI_TABLE_HEADER *MappedTable; UINT32 Length; if (Address == 0) { return (AE_BAD_ADDRESS); } /* * Map the header so we can get the table length. * Use sizeof (ACPI_TABLE_HEADER) as: * 1. it is bigger than 24 to include RSDP->Length * 2. it is smaller than sizeof (ACPI_TABLE_RSDP) */ MappedTable = AcpiOsMapMemory(Address, sizeof (ACPI_TABLE_HEADER)); if (MappedTable == NULL) { (void) fprintf(stderr, "Could not map table header at " "0x%8.8X%8.8X\n", ACPI_FORMAT_UINT64(Address)); return (OslGetLastStatus(AE_BAD_ADDRESS)); } /* If specified, signature must match */ if (Signature != NULL) { if (ACPI_VALIDATE_RSDP_SIG(Signature)) { if (!ACPI_VALIDATE_RSDP_SIG(MappedTable->Signature)) { AcpiOsUnmapMemory(MappedTable, sizeof (ACPI_TABLE_HEADER)); return (AE_BAD_SIGNATURE); } } else if (!ACPI_COMPARE_NAME(Signature, MappedTable->Signature)) { AcpiOsUnmapMemory(MappedTable, sizeof (ACPI_TABLE_HEADER)); return (AE_BAD_SIGNATURE); } } /* Map the entire table */ Length = ApGetTableLength(MappedTable); AcpiOsUnmapMemory(MappedTable, sizeof (ACPI_TABLE_HEADER)); if (Length == 0) { return (AE_BAD_HEADER); } MappedTable = AcpiOsMapMemory(Address, Length); if (MappedTable == NULL) { (void) fprintf(stderr, "Could not map table at 0x%8.8X%8.8X " "length %8.8X\n", ACPI_FORMAT_UINT64(Address), Length); return (OslGetLastStatus(AE_INVALID_TABLE_LENGTH)); } (void) ApIsValidChecksum(MappedTable); *Table = MappedTable; return (AE_OK); } /* * * FUNCTION: OslUnmapTable * * PARAMETERS: Table - A pointer to the mapped table * * RETURN: None * * DESCRIPTION: Unmap entire ACPI table. * */ static void OslUnmapTable(ACPI_TABLE_HEADER *Table) { if (Table != NULL) { AcpiOsUnmapMemory(Table, ApGetTableLength(Table)); } } /* * * 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); } void * AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Where, ACPI_SIZE Length) { int fd; void *p; ulong_t offset; if ((fd = open("/dev/xsvc", O_RDONLY)) < 0) return (NULL); if (pagesize == 0) { pagesize = getpagesize(); } offset = Where % pagesize; p = mmap(NULL, Length + offset, PROT_READ, MAP_SHARED | MAP_NORESERVE, fd, Where - offset); (void) close(fd); if (p == MAP_FAILED) return (NULL); p = (char *)p + offset; return (p); } void AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Size) { ulong_t offset; void *p; offset = (ulong_t)LogicalAddress % pagesize; p = (void *)((char *)LogicalAddress - offset); (void) munmap(p, Size + offset); } /****************************************************************************** * * Module Name: osunixdir - Unix directory access interfaces * *****************************************************************************/ /****************************************************************************** * * 1. Copyright Notice * * Some or all of this work - Copyright (c) 1999 - 2018, 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. * ***************************************************************************** * * Alternatively, you may choose to be licensed under the terms of the * following license: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * substantially similar to the "NO WARRANTY" disclaimer below * ("Disclaimer") and any redistribution must be conditioned upon * including a substantially similar Disclaimer requirement for further * binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Alternatively, you may choose to be licensed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * *****************************************************************************/ #include "acpi.h" #include #include #include #include #include #include #include /* * Allocated structure returned from OsOpenDirectory */ typedef struct ExternalFindInfo { char *DirPathname; DIR *DirPtr; char temp_buffer[256]; char *WildcardSpec; char RequestedFileType; } EXTERNAL_FIND_INFO; /******************************************************************************* * * FUNCTION: AcpiOsOpenDirectory * * PARAMETERS: DirPathname - Full pathname to the directory * WildcardSpec - string of the form "*.c", etc. * * RETURN: A directory "handle" to be used in subsequent search operations. * NULL returned on failure. * * DESCRIPTION: Open a directory in preparation for a wildcard search * ******************************************************************************/ void * AcpiOsOpenDirectory ( char *DirPathname, char *WildcardSpec, char RequestedFileType) { EXTERNAL_FIND_INFO *ExternalInfo; DIR *dir; /* Allocate the info struct that will be returned to the caller */ ExternalInfo = calloc (1, sizeof (EXTERNAL_FIND_INFO)); if (!ExternalInfo) { return (NULL); } /* Get the directory stream */ dir = opendir (DirPathname); if (!dir) { fprintf (stderr, "Cannot open directory - %s\n", DirPathname); free (ExternalInfo); return (NULL); } /* Save the info in the return structure */ ExternalInfo->WildcardSpec = WildcardSpec; ExternalInfo->RequestedFileType = RequestedFileType; ExternalInfo->DirPathname = DirPathname; ExternalInfo->DirPtr = dir; return (ExternalInfo); } /******************************************************************************* * * FUNCTION: AcpiOsGetNextFilename * * PARAMETERS: DirHandle - Created via AcpiOsOpenDirectory * * RETURN: Next filename matched. NULL if no more matches. * * DESCRIPTION: Get the next file in the directory that matches the wildcard * specification. * ******************************************************************************/ char * AcpiOsGetNextFilename ( void *DirHandle) { EXTERNAL_FIND_INFO *ExternalInfo = DirHandle; struct dirent *dir_entry; char *temp_str; int str_len; struct stat temp_stat; int err; while ((dir_entry = readdir (ExternalInfo->DirPtr))) { if (!fnmatch (ExternalInfo->WildcardSpec, dir_entry->d_name, 0)) { if (dir_entry->d_name[0] == '.') { continue; } str_len = strlen (dir_entry->d_name) + strlen (ExternalInfo->DirPathname) + 2; temp_str = calloc (str_len, 1); if (!temp_str) { fprintf (stderr, "Could not allocate buffer for temporary string\n"); return (NULL); } strcpy (temp_str, ExternalInfo->DirPathname); strcat (temp_str, "/"); strcat (temp_str, dir_entry->d_name); err = stat (temp_str, &temp_stat); if (err == -1) { fprintf (stderr, "Cannot stat file (should not happen) - %s\n", temp_str); free (temp_str); return (NULL); } free (temp_str); if ((S_ISDIR (temp_stat.st_mode) && (ExternalInfo->RequestedFileType == REQUEST_DIR_ONLY)) || ((!S_ISDIR (temp_stat.st_mode) && ExternalInfo->RequestedFileType == REQUEST_FILE_ONLY))) { /* copy to a temp buffer because dir_entry struct is on the stack */ strcpy (ExternalInfo->temp_buffer, dir_entry->d_name); return (ExternalInfo->temp_buffer); } } } return (NULL); } /******************************************************************************* * * FUNCTION: AcpiOsCloseDirectory * * PARAMETERS: DirHandle - Created via AcpiOsOpenDirectory * * RETURN: None. * * DESCRIPTION: Close the open directory and cleanup. * ******************************************************************************/ void AcpiOsCloseDirectory ( void *DirHandle) { EXTERNAL_FIND_INFO *ExternalInfo = DirHandle; /* Close the directory and free allocations */ closedir (ExternalInfo->DirPtr); free (DirHandle); }