15943f66cSSascha Wildner /******************************************************************************
25943f66cSSascha Wildner *
35943f66cSSascha Wildner * Module Name: osbsdtbl - BSD OSL for obtaining ACPI tables
45943f66cSSascha Wildner *
55943f66cSSascha Wildner *****************************************************************************/
65943f66cSSascha Wildner
7b4315fc7SSascha Wildner /******************************************************************************
8b4315fc7SSascha Wildner *
9b4315fc7SSascha Wildner * 1. Copyright Notice
10b4315fc7SSascha Wildner *
11*383048acSSascha Wildner * Some or all of this work - Copyright (c) 1999 - 2021, Intel Corp.
125943f66cSSascha Wildner * All rights reserved.
135943f66cSSascha 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 *
1195943f66cSSascha Wildner * Redistribution and use in source and binary forms, with or without
1205943f66cSSascha Wildner * modification, are permitted provided that the following conditions
1215943f66cSSascha Wildner * are met:
1225943f66cSSascha Wildner * 1. Redistributions of source code must retain the above copyright
1235943f66cSSascha Wildner * notice, this list of conditions, and the following disclaimer,
1245943f66cSSascha Wildner * without modification.
1255943f66cSSascha Wildner * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1265943f66cSSascha Wildner * substantially similar to the "NO WARRANTY" disclaimer below
1275943f66cSSascha Wildner * ("Disclaimer") and any redistribution must be conditioned upon
1285943f66cSSascha Wildner * including a substantially similar Disclaimer requirement for further
1295943f66cSSascha Wildner * binary redistribution.
1305943f66cSSascha Wildner * 3. Neither the names of the above-listed copyright holders nor the names
1315943f66cSSascha Wildner * of any contributors may be used to endorse or promote products derived
1325943f66cSSascha Wildner * from this software without specific prior written permission.
1335943f66cSSascha 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
1475943f66cSSascha Wildner * GNU General Public License ("GPL") version 2 as published by the Free
1485943f66cSSascha Wildner * Software Foundation.
1495943f66cSSascha Wildner *
150b4315fc7SSascha Wildner *****************************************************************************/
1515943f66cSSascha Wildner
1525943f66cSSascha Wildner #include "acpidump.h"
1535943f66cSSascha Wildner
1542e03c868SSascha Wildner #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined (__DragonFly__)
1555943f66cSSascha Wildner #include <kenv.h>
1565943f66cSSascha Wildner #endif
1575943f66cSSascha Wildner #include <unistd.h>
1585943f66cSSascha Wildner #include <sys/param.h>
1595943f66cSSascha Wildner #include <sys/sysctl.h>
1605943f66cSSascha Wildner
1615943f66cSSascha Wildner
1625943f66cSSascha Wildner #define _COMPONENT ACPI_OS_SERVICES
1635943f66cSSascha Wildner ACPI_MODULE_NAME ("osbsdtbl")
1645943f66cSSascha Wildner
1655943f66cSSascha Wildner
1665943f66cSSascha Wildner /* Local prototypes */
1675943f66cSSascha Wildner
1685943f66cSSascha Wildner static ACPI_STATUS
1695943f66cSSascha Wildner OslTableInitialize (
1705943f66cSSascha Wildner void);
1715943f66cSSascha Wildner
1725943f66cSSascha Wildner static ACPI_STATUS
1735943f66cSSascha Wildner OslMapTable (
1745943f66cSSascha Wildner ACPI_SIZE Address,
1755943f66cSSascha Wildner char *Signature,
1765943f66cSSascha Wildner ACPI_TABLE_HEADER **Table);
1775943f66cSSascha Wildner
1785943f66cSSascha Wildner static ACPI_STATUS
1795943f66cSSascha Wildner OslAddTablesToList (
1805943f66cSSascha Wildner void);
1815943f66cSSascha Wildner
1825943f66cSSascha Wildner static ACPI_STATUS
1835943f66cSSascha Wildner OslGetTableViaRoot (
1845943f66cSSascha Wildner char *Signature,
1855943f66cSSascha Wildner UINT32 Instance,
1865943f66cSSascha Wildner ACPI_TABLE_HEADER **Table,
1875943f66cSSascha Wildner ACPI_PHYSICAL_ADDRESS *Address);
1885943f66cSSascha Wildner
1895943f66cSSascha Wildner
1905943f66cSSascha Wildner /* Hints for RSDP */
1915943f66cSSascha Wildner #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
1925943f66cSSascha Wildner #define SYSTEM_KENV "hint.acpi.0.rsdp"
1935943f66cSSascha Wildner #define SYSTEM_SYSCTL "machdep.acpi_root"
1945943f66cSSascha Wildner #elif defined(__NetBSD__)
1955943f66cSSascha Wildner #define SYSTEM_SYSCTL "hw.acpi.root"
1965943f66cSSascha Wildner #endif
1975943f66cSSascha Wildner
1985943f66cSSascha Wildner /* Initialization flags */
1995943f66cSSascha Wildner
2005943f66cSSascha Wildner UINT8 Gbl_TableListInitialized = FALSE;
2015943f66cSSascha Wildner UINT8 Gbl_MainTableObtained = FALSE;
2025943f66cSSascha Wildner
2035943f66cSSascha Wildner /* Local copies of main ACPI tables */
2045943f66cSSascha Wildner
2055943f66cSSascha Wildner ACPI_TABLE_RSDP Gbl_Rsdp;
2065943f66cSSascha Wildner ACPI_TABLE_FADT *Gbl_Fadt;
2075943f66cSSascha Wildner ACPI_TABLE_RSDT *Gbl_Rsdt;
2085943f66cSSascha Wildner ACPI_TABLE_XSDT *Gbl_Xsdt;
2095943f66cSSascha Wildner
2105943f66cSSascha Wildner /* Fadt address */
2115943f66cSSascha Wildner
2125943f66cSSascha Wildner ACPI_PHYSICAL_ADDRESS Gbl_FadtAddress;
2135943f66cSSascha Wildner
2145943f66cSSascha Wildner /* Revision of RSD PTR */
2155943f66cSSascha Wildner
2165943f66cSSascha Wildner UINT8 Gbl_Revision;
2175943f66cSSascha Wildner
2185943f66cSSascha Wildner /* List of information about obtained ACPI tables */
2195943f66cSSascha Wildner
2205943f66cSSascha Wildner typedef struct table_info
2215943f66cSSascha Wildner {
2225943f66cSSascha Wildner struct table_info *Next;
2235943f66cSSascha Wildner char Signature[4];
2245943f66cSSascha Wildner UINT32 Instance;
2255943f66cSSascha Wildner ACPI_PHYSICAL_ADDRESS Address;
2265943f66cSSascha Wildner
2275943f66cSSascha Wildner } OSL_TABLE_INFO;
2285943f66cSSascha Wildner
2295943f66cSSascha Wildner OSL_TABLE_INFO *Gbl_TableListHead = NULL;
2305943f66cSSascha Wildner
2315943f66cSSascha Wildner
2325943f66cSSascha Wildner /******************************************************************************
2335943f66cSSascha Wildner *
2345943f66cSSascha Wildner * FUNCTION: AcpiOsGetTableByAddress
2355943f66cSSascha Wildner *
2365943f66cSSascha Wildner * PARAMETERS: Address - Physical address of the ACPI table
2375943f66cSSascha Wildner * Table - Where a pointer to the table is returned
2385943f66cSSascha Wildner *
2395943f66cSSascha Wildner * RETURN: Status; Table buffer is returned if AE_OK.
2405943f66cSSascha Wildner * AE_NOT_FOUND: A valid table was not found at the address
2415943f66cSSascha Wildner *
2425943f66cSSascha Wildner * DESCRIPTION: Get an ACPI table via a physical memory address.
2435943f66cSSascha Wildner *
2445943f66cSSascha Wildner *****************************************************************************/
2455943f66cSSascha Wildner
2465943f66cSSascha Wildner ACPI_STATUS
AcpiOsGetTableByAddress(ACPI_PHYSICAL_ADDRESS Address,ACPI_TABLE_HEADER ** Table)2475943f66cSSascha Wildner AcpiOsGetTableByAddress (
2485943f66cSSascha Wildner ACPI_PHYSICAL_ADDRESS Address,
2495943f66cSSascha Wildner ACPI_TABLE_HEADER **Table)
2505943f66cSSascha Wildner {
2515943f66cSSascha Wildner ACPI_TABLE_HEADER *MappedTable;
2525943f66cSSascha Wildner ACPI_TABLE_HEADER *LocalTable;
2535943f66cSSascha Wildner ACPI_STATUS Status;
2545943f66cSSascha Wildner
2555943f66cSSascha Wildner
2565943f66cSSascha Wildner /* Validate the input physical address to avoid program crash */
2575943f66cSSascha Wildner
2585943f66cSSascha Wildner if (Address < ACPI_HI_RSDP_WINDOW_BASE)
2595943f66cSSascha Wildner {
2605943f66cSSascha Wildner fprintf (stderr, "Invalid table address: 0x%8.8X%8.8X\n",
2615943f66cSSascha Wildner ACPI_FORMAT_UINT64 (Address));
2625943f66cSSascha Wildner return (AE_BAD_ADDRESS);
2635943f66cSSascha Wildner }
2645943f66cSSascha Wildner
2655943f66cSSascha Wildner /* Map the table and validate it */
2665943f66cSSascha Wildner
2675943f66cSSascha Wildner Status = OslMapTable (Address, NULL, &MappedTable);
2685943f66cSSascha Wildner if (ACPI_FAILURE (Status))
2695943f66cSSascha Wildner {
2705943f66cSSascha Wildner return (Status);
2715943f66cSSascha Wildner }
2725943f66cSSascha Wildner
2735943f66cSSascha Wildner /* Copy table to local buffer and return it */
2745943f66cSSascha Wildner
2755943f66cSSascha Wildner LocalTable = calloc (1, MappedTable->Length);
2765943f66cSSascha Wildner if (!LocalTable)
2775943f66cSSascha Wildner {
2785943f66cSSascha Wildner AcpiOsUnmapMemory (MappedTable, MappedTable->Length);
2795943f66cSSascha Wildner return (AE_NO_MEMORY);
2805943f66cSSascha Wildner }
2815943f66cSSascha Wildner
28225ca8c79SSascha Wildner memcpy (LocalTable, MappedTable, MappedTable->Length);
2835943f66cSSascha Wildner AcpiOsUnmapMemory (MappedTable, MappedTable->Length);
2845943f66cSSascha Wildner
2855943f66cSSascha Wildner *Table = LocalTable;
2865943f66cSSascha Wildner return (AE_OK);
2875943f66cSSascha Wildner }
2885943f66cSSascha Wildner
2895943f66cSSascha Wildner
2905943f66cSSascha Wildner /******************************************************************************
2915943f66cSSascha Wildner *
2925943f66cSSascha Wildner * FUNCTION: AcpiOsGetTableByName
2935943f66cSSascha Wildner *
2945943f66cSSascha Wildner * PARAMETERS: Signature - ACPI Signature for desired table. Must be
2955943f66cSSascha Wildner * a null terminated 4-character string.
2965943f66cSSascha Wildner * Instance - Multiple table support for SSDT/UEFI (0...n)
2975943f66cSSascha Wildner * Must be 0 for other tables.
2985943f66cSSascha Wildner * Table - Where a pointer to the table is returned
2995943f66cSSascha Wildner * Address - Where the table physical address is returned
3005943f66cSSascha Wildner *
3015943f66cSSascha Wildner * RETURN: Status; Table buffer and physical address returned if AE_OK.
3025943f66cSSascha Wildner * AE_LIMIT: Instance is beyond valid limit
3035943f66cSSascha Wildner * AE_NOT_FOUND: A table with the signature was not found
3045943f66cSSascha Wildner *
3055943f66cSSascha Wildner * NOTE: Assumes the input signature is uppercase.
3065943f66cSSascha Wildner *
3075943f66cSSascha Wildner *****************************************************************************/
3085943f66cSSascha Wildner
3095943f66cSSascha Wildner ACPI_STATUS
AcpiOsGetTableByName(char * Signature,UINT32 Instance,ACPI_TABLE_HEADER ** Table,ACPI_PHYSICAL_ADDRESS * Address)3105943f66cSSascha Wildner AcpiOsGetTableByName (
3115943f66cSSascha Wildner char *Signature,
3125943f66cSSascha Wildner UINT32 Instance,
3135943f66cSSascha Wildner ACPI_TABLE_HEADER **Table,
3145943f66cSSascha Wildner ACPI_PHYSICAL_ADDRESS *Address)
3155943f66cSSascha Wildner {
3165943f66cSSascha Wildner ACPI_STATUS Status;
3175943f66cSSascha Wildner
3185943f66cSSascha Wildner
3195943f66cSSascha Wildner /* Instance is only valid for SSDT/UEFI tables */
3205943f66cSSascha Wildner
3215943f66cSSascha Wildner if (Instance &&
322c1776041SSascha Wildner !ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_SSDT) &&
323c1776041SSascha Wildner !ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_UEFI))
3245943f66cSSascha Wildner {
3255943f66cSSascha Wildner return (AE_LIMIT);
3265943f66cSSascha Wildner }
3275943f66cSSascha Wildner
3285943f66cSSascha Wildner /* Initialize main tables */
3295943f66cSSascha Wildner
3305943f66cSSascha Wildner Status = OslTableInitialize ();
3315943f66cSSascha Wildner if (ACPI_FAILURE (Status))
3325943f66cSSascha Wildner {
3335943f66cSSascha Wildner return (Status);
3345943f66cSSascha Wildner }
3355943f66cSSascha Wildner
3365943f66cSSascha Wildner /*
3375943f66cSSascha Wildner * If one of the main ACPI tables was requested (RSDT/XSDT/FADT),
3385943f66cSSascha Wildner * simply return it immediately.
3395943f66cSSascha Wildner */
340c1776041SSascha Wildner if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_XSDT))
3415943f66cSSascha Wildner {
3425943f66cSSascha Wildner if (!Gbl_Revision)
3435943f66cSSascha Wildner {
3445943f66cSSascha Wildner return (AE_NOT_FOUND);
3455943f66cSSascha Wildner }
3465943f66cSSascha Wildner
3475943f66cSSascha Wildner *Address = Gbl_Rsdp.XsdtPhysicalAddress;
3485943f66cSSascha Wildner *Table = (ACPI_TABLE_HEADER *) Gbl_Xsdt;
3495943f66cSSascha Wildner return (AE_OK);
3505943f66cSSascha Wildner }
3515943f66cSSascha Wildner
352c1776041SSascha Wildner if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_RSDT))
3535943f66cSSascha Wildner {
3545943f66cSSascha Wildner if (!Gbl_Rsdp.RsdtPhysicalAddress)
3555943f66cSSascha Wildner {
3565943f66cSSascha Wildner return (AE_NOT_FOUND);
3575943f66cSSascha Wildner }
3585943f66cSSascha Wildner
3595943f66cSSascha Wildner *Address = Gbl_Rsdp.RsdtPhysicalAddress;
3605943f66cSSascha Wildner *Table = (ACPI_TABLE_HEADER *) Gbl_Rsdt;
3615943f66cSSascha Wildner return (AE_OK);
3625943f66cSSascha Wildner }
3635943f66cSSascha Wildner
364c1776041SSascha Wildner if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_FADT))
3655943f66cSSascha Wildner {
3665943f66cSSascha Wildner *Address = Gbl_FadtAddress;
3675943f66cSSascha Wildner *Table = (ACPI_TABLE_HEADER *) Gbl_Fadt;
3685943f66cSSascha Wildner return (AE_OK);
3695943f66cSSascha Wildner }
3705943f66cSSascha Wildner
3715943f66cSSascha Wildner /* Not a main ACPI table, attempt to extract it from the RSDT/XSDT */
3725943f66cSSascha Wildner
3735943f66cSSascha Wildner Status = OslGetTableViaRoot (Signature, Instance, Table, Address);
3745943f66cSSascha Wildner if (ACPI_FAILURE (Status))
3755943f66cSSascha Wildner {
3765943f66cSSascha Wildner return (Status);
3775943f66cSSascha Wildner }
3785943f66cSSascha Wildner
3795943f66cSSascha Wildner return (AE_OK);
3805943f66cSSascha Wildner }
3815943f66cSSascha Wildner
3825943f66cSSascha Wildner
3835943f66cSSascha Wildner /******************************************************************************
3845943f66cSSascha Wildner *
3855943f66cSSascha Wildner * FUNCTION: AcpiOsGetTableByIndex
3865943f66cSSascha Wildner *
3875943f66cSSascha Wildner * PARAMETERS: Index - Which table to get
3885943f66cSSascha Wildner * Table - Where a pointer to the table is returned
3895943f66cSSascha Wildner * Instance - Where a pointer to the table instance no. is
3905943f66cSSascha Wildner * returned
3915943f66cSSascha Wildner * Address - Where the table physical address is returned
3925943f66cSSascha Wildner *
3935943f66cSSascha Wildner * RETURN: Status; Table buffer and physical address returned if AE_OK.
3945943f66cSSascha Wildner * AE_LIMIT: Index is beyond valid limit
3955943f66cSSascha Wildner *
3965943f66cSSascha Wildner * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns
3975943f66cSSascha Wildner * AE_LIMIT when an invalid index is reached. Index is not
3985943f66cSSascha Wildner * necessarily an index into the RSDT/XSDT.
3995943f66cSSascha Wildner *
4005943f66cSSascha Wildner *****************************************************************************/
4015943f66cSSascha Wildner
4025943f66cSSascha Wildner ACPI_STATUS
AcpiOsGetTableByIndex(UINT32 Index,ACPI_TABLE_HEADER ** Table,UINT32 * Instance,ACPI_PHYSICAL_ADDRESS * Address)4035943f66cSSascha Wildner AcpiOsGetTableByIndex (
4045943f66cSSascha Wildner UINT32 Index,
4055943f66cSSascha Wildner ACPI_TABLE_HEADER **Table,
4065943f66cSSascha Wildner UINT32 *Instance,
4075943f66cSSascha Wildner ACPI_PHYSICAL_ADDRESS *Address)
4085943f66cSSascha Wildner {
4095943f66cSSascha Wildner OSL_TABLE_INFO *Info;
4105943f66cSSascha Wildner ACPI_STATUS Status;
4115943f66cSSascha Wildner UINT32 i;
4125943f66cSSascha Wildner
4135943f66cSSascha Wildner
4145943f66cSSascha Wildner /* Initialize main tables */
4155943f66cSSascha Wildner
4165943f66cSSascha Wildner Status = OslTableInitialize ();
4175943f66cSSascha Wildner if (ACPI_FAILURE (Status))
4185943f66cSSascha Wildner {
4195943f66cSSascha Wildner return (Status);
4205943f66cSSascha Wildner }
4215943f66cSSascha Wildner
4225943f66cSSascha Wildner /* Add all tables to list */
4235943f66cSSascha Wildner
4245943f66cSSascha Wildner Status = OslAddTablesToList ();
4255943f66cSSascha Wildner if (ACPI_FAILURE (Status))
4265943f66cSSascha Wildner {
4275943f66cSSascha Wildner return (Status);
4285943f66cSSascha Wildner }
4295943f66cSSascha Wildner
4305943f66cSSascha Wildner /* Validate Index */
4315943f66cSSascha Wildner
4325943f66cSSascha Wildner if (Index >= Gbl_TableListHead->Instance)
4335943f66cSSascha Wildner {
4345943f66cSSascha Wildner return (AE_LIMIT);
4355943f66cSSascha Wildner }
4365943f66cSSascha Wildner
4375943f66cSSascha Wildner /* Point to the table list entry specified by the Index argument */
4385943f66cSSascha Wildner
4395943f66cSSascha Wildner Info = Gbl_TableListHead;
4405943f66cSSascha Wildner for (i = 0; i <= Index; i++)
4415943f66cSSascha Wildner {
4425943f66cSSascha Wildner Info = Info->Next;
4435943f66cSSascha Wildner }
4445943f66cSSascha Wildner
4455943f66cSSascha Wildner /* Now we can just get the table via the address or name */
4465943f66cSSascha Wildner
4475943f66cSSascha Wildner if (Info->Address)
4485943f66cSSascha Wildner {
4495943f66cSSascha Wildner Status = AcpiOsGetTableByAddress (Info->Address, Table);
4505943f66cSSascha Wildner if (ACPI_SUCCESS (Status))
4515943f66cSSascha Wildner {
4525943f66cSSascha Wildner *Address = Info->Address;
4535943f66cSSascha Wildner }
4545943f66cSSascha Wildner }
4555943f66cSSascha Wildner else
4565943f66cSSascha Wildner {
4575943f66cSSascha Wildner Status = AcpiOsGetTableByName (Info->Signature, Info->Instance,
4585943f66cSSascha Wildner Table, Address);
4595943f66cSSascha Wildner }
4605943f66cSSascha Wildner
4615943f66cSSascha Wildner if (ACPI_SUCCESS (Status))
4625943f66cSSascha Wildner {
4635943f66cSSascha Wildner *Instance = Info->Instance;
4645943f66cSSascha Wildner }
4655943f66cSSascha Wildner return (Status);
4665943f66cSSascha Wildner }
4675943f66cSSascha Wildner
4685943f66cSSascha Wildner
4695943f66cSSascha Wildner /******************************************************************************
4705943f66cSSascha Wildner *
4715943f66cSSascha Wildner * FUNCTION: OslTableInitialize
4725943f66cSSascha Wildner *
4735943f66cSSascha Wildner * PARAMETERS: None
4745943f66cSSascha Wildner *
4755943f66cSSascha Wildner * RETURN: Status
4765943f66cSSascha Wildner *
4775943f66cSSascha Wildner * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to
4785943f66cSSascha Wildner * local variables. Main ACPI tables include RSDP, FADT, RSDT,
4795943f66cSSascha Wildner * and/or XSDT.
4805943f66cSSascha Wildner *
4815943f66cSSascha Wildner *****************************************************************************/
4825943f66cSSascha Wildner
4835943f66cSSascha Wildner static ACPI_STATUS
OslTableInitialize(void)4845943f66cSSascha Wildner OslTableInitialize (
4855943f66cSSascha Wildner void)
4865943f66cSSascha Wildner {
4872e03c868SSascha Wildner #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
4885943f66cSSascha Wildner char Buffer[32];
4895943f66cSSascha Wildner #endif
4905943f66cSSascha Wildner ACPI_TABLE_HEADER *MappedTable;
4915943f66cSSascha Wildner UINT8 *TableAddress;
4925943f66cSSascha Wildner UINT8 *RsdpAddress;
4935943f66cSSascha Wildner ACPI_PHYSICAL_ADDRESS RsdpBase;
4945943f66cSSascha Wildner ACPI_SIZE RsdpSize;
4955943f66cSSascha Wildner ACPI_STATUS Status;
4965943f66cSSascha Wildner u_long Address = 0;
4972ffe9f16SSascha Wildner #if defined(SYSTEM_SYSCTL)
4985943f66cSSascha Wildner size_t Length = sizeof (Address);
4992ffe9f16SSascha Wildner #endif
5005943f66cSSascha Wildner
5015943f66cSSascha Wildner
5025943f66cSSascha Wildner /* Get main ACPI tables from memory on first invocation of this function */
5035943f66cSSascha Wildner
5045943f66cSSascha Wildner if (Gbl_MainTableObtained)
5055943f66cSSascha Wildner {
5065943f66cSSascha Wildner return (AE_OK);
5075943f66cSSascha Wildner }
5085943f66cSSascha Wildner
5095943f66cSSascha Wildner /* Attempt to use kenv or sysctl to find RSD PTR record. */
5105943f66cSSascha Wildner
5115943f66cSSascha Wildner if (Gbl_RsdpBase)
5125943f66cSSascha Wildner {
5135943f66cSSascha Wildner Address = Gbl_RsdpBase;
5145943f66cSSascha Wildner }
5152e03c868SSascha Wildner #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined (__DragonFly__)
5165943f66cSSascha Wildner else if (kenv (KENV_GET, SYSTEM_KENV, Buffer, sizeof (Buffer)) > 0)
5175943f66cSSascha Wildner {
51825ca8c79SSascha Wildner Address = strtoul (Buffer, NULL, 0);
5195943f66cSSascha Wildner }
5205943f66cSSascha Wildner #endif
5212ffe9f16SSascha Wildner #if defined(SYSTEM_SYSCTL)
5225943f66cSSascha Wildner if (!Address)
5235943f66cSSascha Wildner {
5245943f66cSSascha Wildner if (sysctlbyname (SYSTEM_SYSCTL, &Address, &Length, NULL, 0) != 0)
5255943f66cSSascha Wildner {
5265943f66cSSascha Wildner Address = 0;
5275943f66cSSascha Wildner }
5285943f66cSSascha Wildner }
5292ffe9f16SSascha Wildner #endif
5305943f66cSSascha Wildner if (Address)
5315943f66cSSascha Wildner {
5325943f66cSSascha Wildner RsdpBase = Address;
5335943f66cSSascha Wildner RsdpSize = sizeof (Gbl_Rsdp);
5345943f66cSSascha Wildner }
5355943f66cSSascha Wildner else
5365943f66cSSascha Wildner {
5375943f66cSSascha Wildner RsdpBase = ACPI_HI_RSDP_WINDOW_BASE;
5385943f66cSSascha Wildner RsdpSize = ACPI_HI_RSDP_WINDOW_SIZE;
5395943f66cSSascha Wildner }
5405943f66cSSascha Wildner
5415943f66cSSascha Wildner /* Get RSDP from memory */
5425943f66cSSascha Wildner
5435943f66cSSascha Wildner RsdpAddress = AcpiOsMapMemory (RsdpBase, RsdpSize);
5445943f66cSSascha Wildner if (!RsdpAddress)
5455943f66cSSascha Wildner {
5465943f66cSSascha Wildner return (AE_BAD_ADDRESS);
5475943f66cSSascha Wildner }
5485943f66cSSascha Wildner
5495943f66cSSascha Wildner /* Search low memory for the RSDP */
5505943f66cSSascha Wildner
5515943f66cSSascha Wildner TableAddress = AcpiTbScanMemoryForRsdp (RsdpAddress, RsdpSize);
5525943f66cSSascha Wildner if (!TableAddress)
5535943f66cSSascha Wildner {
5545943f66cSSascha Wildner AcpiOsUnmapMemory (RsdpAddress, RsdpSize);
5555943f66cSSascha Wildner return (AE_ERROR);
5565943f66cSSascha Wildner }
5575943f66cSSascha Wildner
55825ca8c79SSascha Wildner memcpy (&Gbl_Rsdp, TableAddress, sizeof (Gbl_Rsdp));
5595943f66cSSascha Wildner AcpiOsUnmapMemory (RsdpAddress, RsdpSize);
5605943f66cSSascha Wildner
5615943f66cSSascha Wildner /* Get XSDT from memory */
5625943f66cSSascha Wildner
5635943f66cSSascha Wildner if (Gbl_Rsdp.Revision)
5645943f66cSSascha Wildner {
5655943f66cSSascha Wildner Status = OslMapTable (Gbl_Rsdp.XsdtPhysicalAddress,
5665943f66cSSascha Wildner ACPI_SIG_XSDT, &MappedTable);
5675943f66cSSascha Wildner if (ACPI_FAILURE (Status))
5685943f66cSSascha Wildner {
5695943f66cSSascha Wildner return (Status);
5705943f66cSSascha Wildner }
5715943f66cSSascha Wildner
5725943f66cSSascha Wildner Gbl_Revision = 2;
5735943f66cSSascha Wildner Gbl_Xsdt = calloc (1, MappedTable->Length);
5745943f66cSSascha Wildner if (!Gbl_Xsdt)
5755943f66cSSascha Wildner {
5765943f66cSSascha Wildner fprintf (stderr,
5775943f66cSSascha Wildner "XSDT: Could not allocate buffer for table of length %X\n",
5785943f66cSSascha Wildner MappedTable->Length);
5795943f66cSSascha Wildner AcpiOsUnmapMemory (MappedTable, MappedTable->Length);
5805943f66cSSascha Wildner return (AE_NO_MEMORY);
5815943f66cSSascha Wildner }
5825943f66cSSascha Wildner
58325ca8c79SSascha Wildner memcpy (Gbl_Xsdt, MappedTable, MappedTable->Length);
5845943f66cSSascha Wildner AcpiOsUnmapMemory (MappedTable, MappedTable->Length);
5855943f66cSSascha Wildner }
5865943f66cSSascha Wildner
5875943f66cSSascha Wildner /* Get RSDT from memory */
5885943f66cSSascha Wildner
5895943f66cSSascha Wildner if (Gbl_Rsdp.RsdtPhysicalAddress)
5905943f66cSSascha Wildner {
5915943f66cSSascha Wildner Status = OslMapTable (Gbl_Rsdp.RsdtPhysicalAddress,
5925943f66cSSascha Wildner ACPI_SIG_RSDT, &MappedTable);
5935943f66cSSascha Wildner if (ACPI_FAILURE (Status))
5945943f66cSSascha Wildner {
5955943f66cSSascha Wildner return (Status);
5965943f66cSSascha Wildner }
5975943f66cSSascha Wildner
5985943f66cSSascha Wildner Gbl_Rsdt = calloc (1, MappedTable->Length);
5995943f66cSSascha Wildner if (!Gbl_Rsdt)
6005943f66cSSascha Wildner {
6015943f66cSSascha Wildner fprintf (stderr,
6025943f66cSSascha Wildner "RSDT: Could not allocate buffer for table of length %X\n",
6035943f66cSSascha Wildner MappedTable->Length);
6045943f66cSSascha Wildner AcpiOsUnmapMemory (MappedTable, MappedTable->Length);
6055943f66cSSascha Wildner return (AE_NO_MEMORY);
6065943f66cSSascha Wildner }
6075943f66cSSascha Wildner
60825ca8c79SSascha Wildner memcpy (Gbl_Rsdt, MappedTable, MappedTable->Length);
6095943f66cSSascha Wildner AcpiOsUnmapMemory (MappedTable, MappedTable->Length);
6105943f66cSSascha Wildner }
6115943f66cSSascha Wildner
6125943f66cSSascha Wildner /* Get FADT from memory */
6135943f66cSSascha Wildner
6145943f66cSSascha Wildner if (Gbl_Revision)
6155943f66cSSascha Wildner {
6165943f66cSSascha Wildner Gbl_FadtAddress = Gbl_Xsdt->TableOffsetEntry[0];
6175943f66cSSascha Wildner }
6185943f66cSSascha Wildner else
6195943f66cSSascha Wildner {
6205943f66cSSascha Wildner Gbl_FadtAddress = Gbl_Rsdt->TableOffsetEntry[0];
6215943f66cSSascha Wildner }
6225943f66cSSascha Wildner
6235943f66cSSascha Wildner if (!Gbl_FadtAddress)
6245943f66cSSascha Wildner {
6255943f66cSSascha Wildner fprintf(stderr, "FADT: Table could not be found\n");
6265943f66cSSascha Wildner return (AE_ERROR);
6275943f66cSSascha Wildner }
6285943f66cSSascha Wildner
6295943f66cSSascha Wildner Status = OslMapTable (Gbl_FadtAddress, ACPI_SIG_FADT, &MappedTable);
6305943f66cSSascha Wildner if (ACPI_FAILURE (Status))
6315943f66cSSascha Wildner {
6325943f66cSSascha Wildner return (Status);
6335943f66cSSascha Wildner }
6345943f66cSSascha Wildner
6355943f66cSSascha Wildner Gbl_Fadt = calloc (1, MappedTable->Length);
6365943f66cSSascha Wildner if (!Gbl_Fadt)
6375943f66cSSascha Wildner {
6385943f66cSSascha Wildner fprintf (stderr,
6395943f66cSSascha Wildner "FADT: Could not allocate buffer for table of length %X\n",
6405943f66cSSascha Wildner MappedTable->Length);
6415943f66cSSascha Wildner AcpiOsUnmapMemory (MappedTable, MappedTable->Length);
6425943f66cSSascha Wildner return (AE_NO_MEMORY);
6435943f66cSSascha Wildner }
6445943f66cSSascha Wildner
64525ca8c79SSascha Wildner memcpy (Gbl_Fadt, MappedTable, MappedTable->Length);
6465943f66cSSascha Wildner AcpiOsUnmapMemory (MappedTable, MappedTable->Length);
6475943f66cSSascha Wildner Gbl_MainTableObtained = TRUE;
6485943f66cSSascha Wildner return (AE_OK);
6495943f66cSSascha Wildner }
6505943f66cSSascha Wildner
6515943f66cSSascha Wildner
6525943f66cSSascha Wildner /******************************************************************************
6535943f66cSSascha Wildner *
6545943f66cSSascha Wildner * FUNCTION: OslGetTableViaRoot
6555943f66cSSascha Wildner *
6565943f66cSSascha Wildner * PARAMETERS: Signature - ACPI Signature for common table. Must be
6575943f66cSSascha Wildner * a null terminated 4-character string.
6585943f66cSSascha Wildner * Instance - Multiple table support for SSDT/UEFI (0...n)
6595943f66cSSascha Wildner * Must be 0 for other tables.
6605943f66cSSascha Wildner * Table - Where a pointer to the table is returned
6615943f66cSSascha Wildner * Address - Where the table physical address is returned
6625943f66cSSascha Wildner *
6635943f66cSSascha Wildner * RETURN: Status; Table buffer and physical address returned if AE_OK.
6645943f66cSSascha Wildner * AE_LIMIT: Instance is beyond valid limit
6655943f66cSSascha Wildner * AE_NOT_FOUND: A table with the signature was not found
6665943f66cSSascha Wildner *
6675943f66cSSascha Wildner * DESCRIPTION: Get an ACPI table via the root table (RSDT/XSDT)
6685943f66cSSascha Wildner *
6695943f66cSSascha Wildner * NOTE: Assumes the input signature is uppercase.
6705943f66cSSascha Wildner *
6715943f66cSSascha Wildner *****************************************************************************/
6725943f66cSSascha Wildner
6735943f66cSSascha Wildner static ACPI_STATUS
OslGetTableViaRoot(char * Signature,UINT32 Instance,ACPI_TABLE_HEADER ** Table,ACPI_PHYSICAL_ADDRESS * Address)6745943f66cSSascha Wildner OslGetTableViaRoot (
6755943f66cSSascha Wildner char *Signature,
6765943f66cSSascha Wildner UINT32 Instance,
6775943f66cSSascha Wildner ACPI_TABLE_HEADER **Table,
6785943f66cSSascha Wildner ACPI_PHYSICAL_ADDRESS *Address)
6795943f66cSSascha Wildner {
6805943f66cSSascha Wildner ACPI_TABLE_HEADER *LocalTable = NULL;
6815943f66cSSascha Wildner ACPI_TABLE_HEADER *MappedTable = NULL;
6825943f66cSSascha Wildner UINT8 NumberOfTables;
6835943f66cSSascha Wildner UINT32 CurrentInstance = 0;
6845943f66cSSascha Wildner ACPI_PHYSICAL_ADDRESS TableAddress = 0;
6855943f66cSSascha Wildner ACPI_STATUS Status;
6865943f66cSSascha Wildner UINT32 i;
6875943f66cSSascha Wildner
6885943f66cSSascha Wildner
6895943f66cSSascha Wildner /* DSDT and FACS address must be extracted from the FADT */
6905943f66cSSascha Wildner
691c1776041SSascha Wildner if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_DSDT) ||
692c1776041SSascha Wildner ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_FACS))
6935943f66cSSascha Wildner {
6945943f66cSSascha Wildner /*
6955943f66cSSascha Wildner * Get the appropriate address, either 32-bit or 64-bit. Be very
6965943f66cSSascha Wildner * careful about the FADT length and validate table addresses.
6975943f66cSSascha Wildner * Note: The 64-bit addresses have priority.
6985943f66cSSascha Wildner */
699c1776041SSascha Wildner if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_DSDT))
7005943f66cSSascha Wildner {
7015943f66cSSascha Wildner if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XDSDT) &&
7025943f66cSSascha Wildner Gbl_Fadt->XDsdt)
7035943f66cSSascha Wildner {
7045943f66cSSascha Wildner TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XDsdt;
7055943f66cSSascha Wildner }
7065943f66cSSascha Wildner else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_DSDT) &&
7075943f66cSSascha Wildner Gbl_Fadt->Dsdt)
7085943f66cSSascha Wildner {
7095943f66cSSascha Wildner TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Dsdt;
7105943f66cSSascha Wildner }
7115943f66cSSascha Wildner }
7125943f66cSSascha Wildner else /* FACS */
7135943f66cSSascha Wildner {
7145943f66cSSascha Wildner if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XFACS) &&
7155943f66cSSascha Wildner Gbl_Fadt->XFacs)
7165943f66cSSascha Wildner {
7175943f66cSSascha Wildner TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XFacs;
7185943f66cSSascha Wildner }
7195943f66cSSascha Wildner else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_FACS) &&
7205943f66cSSascha Wildner Gbl_Fadt->Facs)
7215943f66cSSascha Wildner {
7225943f66cSSascha Wildner TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Facs;
7235943f66cSSascha Wildner }
7245943f66cSSascha Wildner }
7255943f66cSSascha Wildner }
7265943f66cSSascha Wildner else /* Case for a normal ACPI table */
7275943f66cSSascha Wildner {
7285943f66cSSascha Wildner if (Gbl_Revision)
7295943f66cSSascha Wildner {
7305943f66cSSascha Wildner NumberOfTables =
7315943f66cSSascha Wildner (Gbl_Xsdt->Header.Length - sizeof (Gbl_Xsdt->Header))
7325943f66cSSascha Wildner / sizeof (Gbl_Xsdt->TableOffsetEntry[0]);
7335943f66cSSascha Wildner }
7345943f66cSSascha Wildner else /* Use RSDT if XSDT is not available */
7355943f66cSSascha Wildner {
7365943f66cSSascha Wildner NumberOfTables =
7375943f66cSSascha Wildner (Gbl_Rsdt->Header.Length - sizeof (Gbl_Rsdt->Header))
7385943f66cSSascha Wildner / sizeof (Gbl_Rsdt->TableOffsetEntry[0]);
7395943f66cSSascha Wildner }
7405943f66cSSascha Wildner
7415943f66cSSascha Wildner /* Search RSDT/XSDT for the requested table */
7425943f66cSSascha Wildner
7435943f66cSSascha Wildner for (i = 0; i < NumberOfTables; i++)
7445943f66cSSascha Wildner {
7455943f66cSSascha Wildner if (Gbl_Revision)
7465943f66cSSascha Wildner {
7475943f66cSSascha Wildner TableAddress = Gbl_Xsdt->TableOffsetEntry[i];
7485943f66cSSascha Wildner }
7495943f66cSSascha Wildner else
7505943f66cSSascha Wildner {
7515943f66cSSascha Wildner TableAddress = Gbl_Rsdt->TableOffsetEntry[i];
7525943f66cSSascha Wildner }
7535943f66cSSascha Wildner
7545943f66cSSascha Wildner MappedTable = AcpiOsMapMemory (TableAddress, sizeof (*MappedTable));
7555943f66cSSascha Wildner if (!MappedTable)
7565943f66cSSascha Wildner {
7575943f66cSSascha Wildner return (AE_BAD_ADDRESS);
7585943f66cSSascha Wildner }
7595943f66cSSascha Wildner
7605943f66cSSascha Wildner /* Does this table match the requested signature? */
7615943f66cSSascha Wildner
762c1776041SSascha Wildner if (ACPI_COMPARE_NAMESEG (MappedTable->Signature, Signature))
7635943f66cSSascha Wildner {
7645943f66cSSascha Wildner
7655943f66cSSascha Wildner /* Match table instance (for SSDT/UEFI tables) */
7665943f66cSSascha Wildner
7675943f66cSSascha Wildner if (CurrentInstance == Instance)
7685943f66cSSascha Wildner {
7695943f66cSSascha Wildner AcpiOsUnmapMemory (MappedTable, sizeof (*MappedTable));
7705943f66cSSascha Wildner break;
7715943f66cSSascha Wildner }
7725943f66cSSascha Wildner
7735943f66cSSascha Wildner CurrentInstance++;
7745943f66cSSascha Wildner }
7755943f66cSSascha Wildner
7765943f66cSSascha Wildner AcpiOsUnmapMemory (MappedTable, MappedTable->Length);
7775943f66cSSascha Wildner TableAddress = 0;
7785943f66cSSascha Wildner }
7795943f66cSSascha Wildner }
7805943f66cSSascha Wildner
7815943f66cSSascha Wildner if (!TableAddress)
7825943f66cSSascha Wildner {
7835943f66cSSascha Wildner if (CurrentInstance)
7845943f66cSSascha Wildner {
7855943f66cSSascha Wildner return (AE_LIMIT);
7865943f66cSSascha Wildner }
7875943f66cSSascha Wildner return (AE_NOT_FOUND);
7885943f66cSSascha Wildner }
7895943f66cSSascha Wildner
7905943f66cSSascha Wildner /* Now we can get the requested table */
7915943f66cSSascha Wildner
7925943f66cSSascha Wildner Status = OslMapTable (TableAddress, Signature, &MappedTable);
7935943f66cSSascha Wildner if (ACPI_FAILURE (Status))
7945943f66cSSascha Wildner {
7955943f66cSSascha Wildner return (Status);
7965943f66cSSascha Wildner }
7975943f66cSSascha Wildner
7985943f66cSSascha Wildner /* Copy table to local buffer and return it */
7995943f66cSSascha Wildner
8005943f66cSSascha Wildner LocalTable = calloc (1, MappedTable->Length);
8015943f66cSSascha Wildner if (!LocalTable)
8025943f66cSSascha Wildner {
8035943f66cSSascha Wildner AcpiOsUnmapMemory (MappedTable, MappedTable->Length);
8045943f66cSSascha Wildner return (AE_NO_MEMORY);
8055943f66cSSascha Wildner }
8065943f66cSSascha Wildner
80725ca8c79SSascha Wildner memcpy (LocalTable, MappedTable, MappedTable->Length);
8085943f66cSSascha Wildner AcpiOsUnmapMemory (MappedTable, MappedTable->Length);
8095943f66cSSascha Wildner *Table = LocalTable;
8105943f66cSSascha Wildner *Address = TableAddress;
8115943f66cSSascha Wildner return (AE_OK);
8125943f66cSSascha Wildner }
8135943f66cSSascha Wildner
8145943f66cSSascha Wildner
8155943f66cSSascha Wildner /******************************************************************************
8165943f66cSSascha Wildner *
8175943f66cSSascha Wildner * FUNCTION: OslAddTablesToList
8185943f66cSSascha Wildner *
8195943f66cSSascha Wildner * PARAMETERS: None
8205943f66cSSascha Wildner *
8215943f66cSSascha Wildner * RETURN: Status; Table list is initialized if AE_OK.
8225943f66cSSascha Wildner *
8235943f66cSSascha Wildner * DESCRIPTION: Add ACPI tables to the table list.
8245943f66cSSascha Wildner *
8255943f66cSSascha Wildner *****************************************************************************/
8265943f66cSSascha Wildner
8275943f66cSSascha Wildner static ACPI_STATUS
OslAddTablesToList(void)8285943f66cSSascha Wildner OslAddTablesToList(
8295943f66cSSascha Wildner void)
8305943f66cSSascha Wildner {
8315943f66cSSascha Wildner ACPI_PHYSICAL_ADDRESS TableAddress;
8325943f66cSSascha Wildner OSL_TABLE_INFO *Info = NULL;
8335943f66cSSascha Wildner OSL_TABLE_INFO *NewInfo;
8345943f66cSSascha Wildner ACPI_TABLE_HEADER *Table;
8355943f66cSSascha Wildner UINT8 Instance;
8365943f66cSSascha Wildner UINT8 NumberOfTables;
8375943f66cSSascha Wildner int i;
8385943f66cSSascha Wildner
8395943f66cSSascha Wildner
8405943f66cSSascha Wildner /* Initialize the table list on first invocation */
8415943f66cSSascha Wildner
8425943f66cSSascha Wildner if (Gbl_TableListInitialized)
8435943f66cSSascha Wildner {
8445943f66cSSascha Wildner return (AE_OK);
8455943f66cSSascha Wildner }
8465943f66cSSascha Wildner
8475943f66cSSascha Wildner /* Add mandatory tables to global table list first */
8485943f66cSSascha Wildner
8495943f66cSSascha Wildner for (i = 0; i < 4; i++)
8505943f66cSSascha Wildner {
8515943f66cSSascha Wildner NewInfo = calloc (1, sizeof (*NewInfo));
8525943f66cSSascha Wildner if (!NewInfo)
8535943f66cSSascha Wildner {
8545943f66cSSascha Wildner return (AE_NO_MEMORY);
8555943f66cSSascha Wildner }
8565943f66cSSascha Wildner
8575943f66cSSascha Wildner switch (i) {
8585943f66cSSascha Wildner case 0:
8595943f66cSSascha Wildner
8605943f66cSSascha Wildner Gbl_TableListHead = Info = NewInfo;
8615943f66cSSascha Wildner continue;
8625943f66cSSascha Wildner
8635943f66cSSascha Wildner case 1:
8645943f66cSSascha Wildner
865c1776041SSascha Wildner ACPI_COPY_NAMESEG (NewInfo->Signature,
8665943f66cSSascha Wildner Gbl_Revision ? ACPI_SIG_XSDT : ACPI_SIG_RSDT);
8675943f66cSSascha Wildner break;
8685943f66cSSascha Wildner
8695943f66cSSascha Wildner case 2:
8705943f66cSSascha Wildner
871c1776041SSascha Wildner ACPI_COPY_NAMESEG (NewInfo->Signature, ACPI_SIG_FACS);
8725943f66cSSascha Wildner break;
8735943f66cSSascha Wildner
8745943f66cSSascha Wildner default:
8755943f66cSSascha Wildner
876c1776041SSascha Wildner ACPI_COPY_NAMESEG (NewInfo->Signature, ACPI_SIG_DSDT);
8775943f66cSSascha Wildner
8785943f66cSSascha Wildner }
8795943f66cSSascha Wildner
8805943f66cSSascha Wildner Info->Next = NewInfo;
8815943f66cSSascha Wildner Info = NewInfo;
8825943f66cSSascha Wildner Gbl_TableListHead->Instance++;
8835943f66cSSascha Wildner }
8845943f66cSSascha Wildner
8855943f66cSSascha Wildner /* Add normal tables from RSDT/XSDT to global list */
8865943f66cSSascha Wildner
8875943f66cSSascha Wildner if (Gbl_Revision)
8885943f66cSSascha Wildner {
8895943f66cSSascha Wildner NumberOfTables =
8905943f66cSSascha Wildner (Gbl_Xsdt->Header.Length - sizeof (Gbl_Xsdt->Header))
8915943f66cSSascha Wildner / sizeof (Gbl_Xsdt->TableOffsetEntry[0]);
8925943f66cSSascha Wildner }
8935943f66cSSascha Wildner else
8945943f66cSSascha Wildner {
8955943f66cSSascha Wildner NumberOfTables =
8965943f66cSSascha Wildner (Gbl_Rsdt->Header.Length - sizeof (Gbl_Rsdt->Header))
8975943f66cSSascha Wildner / sizeof (Gbl_Rsdt->TableOffsetEntry[0]);
8985943f66cSSascha Wildner }
8995943f66cSSascha Wildner
9005943f66cSSascha Wildner for (i = 0; i < NumberOfTables; i++)
9015943f66cSSascha Wildner {
9025943f66cSSascha Wildner if (Gbl_Revision)
9035943f66cSSascha Wildner {
9045943f66cSSascha Wildner TableAddress = Gbl_Xsdt->TableOffsetEntry[i];
9055943f66cSSascha Wildner }
9065943f66cSSascha Wildner else
9075943f66cSSascha Wildner {
9085943f66cSSascha Wildner TableAddress = Gbl_Rsdt->TableOffsetEntry[i];
9095943f66cSSascha Wildner }
9105943f66cSSascha Wildner
9115943f66cSSascha Wildner Table = AcpiOsMapMemory (TableAddress, sizeof (*Table));
9125943f66cSSascha Wildner if (!Table)
9135943f66cSSascha Wildner {
9145943f66cSSascha Wildner return (AE_BAD_ADDRESS);
9155943f66cSSascha Wildner }
9165943f66cSSascha Wildner
9175943f66cSSascha Wildner Instance = 0;
9185943f66cSSascha Wildner NewInfo = Gbl_TableListHead;
9195943f66cSSascha Wildner while (NewInfo->Next != NULL)
9205943f66cSSascha Wildner {
9215943f66cSSascha Wildner NewInfo = NewInfo->Next;
922c1776041SSascha Wildner if (ACPI_COMPARE_NAMESEG (Table->Signature, NewInfo->Signature))
9235943f66cSSascha Wildner {
9245943f66cSSascha Wildner Instance++;
9255943f66cSSascha Wildner }
9265943f66cSSascha Wildner }
9275943f66cSSascha Wildner
9285943f66cSSascha Wildner NewInfo = calloc (1, sizeof (*NewInfo));
9295943f66cSSascha Wildner if (!NewInfo)
9305943f66cSSascha Wildner {
9315943f66cSSascha Wildner AcpiOsUnmapMemory (Table, sizeof (*Table));
9325943f66cSSascha Wildner return (AE_NO_MEMORY);
9335943f66cSSascha Wildner }
9345943f66cSSascha Wildner
935c1776041SSascha Wildner ACPI_COPY_NAMESEG (NewInfo->Signature, Table->Signature);
9365943f66cSSascha Wildner
9375943f66cSSascha Wildner AcpiOsUnmapMemory (Table, sizeof (*Table));
9385943f66cSSascha Wildner
9395943f66cSSascha Wildner NewInfo->Instance = Instance;
9405943f66cSSascha Wildner NewInfo->Address = TableAddress;
9415943f66cSSascha Wildner Info->Next = NewInfo;
9425943f66cSSascha Wildner Info = NewInfo;
9435943f66cSSascha Wildner Gbl_TableListHead->Instance++;
9445943f66cSSascha Wildner }
9455943f66cSSascha Wildner
9465943f66cSSascha Wildner Gbl_TableListInitialized = TRUE;
9475943f66cSSascha Wildner return (AE_OK);
9485943f66cSSascha Wildner }
9495943f66cSSascha Wildner
9505943f66cSSascha Wildner
9515943f66cSSascha Wildner /******************************************************************************
9525943f66cSSascha Wildner *
9535943f66cSSascha Wildner * FUNCTION: OslMapTable
9545943f66cSSascha Wildner *
9555943f66cSSascha Wildner * PARAMETERS: Address - Address of the table in memory
9565943f66cSSascha Wildner * Signature - Optional ACPI Signature for desired table.
9575943f66cSSascha Wildner * Null terminated 4-character string.
9585943f66cSSascha Wildner * Table - Where a pointer to the mapped table is
9595943f66cSSascha Wildner * returned
9605943f66cSSascha Wildner *
9615943f66cSSascha Wildner * RETURN: Status; Mapped table is returned if AE_OK.
9625943f66cSSascha Wildner *
9635943f66cSSascha Wildner * DESCRIPTION: Map entire ACPI table into caller's address space. Also
9645943f66cSSascha Wildner * validates the table and checksum.
9655943f66cSSascha Wildner *
9665943f66cSSascha Wildner *****************************************************************************/
9675943f66cSSascha Wildner
9685943f66cSSascha Wildner static ACPI_STATUS
OslMapTable(ACPI_SIZE Address,char * Signature,ACPI_TABLE_HEADER ** Table)9695943f66cSSascha Wildner OslMapTable (
9705943f66cSSascha Wildner ACPI_SIZE Address,
9715943f66cSSascha Wildner char *Signature,
9725943f66cSSascha Wildner ACPI_TABLE_HEADER **Table)
9735943f66cSSascha Wildner {
9745943f66cSSascha Wildner ACPI_TABLE_HEADER *MappedTable;
9755943f66cSSascha Wildner UINT32 Length;
9765943f66cSSascha Wildner
9775943f66cSSascha Wildner
9785943f66cSSascha Wildner /* Map the header so we can get the table length */
9795943f66cSSascha Wildner
9805943f66cSSascha Wildner MappedTable = AcpiOsMapMemory (Address, sizeof (*MappedTable));
9815943f66cSSascha Wildner if (!MappedTable)
9825943f66cSSascha Wildner {
9835943f66cSSascha Wildner return (AE_BAD_ADDRESS);
9845943f66cSSascha Wildner }
9855943f66cSSascha Wildner
9865943f66cSSascha Wildner /* Check if table is valid */
9875943f66cSSascha Wildner
9885943f66cSSascha Wildner if (!ApIsValidHeader (MappedTable))
9895943f66cSSascha Wildner {
9905943f66cSSascha Wildner AcpiOsUnmapMemory (MappedTable, sizeof (*MappedTable));
9915943f66cSSascha Wildner return (AE_BAD_HEADER);
9925943f66cSSascha Wildner }
9935943f66cSSascha Wildner
9945943f66cSSascha Wildner /* If specified, signature must match */
9955943f66cSSascha Wildner
9965943f66cSSascha Wildner if (Signature &&
997c1776041SSascha Wildner !ACPI_COMPARE_NAMESEG (Signature, MappedTable->Signature))
9985943f66cSSascha Wildner {
9995943f66cSSascha Wildner AcpiOsUnmapMemory (MappedTable, sizeof (*MappedTable));
10005943f66cSSascha Wildner return (AE_NOT_EXIST);
10015943f66cSSascha Wildner }
10025943f66cSSascha Wildner
10035943f66cSSascha Wildner /* Map the entire table */
10045943f66cSSascha Wildner
10055943f66cSSascha Wildner Length = MappedTable->Length;
10065943f66cSSascha Wildner AcpiOsUnmapMemory (MappedTable, sizeof (*MappedTable));
10075943f66cSSascha Wildner
10085943f66cSSascha Wildner MappedTable = AcpiOsMapMemory (Address, Length);
10095943f66cSSascha Wildner if (!MappedTable)
10105943f66cSSascha Wildner {
10115943f66cSSascha Wildner return (AE_BAD_ADDRESS);
10125943f66cSSascha Wildner }
10135943f66cSSascha Wildner
10145943f66cSSascha Wildner (void) ApIsValidChecksum (MappedTable);
10155943f66cSSascha Wildner
10165943f66cSSascha Wildner *Table = MappedTable;
10175943f66cSSascha Wildner
10185943f66cSSascha Wildner return (AE_OK);
10195943f66cSSascha Wildner }
1020