10d02842fSSascha Wildner /****************************************************************************** 20d02842fSSascha Wildner * 30d02842fSSascha Wildner * Module Name: oslinuxtbl - Linux OSL for obtaining ACPI tables 40d02842fSSascha Wildner * 50d02842fSSascha Wildner *****************************************************************************/ 60d02842fSSascha Wildner 7b4315fc7SSascha Wildner /****************************************************************************** 8b4315fc7SSascha Wildner * 9b4315fc7SSascha Wildner * 1. Copyright Notice 10b4315fc7SSascha Wildner * 11b4315fc7SSascha Wildner * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. 120d02842fSSascha Wildner * All rights reserved. 130d02842fSSascha Wildner * 14b4315fc7SSascha Wildner * 2. License 15b4315fc7SSascha Wildner * 16b4315fc7SSascha Wildner * 2.1. This is your license from Intel Corp. under its intellectual property 17b4315fc7SSascha Wildner * rights. You may have additional license terms from the party that provided 18b4315fc7SSascha Wildner * you this software, covering your right to use that party's intellectual 19b4315fc7SSascha Wildner * property rights. 20b4315fc7SSascha Wildner * 21b4315fc7SSascha Wildner * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22b4315fc7SSascha Wildner * copy of the source code appearing in this file ("Covered Code") an 23b4315fc7SSascha Wildner * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24b4315fc7SSascha Wildner * base code distributed originally by Intel ("Original Intel Code") to copy, 25b4315fc7SSascha Wildner * make derivatives, distribute, use and display any portion of the Covered 26b4315fc7SSascha Wildner * Code in any form, with the right to sublicense such rights; and 27b4315fc7SSascha Wildner * 28b4315fc7SSascha Wildner * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29b4315fc7SSascha Wildner * license (with the right to sublicense), under only those claims of Intel 30b4315fc7SSascha Wildner * patents that are infringed by the Original Intel Code, to make, use, sell, 31b4315fc7SSascha Wildner * offer to sell, and import the Covered Code and derivative works thereof 32b4315fc7SSascha Wildner * solely to the minimum extent necessary to exercise the above copyright 33b4315fc7SSascha Wildner * license, and in no event shall the patent license extend to any additions 34b4315fc7SSascha Wildner * to or modifications of the Original Intel Code. No other license or right 35b4315fc7SSascha Wildner * is granted directly or by implication, estoppel or otherwise; 36b4315fc7SSascha Wildner * 37b4315fc7SSascha Wildner * The above copyright and patent license is granted only if the following 38b4315fc7SSascha Wildner * conditions are met: 39b4315fc7SSascha Wildner * 40b4315fc7SSascha Wildner * 3. Conditions 41b4315fc7SSascha Wildner * 42b4315fc7SSascha Wildner * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43b4315fc7SSascha Wildner * Redistribution of source code of any substantial portion of the Covered 44b4315fc7SSascha Wildner * Code or modification with rights to further distribute source must include 45b4315fc7SSascha Wildner * the above Copyright Notice, the above License, this list of Conditions, 46b4315fc7SSascha Wildner * and the following Disclaimer and Export Compliance provision. In addition, 47b4315fc7SSascha Wildner * Licensee must cause all Covered Code to which Licensee contributes to 48b4315fc7SSascha Wildner * contain a file documenting the changes Licensee made to create that Covered 49b4315fc7SSascha Wildner * Code and the date of any change. Licensee must include in that file the 50b4315fc7SSascha Wildner * documentation of any changes made by any predecessor Licensee. Licensee 51b4315fc7SSascha Wildner * must include a prominent statement that the modification is derived, 52b4315fc7SSascha Wildner * directly or indirectly, from Original Intel Code. 53b4315fc7SSascha Wildner * 54b4315fc7SSascha Wildner * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55b4315fc7SSascha Wildner * Redistribution of source code of any substantial portion of the Covered 56b4315fc7SSascha Wildner * Code or modification without rights to further distribute source must 57b4315fc7SSascha Wildner * include the following Disclaimer and Export Compliance provision in the 58b4315fc7SSascha Wildner * documentation and/or other materials provided with distribution. In 59b4315fc7SSascha Wildner * addition, Licensee may not authorize further sublicense of source of any 60b4315fc7SSascha Wildner * portion of the Covered Code, and must include terms to the effect that the 61b4315fc7SSascha Wildner * license from Licensee to its licensee is limited to the intellectual 62b4315fc7SSascha Wildner * property embodied in the software Licensee provides to its licensee, and 63b4315fc7SSascha Wildner * not to intellectual property embodied in modifications its licensee may 64b4315fc7SSascha Wildner * make. 65b4315fc7SSascha Wildner * 66b4315fc7SSascha Wildner * 3.3. Redistribution of Executable. Redistribution in executable form of any 67b4315fc7SSascha Wildner * substantial portion of the Covered Code or modification must reproduce the 68b4315fc7SSascha Wildner * above Copyright Notice, and the following Disclaimer and Export Compliance 69b4315fc7SSascha Wildner * provision in the documentation and/or other materials provided with the 70b4315fc7SSascha Wildner * distribution. 71b4315fc7SSascha Wildner * 72b4315fc7SSascha Wildner * 3.4. Intel retains all right, title, and interest in and to the Original 73b4315fc7SSascha Wildner * Intel Code. 74b4315fc7SSascha Wildner * 75b4315fc7SSascha Wildner * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76b4315fc7SSascha Wildner * Intel shall be used in advertising or otherwise to promote the sale, use or 77b4315fc7SSascha Wildner * other dealings in products derived from or relating to the Covered Code 78b4315fc7SSascha Wildner * without prior written authorization from Intel. 79b4315fc7SSascha Wildner * 80b4315fc7SSascha Wildner * 4. Disclaimer and Export Compliance 81b4315fc7SSascha Wildner * 82b4315fc7SSascha Wildner * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83b4315fc7SSascha Wildner * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84b4315fc7SSascha Wildner * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85b4315fc7SSascha Wildner * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86b4315fc7SSascha Wildner * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87b4315fc7SSascha Wildner * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88b4315fc7SSascha Wildner * PARTICULAR PURPOSE. 89b4315fc7SSascha Wildner * 90b4315fc7SSascha Wildner * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91b4315fc7SSascha Wildner * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92b4315fc7SSascha Wildner * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93b4315fc7SSascha Wildner * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94b4315fc7SSascha Wildner * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95b4315fc7SSascha Wildner * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96b4315fc7SSascha Wildner * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97b4315fc7SSascha Wildner * LIMITED REMEDY. 98b4315fc7SSascha Wildner * 99b4315fc7SSascha Wildner * 4.3. Licensee shall not export, either directly or indirectly, any of this 100b4315fc7SSascha Wildner * software or system incorporating such software without first obtaining any 101b4315fc7SSascha Wildner * required license or other approval from the U. S. Department of Commerce or 102b4315fc7SSascha Wildner * any other agency or department of the United States Government. In the 103b4315fc7SSascha Wildner * event Licensee exports any such software from the United States or 104b4315fc7SSascha Wildner * re-exports any such software from a foreign destination, Licensee shall 105b4315fc7SSascha Wildner * ensure that the distribution and export/re-export of the software is in 106b4315fc7SSascha Wildner * compliance with all laws, regulations, orders, or other restrictions of the 107b4315fc7SSascha Wildner * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108b4315fc7SSascha Wildner * any of its subsidiaries will export/re-export any technical data, process, 109b4315fc7SSascha Wildner * software, or service, directly or indirectly, to any country for which the 110b4315fc7SSascha Wildner * United States government or any agency thereof requires an export license, 111b4315fc7SSascha Wildner * other governmental approval, or letter of assurance, without first obtaining 112b4315fc7SSascha Wildner * such license, approval or letter. 113b4315fc7SSascha Wildner * 114b4315fc7SSascha Wildner ***************************************************************************** 115b4315fc7SSascha Wildner * 116b4315fc7SSascha Wildner * Alternatively, you may choose to be licensed under the terms of the 117b4315fc7SSascha Wildner * following license: 118b4315fc7SSascha Wildner * 1190d02842fSSascha Wildner * Redistribution and use in source and binary forms, with or without 1200d02842fSSascha Wildner * modification, are permitted provided that the following conditions 1210d02842fSSascha Wildner * are met: 1220d02842fSSascha Wildner * 1. Redistributions of source code must retain the above copyright 1230d02842fSSascha Wildner * notice, this list of conditions, and the following disclaimer, 1240d02842fSSascha Wildner * without modification. 1250d02842fSSascha Wildner * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1260d02842fSSascha Wildner * substantially similar to the "NO WARRANTY" disclaimer below 1270d02842fSSascha Wildner * ("Disclaimer") and any redistribution must be conditioned upon 1280d02842fSSascha Wildner * including a substantially similar Disclaimer requirement for further 1290d02842fSSascha Wildner * binary redistribution. 1300d02842fSSascha Wildner * 3. Neither the names of the above-listed copyright holders nor the names 1310d02842fSSascha Wildner * of any contributors may be used to endorse or promote products derived 1320d02842fSSascha Wildner * from this software without specific prior written permission. 1330d02842fSSascha Wildner * 134b4315fc7SSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135b4315fc7SSascha Wildner * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136b4315fc7SSascha Wildner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137b4315fc7SSascha Wildner * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138b4315fc7SSascha Wildner * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139b4315fc7SSascha Wildner * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140b4315fc7SSascha Wildner * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141b4315fc7SSascha Wildner * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142b4315fc7SSascha Wildner * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143b4315fc7SSascha Wildner * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144b4315fc7SSascha Wildner * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145b4315fc7SSascha Wildner * 146b4315fc7SSascha Wildner * Alternatively, you may choose to be licensed under the terms of the 1470d02842fSSascha Wildner * GNU General Public License ("GPL") version 2 as published by the Free 1480d02842fSSascha Wildner * Software Foundation. 1490d02842fSSascha Wildner * 150b4315fc7SSascha Wildner *****************************************************************************/ 1510d02842fSSascha Wildner 1520d02842fSSascha Wildner #include "acpidump.h" 1530d02842fSSascha Wildner 1540d02842fSSascha Wildner 1550d02842fSSascha Wildner #define _COMPONENT ACPI_OS_SERVICES 1560d02842fSSascha Wildner ACPI_MODULE_NAME ("oslinuxtbl") 1570d02842fSSascha Wildner 1580d02842fSSascha Wildner 1590d02842fSSascha Wildner #ifndef PATH_MAX 1600d02842fSSascha Wildner #define PATH_MAX 256 1610d02842fSSascha Wildner #endif 1620d02842fSSascha Wildner 1630d02842fSSascha Wildner 1640d02842fSSascha Wildner /* List of information about obtained ACPI tables */ 1650d02842fSSascha Wildner 166d4972a9cSSascha Wildner typedef struct osl_table_info 1670d02842fSSascha Wildner { 168d4972a9cSSascha Wildner struct osl_table_info *Next; 1690d02842fSSascha Wildner UINT32 Instance; 1700d02842fSSascha Wildner char Signature[ACPI_NAME_SIZE]; 1710d02842fSSascha Wildner 1720d02842fSSascha Wildner } OSL_TABLE_INFO; 1730d02842fSSascha Wildner 1740d02842fSSascha Wildner /* Local prototypes */ 1750d02842fSSascha Wildner 1760d02842fSSascha Wildner static ACPI_STATUS 1770d02842fSSascha Wildner OslTableInitialize ( 1780d02842fSSascha Wildner void); 1790d02842fSSascha Wildner 1800d02842fSSascha Wildner static ACPI_STATUS 1810d02842fSSascha Wildner OslTableNameFromFile ( 1820d02842fSSascha Wildner char *Filename, 1830d02842fSSascha Wildner char *Signature, 1840d02842fSSascha Wildner UINT32 *Instance); 1850d02842fSSascha Wildner 1860d02842fSSascha Wildner static ACPI_STATUS 1870d02842fSSascha Wildner OslAddTableToList ( 1880d02842fSSascha Wildner char *Signature, 1890d02842fSSascha Wildner UINT32 Instance); 1900d02842fSSascha Wildner 1910d02842fSSascha Wildner static ACPI_STATUS 1920d02842fSSascha Wildner OslReadTableFromFile ( 1930d02842fSSascha Wildner char *Filename, 1940d02842fSSascha Wildner ACPI_SIZE FileOffset, 1950d02842fSSascha Wildner char *Signature, 1960d02842fSSascha Wildner ACPI_TABLE_HEADER **Table); 1970d02842fSSascha Wildner 1980d02842fSSascha Wildner static ACPI_STATUS 1990d02842fSSascha Wildner OslMapTable ( 2000d02842fSSascha Wildner ACPI_SIZE Address, 2010d02842fSSascha Wildner char *Signature, 2020d02842fSSascha Wildner ACPI_TABLE_HEADER **Table); 2030d02842fSSascha Wildner 2040d02842fSSascha Wildner static void 2050d02842fSSascha Wildner OslUnmapTable ( 2060d02842fSSascha Wildner ACPI_TABLE_HEADER *Table); 2070d02842fSSascha Wildner 2080d02842fSSascha Wildner static ACPI_PHYSICAL_ADDRESS 2095f39c7e7SSascha Wildner OslFindRsdpViaEfiByKeyword ( 2105f39c7e7SSascha Wildner FILE *File, 2115f39c7e7SSascha Wildner const char *Keyword); 2125f39c7e7SSascha Wildner 2135f39c7e7SSascha Wildner static ACPI_PHYSICAL_ADDRESS 2140d02842fSSascha Wildner OslFindRsdpViaEfi ( 2150d02842fSSascha Wildner void); 2160d02842fSSascha Wildner 2170d02842fSSascha Wildner static ACPI_STATUS 2180d02842fSSascha Wildner OslLoadRsdp ( 2190d02842fSSascha Wildner void); 2200d02842fSSascha Wildner 2210d02842fSSascha Wildner static ACPI_STATUS 2220d02842fSSascha Wildner OslListCustomizedTables ( 2230d02842fSSascha Wildner char *Directory); 2240d02842fSSascha Wildner 2250d02842fSSascha Wildner static ACPI_STATUS 2260d02842fSSascha Wildner OslGetCustomizedTable ( 2270d02842fSSascha Wildner char *Pathname, 2280d02842fSSascha Wildner char *Signature, 2290d02842fSSascha Wildner UINT32 Instance, 2300d02842fSSascha Wildner ACPI_TABLE_HEADER **Table, 2310d02842fSSascha Wildner ACPI_PHYSICAL_ADDRESS *Address); 2320d02842fSSascha Wildner 2330d02842fSSascha Wildner static ACPI_STATUS 2340d02842fSSascha Wildner OslListBiosTables ( 2350d02842fSSascha Wildner void); 2360d02842fSSascha Wildner 2370d02842fSSascha Wildner static ACPI_STATUS 2380d02842fSSascha Wildner OslGetBiosTable ( 2390d02842fSSascha Wildner char *Signature, 2400d02842fSSascha Wildner UINT32 Instance, 2410d02842fSSascha Wildner ACPI_TABLE_HEADER **Table, 2420d02842fSSascha Wildner ACPI_PHYSICAL_ADDRESS *Address); 2430d02842fSSascha Wildner 2440d02842fSSascha Wildner static ACPI_STATUS 2450d02842fSSascha Wildner OslGetLastStatus ( 2460d02842fSSascha Wildner ACPI_STATUS DefaultStatus); 2470d02842fSSascha Wildner 2480d02842fSSascha Wildner 2490d02842fSSascha Wildner /* File locations */ 2500d02842fSSascha Wildner 2510d02842fSSascha Wildner #define DYNAMIC_TABLE_DIR "/sys/firmware/acpi/tables/dynamic" 2520d02842fSSascha Wildner #define STATIC_TABLE_DIR "/sys/firmware/acpi/tables" 2530d02842fSSascha Wildner #define EFI_SYSTAB "/sys/firmware/efi/systab" 2540d02842fSSascha Wildner 2550d02842fSSascha Wildner /* Should we get dynamically loaded SSDTs from DYNAMIC_TABLE_DIR? */ 2560d02842fSSascha Wildner 2570d02842fSSascha Wildner UINT8 Gbl_DumpDynamicTables = TRUE; 2580d02842fSSascha Wildner 2590d02842fSSascha Wildner /* Initialization flags */ 2600d02842fSSascha Wildner 2610d02842fSSascha Wildner UINT8 Gbl_TableListInitialized = FALSE; 2620d02842fSSascha Wildner 2630d02842fSSascha Wildner /* Local copies of main ACPI tables */ 2640d02842fSSascha Wildner 2650d02842fSSascha Wildner ACPI_TABLE_RSDP Gbl_Rsdp; 2660d02842fSSascha Wildner ACPI_TABLE_FADT *Gbl_Fadt = NULL; 2670d02842fSSascha Wildner ACPI_TABLE_RSDT *Gbl_Rsdt = NULL; 2680d02842fSSascha Wildner ACPI_TABLE_XSDT *Gbl_Xsdt = NULL; 2690d02842fSSascha Wildner 2700d02842fSSascha Wildner /* Table addresses */ 2710d02842fSSascha Wildner 2720d02842fSSascha Wildner ACPI_PHYSICAL_ADDRESS Gbl_FadtAddress = 0; 2730d02842fSSascha Wildner ACPI_PHYSICAL_ADDRESS Gbl_RsdpAddress = 0; 2740d02842fSSascha Wildner 2750d02842fSSascha Wildner /* Revision of RSD PTR */ 2760d02842fSSascha Wildner 2770d02842fSSascha Wildner UINT8 Gbl_Revision = 0; 2780d02842fSSascha Wildner 2790d02842fSSascha Wildner OSL_TABLE_INFO *Gbl_TableListHead = NULL; 2800d02842fSSascha Wildner UINT32 Gbl_TableCount = 0; 2810d02842fSSascha Wildner 2820d02842fSSascha Wildner 2830d02842fSSascha Wildner /****************************************************************************** 2840d02842fSSascha Wildner * 2850d02842fSSascha Wildner * FUNCTION: OslGetLastStatus 2860d02842fSSascha Wildner * 2870d02842fSSascha Wildner * PARAMETERS: DefaultStatus - Default error status to return 2880d02842fSSascha Wildner * 2890d02842fSSascha Wildner * RETURN: Status; Converted from errno. 2900d02842fSSascha Wildner * 2910d02842fSSascha Wildner * DESCRIPTION: Get last errno and conver it to ACPI_STATUS. 2920d02842fSSascha Wildner * 2930d02842fSSascha Wildner *****************************************************************************/ 2940d02842fSSascha Wildner 2950d02842fSSascha Wildner static ACPI_STATUS 2960d02842fSSascha Wildner OslGetLastStatus ( 2970d02842fSSascha Wildner ACPI_STATUS DefaultStatus) 2980d02842fSSascha Wildner { 2990d02842fSSascha Wildner 3000d02842fSSascha Wildner switch (errno) 3010d02842fSSascha Wildner { 3020d02842fSSascha Wildner case EACCES: 3030d02842fSSascha Wildner case EPERM: 3040d02842fSSascha Wildner 3050d02842fSSascha Wildner return (AE_ACCESS); 3060d02842fSSascha Wildner 3070d02842fSSascha Wildner case ENOENT: 3080d02842fSSascha Wildner 3090d02842fSSascha Wildner return (AE_NOT_FOUND); 3100d02842fSSascha Wildner 3110d02842fSSascha Wildner case ENOMEM: 3120d02842fSSascha Wildner 3130d02842fSSascha Wildner return (AE_NO_MEMORY); 3140d02842fSSascha Wildner 3150d02842fSSascha Wildner default: 3160d02842fSSascha Wildner 3170d02842fSSascha Wildner return (DefaultStatus); 3180d02842fSSascha Wildner } 3190d02842fSSascha Wildner } 3200d02842fSSascha Wildner 3210d02842fSSascha Wildner 3220d02842fSSascha Wildner /****************************************************************************** 3230d02842fSSascha Wildner * 3240d02842fSSascha Wildner * FUNCTION: AcpiOsGetTableByAddress 3250d02842fSSascha Wildner * 3260d02842fSSascha Wildner * PARAMETERS: Address - Physical address of the ACPI table 3270d02842fSSascha Wildner * Table - Where a pointer to the table is returned 3280d02842fSSascha Wildner * 3290d02842fSSascha Wildner * RETURN: Status; Table buffer is returned if AE_OK. 3300d02842fSSascha Wildner * AE_NOT_FOUND: A valid table was not found at the address 3310d02842fSSascha Wildner * 3320d02842fSSascha Wildner * DESCRIPTION: Get an ACPI table via a physical memory address. 3330d02842fSSascha Wildner * 3340d02842fSSascha Wildner *****************************************************************************/ 3350d02842fSSascha Wildner 3360d02842fSSascha Wildner ACPI_STATUS 3370d02842fSSascha Wildner AcpiOsGetTableByAddress ( 3380d02842fSSascha Wildner ACPI_PHYSICAL_ADDRESS Address, 3390d02842fSSascha Wildner ACPI_TABLE_HEADER **Table) 3400d02842fSSascha Wildner { 3410d02842fSSascha Wildner UINT32 TableLength; 3420d02842fSSascha Wildner ACPI_TABLE_HEADER *MappedTable; 3430d02842fSSascha Wildner ACPI_TABLE_HEADER *LocalTable = NULL; 3440d02842fSSascha Wildner ACPI_STATUS Status = AE_OK; 3450d02842fSSascha Wildner 3460d02842fSSascha Wildner 3470d02842fSSascha Wildner /* Get main ACPI tables from memory on first invocation of this function */ 3480d02842fSSascha Wildner 3490d02842fSSascha Wildner Status = OslTableInitialize (); 3500d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 3510d02842fSSascha Wildner { 3520d02842fSSascha Wildner return (Status); 3530d02842fSSascha Wildner } 3540d02842fSSascha Wildner 3550d02842fSSascha Wildner /* Map the table and validate it */ 3560d02842fSSascha Wildner 3570d02842fSSascha Wildner Status = OslMapTable (Address, NULL, &MappedTable); 3580d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 3590d02842fSSascha Wildner { 3600d02842fSSascha Wildner return (Status); 3610d02842fSSascha Wildner } 3620d02842fSSascha Wildner 3630d02842fSSascha Wildner /* Copy table to local buffer and return it */ 3640d02842fSSascha Wildner 3650d02842fSSascha Wildner TableLength = ApGetTableLength (MappedTable); 3660d02842fSSascha Wildner if (TableLength == 0) 3670d02842fSSascha Wildner { 3680d02842fSSascha Wildner Status = AE_BAD_HEADER; 369d4972a9cSSascha Wildner goto Exit; 3700d02842fSSascha Wildner } 3710d02842fSSascha Wildner 3720d02842fSSascha Wildner LocalTable = calloc (1, TableLength); 3730d02842fSSascha Wildner if (!LocalTable) 3740d02842fSSascha Wildner { 3750d02842fSSascha Wildner Status = AE_NO_MEMORY; 376d4972a9cSSascha Wildner goto Exit; 3770d02842fSSascha Wildner } 3780d02842fSSascha Wildner 37925ca8c79SSascha Wildner memcpy (LocalTable, MappedTable, TableLength); 3800d02842fSSascha Wildner 381d4972a9cSSascha Wildner Exit: 3820d02842fSSascha Wildner OslUnmapTable (MappedTable); 3830d02842fSSascha Wildner *Table = LocalTable; 384d4972a9cSSascha Wildner return (Status); 3850d02842fSSascha Wildner } 3860d02842fSSascha Wildner 3870d02842fSSascha Wildner 3880d02842fSSascha Wildner /****************************************************************************** 3890d02842fSSascha Wildner * 3900d02842fSSascha Wildner * FUNCTION: AcpiOsGetTableByName 3910d02842fSSascha Wildner * 3920d02842fSSascha Wildner * PARAMETERS: Signature - ACPI Signature for desired table. Must be 3930d02842fSSascha Wildner * a null terminated 4-character string. 3940d02842fSSascha Wildner * Instance - Multiple table support for SSDT/UEFI (0...n) 3950d02842fSSascha Wildner * Must be 0 for other tables. 3960d02842fSSascha Wildner * Table - Where a pointer to the table is returned 3970d02842fSSascha Wildner * Address - Where the table physical address is returned 3980d02842fSSascha Wildner * 3990d02842fSSascha Wildner * RETURN: Status; Table buffer and physical address returned if AE_OK. 4000d02842fSSascha Wildner * AE_LIMIT: Instance is beyond valid limit 4010d02842fSSascha Wildner * AE_NOT_FOUND: A table with the signature was not found 4020d02842fSSascha Wildner * 4030d02842fSSascha Wildner * NOTE: Assumes the input signature is uppercase. 4040d02842fSSascha Wildner * 4050d02842fSSascha Wildner *****************************************************************************/ 4060d02842fSSascha Wildner 4070d02842fSSascha Wildner ACPI_STATUS 4080d02842fSSascha Wildner AcpiOsGetTableByName ( 4090d02842fSSascha Wildner char *Signature, 4100d02842fSSascha Wildner UINT32 Instance, 4110d02842fSSascha Wildner ACPI_TABLE_HEADER **Table, 4120d02842fSSascha Wildner ACPI_PHYSICAL_ADDRESS *Address) 4130d02842fSSascha Wildner { 4140d02842fSSascha Wildner ACPI_STATUS Status; 4150d02842fSSascha Wildner 4160d02842fSSascha Wildner 4170d02842fSSascha Wildner /* Get main ACPI tables from memory on first invocation of this function */ 4180d02842fSSascha Wildner 4190d02842fSSascha Wildner Status = OslTableInitialize (); 4200d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 4210d02842fSSascha Wildner { 4220d02842fSSascha Wildner return (Status); 4230d02842fSSascha Wildner } 4240d02842fSSascha Wildner 4250d02842fSSascha Wildner /* Not a main ACPI table, attempt to extract it from the RSDT/XSDT */ 4260d02842fSSascha Wildner 4270d02842fSSascha Wildner if (!Gbl_DumpCustomizedTables) 4280d02842fSSascha Wildner { 4290d02842fSSascha Wildner /* Attempt to get the table from the memory */ 4300d02842fSSascha Wildner 4310d02842fSSascha Wildner Status = OslGetBiosTable (Signature, Instance, Table, Address); 4320d02842fSSascha Wildner } 4330d02842fSSascha Wildner else 4340d02842fSSascha Wildner { 4350d02842fSSascha Wildner /* Attempt to get the table from the static directory */ 4360d02842fSSascha Wildner 4370d02842fSSascha Wildner Status = OslGetCustomizedTable (STATIC_TABLE_DIR, Signature, 4380d02842fSSascha Wildner Instance, Table, Address); 4390d02842fSSascha Wildner } 4400d02842fSSascha Wildner 4410d02842fSSascha Wildner if (ACPI_FAILURE (Status) && Status == AE_LIMIT) 4420d02842fSSascha Wildner { 4430d02842fSSascha Wildner if (Gbl_DumpDynamicTables) 4440d02842fSSascha Wildner { 4450d02842fSSascha Wildner /* Attempt to get a dynamic table */ 4460d02842fSSascha Wildner 4470d02842fSSascha Wildner Status = OslGetCustomizedTable (DYNAMIC_TABLE_DIR, Signature, 4480d02842fSSascha Wildner Instance, Table, Address); 4490d02842fSSascha Wildner } 4500d02842fSSascha Wildner } 4510d02842fSSascha Wildner 4520d02842fSSascha Wildner return (Status); 4530d02842fSSascha Wildner } 4540d02842fSSascha Wildner 4550d02842fSSascha Wildner 4560d02842fSSascha Wildner /****************************************************************************** 4570d02842fSSascha Wildner * 4580d02842fSSascha Wildner * FUNCTION: OslAddTableToList 4590d02842fSSascha Wildner * 4600d02842fSSascha Wildner * PARAMETERS: Signature - Table signature 4610d02842fSSascha Wildner * Instance - Table instance 4620d02842fSSascha Wildner * 4630d02842fSSascha Wildner * RETURN: Status; Successfully added if AE_OK. 4640d02842fSSascha Wildner * AE_NO_MEMORY: Memory allocation error 4650d02842fSSascha Wildner * 4660d02842fSSascha Wildner * DESCRIPTION: Insert a table structure into OSL table list. 4670d02842fSSascha Wildner * 4680d02842fSSascha Wildner *****************************************************************************/ 4690d02842fSSascha Wildner 4700d02842fSSascha Wildner static ACPI_STATUS 4710d02842fSSascha Wildner OslAddTableToList ( 4720d02842fSSascha Wildner char *Signature, 4730d02842fSSascha Wildner UINT32 Instance) 4740d02842fSSascha Wildner { 4750d02842fSSascha Wildner OSL_TABLE_INFO *NewInfo; 4760d02842fSSascha Wildner OSL_TABLE_INFO *Next; 4770d02842fSSascha Wildner UINT32 NextInstance = 0; 4780d02842fSSascha Wildner BOOLEAN Found = FALSE; 4790d02842fSSascha Wildner 4800d02842fSSascha Wildner 4810d02842fSSascha Wildner NewInfo = calloc (1, sizeof (OSL_TABLE_INFO)); 4820d02842fSSascha Wildner if (!NewInfo) 4830d02842fSSascha Wildner { 4840d02842fSSascha Wildner return (AE_NO_MEMORY); 4850d02842fSSascha Wildner } 4860d02842fSSascha Wildner 4870d02842fSSascha Wildner ACPI_MOVE_NAME (NewInfo->Signature, Signature); 4880d02842fSSascha Wildner 4890d02842fSSascha Wildner if (!Gbl_TableListHead) 4900d02842fSSascha Wildner { 4910d02842fSSascha Wildner Gbl_TableListHead = NewInfo; 4920d02842fSSascha Wildner } 4930d02842fSSascha Wildner else 4940d02842fSSascha Wildner { 4950d02842fSSascha Wildner Next = Gbl_TableListHead; 4960d02842fSSascha Wildner while (1) 4970d02842fSSascha Wildner { 4980d02842fSSascha Wildner if (ACPI_COMPARE_NAME (Next->Signature, Signature)) 4990d02842fSSascha Wildner { 5000d02842fSSascha Wildner if (Next->Instance == Instance) 5010d02842fSSascha Wildner { 5020d02842fSSascha Wildner Found = TRUE; 5030d02842fSSascha Wildner } 5040d02842fSSascha Wildner if (Next->Instance >= NextInstance) 5050d02842fSSascha Wildner { 5060d02842fSSascha Wildner NextInstance = Next->Instance + 1; 5070d02842fSSascha Wildner } 5080d02842fSSascha Wildner } 5090d02842fSSascha Wildner 5100d02842fSSascha Wildner if (!Next->Next) 5110d02842fSSascha Wildner { 5120d02842fSSascha Wildner break; 5130d02842fSSascha Wildner } 5140d02842fSSascha Wildner Next = Next->Next; 5150d02842fSSascha Wildner } 5160d02842fSSascha Wildner Next->Next = NewInfo; 5170d02842fSSascha Wildner } 5180d02842fSSascha Wildner 5190d02842fSSascha Wildner if (Found) 5200d02842fSSascha Wildner { 5210d02842fSSascha Wildner if (Instance) 5220d02842fSSascha Wildner { 5230d02842fSSascha Wildner fprintf (stderr, 5240d02842fSSascha Wildner "%4.4s: Warning unmatched table instance %d, expected %d\n", 5250d02842fSSascha Wildner Signature, Instance, NextInstance); 5260d02842fSSascha Wildner } 5270d02842fSSascha Wildner Instance = NextInstance; 5280d02842fSSascha Wildner } 5290d02842fSSascha Wildner 5300d02842fSSascha Wildner NewInfo->Instance = Instance; 5310d02842fSSascha Wildner Gbl_TableCount++; 5320d02842fSSascha Wildner 5330d02842fSSascha Wildner return (AE_OK); 5340d02842fSSascha Wildner } 5350d02842fSSascha Wildner 5360d02842fSSascha Wildner 5370d02842fSSascha Wildner /****************************************************************************** 5380d02842fSSascha Wildner * 5390d02842fSSascha Wildner * FUNCTION: AcpiOsGetTableByIndex 5400d02842fSSascha Wildner * 5410d02842fSSascha Wildner * PARAMETERS: Index - Which table to get 5420d02842fSSascha Wildner * Table - Where a pointer to the table is returned 5430d02842fSSascha Wildner * Instance - Where a pointer to the table instance no. is 5440d02842fSSascha Wildner * returned 5450d02842fSSascha Wildner * Address - Where the table physical address is returned 5460d02842fSSascha Wildner * 5470d02842fSSascha Wildner * RETURN: Status; Table buffer and physical address returned if AE_OK. 5480d02842fSSascha Wildner * AE_LIMIT: Index is beyond valid limit 5490d02842fSSascha Wildner * 5500d02842fSSascha Wildner * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns 5510d02842fSSascha Wildner * AE_LIMIT when an invalid index is reached. Index is not 5520d02842fSSascha Wildner * necessarily an index into the RSDT/XSDT. 5530d02842fSSascha Wildner * 5540d02842fSSascha Wildner *****************************************************************************/ 5550d02842fSSascha Wildner 5560d02842fSSascha Wildner ACPI_STATUS 5570d02842fSSascha Wildner AcpiOsGetTableByIndex ( 5580d02842fSSascha Wildner UINT32 Index, 5590d02842fSSascha Wildner ACPI_TABLE_HEADER **Table, 5600d02842fSSascha Wildner UINT32 *Instance, 5610d02842fSSascha Wildner ACPI_PHYSICAL_ADDRESS *Address) 5620d02842fSSascha Wildner { 5630d02842fSSascha Wildner OSL_TABLE_INFO *Info; 5640d02842fSSascha Wildner ACPI_STATUS Status; 5650d02842fSSascha Wildner UINT32 i; 5660d02842fSSascha Wildner 5670d02842fSSascha Wildner 5680d02842fSSascha Wildner /* Get main ACPI tables from memory on first invocation of this function */ 5690d02842fSSascha Wildner 5700d02842fSSascha Wildner Status = OslTableInitialize (); 5710d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 5720d02842fSSascha Wildner { 5730d02842fSSascha Wildner return (Status); 5740d02842fSSascha Wildner } 5750d02842fSSascha Wildner 5760d02842fSSascha Wildner /* Validate Index */ 5770d02842fSSascha Wildner 5780d02842fSSascha Wildner if (Index >= Gbl_TableCount) 5790d02842fSSascha Wildner { 5800d02842fSSascha Wildner return (AE_LIMIT); 5810d02842fSSascha Wildner } 5820d02842fSSascha Wildner 5830d02842fSSascha Wildner /* Point to the table list entry specified by the Index argument */ 5840d02842fSSascha Wildner 5850d02842fSSascha Wildner Info = Gbl_TableListHead; 5860d02842fSSascha Wildner for (i = 0; i < Index; i++) 5870d02842fSSascha Wildner { 5880d02842fSSascha Wildner Info = Info->Next; 5890d02842fSSascha Wildner } 5900d02842fSSascha Wildner 5910d02842fSSascha Wildner /* Now we can just get the table via the signature */ 5920d02842fSSascha Wildner 5930d02842fSSascha Wildner Status = AcpiOsGetTableByName (Info->Signature, Info->Instance, 5940d02842fSSascha Wildner Table, Address); 5950d02842fSSascha Wildner 5960d02842fSSascha Wildner if (ACPI_SUCCESS (Status)) 5970d02842fSSascha Wildner { 5980d02842fSSascha Wildner *Instance = Info->Instance; 5990d02842fSSascha Wildner } 6000d02842fSSascha Wildner return (Status); 6010d02842fSSascha Wildner } 6020d02842fSSascha Wildner 6030d02842fSSascha Wildner 6040d02842fSSascha Wildner /****************************************************************************** 6050d02842fSSascha Wildner * 6065f39c7e7SSascha Wildner * FUNCTION: OslFindRsdpViaEfiByKeyword 6075f39c7e7SSascha Wildner * 6085f39c7e7SSascha Wildner * PARAMETERS: Keyword - Character string indicating ACPI GUID version 6095f39c7e7SSascha Wildner * in the EFI table 6105f39c7e7SSascha Wildner * 6115f39c7e7SSascha Wildner * RETURN: RSDP address if found 6125f39c7e7SSascha Wildner * 6135f39c7e7SSascha Wildner * DESCRIPTION: Find RSDP address via EFI using keyword indicating the ACPI 6145f39c7e7SSascha Wildner * GUID version. 6155f39c7e7SSascha Wildner * 6165f39c7e7SSascha Wildner *****************************************************************************/ 6175f39c7e7SSascha Wildner 6185f39c7e7SSascha Wildner static ACPI_PHYSICAL_ADDRESS 6195f39c7e7SSascha Wildner OslFindRsdpViaEfiByKeyword ( 6205f39c7e7SSascha Wildner FILE *File, 6215f39c7e7SSascha Wildner const char *Keyword) 6225f39c7e7SSascha Wildner { 6235f39c7e7SSascha Wildner char Buffer[80]; 6245f39c7e7SSascha Wildner unsigned long long Address = 0; 6255f39c7e7SSascha Wildner char Format[32]; 6265f39c7e7SSascha Wildner 6275f39c7e7SSascha Wildner 6285f39c7e7SSascha Wildner snprintf (Format, 32, "%s=%s", Keyword, "%llx"); 6295f39c7e7SSascha Wildner fseek (File, 0, SEEK_SET); 6305f39c7e7SSascha Wildner while (fgets (Buffer, 80, File)) 6315f39c7e7SSascha Wildner { 6325f39c7e7SSascha Wildner if (sscanf (Buffer, Format, &Address) == 1) 6335f39c7e7SSascha Wildner { 6345f39c7e7SSascha Wildner break; 6355f39c7e7SSascha Wildner } 6365f39c7e7SSascha Wildner } 6375f39c7e7SSascha Wildner 6385f39c7e7SSascha Wildner return ((ACPI_PHYSICAL_ADDRESS) (Address)); 6395f39c7e7SSascha Wildner } 6405f39c7e7SSascha Wildner 6415f39c7e7SSascha Wildner 6425f39c7e7SSascha Wildner /****************************************************************************** 6435f39c7e7SSascha Wildner * 6440d02842fSSascha Wildner * FUNCTION: OslFindRsdpViaEfi 6450d02842fSSascha Wildner * 6460d02842fSSascha Wildner * PARAMETERS: None 6470d02842fSSascha Wildner * 6480d02842fSSascha Wildner * RETURN: RSDP address if found 6490d02842fSSascha Wildner * 6500d02842fSSascha Wildner * DESCRIPTION: Find RSDP address via EFI. 6510d02842fSSascha Wildner * 6520d02842fSSascha Wildner *****************************************************************************/ 6530d02842fSSascha Wildner 6540d02842fSSascha Wildner static ACPI_PHYSICAL_ADDRESS 6550d02842fSSascha Wildner OslFindRsdpViaEfi ( 6560d02842fSSascha Wildner void) 6570d02842fSSascha Wildner { 6580d02842fSSascha Wildner FILE *File; 6595f39c7e7SSascha Wildner ACPI_PHYSICAL_ADDRESS Address = 0; 6600d02842fSSascha Wildner 6610d02842fSSascha Wildner 6620d02842fSSascha Wildner File = fopen (EFI_SYSTAB, "r"); 6630d02842fSSascha Wildner if (File) 6640d02842fSSascha Wildner { 6655f39c7e7SSascha Wildner Address = OslFindRsdpViaEfiByKeyword (File, "ACPI20"); 6665f39c7e7SSascha Wildner if (!Address) 6670d02842fSSascha Wildner { 6685f39c7e7SSascha Wildner Address = OslFindRsdpViaEfiByKeyword (File, "ACPI"); 6690d02842fSSascha Wildner } 6700d02842fSSascha Wildner fclose (File); 6710d02842fSSascha Wildner } 6720d02842fSSascha Wildner 6735f39c7e7SSascha Wildner return (Address); 6740d02842fSSascha Wildner } 6750d02842fSSascha Wildner 6760d02842fSSascha Wildner 6770d02842fSSascha Wildner /****************************************************************************** 6780d02842fSSascha Wildner * 6790d02842fSSascha Wildner * FUNCTION: OslLoadRsdp 6800d02842fSSascha Wildner * 6810d02842fSSascha Wildner * PARAMETERS: None 6820d02842fSSascha Wildner * 6830d02842fSSascha Wildner * RETURN: Status 6840d02842fSSascha Wildner * 6850d02842fSSascha Wildner * DESCRIPTION: Scan and load RSDP. 6860d02842fSSascha Wildner * 6870d02842fSSascha Wildner *****************************************************************************/ 6880d02842fSSascha Wildner 6890d02842fSSascha Wildner static ACPI_STATUS 6900d02842fSSascha Wildner OslLoadRsdp ( 6910d02842fSSascha Wildner void) 6920d02842fSSascha Wildner { 6930d02842fSSascha Wildner ACPI_TABLE_HEADER *MappedTable; 6940d02842fSSascha Wildner UINT8 *RsdpAddress; 6950d02842fSSascha Wildner ACPI_PHYSICAL_ADDRESS RsdpBase; 6960d02842fSSascha Wildner ACPI_SIZE RsdpSize; 6970d02842fSSascha Wildner 6980d02842fSSascha Wildner 6990d02842fSSascha Wildner /* Get RSDP from memory */ 7000d02842fSSascha Wildner 7010d02842fSSascha Wildner RsdpSize = sizeof (ACPI_TABLE_RSDP); 7020d02842fSSascha Wildner if (Gbl_RsdpBase) 7030d02842fSSascha Wildner { 7040d02842fSSascha Wildner RsdpBase = Gbl_RsdpBase; 7050d02842fSSascha Wildner } 7060d02842fSSascha Wildner else 7070d02842fSSascha Wildner { 7080d02842fSSascha Wildner RsdpBase = OslFindRsdpViaEfi (); 7090d02842fSSascha Wildner } 7100d02842fSSascha Wildner 7110d02842fSSascha Wildner if (!RsdpBase) 7120d02842fSSascha Wildner { 7130d02842fSSascha Wildner RsdpBase = ACPI_HI_RSDP_WINDOW_BASE; 7140d02842fSSascha Wildner RsdpSize = ACPI_HI_RSDP_WINDOW_SIZE; 7150d02842fSSascha Wildner } 7160d02842fSSascha Wildner 7170d02842fSSascha Wildner RsdpAddress = AcpiOsMapMemory (RsdpBase, RsdpSize); 7180d02842fSSascha Wildner if (!RsdpAddress) 7190d02842fSSascha Wildner { 7200d02842fSSascha Wildner return (OslGetLastStatus (AE_BAD_ADDRESS)); 7210d02842fSSascha Wildner } 7220d02842fSSascha Wildner 7230d02842fSSascha Wildner /* Search low memory for the RSDP */ 7240d02842fSSascha Wildner 7250d02842fSSascha Wildner MappedTable = ACPI_CAST_PTR (ACPI_TABLE_HEADER, 7260d02842fSSascha Wildner AcpiTbScanMemoryForRsdp (RsdpAddress, RsdpSize)); 7270d02842fSSascha Wildner if (!MappedTable) 7280d02842fSSascha Wildner { 7290d02842fSSascha Wildner AcpiOsUnmapMemory (RsdpAddress, RsdpSize); 7300d02842fSSascha Wildner return (AE_NOT_FOUND); 7310d02842fSSascha Wildner } 7320d02842fSSascha Wildner 7330d02842fSSascha Wildner Gbl_RsdpAddress = RsdpBase + (ACPI_CAST8 (MappedTable) - RsdpAddress); 7340d02842fSSascha Wildner 73525ca8c79SSascha Wildner memcpy (&Gbl_Rsdp, MappedTable, sizeof (ACPI_TABLE_RSDP)); 7360d02842fSSascha Wildner AcpiOsUnmapMemory (RsdpAddress, RsdpSize); 7370d02842fSSascha Wildner 7380d02842fSSascha Wildner return (AE_OK); 7390d02842fSSascha Wildner } 7400d02842fSSascha Wildner 7410d02842fSSascha Wildner 7420d02842fSSascha Wildner /****************************************************************************** 7430d02842fSSascha Wildner * 7449e1c0880SSascha Wildner * FUNCTION: OslCanUseXsdt 7459e1c0880SSascha Wildner * 7469e1c0880SSascha Wildner * PARAMETERS: None 7479e1c0880SSascha Wildner * 7489e1c0880SSascha Wildner * RETURN: TRUE if XSDT is allowed to be used. 7499e1c0880SSascha Wildner * 7509e1c0880SSascha Wildner * DESCRIPTION: This function collects logic that can be used to determine if 7519e1c0880SSascha Wildner * XSDT should be used instead of RSDT. 7529e1c0880SSascha Wildner * 7539e1c0880SSascha Wildner *****************************************************************************/ 7549e1c0880SSascha Wildner 7559e1c0880SSascha Wildner static BOOLEAN 7569e1c0880SSascha Wildner OslCanUseXsdt ( 7579e1c0880SSascha Wildner void) 7589e1c0880SSascha Wildner { 7599e1c0880SSascha Wildner if (Gbl_Revision && !AcpiGbl_DoNotUseXsdt) 7609e1c0880SSascha Wildner { 7619e1c0880SSascha Wildner return (TRUE); 7629e1c0880SSascha Wildner } 7639e1c0880SSascha Wildner else 7649e1c0880SSascha Wildner { 7659e1c0880SSascha Wildner return (FALSE); 7669e1c0880SSascha Wildner } 7679e1c0880SSascha Wildner } 7689e1c0880SSascha Wildner 7699e1c0880SSascha Wildner 7709e1c0880SSascha Wildner /****************************************************************************** 7719e1c0880SSascha Wildner * 7720d02842fSSascha Wildner * FUNCTION: OslTableInitialize 7730d02842fSSascha Wildner * 7740d02842fSSascha Wildner * PARAMETERS: None 7750d02842fSSascha Wildner * 7760d02842fSSascha Wildner * RETURN: Status 7770d02842fSSascha Wildner * 7780d02842fSSascha Wildner * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to 7790d02842fSSascha Wildner * local variables. Main ACPI tables include RSDT, FADT, RSDT, 7800d02842fSSascha Wildner * and/or XSDT. 7810d02842fSSascha Wildner * 7820d02842fSSascha Wildner *****************************************************************************/ 7830d02842fSSascha Wildner 7840d02842fSSascha Wildner static ACPI_STATUS 7850d02842fSSascha Wildner OslTableInitialize ( 7860d02842fSSascha Wildner void) 7870d02842fSSascha Wildner { 7880d02842fSSascha Wildner ACPI_STATUS Status; 7890d02842fSSascha Wildner ACPI_PHYSICAL_ADDRESS Address; 7900d02842fSSascha Wildner 7910d02842fSSascha Wildner 7920d02842fSSascha Wildner if (Gbl_TableListInitialized) 7930d02842fSSascha Wildner { 7940d02842fSSascha Wildner return (AE_OK); 7950d02842fSSascha Wildner } 7960d02842fSSascha Wildner 79725ca8c79SSascha Wildner if (!Gbl_DumpCustomizedTables) 79825ca8c79SSascha Wildner { 7990d02842fSSascha Wildner /* Get RSDP from memory */ 8000d02842fSSascha Wildner 8010d02842fSSascha Wildner Status = OslLoadRsdp (); 8020d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 8030d02842fSSascha Wildner { 8040d02842fSSascha Wildner return (Status); 8050d02842fSSascha Wildner } 8060d02842fSSascha Wildner 8070d02842fSSascha Wildner /* Get XSDT from memory */ 8080d02842fSSascha Wildner 8099e1c0880SSascha Wildner if (Gbl_Rsdp.Revision && !Gbl_DoNotDumpXsdt) 8100d02842fSSascha Wildner { 8110d02842fSSascha Wildner if (Gbl_Xsdt) 8120d02842fSSascha Wildner { 8130d02842fSSascha Wildner free (Gbl_Xsdt); 8140d02842fSSascha Wildner Gbl_Xsdt = NULL; 8150d02842fSSascha Wildner } 8160d02842fSSascha Wildner 8170d02842fSSascha Wildner Gbl_Revision = 2; 8180d02842fSSascha Wildner Status = OslGetBiosTable (ACPI_SIG_XSDT, 0, 8190d02842fSSascha Wildner ACPI_CAST_PTR (ACPI_TABLE_HEADER *, &Gbl_Xsdt), &Address); 8200d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 8210d02842fSSascha Wildner { 8220d02842fSSascha Wildner return (Status); 8230d02842fSSascha Wildner } 8240d02842fSSascha Wildner } 8250d02842fSSascha Wildner 8260d02842fSSascha Wildner /* Get RSDT from memory */ 8270d02842fSSascha Wildner 8280d02842fSSascha Wildner if (Gbl_Rsdp.RsdtPhysicalAddress) 8290d02842fSSascha Wildner { 8300d02842fSSascha Wildner if (Gbl_Rsdt) 8310d02842fSSascha Wildner { 8320d02842fSSascha Wildner free (Gbl_Rsdt); 8330d02842fSSascha Wildner Gbl_Rsdt = NULL; 8340d02842fSSascha Wildner } 8350d02842fSSascha Wildner 8360d02842fSSascha Wildner Status = OslGetBiosTable (ACPI_SIG_RSDT, 0, 8370d02842fSSascha Wildner ACPI_CAST_PTR (ACPI_TABLE_HEADER *, &Gbl_Rsdt), &Address); 8380d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 8390d02842fSSascha Wildner { 8400d02842fSSascha Wildner return (Status); 8410d02842fSSascha Wildner } 8420d02842fSSascha Wildner } 8430d02842fSSascha Wildner 8440d02842fSSascha Wildner /* Get FADT from memory */ 8450d02842fSSascha Wildner 8460d02842fSSascha Wildner if (Gbl_Fadt) 8470d02842fSSascha Wildner { 8480d02842fSSascha Wildner free (Gbl_Fadt); 8490d02842fSSascha Wildner Gbl_Fadt = NULL; 8500d02842fSSascha Wildner } 8510d02842fSSascha Wildner 8520d02842fSSascha Wildner Status = OslGetBiosTable (ACPI_SIG_FADT, 0, 8530d02842fSSascha Wildner ACPI_CAST_PTR (ACPI_TABLE_HEADER *, &Gbl_Fadt), &Gbl_FadtAddress); 8540d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 8550d02842fSSascha Wildner { 8560d02842fSSascha Wildner return (Status); 8570d02842fSSascha Wildner } 8580d02842fSSascha Wildner 8590d02842fSSascha Wildner /* Add mandatory tables to global table list first */ 8600d02842fSSascha Wildner 86120294b7eSSascha Wildner Status = OslAddTableToList (ACPI_RSDP_NAME, 0); 8620d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 8630d02842fSSascha Wildner { 8640d02842fSSascha Wildner return (Status); 8650d02842fSSascha Wildner } 8660d02842fSSascha Wildner 8670d02842fSSascha Wildner Status = OslAddTableToList (ACPI_SIG_RSDT, 0); 8680d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 8690d02842fSSascha Wildner { 8700d02842fSSascha Wildner return (Status); 8710d02842fSSascha Wildner } 8720d02842fSSascha Wildner 8730d02842fSSascha Wildner if (Gbl_Revision == 2) 8740d02842fSSascha Wildner { 8750d02842fSSascha Wildner Status = OslAddTableToList (ACPI_SIG_XSDT, 0); 8760d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 8770d02842fSSascha Wildner { 8780d02842fSSascha Wildner return (Status); 8790d02842fSSascha Wildner } 8800d02842fSSascha Wildner } 8810d02842fSSascha Wildner 8820d02842fSSascha Wildner Status = OslAddTableToList (ACPI_SIG_DSDT, 0); 8830d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 8840d02842fSSascha Wildner { 8850d02842fSSascha Wildner return (Status); 8860d02842fSSascha Wildner } 8870d02842fSSascha Wildner 8880d02842fSSascha Wildner Status = OslAddTableToList (ACPI_SIG_FACS, 0); 8890d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 8900d02842fSSascha Wildner { 8910d02842fSSascha Wildner return (Status); 8920d02842fSSascha Wildner } 8930d02842fSSascha Wildner 8940d02842fSSascha Wildner /* Add all tables found in the memory */ 8950d02842fSSascha Wildner 8960d02842fSSascha Wildner Status = OslListBiosTables (); 8970d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 8980d02842fSSascha Wildner { 8990d02842fSSascha Wildner return (Status); 9000d02842fSSascha Wildner } 9010d02842fSSascha Wildner } 9020d02842fSSascha Wildner else 9030d02842fSSascha Wildner { 9040d02842fSSascha Wildner /* Add all tables found in the static directory */ 9050d02842fSSascha Wildner 9060d02842fSSascha Wildner Status = OslListCustomizedTables (STATIC_TABLE_DIR); 9070d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 9080d02842fSSascha Wildner { 9090d02842fSSascha Wildner return (Status); 9100d02842fSSascha Wildner } 9110d02842fSSascha Wildner } 9120d02842fSSascha Wildner 9130d02842fSSascha Wildner if (Gbl_DumpDynamicTables) 9140d02842fSSascha Wildner { 9150d02842fSSascha Wildner /* Add all dynamically loaded tables in the dynamic directory */ 9160d02842fSSascha Wildner 9170d02842fSSascha Wildner Status = OslListCustomizedTables (DYNAMIC_TABLE_DIR); 9180d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 9190d02842fSSascha Wildner { 9200d02842fSSascha Wildner return (Status); 9210d02842fSSascha Wildner } 9220d02842fSSascha Wildner } 9230d02842fSSascha Wildner 9240d02842fSSascha Wildner Gbl_TableListInitialized = TRUE; 9250d02842fSSascha Wildner return (AE_OK); 9260d02842fSSascha Wildner } 9270d02842fSSascha Wildner 9280d02842fSSascha Wildner 9290d02842fSSascha Wildner /****************************************************************************** 9300d02842fSSascha Wildner * 9310d02842fSSascha Wildner * FUNCTION: OslListBiosTables 9320d02842fSSascha Wildner * 9330d02842fSSascha Wildner * PARAMETERS: None 9340d02842fSSascha Wildner * 9350d02842fSSascha Wildner * RETURN: Status; Table list is initialized if AE_OK. 9360d02842fSSascha Wildner * 9370d02842fSSascha Wildner * DESCRIPTION: Add ACPI tables to the table list from memory. 9380d02842fSSascha Wildner * 9390d02842fSSascha Wildner * NOTE: This works on Linux as table customization does not modify the 9400d02842fSSascha Wildner * addresses stored in RSDP/RSDT/XSDT/FADT. 9410d02842fSSascha Wildner * 9420d02842fSSascha Wildner *****************************************************************************/ 9430d02842fSSascha Wildner 9440d02842fSSascha Wildner static ACPI_STATUS 9450d02842fSSascha Wildner OslListBiosTables ( 9460d02842fSSascha Wildner void) 9470d02842fSSascha Wildner { 9480d02842fSSascha Wildner ACPI_TABLE_HEADER *MappedTable = NULL; 9490d02842fSSascha Wildner UINT8 *TableData; 9500d02842fSSascha Wildner UINT8 NumberOfTables; 9510d02842fSSascha Wildner UINT8 ItemSize; 9520d02842fSSascha Wildner ACPI_PHYSICAL_ADDRESS TableAddress = 0; 9530d02842fSSascha Wildner ACPI_STATUS Status = AE_OK; 9540d02842fSSascha Wildner UINT32 i; 9550d02842fSSascha Wildner 9560d02842fSSascha Wildner 9579e1c0880SSascha Wildner if (OslCanUseXsdt ()) 9580d02842fSSascha Wildner { 9590d02842fSSascha Wildner ItemSize = sizeof (UINT64); 9600d02842fSSascha Wildner TableData = ACPI_CAST8 (Gbl_Xsdt) + sizeof (ACPI_TABLE_HEADER); 9610d02842fSSascha Wildner NumberOfTables = 9620d02842fSSascha Wildner (UINT8) ((Gbl_Xsdt->Header.Length - sizeof (ACPI_TABLE_HEADER)) 9630d02842fSSascha Wildner / ItemSize); 9640d02842fSSascha Wildner } 9650d02842fSSascha Wildner else /* Use RSDT if XSDT is not available */ 9660d02842fSSascha Wildner { 9670d02842fSSascha Wildner ItemSize = sizeof (UINT32); 9680d02842fSSascha Wildner TableData = ACPI_CAST8 (Gbl_Rsdt) + sizeof (ACPI_TABLE_HEADER); 9690d02842fSSascha Wildner NumberOfTables = 9700d02842fSSascha Wildner (UINT8) ((Gbl_Rsdt->Header.Length - sizeof (ACPI_TABLE_HEADER)) 9710d02842fSSascha Wildner / ItemSize); 9720d02842fSSascha Wildner } 9730d02842fSSascha Wildner 9740d02842fSSascha Wildner /* Search RSDT/XSDT for the requested table */ 9750d02842fSSascha Wildner 9760d02842fSSascha Wildner for (i = 0; i < NumberOfTables; ++i, TableData += ItemSize) 9770d02842fSSascha Wildner { 9789e1c0880SSascha Wildner if (OslCanUseXsdt ()) 9790d02842fSSascha Wildner { 9800d02842fSSascha Wildner TableAddress = 9810d02842fSSascha Wildner (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST64 (TableData)); 9820d02842fSSascha Wildner } 9830d02842fSSascha Wildner else 9840d02842fSSascha Wildner { 9850d02842fSSascha Wildner TableAddress = 9860d02842fSSascha Wildner (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST32 (TableData)); 9870d02842fSSascha Wildner } 9880d02842fSSascha Wildner 9899e1c0880SSascha Wildner /* Skip NULL entries in RSDT/XSDT */ 9909e1c0880SSascha Wildner 991*3c639e0cSSascha Wildner if (TableAddress == 0) 9929e1c0880SSascha Wildner { 9939e1c0880SSascha Wildner continue; 9949e1c0880SSascha Wildner } 9959e1c0880SSascha Wildner 9960d02842fSSascha Wildner Status = OslMapTable (TableAddress, NULL, &MappedTable); 9970d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 9980d02842fSSascha Wildner { 9990d02842fSSascha Wildner return (Status); 10000d02842fSSascha Wildner } 10010d02842fSSascha Wildner 10020d02842fSSascha Wildner OslAddTableToList (MappedTable->Signature, 0); 10030d02842fSSascha Wildner OslUnmapTable (MappedTable); 10040d02842fSSascha Wildner } 10050d02842fSSascha Wildner 10060d02842fSSascha Wildner return (AE_OK); 10070d02842fSSascha Wildner } 10080d02842fSSascha Wildner 10090d02842fSSascha Wildner 10100d02842fSSascha Wildner /****************************************************************************** 10110d02842fSSascha Wildner * 10120d02842fSSascha Wildner * FUNCTION: OslGetBiosTable 10130d02842fSSascha Wildner * 10140d02842fSSascha Wildner * PARAMETERS: Signature - ACPI Signature for common table. Must be 10150d02842fSSascha Wildner * a null terminated 4-character string. 10160d02842fSSascha Wildner * Instance - Multiple table support for SSDT/UEFI (0...n) 10170d02842fSSascha Wildner * Must be 0 for other tables. 10180d02842fSSascha Wildner * Table - Where a pointer to the table is returned 10190d02842fSSascha Wildner * Address - Where the table physical address is returned 10200d02842fSSascha Wildner * 10210d02842fSSascha Wildner * RETURN: Status; Table buffer and physical address returned if AE_OK. 10220d02842fSSascha Wildner * AE_LIMIT: Instance is beyond valid limit 10230d02842fSSascha Wildner * AE_NOT_FOUND: A table with the signature was not found 10240d02842fSSascha Wildner * 10250d02842fSSascha Wildner * DESCRIPTION: Get a BIOS provided ACPI table 10260d02842fSSascha Wildner * 10270d02842fSSascha Wildner * NOTE: Assumes the input signature is uppercase. 10280d02842fSSascha Wildner * 10290d02842fSSascha Wildner *****************************************************************************/ 10300d02842fSSascha Wildner 10310d02842fSSascha Wildner static ACPI_STATUS 10320d02842fSSascha Wildner OslGetBiosTable ( 10330d02842fSSascha Wildner char *Signature, 10340d02842fSSascha Wildner UINT32 Instance, 10350d02842fSSascha Wildner ACPI_TABLE_HEADER **Table, 10360d02842fSSascha Wildner ACPI_PHYSICAL_ADDRESS *Address) 10370d02842fSSascha Wildner { 10380d02842fSSascha Wildner ACPI_TABLE_HEADER *LocalTable = NULL; 10390d02842fSSascha Wildner ACPI_TABLE_HEADER *MappedTable = NULL; 10400d02842fSSascha Wildner UINT8 *TableData; 10410d02842fSSascha Wildner UINT8 NumberOfTables; 10420d02842fSSascha Wildner UINT8 ItemSize; 10430d02842fSSascha Wildner UINT32 CurrentInstance = 0; 1044*3c639e0cSSascha Wildner ACPI_PHYSICAL_ADDRESS TableAddress; 1045*3c639e0cSSascha Wildner ACPI_PHYSICAL_ADDRESS FirstTableAddress = 0; 10460d02842fSSascha Wildner UINT32 TableLength = 0; 10470d02842fSSascha Wildner ACPI_STATUS Status = AE_OK; 10480d02842fSSascha Wildner UINT32 i; 10490d02842fSSascha Wildner 10500d02842fSSascha Wildner 10510d02842fSSascha Wildner /* Handle special tables whose addresses are not in RSDT/XSDT */ 10520d02842fSSascha Wildner 105320294b7eSSascha Wildner if (ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME) || 10540d02842fSSascha Wildner ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDT) || 10550d02842fSSascha Wildner ACPI_COMPARE_NAME (Signature, ACPI_SIG_XSDT) || 10560d02842fSSascha Wildner ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT) || 10570d02842fSSascha Wildner ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) 10580d02842fSSascha Wildner { 1059*3c639e0cSSascha Wildner 1060*3c639e0cSSascha Wildner FindNextInstance: 1061*3c639e0cSSascha Wildner 1062*3c639e0cSSascha Wildner TableAddress = 0; 10635f39c7e7SSascha Wildner 10640d02842fSSascha Wildner /* 10650d02842fSSascha Wildner * Get the appropriate address, either 32-bit or 64-bit. Be very 10660d02842fSSascha Wildner * careful about the FADT length and validate table addresses. 10670d02842fSSascha Wildner * Note: The 64-bit addresses have priority. 10680d02842fSSascha Wildner */ 10690d02842fSSascha Wildner if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT)) 10700d02842fSSascha Wildner { 1071*3c639e0cSSascha Wildner if (CurrentInstance < 2) 1072*3c639e0cSSascha Wildner { 10730d02842fSSascha Wildner if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XDSDT) && 1074*3c639e0cSSascha Wildner Gbl_Fadt->XDsdt && CurrentInstance == 0) 10750d02842fSSascha Wildner { 10760d02842fSSascha Wildner TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XDsdt; 10770d02842fSSascha Wildner } 10780d02842fSSascha Wildner else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_DSDT) && 1079*3c639e0cSSascha Wildner Gbl_Fadt->Dsdt != FirstTableAddress) 10800d02842fSSascha Wildner { 10810d02842fSSascha Wildner TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Dsdt; 10820d02842fSSascha Wildner } 10830d02842fSSascha Wildner } 1084*3c639e0cSSascha Wildner } 10850d02842fSSascha Wildner else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) 10860d02842fSSascha Wildner { 1087*3c639e0cSSascha Wildner if (CurrentInstance < 2) 1088*3c639e0cSSascha Wildner { 10890d02842fSSascha Wildner if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XFACS) && 1090*3c639e0cSSascha Wildner Gbl_Fadt->XFacs && CurrentInstance == 0) 10910d02842fSSascha Wildner { 10920d02842fSSascha Wildner TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XFacs; 10930d02842fSSascha Wildner } 10940d02842fSSascha Wildner else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_FACS) && 1095*3c639e0cSSascha Wildner Gbl_Fadt->Facs != FirstTableAddress) 10960d02842fSSascha Wildner { 10970d02842fSSascha Wildner TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Facs; 10980d02842fSSascha Wildner } 10990d02842fSSascha Wildner } 1100*3c639e0cSSascha Wildner } 11010d02842fSSascha Wildner else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_XSDT)) 11020d02842fSSascha Wildner { 11030d02842fSSascha Wildner if (!Gbl_Revision) 11040d02842fSSascha Wildner { 11050d02842fSSascha Wildner return (AE_BAD_SIGNATURE); 11060d02842fSSascha Wildner } 1107*3c639e0cSSascha Wildner if (CurrentInstance == 0) 1108*3c639e0cSSascha Wildner { 1109*3c639e0cSSascha Wildner TableAddress = 1110*3c639e0cSSascha Wildner (ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.XsdtPhysicalAddress; 1111*3c639e0cSSascha Wildner } 11120d02842fSSascha Wildner } 11130d02842fSSascha Wildner else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDT)) 11140d02842fSSascha Wildner { 1115*3c639e0cSSascha Wildner if (CurrentInstance == 0) 1116*3c639e0cSSascha Wildner { 1117*3c639e0cSSascha Wildner TableAddress = 1118*3c639e0cSSascha Wildner (ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.RsdtPhysicalAddress; 1119*3c639e0cSSascha Wildner } 11200d02842fSSascha Wildner } 11210d02842fSSascha Wildner else 11220d02842fSSascha Wildner { 1123*3c639e0cSSascha Wildner if (CurrentInstance == 0) 1124*3c639e0cSSascha Wildner { 11250d02842fSSascha Wildner TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_RsdpAddress; 11260d02842fSSascha Wildner Signature = ACPI_SIG_RSDP; 11270d02842fSSascha Wildner } 1128*3c639e0cSSascha Wildner } 1129*3c639e0cSSascha Wildner 1130*3c639e0cSSascha Wildner if (TableAddress == 0) 1131*3c639e0cSSascha Wildner { 1132*3c639e0cSSascha Wildner goto ExitFindTable; 1133*3c639e0cSSascha Wildner } 11340d02842fSSascha Wildner 11350d02842fSSascha Wildner /* Now we can get the requested special table */ 11360d02842fSSascha Wildner 11370d02842fSSascha Wildner Status = OslMapTable (TableAddress, Signature, &MappedTable); 11380d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 11390d02842fSSascha Wildner { 11400d02842fSSascha Wildner return (Status); 11410d02842fSSascha Wildner } 11420d02842fSSascha Wildner 11430d02842fSSascha Wildner TableLength = ApGetTableLength (MappedTable); 1144*3c639e0cSSascha Wildner if (FirstTableAddress == 0) 1145*3c639e0cSSascha Wildner { 1146*3c639e0cSSascha Wildner FirstTableAddress = TableAddress; 1147*3c639e0cSSascha Wildner } 1148*3c639e0cSSascha Wildner 1149*3c639e0cSSascha Wildner /* Match table instance */ 1150*3c639e0cSSascha Wildner 1151*3c639e0cSSascha Wildner if (CurrentInstance != Instance) 1152*3c639e0cSSascha Wildner { 1153*3c639e0cSSascha Wildner OslUnmapTable (MappedTable); 1154*3c639e0cSSascha Wildner MappedTable = NULL; 1155*3c639e0cSSascha Wildner CurrentInstance++; 1156*3c639e0cSSascha Wildner goto FindNextInstance; 1157*3c639e0cSSascha Wildner } 11580d02842fSSascha Wildner } 11590d02842fSSascha Wildner else /* Case for a normal ACPI table */ 11600d02842fSSascha Wildner { 11619e1c0880SSascha Wildner if (OslCanUseXsdt ()) 11620d02842fSSascha Wildner { 11630d02842fSSascha Wildner ItemSize = sizeof (UINT64); 11640d02842fSSascha Wildner TableData = ACPI_CAST8 (Gbl_Xsdt) + sizeof (ACPI_TABLE_HEADER); 11650d02842fSSascha Wildner NumberOfTables = 11660d02842fSSascha Wildner (UINT8) ((Gbl_Xsdt->Header.Length - sizeof (ACPI_TABLE_HEADER)) 11670d02842fSSascha Wildner / ItemSize); 11680d02842fSSascha Wildner } 11690d02842fSSascha Wildner else /* Use RSDT if XSDT is not available */ 11700d02842fSSascha Wildner { 11710d02842fSSascha Wildner ItemSize = sizeof (UINT32); 11720d02842fSSascha Wildner TableData = ACPI_CAST8 (Gbl_Rsdt) + sizeof (ACPI_TABLE_HEADER); 11730d02842fSSascha Wildner NumberOfTables = 11740d02842fSSascha Wildner (UINT8) ((Gbl_Rsdt->Header.Length - sizeof (ACPI_TABLE_HEADER)) 11750d02842fSSascha Wildner / ItemSize); 11760d02842fSSascha Wildner } 11770d02842fSSascha Wildner 11780d02842fSSascha Wildner /* Search RSDT/XSDT for the requested table */ 11790d02842fSSascha Wildner 11800d02842fSSascha Wildner for (i = 0; i < NumberOfTables; ++i, TableData += ItemSize) 11810d02842fSSascha Wildner { 11829e1c0880SSascha Wildner if (OslCanUseXsdt ()) 11830d02842fSSascha Wildner { 11840d02842fSSascha Wildner TableAddress = 11850d02842fSSascha Wildner (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST64 (TableData)); 11860d02842fSSascha Wildner } 11870d02842fSSascha Wildner else 11880d02842fSSascha Wildner { 11890d02842fSSascha Wildner TableAddress = 11900d02842fSSascha Wildner (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST32 (TableData)); 11910d02842fSSascha Wildner } 11920d02842fSSascha Wildner 11939e1c0880SSascha Wildner /* Skip NULL entries in RSDT/XSDT */ 11949e1c0880SSascha Wildner 1195*3c639e0cSSascha Wildner if (TableAddress == 0) 11969e1c0880SSascha Wildner { 11979e1c0880SSascha Wildner continue; 11989e1c0880SSascha Wildner } 11999e1c0880SSascha Wildner 12000d02842fSSascha Wildner Status = OslMapTable (TableAddress, NULL, &MappedTable); 12010d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 12020d02842fSSascha Wildner { 12030d02842fSSascha Wildner return (Status); 12040d02842fSSascha Wildner } 12050d02842fSSascha Wildner TableLength = MappedTable->Length; 12060d02842fSSascha Wildner 12070d02842fSSascha Wildner /* Does this table match the requested signature? */ 12080d02842fSSascha Wildner 12090d02842fSSascha Wildner if (!ACPI_COMPARE_NAME (MappedTable->Signature, Signature)) 12100d02842fSSascha Wildner { 12110d02842fSSascha Wildner OslUnmapTable (MappedTable); 12120d02842fSSascha Wildner MappedTable = NULL; 12130d02842fSSascha Wildner continue; 12140d02842fSSascha Wildner } 12150d02842fSSascha Wildner 12160d02842fSSascha Wildner /* Match table instance (for SSDT/UEFI tables) */ 12170d02842fSSascha Wildner 12180d02842fSSascha Wildner if (CurrentInstance != Instance) 12190d02842fSSascha Wildner { 12200d02842fSSascha Wildner OslUnmapTable (MappedTable); 12210d02842fSSascha Wildner MappedTable = NULL; 12220d02842fSSascha Wildner CurrentInstance++; 12230d02842fSSascha Wildner continue; 12240d02842fSSascha Wildner } 12250d02842fSSascha Wildner 12260d02842fSSascha Wildner break; 12270d02842fSSascha Wildner } 12280d02842fSSascha Wildner } 12290d02842fSSascha Wildner 1230*3c639e0cSSascha Wildner ExitFindTable: 1231*3c639e0cSSascha Wildner 12320d02842fSSascha Wildner if (!MappedTable) 12330d02842fSSascha Wildner { 12340d02842fSSascha Wildner return (AE_LIMIT); 12350d02842fSSascha Wildner } 12360d02842fSSascha Wildner 12370d02842fSSascha Wildner if (TableLength == 0) 12380d02842fSSascha Wildner { 12390d02842fSSascha Wildner Status = AE_BAD_HEADER; 1240d4972a9cSSascha Wildner goto Exit; 12410d02842fSSascha Wildner } 12420d02842fSSascha Wildner 12430d02842fSSascha Wildner /* Copy table to local buffer and return it */ 12440d02842fSSascha Wildner 12450d02842fSSascha Wildner LocalTable = calloc (1, TableLength); 12460d02842fSSascha Wildner if (!LocalTable) 12470d02842fSSascha Wildner { 12480d02842fSSascha Wildner Status = AE_NO_MEMORY; 1249d4972a9cSSascha Wildner goto Exit; 12500d02842fSSascha Wildner } 12510d02842fSSascha Wildner 125225ca8c79SSascha Wildner memcpy (LocalTable, MappedTable, TableLength); 12530d02842fSSascha Wildner *Address = TableAddress; 12540d02842fSSascha Wildner *Table = LocalTable; 12550d02842fSSascha Wildner 1256d4972a9cSSascha Wildner Exit: 12570d02842fSSascha Wildner OslUnmapTable (MappedTable); 1258d4972a9cSSascha Wildner return (Status); 12590d02842fSSascha Wildner } 12600d02842fSSascha Wildner 12610d02842fSSascha Wildner 12620d02842fSSascha Wildner /****************************************************************************** 12630d02842fSSascha Wildner * 12640d02842fSSascha Wildner * FUNCTION: OslListCustomizedTables 12650d02842fSSascha Wildner * 12660d02842fSSascha Wildner * PARAMETERS: Directory - Directory that contains the tables 12670d02842fSSascha Wildner * 12680d02842fSSascha Wildner * RETURN: Status; Table list is initialized if AE_OK. 12690d02842fSSascha Wildner * 12700d02842fSSascha Wildner * DESCRIPTION: Add ACPI tables to the table list from a directory. 12710d02842fSSascha Wildner * 12720d02842fSSascha Wildner *****************************************************************************/ 12730d02842fSSascha Wildner 12740d02842fSSascha Wildner static ACPI_STATUS 12750d02842fSSascha Wildner OslListCustomizedTables ( 12760d02842fSSascha Wildner char *Directory) 12770d02842fSSascha Wildner { 12780d02842fSSascha Wildner void *TableDir; 12790d02842fSSascha Wildner UINT32 Instance; 12800d02842fSSascha Wildner char TempName[ACPI_NAME_SIZE]; 12810d02842fSSascha Wildner char *Filename; 12820d02842fSSascha Wildner ACPI_STATUS Status = AE_OK; 12830d02842fSSascha Wildner 12840d02842fSSascha Wildner 12850d02842fSSascha Wildner /* Open the requested directory */ 12860d02842fSSascha Wildner 12870d02842fSSascha Wildner TableDir = AcpiOsOpenDirectory (Directory, "*", REQUEST_FILE_ONLY); 12880d02842fSSascha Wildner if (!TableDir) 12890d02842fSSascha Wildner { 12900d02842fSSascha Wildner return (OslGetLastStatus (AE_NOT_FOUND)); 12910d02842fSSascha Wildner } 12920d02842fSSascha Wildner 12930d02842fSSascha Wildner /* Examine all entries in this directory */ 12940d02842fSSascha Wildner 12950d02842fSSascha Wildner while ((Filename = AcpiOsGetNextFilename (TableDir))) 12960d02842fSSascha Wildner { 12970d02842fSSascha Wildner /* Extract table name and instance number */ 12980d02842fSSascha Wildner 12990d02842fSSascha Wildner Status = OslTableNameFromFile (Filename, TempName, &Instance); 13000d02842fSSascha Wildner 13010d02842fSSascha Wildner /* Ignore meaningless files */ 13020d02842fSSascha Wildner 13030d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 13040d02842fSSascha Wildner { 13050d02842fSSascha Wildner continue; 13060d02842fSSascha Wildner } 13070d02842fSSascha Wildner 13080d02842fSSascha Wildner /* Add new info node to global table list */ 13090d02842fSSascha Wildner 13100d02842fSSascha Wildner Status = OslAddTableToList (TempName, Instance); 13110d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 13120d02842fSSascha Wildner { 13130d02842fSSascha Wildner break; 13140d02842fSSascha Wildner } 13150d02842fSSascha Wildner } 13160d02842fSSascha Wildner 13170d02842fSSascha Wildner AcpiOsCloseDirectory (TableDir); 13180d02842fSSascha Wildner return (Status); 13190d02842fSSascha Wildner } 13200d02842fSSascha Wildner 13210d02842fSSascha Wildner 13220d02842fSSascha Wildner /****************************************************************************** 13230d02842fSSascha Wildner * 13240d02842fSSascha Wildner * FUNCTION: OslMapTable 13250d02842fSSascha Wildner * 13260d02842fSSascha Wildner * PARAMETERS: Address - Address of the table in memory 13270d02842fSSascha Wildner * Signature - Optional ACPI Signature for desired table. 13280d02842fSSascha Wildner * Null terminated 4-character string. 13290d02842fSSascha Wildner * Table - Where a pointer to the mapped table is 13300d02842fSSascha Wildner * returned 13310d02842fSSascha Wildner * 13320d02842fSSascha Wildner * RETURN: Status; Mapped table is returned if AE_OK. 13330d02842fSSascha Wildner * AE_NOT_FOUND: A valid table was not found at the address 13340d02842fSSascha Wildner * 13350d02842fSSascha Wildner * DESCRIPTION: Map entire ACPI table into caller's address space. 13360d02842fSSascha Wildner * 13370d02842fSSascha Wildner *****************************************************************************/ 13380d02842fSSascha Wildner 13390d02842fSSascha Wildner static ACPI_STATUS 13400d02842fSSascha Wildner OslMapTable ( 13410d02842fSSascha Wildner ACPI_SIZE Address, 13420d02842fSSascha Wildner char *Signature, 13430d02842fSSascha Wildner ACPI_TABLE_HEADER **Table) 13440d02842fSSascha Wildner { 13450d02842fSSascha Wildner ACPI_TABLE_HEADER *MappedTable; 13460d02842fSSascha Wildner UINT32 Length; 13470d02842fSSascha Wildner 13480d02842fSSascha Wildner 13490d02842fSSascha Wildner if (!Address) 13500d02842fSSascha Wildner { 13510d02842fSSascha Wildner return (AE_BAD_ADDRESS); 13520d02842fSSascha Wildner } 13530d02842fSSascha Wildner 13540d02842fSSascha Wildner /* 13550d02842fSSascha Wildner * Map the header so we can get the table length. 13560d02842fSSascha Wildner * Use sizeof (ACPI_TABLE_HEADER) as: 13570d02842fSSascha Wildner * 1. it is bigger than 24 to include RSDP->Length 13580d02842fSSascha Wildner * 2. it is smaller than sizeof (ACPI_TABLE_RSDP) 13590d02842fSSascha Wildner */ 13600d02842fSSascha Wildner MappedTable = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); 13610d02842fSSascha Wildner if (!MappedTable) 13620d02842fSSascha Wildner { 13630d02842fSSascha Wildner fprintf (stderr, "Could not map table header at 0x%8.8X%8.8X\n", 13640d02842fSSascha Wildner ACPI_FORMAT_UINT64 (Address)); 13650d02842fSSascha Wildner return (OslGetLastStatus (AE_BAD_ADDRESS)); 13660d02842fSSascha Wildner } 13670d02842fSSascha Wildner 13680d02842fSSascha Wildner /* If specified, signature must match */ 13690d02842fSSascha Wildner 13709e1c0880SSascha Wildner if (Signature) 13719e1c0880SSascha Wildner { 13729e1c0880SSascha Wildner if (ACPI_VALIDATE_RSDP_SIG (Signature)) 13739e1c0880SSascha Wildner { 13749e1c0880SSascha Wildner if (!ACPI_VALIDATE_RSDP_SIG (MappedTable->Signature)) 13750d02842fSSascha Wildner { 13760d02842fSSascha Wildner AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER)); 13770d02842fSSascha Wildner return (AE_BAD_SIGNATURE); 13780d02842fSSascha Wildner } 13799e1c0880SSascha Wildner } 13809e1c0880SSascha Wildner else if (!ACPI_COMPARE_NAME (Signature, MappedTable->Signature)) 13819e1c0880SSascha Wildner { 13829e1c0880SSascha Wildner AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER)); 13839e1c0880SSascha Wildner return (AE_BAD_SIGNATURE); 13849e1c0880SSascha Wildner } 13859e1c0880SSascha Wildner } 13860d02842fSSascha Wildner 13870d02842fSSascha Wildner /* Map the entire table */ 13880d02842fSSascha Wildner 13890d02842fSSascha Wildner Length = ApGetTableLength (MappedTable); 13900d02842fSSascha Wildner AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER)); 13910d02842fSSascha Wildner if (Length == 0) 13920d02842fSSascha Wildner { 13930d02842fSSascha Wildner return (AE_BAD_HEADER); 13940d02842fSSascha Wildner } 13950d02842fSSascha Wildner 13960d02842fSSascha Wildner MappedTable = AcpiOsMapMemory (Address, Length); 13970d02842fSSascha Wildner if (!MappedTable) 13980d02842fSSascha Wildner { 13990d02842fSSascha Wildner fprintf (stderr, "Could not map table at 0x%8.8X%8.8X length %8.8X\n", 14000d02842fSSascha Wildner ACPI_FORMAT_UINT64 (Address), Length); 14010d02842fSSascha Wildner return (OslGetLastStatus (AE_INVALID_TABLE_LENGTH)); 14020d02842fSSascha Wildner } 14030d02842fSSascha Wildner 14040d02842fSSascha Wildner (void) ApIsValidChecksum (MappedTable); 14050d02842fSSascha Wildner 14060d02842fSSascha Wildner *Table = MappedTable; 14070d02842fSSascha Wildner return (AE_OK); 14080d02842fSSascha Wildner } 14090d02842fSSascha Wildner 14100d02842fSSascha Wildner 14110d02842fSSascha Wildner /****************************************************************************** 14120d02842fSSascha Wildner * 14130d02842fSSascha Wildner * FUNCTION: OslUnmapTable 14140d02842fSSascha Wildner * 14150d02842fSSascha Wildner * PARAMETERS: Table - A pointer to the mapped table 14160d02842fSSascha Wildner * 14170d02842fSSascha Wildner * RETURN: None 14180d02842fSSascha Wildner * 14190d02842fSSascha Wildner * DESCRIPTION: Unmap entire ACPI table. 14200d02842fSSascha Wildner * 14210d02842fSSascha Wildner *****************************************************************************/ 14220d02842fSSascha Wildner 14230d02842fSSascha Wildner static void 14240d02842fSSascha Wildner OslUnmapTable ( 14250d02842fSSascha Wildner ACPI_TABLE_HEADER *Table) 14260d02842fSSascha Wildner { 14270d02842fSSascha Wildner if (Table) 14280d02842fSSascha Wildner { 14290d02842fSSascha Wildner AcpiOsUnmapMemory (Table, ApGetTableLength (Table)); 14300d02842fSSascha Wildner } 14310d02842fSSascha Wildner } 14320d02842fSSascha Wildner 14330d02842fSSascha Wildner 14340d02842fSSascha Wildner /****************************************************************************** 14350d02842fSSascha Wildner * 14360d02842fSSascha Wildner * FUNCTION: OslTableNameFromFile 14370d02842fSSascha Wildner * 14380d02842fSSascha Wildner * PARAMETERS: Filename - File that contains the desired table 14390d02842fSSascha Wildner * Signature - Pointer to 4-character buffer to store 14400d02842fSSascha Wildner * extracted table signature. 14410d02842fSSascha Wildner * Instance - Pointer to integer to store extracted 14420d02842fSSascha Wildner * table instance number. 14430d02842fSSascha Wildner * 14440d02842fSSascha Wildner * RETURN: Status; Table name is extracted if AE_OK. 14450d02842fSSascha Wildner * 14460d02842fSSascha Wildner * DESCRIPTION: Extract table signature and instance number from a table file 14470d02842fSSascha Wildner * name. 14480d02842fSSascha Wildner * 14490d02842fSSascha Wildner *****************************************************************************/ 14500d02842fSSascha Wildner 14510d02842fSSascha Wildner static ACPI_STATUS 14520d02842fSSascha Wildner OslTableNameFromFile ( 14530d02842fSSascha Wildner char *Filename, 14540d02842fSSascha Wildner char *Signature, 14550d02842fSSascha Wildner UINT32 *Instance) 14560d02842fSSascha Wildner { 14570d02842fSSascha Wildner 14580d02842fSSascha Wildner /* Ignore meaningless files */ 14590d02842fSSascha Wildner 14600d02842fSSascha Wildner if (strlen (Filename) < ACPI_NAME_SIZE) 14610d02842fSSascha Wildner { 14620d02842fSSascha Wildner return (AE_BAD_SIGNATURE); 14630d02842fSSascha Wildner } 14640d02842fSSascha Wildner 14650d02842fSSascha Wildner /* Extract instance number */ 14660d02842fSSascha Wildner 14670d02842fSSascha Wildner if (isdigit ((int) Filename[ACPI_NAME_SIZE])) 14680d02842fSSascha Wildner { 14695943f66cSSascha Wildner sscanf (&Filename[ACPI_NAME_SIZE], "%u", Instance); 14700d02842fSSascha Wildner } 14710d02842fSSascha Wildner else if (strlen (Filename) != ACPI_NAME_SIZE) 14720d02842fSSascha Wildner { 14730d02842fSSascha Wildner return (AE_BAD_SIGNATURE); 14740d02842fSSascha Wildner } 14750d02842fSSascha Wildner else 14760d02842fSSascha Wildner { 14770d02842fSSascha Wildner *Instance = 0; 14780d02842fSSascha Wildner } 14790d02842fSSascha Wildner 14800d02842fSSascha Wildner /* Extract signature */ 14810d02842fSSascha Wildner 14820d02842fSSascha Wildner ACPI_MOVE_NAME (Signature, Filename); 14830d02842fSSascha Wildner return (AE_OK); 14840d02842fSSascha Wildner } 14850d02842fSSascha Wildner 14860d02842fSSascha Wildner 14870d02842fSSascha Wildner /****************************************************************************** 14880d02842fSSascha Wildner * 14890d02842fSSascha Wildner * FUNCTION: OslReadTableFromFile 14900d02842fSSascha Wildner * 14910d02842fSSascha Wildner * PARAMETERS: Filename - File that contains the desired table 14920d02842fSSascha Wildner * FileOffset - Offset of the table in file 14930d02842fSSascha Wildner * Signature - Optional ACPI Signature for desired table. 14940d02842fSSascha Wildner * A null terminated 4-character string. 14950d02842fSSascha Wildner * Table - Where a pointer to the table is returned 14960d02842fSSascha Wildner * 14970d02842fSSascha Wildner * RETURN: Status; Table buffer is returned if AE_OK. 14980d02842fSSascha Wildner * 14990d02842fSSascha Wildner * DESCRIPTION: Read a ACPI table from a file. 15000d02842fSSascha Wildner * 15010d02842fSSascha Wildner *****************************************************************************/ 15020d02842fSSascha Wildner 15030d02842fSSascha Wildner static ACPI_STATUS 15040d02842fSSascha Wildner OslReadTableFromFile ( 15050d02842fSSascha Wildner char *Filename, 15060d02842fSSascha Wildner ACPI_SIZE FileOffset, 15070d02842fSSascha Wildner char *Signature, 15080d02842fSSascha Wildner ACPI_TABLE_HEADER **Table) 15090d02842fSSascha Wildner { 15100d02842fSSascha Wildner FILE *TableFile; 15110d02842fSSascha Wildner ACPI_TABLE_HEADER Header; 15120d02842fSSascha Wildner ACPI_TABLE_HEADER *LocalTable = NULL; 15130d02842fSSascha Wildner UINT32 TableLength; 15140d02842fSSascha Wildner INT32 Count; 15150d02842fSSascha Wildner ACPI_STATUS Status = AE_OK; 15160d02842fSSascha Wildner 15170d02842fSSascha Wildner 15180d02842fSSascha Wildner /* Open the file */ 15190d02842fSSascha Wildner 15200d02842fSSascha Wildner TableFile = fopen (Filename, "rb"); 15210d02842fSSascha Wildner if (TableFile == NULL) 15220d02842fSSascha Wildner { 15230d02842fSSascha Wildner fprintf (stderr, "Could not open table file: %s\n", Filename); 15240d02842fSSascha Wildner return (OslGetLastStatus (AE_NOT_FOUND)); 15250d02842fSSascha Wildner } 15260d02842fSSascha Wildner 15270d02842fSSascha Wildner fseek (TableFile, FileOffset, SEEK_SET); 15280d02842fSSascha Wildner 15290d02842fSSascha Wildner /* Read the Table header to get the table length */ 15300d02842fSSascha Wildner 15310d02842fSSascha Wildner Count = fread (&Header, 1, sizeof (ACPI_TABLE_HEADER), TableFile); 15320d02842fSSascha Wildner if (Count != sizeof (ACPI_TABLE_HEADER)) 15330d02842fSSascha Wildner { 15340d02842fSSascha Wildner fprintf (stderr, "Could not read table header: %s\n", Filename); 15350d02842fSSascha Wildner Status = AE_BAD_HEADER; 1536d4972a9cSSascha Wildner goto Exit; 15370d02842fSSascha Wildner } 15380d02842fSSascha Wildner 15390d02842fSSascha Wildner /* If signature is specified, it must match the table */ 15400d02842fSSascha Wildner 15419e1c0880SSascha Wildner if (Signature) 15429e1c0880SSascha Wildner { 15439e1c0880SSascha Wildner if (ACPI_VALIDATE_RSDP_SIG (Signature)) 15449e1c0880SSascha Wildner { 15459e1c0880SSascha Wildner if (!ACPI_VALIDATE_RSDP_SIG (Header.Signature)) { 15469e1c0880SSascha Wildner fprintf (stderr, "Incorrect RSDP signature: found %8.8s\n", 15479e1c0880SSascha Wildner Header.Signature); 15489e1c0880SSascha Wildner Status = AE_BAD_SIGNATURE; 15499e1c0880SSascha Wildner goto Exit; 15509e1c0880SSascha Wildner } 15519e1c0880SSascha Wildner } 15529e1c0880SSascha Wildner else if (!ACPI_COMPARE_NAME (Signature, Header.Signature)) 15530d02842fSSascha Wildner { 15540d02842fSSascha Wildner fprintf (stderr, "Incorrect signature: Expecting %4.4s, found %4.4s\n", 15550d02842fSSascha Wildner Signature, Header.Signature); 15560d02842fSSascha Wildner Status = AE_BAD_SIGNATURE; 1557d4972a9cSSascha Wildner goto Exit; 15580d02842fSSascha Wildner } 15599e1c0880SSascha Wildner } 15600d02842fSSascha Wildner 15610d02842fSSascha Wildner TableLength = ApGetTableLength (&Header); 15620d02842fSSascha Wildner if (TableLength == 0) 15630d02842fSSascha Wildner { 15640d02842fSSascha Wildner Status = AE_BAD_HEADER; 1565d4972a9cSSascha Wildner goto Exit; 15660d02842fSSascha Wildner } 15670d02842fSSascha Wildner 15680d02842fSSascha Wildner /* Read the entire table into a local buffer */ 15690d02842fSSascha Wildner 15700d02842fSSascha Wildner LocalTable = calloc (1, TableLength); 15710d02842fSSascha Wildner if (!LocalTable) 15720d02842fSSascha Wildner { 15730d02842fSSascha Wildner fprintf (stderr, 15740d02842fSSascha Wildner "%4.4s: Could not allocate buffer for table of length %X\n", 15750d02842fSSascha Wildner Header.Signature, TableLength); 15760d02842fSSascha Wildner Status = AE_NO_MEMORY; 1577d4972a9cSSascha Wildner goto Exit; 15780d02842fSSascha Wildner } 15790d02842fSSascha Wildner 15800d02842fSSascha Wildner fseek (TableFile, FileOffset, SEEK_SET); 15810d02842fSSascha Wildner 15829e1c0880SSascha Wildner Count = fread (LocalTable, 1, TableLength, TableFile); 15839e1c0880SSascha Wildner if (Count != TableLength) 15840d02842fSSascha Wildner { 15850d02842fSSascha Wildner fprintf (stderr, "%4.4s: Could not read table content\n", 15860d02842fSSascha Wildner Header.Signature); 15870d02842fSSascha Wildner Status = AE_INVALID_TABLE_LENGTH; 1588d4972a9cSSascha Wildner goto Exit; 15890d02842fSSascha Wildner } 15900d02842fSSascha Wildner 15910d02842fSSascha Wildner /* Validate checksum */ 15920d02842fSSascha Wildner 15930d02842fSSascha Wildner (void) ApIsValidChecksum (LocalTable); 15940d02842fSSascha Wildner 1595d4972a9cSSascha Wildner Exit: 15960d02842fSSascha Wildner fclose (TableFile); 15970d02842fSSascha Wildner *Table = LocalTable; 15980d02842fSSascha Wildner return (Status); 15990d02842fSSascha Wildner } 16000d02842fSSascha Wildner 16010d02842fSSascha Wildner 16020d02842fSSascha Wildner /****************************************************************************** 16030d02842fSSascha Wildner * 16040d02842fSSascha Wildner * FUNCTION: OslGetCustomizedTable 16050d02842fSSascha Wildner * 16060d02842fSSascha Wildner * PARAMETERS: Pathname - Directory to find Linux customized table 16070d02842fSSascha Wildner * Signature - ACPI Signature for desired table. Must be 16080d02842fSSascha Wildner * a null terminated 4-character string. 16090d02842fSSascha Wildner * Instance - Multiple table support for SSDT/UEFI (0...n) 16100d02842fSSascha Wildner * Must be 0 for other tables. 16110d02842fSSascha Wildner * Table - Where a pointer to the table is returned 16120d02842fSSascha Wildner * Address - Where the table physical address is returned 16130d02842fSSascha Wildner * 16140d02842fSSascha Wildner * RETURN: Status; Table buffer is returned if AE_OK. 16150d02842fSSascha Wildner * AE_LIMIT: Instance is beyond valid limit 16160d02842fSSascha Wildner * AE_NOT_FOUND: A table with the signature was not found 16170d02842fSSascha Wildner * 16180d02842fSSascha Wildner * DESCRIPTION: Get an OS customized table. 16190d02842fSSascha Wildner * 16200d02842fSSascha Wildner *****************************************************************************/ 16210d02842fSSascha Wildner 16220d02842fSSascha Wildner static ACPI_STATUS 16230d02842fSSascha Wildner OslGetCustomizedTable ( 16240d02842fSSascha Wildner char *Pathname, 16250d02842fSSascha Wildner char *Signature, 16260d02842fSSascha Wildner UINT32 Instance, 16270d02842fSSascha Wildner ACPI_TABLE_HEADER **Table, 16280d02842fSSascha Wildner ACPI_PHYSICAL_ADDRESS *Address) 16290d02842fSSascha Wildner { 16300d02842fSSascha Wildner void *TableDir; 16310d02842fSSascha Wildner UINT32 CurrentInstance = 0; 16320d02842fSSascha Wildner char TempName[ACPI_NAME_SIZE]; 16330d02842fSSascha Wildner char TableFilename[PATH_MAX]; 16340d02842fSSascha Wildner char *Filename; 16350d02842fSSascha Wildner ACPI_STATUS Status; 16360d02842fSSascha Wildner 16370d02842fSSascha Wildner 16380d02842fSSascha Wildner /* Open the directory for customized tables */ 16390d02842fSSascha Wildner 16400d02842fSSascha Wildner TableDir = AcpiOsOpenDirectory (Pathname, "*", REQUEST_FILE_ONLY); 16410d02842fSSascha Wildner if (!TableDir) 16420d02842fSSascha Wildner { 16430d02842fSSascha Wildner return (OslGetLastStatus (AE_NOT_FOUND)); 16440d02842fSSascha Wildner } 16450d02842fSSascha Wildner 16460d02842fSSascha Wildner /* Attempt to find the table in the directory */ 16470d02842fSSascha Wildner 16480d02842fSSascha Wildner while ((Filename = AcpiOsGetNextFilename (TableDir))) 16490d02842fSSascha Wildner { 16500d02842fSSascha Wildner /* Ignore meaningless files */ 16510d02842fSSascha Wildner 16520d02842fSSascha Wildner if (!ACPI_COMPARE_NAME (Filename, Signature)) 16530d02842fSSascha Wildner { 16540d02842fSSascha Wildner continue; 16550d02842fSSascha Wildner } 16560d02842fSSascha Wildner 16570d02842fSSascha Wildner /* Extract table name and instance number */ 16580d02842fSSascha Wildner 16590d02842fSSascha Wildner Status = OslTableNameFromFile (Filename, TempName, &CurrentInstance); 16600d02842fSSascha Wildner 16610d02842fSSascha Wildner /* Ignore meaningless files */ 16620d02842fSSascha Wildner 16630d02842fSSascha Wildner if (ACPI_FAILURE (Status) || CurrentInstance != Instance) 16640d02842fSSascha Wildner { 16650d02842fSSascha Wildner continue; 16660d02842fSSascha Wildner } 16670d02842fSSascha Wildner 16680d02842fSSascha Wildner /* Create the table pathname */ 16690d02842fSSascha Wildner 16700d02842fSSascha Wildner if (Instance != 0) 16710d02842fSSascha Wildner { 16720d02842fSSascha Wildner sprintf (TableFilename, "%s/%4.4s%d", Pathname, TempName, Instance); 16730d02842fSSascha Wildner } 16740d02842fSSascha Wildner else 16750d02842fSSascha Wildner { 16760d02842fSSascha Wildner sprintf (TableFilename, "%s/%4.4s", Pathname, TempName); 16770d02842fSSascha Wildner } 16780d02842fSSascha Wildner break; 16790d02842fSSascha Wildner } 16800d02842fSSascha Wildner 16810d02842fSSascha Wildner AcpiOsCloseDirectory (TableDir); 16820d02842fSSascha Wildner 16830d02842fSSascha Wildner if (!Filename) 16840d02842fSSascha Wildner { 16850d02842fSSascha Wildner return (AE_LIMIT); 16860d02842fSSascha Wildner } 16870d02842fSSascha Wildner 16880d02842fSSascha Wildner /* There is no physical address saved for customized tables, use zero */ 16890d02842fSSascha Wildner 16900d02842fSSascha Wildner *Address = 0; 16910d02842fSSascha Wildner Status = OslReadTableFromFile (TableFilename, 0, NULL, Table); 16920d02842fSSascha Wildner 16930d02842fSSascha Wildner return (Status); 16940d02842fSSascha Wildner } 1695