xref: /minix/minix/drivers/power/acpi/tables/tbxfload.c (revision 29492bb7)
1*29492bb7SDavid van Moolenbroek /******************************************************************************
2*29492bb7SDavid van Moolenbroek  *
3*29492bb7SDavid van Moolenbroek  * Module Name: tbxfload - Table load/unload external interfaces
4*29492bb7SDavid van Moolenbroek  *
5*29492bb7SDavid van Moolenbroek  *****************************************************************************/
6*29492bb7SDavid van Moolenbroek 
7*29492bb7SDavid van Moolenbroek /*
8*29492bb7SDavid van Moolenbroek  * Copyright (C) 2000 - 2014, Intel Corp.
9*29492bb7SDavid van Moolenbroek  * All rights reserved.
10*29492bb7SDavid van Moolenbroek  *
11*29492bb7SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
12*29492bb7SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
13*29492bb7SDavid van Moolenbroek  * are met:
14*29492bb7SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
15*29492bb7SDavid van Moolenbroek  *    notice, this list of conditions, and the following disclaimer,
16*29492bb7SDavid van Moolenbroek  *    without modification.
17*29492bb7SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*29492bb7SDavid van Moolenbroek  *    substantially similar to the "NO WARRANTY" disclaimer below
19*29492bb7SDavid van Moolenbroek  *    ("Disclaimer") and any redistribution must be conditioned upon
20*29492bb7SDavid van Moolenbroek  *    including a substantially similar Disclaimer requirement for further
21*29492bb7SDavid van Moolenbroek  *    binary redistribution.
22*29492bb7SDavid van Moolenbroek  * 3. Neither the names of the above-listed copyright holders nor the names
23*29492bb7SDavid van Moolenbroek  *    of any contributors may be used to endorse or promote products derived
24*29492bb7SDavid van Moolenbroek  *    from this software without specific prior written permission.
25*29492bb7SDavid van Moolenbroek  *
26*29492bb7SDavid van Moolenbroek  * Alternatively, this software may be distributed under the terms of the
27*29492bb7SDavid van Moolenbroek  * GNU General Public License ("GPL") version 2 as published by the Free
28*29492bb7SDavid van Moolenbroek  * Software Foundation.
29*29492bb7SDavid van Moolenbroek  *
30*29492bb7SDavid van Moolenbroek  * NO WARRANTY
31*29492bb7SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*29492bb7SDavid van Moolenbroek  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*29492bb7SDavid van Moolenbroek  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*29492bb7SDavid van Moolenbroek  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*29492bb7SDavid van Moolenbroek  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*29492bb7SDavid van Moolenbroek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*29492bb7SDavid van Moolenbroek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*29492bb7SDavid van Moolenbroek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*29492bb7SDavid van Moolenbroek  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*29492bb7SDavid van Moolenbroek  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*29492bb7SDavid van Moolenbroek  * POSSIBILITY OF SUCH DAMAGES.
42*29492bb7SDavid van Moolenbroek  */
43*29492bb7SDavid van Moolenbroek 
44*29492bb7SDavid van Moolenbroek #define EXPORT_ACPI_INTERFACES
45*29492bb7SDavid van Moolenbroek 
46*29492bb7SDavid van Moolenbroek #include "acpi.h"
47*29492bb7SDavid van Moolenbroek #include "accommon.h"
48*29492bb7SDavid van Moolenbroek #include "acnamesp.h"
49*29492bb7SDavid van Moolenbroek #include "actables.h"
50*29492bb7SDavid van Moolenbroek 
51*29492bb7SDavid van Moolenbroek #define _COMPONENT          ACPI_TABLES
52*29492bb7SDavid van Moolenbroek         ACPI_MODULE_NAME    ("tbxfload")
53*29492bb7SDavid van Moolenbroek 
54*29492bb7SDavid van Moolenbroek /* Local prototypes */
55*29492bb7SDavid van Moolenbroek 
56*29492bb7SDavid van Moolenbroek static ACPI_STATUS
57*29492bb7SDavid van Moolenbroek AcpiTbLoadNamespace (
58*29492bb7SDavid van Moolenbroek     void);
59*29492bb7SDavid van Moolenbroek 
60*29492bb7SDavid van Moolenbroek 
61*29492bb7SDavid van Moolenbroek /*******************************************************************************
62*29492bb7SDavid van Moolenbroek  *
63*29492bb7SDavid van Moolenbroek  * FUNCTION:    AcpiLoadTables
64*29492bb7SDavid van Moolenbroek  *
65*29492bb7SDavid van Moolenbroek  * PARAMETERS:  None
66*29492bb7SDavid van Moolenbroek  *
67*29492bb7SDavid van Moolenbroek  * RETURN:      Status
68*29492bb7SDavid van Moolenbroek  *
69*29492bb7SDavid van Moolenbroek  * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
70*29492bb7SDavid van Moolenbroek  *
71*29492bb7SDavid van Moolenbroek  ******************************************************************************/
72*29492bb7SDavid van Moolenbroek 
73*29492bb7SDavid van Moolenbroek ACPI_STATUS
AcpiLoadTables(void)74*29492bb7SDavid van Moolenbroek AcpiLoadTables (
75*29492bb7SDavid van Moolenbroek     void)
76*29492bb7SDavid van Moolenbroek {
77*29492bb7SDavid van Moolenbroek     ACPI_STATUS             Status;
78*29492bb7SDavid van Moolenbroek 
79*29492bb7SDavid van Moolenbroek 
80*29492bb7SDavid van Moolenbroek     ACPI_FUNCTION_TRACE (AcpiLoadTables);
81*29492bb7SDavid van Moolenbroek 
82*29492bb7SDavid van Moolenbroek 
83*29492bb7SDavid van Moolenbroek     /* Load the namespace from the tables */
84*29492bb7SDavid van Moolenbroek 
85*29492bb7SDavid van Moolenbroek     Status = AcpiTbLoadNamespace ();
86*29492bb7SDavid van Moolenbroek     if (ACPI_FAILURE (Status))
87*29492bb7SDavid van Moolenbroek     {
88*29492bb7SDavid van Moolenbroek         ACPI_EXCEPTION ((AE_INFO, Status,
89*29492bb7SDavid van Moolenbroek             "While loading namespace from ACPI tables"));
90*29492bb7SDavid van Moolenbroek     }
91*29492bb7SDavid van Moolenbroek 
92*29492bb7SDavid van Moolenbroek     return_ACPI_STATUS (Status);
93*29492bb7SDavid van Moolenbroek }
94*29492bb7SDavid van Moolenbroek 
ACPI_EXPORT_SYMBOL_INIT(AcpiLoadTables)95*29492bb7SDavid van Moolenbroek ACPI_EXPORT_SYMBOL_INIT (AcpiLoadTables)
96*29492bb7SDavid van Moolenbroek 
97*29492bb7SDavid van Moolenbroek 
98*29492bb7SDavid van Moolenbroek /*******************************************************************************
99*29492bb7SDavid van Moolenbroek  *
100*29492bb7SDavid van Moolenbroek  * FUNCTION:    AcpiTbLoadNamespace
101*29492bb7SDavid van Moolenbroek  *
102*29492bb7SDavid van Moolenbroek  * PARAMETERS:  None
103*29492bb7SDavid van Moolenbroek  *
104*29492bb7SDavid van Moolenbroek  * RETURN:      Status
105*29492bb7SDavid van Moolenbroek  *
106*29492bb7SDavid van Moolenbroek  * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
107*29492bb7SDavid van Moolenbroek  *              the RSDT/XSDT.
108*29492bb7SDavid van Moolenbroek  *
109*29492bb7SDavid van Moolenbroek  ******************************************************************************/
110*29492bb7SDavid van Moolenbroek 
111*29492bb7SDavid van Moolenbroek static ACPI_STATUS
112*29492bb7SDavid van Moolenbroek AcpiTbLoadNamespace (
113*29492bb7SDavid van Moolenbroek     void)
114*29492bb7SDavid van Moolenbroek {
115*29492bb7SDavid van Moolenbroek     ACPI_STATUS             Status;
116*29492bb7SDavid van Moolenbroek     UINT32                  i;
117*29492bb7SDavid van Moolenbroek     ACPI_TABLE_HEADER       *NewDsdt;
118*29492bb7SDavid van Moolenbroek 
119*29492bb7SDavid van Moolenbroek 
120*29492bb7SDavid van Moolenbroek     ACPI_FUNCTION_TRACE (TbLoadNamespace);
121*29492bb7SDavid van Moolenbroek 
122*29492bb7SDavid van Moolenbroek 
123*29492bb7SDavid van Moolenbroek     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
124*29492bb7SDavid van Moolenbroek 
125*29492bb7SDavid van Moolenbroek     /*
126*29492bb7SDavid van Moolenbroek      * Load the namespace. The DSDT is required, but any SSDT and
127*29492bb7SDavid van Moolenbroek      * PSDT tables are optional. Verify the DSDT.
128*29492bb7SDavid van Moolenbroek      */
129*29492bb7SDavid van Moolenbroek     if (!AcpiGbl_RootTableList.CurrentTableCount ||
130*29492bb7SDavid van Moolenbroek         !ACPI_COMPARE_NAME (
131*29492bb7SDavid van Moolenbroek             &(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature),
132*29492bb7SDavid van Moolenbroek             ACPI_SIG_DSDT) ||
133*29492bb7SDavid van Moolenbroek          ACPI_FAILURE (AcpiTbValidateTable (
134*29492bb7SDavid van Moolenbroek             &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT])))
135*29492bb7SDavid van Moolenbroek     {
136*29492bb7SDavid van Moolenbroek         Status = AE_NO_ACPI_TABLES;
137*29492bb7SDavid van Moolenbroek         goto UnlockAndExit;
138*29492bb7SDavid van Moolenbroek     }
139*29492bb7SDavid van Moolenbroek 
140*29492bb7SDavid van Moolenbroek     /*
141*29492bb7SDavid van Moolenbroek      * Save the DSDT pointer for simple access. This is the mapped memory
142*29492bb7SDavid van Moolenbroek      * address. We must take care here because the address of the .Tables
143*29492bb7SDavid van Moolenbroek      * array can change dynamically as tables are loaded at run-time. Note:
144*29492bb7SDavid van Moolenbroek      * .Pointer field is not validated until after call to AcpiTbValidateTable.
145*29492bb7SDavid van Moolenbroek      */
146*29492bb7SDavid van Moolenbroek     AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer;
147*29492bb7SDavid van Moolenbroek 
148*29492bb7SDavid van Moolenbroek     /*
149*29492bb7SDavid van Moolenbroek      * Optionally copy the entire DSDT to local memory (instead of simply
150*29492bb7SDavid van Moolenbroek      * mapping it.) There are some BIOSs that corrupt or replace the original
151*29492bb7SDavid van Moolenbroek      * DSDT, creating the need for this option. Default is FALSE, do not copy
152*29492bb7SDavid van Moolenbroek      * the DSDT.
153*29492bb7SDavid van Moolenbroek      */
154*29492bb7SDavid van Moolenbroek     if (AcpiGbl_CopyDsdtLocally)
155*29492bb7SDavid van Moolenbroek     {
156*29492bb7SDavid van Moolenbroek         NewDsdt = AcpiTbCopyDsdt (ACPI_TABLE_INDEX_DSDT);
157*29492bb7SDavid van Moolenbroek         if (NewDsdt)
158*29492bb7SDavid van Moolenbroek         {
159*29492bb7SDavid van Moolenbroek             AcpiGbl_DSDT = NewDsdt;
160*29492bb7SDavid van Moolenbroek         }
161*29492bb7SDavid van Moolenbroek     }
162*29492bb7SDavid van Moolenbroek 
163*29492bb7SDavid van Moolenbroek     /*
164*29492bb7SDavid van Moolenbroek      * Save the original DSDT header for detection of table corruption
165*29492bb7SDavid van Moolenbroek      * and/or replacement of the DSDT from outside the OS.
166*29492bb7SDavid van Moolenbroek      */
167*29492bb7SDavid van Moolenbroek     ACPI_MEMCPY (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
168*29492bb7SDavid van Moolenbroek         sizeof (ACPI_TABLE_HEADER));
169*29492bb7SDavid van Moolenbroek 
170*29492bb7SDavid van Moolenbroek     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
171*29492bb7SDavid van Moolenbroek 
172*29492bb7SDavid van Moolenbroek     /* Load and parse tables */
173*29492bb7SDavid van Moolenbroek 
174*29492bb7SDavid van Moolenbroek     Status = AcpiNsLoadTable (ACPI_TABLE_INDEX_DSDT, AcpiGbl_RootNode);
175*29492bb7SDavid van Moolenbroek     if (ACPI_FAILURE (Status))
176*29492bb7SDavid van Moolenbroek     {
177*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (Status);
178*29492bb7SDavid van Moolenbroek     }
179*29492bb7SDavid van Moolenbroek 
180*29492bb7SDavid van Moolenbroek     /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
181*29492bb7SDavid van Moolenbroek 
182*29492bb7SDavid van Moolenbroek     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
183*29492bb7SDavid van Moolenbroek     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
184*29492bb7SDavid van Moolenbroek     {
185*29492bb7SDavid van Moolenbroek         if ((!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
186*29492bb7SDavid van Moolenbroek                     ACPI_SIG_SSDT) &&
187*29492bb7SDavid van Moolenbroek              !ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
188*29492bb7SDavid van Moolenbroek                     ACPI_SIG_PSDT)) ||
189*29492bb7SDavid van Moolenbroek              ACPI_FAILURE (AcpiTbValidateTable (
190*29492bb7SDavid van Moolenbroek                 &AcpiGbl_RootTableList.Tables[i])))
191*29492bb7SDavid van Moolenbroek         {
192*29492bb7SDavid van Moolenbroek             continue;
193*29492bb7SDavid van Moolenbroek         }
194*29492bb7SDavid van Moolenbroek 
195*29492bb7SDavid van Moolenbroek         /* Ignore errors while loading tables, get as many as possible */
196*29492bb7SDavid van Moolenbroek 
197*29492bb7SDavid van Moolenbroek         (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
198*29492bb7SDavid van Moolenbroek         (void) AcpiNsLoadTable (i, AcpiGbl_RootNode);
199*29492bb7SDavid van Moolenbroek         (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
200*29492bb7SDavid van Moolenbroek     }
201*29492bb7SDavid van Moolenbroek 
202*29492bb7SDavid van Moolenbroek     ACPI_INFO ((AE_INFO, "All ACPI Tables successfully acquired"));
203*29492bb7SDavid van Moolenbroek 
204*29492bb7SDavid van Moolenbroek UnlockAndExit:
205*29492bb7SDavid van Moolenbroek     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
206*29492bb7SDavid van Moolenbroek     return_ACPI_STATUS (Status);
207*29492bb7SDavid van Moolenbroek }
208*29492bb7SDavid van Moolenbroek 
209*29492bb7SDavid van Moolenbroek 
210*29492bb7SDavid van Moolenbroek /*******************************************************************************
211*29492bb7SDavid van Moolenbroek  *
212*29492bb7SDavid van Moolenbroek  * FUNCTION:    AcpiInstallTable
213*29492bb7SDavid van Moolenbroek  *
214*29492bb7SDavid van Moolenbroek  * PARAMETERS:  Address             - Address of the ACPI table to be installed.
215*29492bb7SDavid van Moolenbroek  *              Physical            - Whether the address is a physical table
216*29492bb7SDavid van Moolenbroek  *                                    address or not
217*29492bb7SDavid van Moolenbroek  *
218*29492bb7SDavid van Moolenbroek  * RETURN:      Status
219*29492bb7SDavid van Moolenbroek  *
220*29492bb7SDavid van Moolenbroek  * DESCRIPTION: Dynamically install an ACPI table.
221*29492bb7SDavid van Moolenbroek  *              Note: This function should only be invoked after
222*29492bb7SDavid van Moolenbroek  *                    AcpiInitializeTables() and before AcpiLoadTables().
223*29492bb7SDavid van Moolenbroek  *
224*29492bb7SDavid van Moolenbroek  ******************************************************************************/
225*29492bb7SDavid van Moolenbroek 
226*29492bb7SDavid van Moolenbroek ACPI_STATUS
AcpiInstallTable(ACPI_PHYSICAL_ADDRESS Address,BOOLEAN Physical)227*29492bb7SDavid van Moolenbroek AcpiInstallTable (
228*29492bb7SDavid van Moolenbroek     ACPI_PHYSICAL_ADDRESS   Address,
229*29492bb7SDavid van Moolenbroek     BOOLEAN                 Physical)
230*29492bb7SDavid van Moolenbroek {
231*29492bb7SDavid van Moolenbroek     ACPI_STATUS             Status;
232*29492bb7SDavid van Moolenbroek     UINT8                   Flags;
233*29492bb7SDavid van Moolenbroek     UINT32                  TableIndex;
234*29492bb7SDavid van Moolenbroek 
235*29492bb7SDavid van Moolenbroek 
236*29492bb7SDavid van Moolenbroek     ACPI_FUNCTION_TRACE (AcpiInstallTable);
237*29492bb7SDavid van Moolenbroek 
238*29492bb7SDavid van Moolenbroek 
239*29492bb7SDavid van Moolenbroek     if (Physical)
240*29492bb7SDavid van Moolenbroek     {
241*29492bb7SDavid van Moolenbroek         Flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL;
242*29492bb7SDavid van Moolenbroek     }
243*29492bb7SDavid van Moolenbroek     else
244*29492bb7SDavid van Moolenbroek     {
245*29492bb7SDavid van Moolenbroek         Flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL;
246*29492bb7SDavid van Moolenbroek     }
247*29492bb7SDavid van Moolenbroek 
248*29492bb7SDavid van Moolenbroek     Status = AcpiTbInstallStandardTable (Address, Flags,
249*29492bb7SDavid van Moolenbroek         FALSE, FALSE, &TableIndex);
250*29492bb7SDavid van Moolenbroek 
251*29492bb7SDavid van Moolenbroek     return_ACPI_STATUS (Status);
252*29492bb7SDavid van Moolenbroek }
253*29492bb7SDavid van Moolenbroek 
ACPI_EXPORT_SYMBOL_INIT(AcpiInstallTable)254*29492bb7SDavid van Moolenbroek ACPI_EXPORT_SYMBOL_INIT (AcpiInstallTable)
255*29492bb7SDavid van Moolenbroek 
256*29492bb7SDavid van Moolenbroek 
257*29492bb7SDavid van Moolenbroek /*******************************************************************************
258*29492bb7SDavid van Moolenbroek  *
259*29492bb7SDavid van Moolenbroek  * FUNCTION:    AcpiLoadTable
260*29492bb7SDavid van Moolenbroek  *
261*29492bb7SDavid van Moolenbroek  * PARAMETERS:  Table               - Pointer to a buffer containing the ACPI
262*29492bb7SDavid van Moolenbroek  *                                    table to be loaded.
263*29492bb7SDavid van Moolenbroek  *
264*29492bb7SDavid van Moolenbroek  * RETURN:      Status
265*29492bb7SDavid van Moolenbroek  *
266*29492bb7SDavid van Moolenbroek  * DESCRIPTION: Dynamically load an ACPI table from the caller's buffer. Must
267*29492bb7SDavid van Moolenbroek  *              be a valid ACPI table with a valid ACPI table header.
268*29492bb7SDavid van Moolenbroek  *              Note1: Mainly intended to support hotplug addition of SSDTs.
269*29492bb7SDavid van Moolenbroek  *              Note2: Does not copy the incoming table. User is responsible
270*29492bb7SDavid van Moolenbroek  *              to ensure that the table is not deleted or unmapped.
271*29492bb7SDavid van Moolenbroek  *
272*29492bb7SDavid van Moolenbroek  ******************************************************************************/
273*29492bb7SDavid van Moolenbroek 
274*29492bb7SDavid van Moolenbroek ACPI_STATUS
275*29492bb7SDavid van Moolenbroek AcpiLoadTable (
276*29492bb7SDavid van Moolenbroek     ACPI_TABLE_HEADER       *Table)
277*29492bb7SDavid van Moolenbroek {
278*29492bb7SDavid van Moolenbroek     ACPI_STATUS             Status;
279*29492bb7SDavid van Moolenbroek     UINT32                  TableIndex;
280*29492bb7SDavid van Moolenbroek 
281*29492bb7SDavid van Moolenbroek 
282*29492bb7SDavid van Moolenbroek     ACPI_FUNCTION_TRACE (AcpiLoadTable);
283*29492bb7SDavid van Moolenbroek 
284*29492bb7SDavid van Moolenbroek 
285*29492bb7SDavid van Moolenbroek     /* Parameter validation */
286*29492bb7SDavid van Moolenbroek 
287*29492bb7SDavid van Moolenbroek     if (!Table)
288*29492bb7SDavid van Moolenbroek     {
289*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (AE_BAD_PARAMETER);
290*29492bb7SDavid van Moolenbroek     }
291*29492bb7SDavid van Moolenbroek 
292*29492bb7SDavid van Moolenbroek     /* Must acquire the interpreter lock during this operation */
293*29492bb7SDavid van Moolenbroek 
294*29492bb7SDavid van Moolenbroek     Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
295*29492bb7SDavid van Moolenbroek     if (ACPI_FAILURE (Status))
296*29492bb7SDavid van Moolenbroek     {
297*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (Status);
298*29492bb7SDavid van Moolenbroek     }
299*29492bb7SDavid van Moolenbroek 
300*29492bb7SDavid van Moolenbroek     /* Install the table and load it into the namespace */
301*29492bb7SDavid van Moolenbroek 
302*29492bb7SDavid van Moolenbroek     ACPI_INFO ((AE_INFO, "Host-directed Dynamic ACPI Table Load:"));
303*29492bb7SDavid van Moolenbroek     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
304*29492bb7SDavid van Moolenbroek 
305*29492bb7SDavid van Moolenbroek     Status = AcpiTbInstallStandardTable (ACPI_PTR_TO_PHYSADDR (Table),
306*29492bb7SDavid van Moolenbroek                 ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, TRUE, FALSE,
307*29492bb7SDavid van Moolenbroek                 &TableIndex);
308*29492bb7SDavid van Moolenbroek 
309*29492bb7SDavid van Moolenbroek     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
310*29492bb7SDavid van Moolenbroek     if (ACPI_FAILURE (Status))
311*29492bb7SDavid van Moolenbroek     {
312*29492bb7SDavid van Moolenbroek         goto UnlockAndExit;
313*29492bb7SDavid van Moolenbroek     }
314*29492bb7SDavid van Moolenbroek 
315*29492bb7SDavid van Moolenbroek     /*
316*29492bb7SDavid van Moolenbroek      * Note: Now table is "INSTALLED", it must be validated before
317*29492bb7SDavid van Moolenbroek      * using.
318*29492bb7SDavid van Moolenbroek      */
319*29492bb7SDavid van Moolenbroek     Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[TableIndex]);
320*29492bb7SDavid van Moolenbroek     if (ACPI_FAILURE (Status))
321*29492bb7SDavid van Moolenbroek     {
322*29492bb7SDavid van Moolenbroek         goto UnlockAndExit;
323*29492bb7SDavid van Moolenbroek     }
324*29492bb7SDavid van Moolenbroek 
325*29492bb7SDavid van Moolenbroek     Status = AcpiNsLoadTable (TableIndex, AcpiGbl_RootNode);
326*29492bb7SDavid van Moolenbroek 
327*29492bb7SDavid van Moolenbroek     /* Invoke table handler if present */
328*29492bb7SDavid van Moolenbroek 
329*29492bb7SDavid van Moolenbroek     if (AcpiGbl_TableHandler)
330*29492bb7SDavid van Moolenbroek     {
331*29492bb7SDavid van Moolenbroek         (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
332*29492bb7SDavid van Moolenbroek                     AcpiGbl_TableHandlerContext);
333*29492bb7SDavid van Moolenbroek     }
334*29492bb7SDavid van Moolenbroek 
335*29492bb7SDavid van Moolenbroek UnlockAndExit:
336*29492bb7SDavid van Moolenbroek     (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
337*29492bb7SDavid van Moolenbroek     return_ACPI_STATUS (Status);
338*29492bb7SDavid van Moolenbroek }
339*29492bb7SDavid van Moolenbroek 
ACPI_EXPORT_SYMBOL(AcpiLoadTable)340*29492bb7SDavid van Moolenbroek ACPI_EXPORT_SYMBOL (AcpiLoadTable)
341*29492bb7SDavid van Moolenbroek 
342*29492bb7SDavid van Moolenbroek 
343*29492bb7SDavid van Moolenbroek /*******************************************************************************
344*29492bb7SDavid van Moolenbroek  *
345*29492bb7SDavid van Moolenbroek  * FUNCTION:    AcpiUnloadParentTable
346*29492bb7SDavid van Moolenbroek  *
347*29492bb7SDavid van Moolenbroek  * PARAMETERS:  Object              - Handle to any namespace object owned by
348*29492bb7SDavid van Moolenbroek  *                                    the table to be unloaded
349*29492bb7SDavid van Moolenbroek  *
350*29492bb7SDavid van Moolenbroek  * RETURN:      Status
351*29492bb7SDavid van Moolenbroek  *
352*29492bb7SDavid van Moolenbroek  * DESCRIPTION: Via any namespace object within an SSDT or OEMx table, unloads
353*29492bb7SDavid van Moolenbroek  *              the table and deletes all namespace objects associated with
354*29492bb7SDavid van Moolenbroek  *              that table. Unloading of the DSDT is not allowed.
355*29492bb7SDavid van Moolenbroek  *              Note: Mainly intended to support hotplug removal of SSDTs.
356*29492bb7SDavid van Moolenbroek  *
357*29492bb7SDavid van Moolenbroek  ******************************************************************************/
358*29492bb7SDavid van Moolenbroek 
359*29492bb7SDavid van Moolenbroek ACPI_STATUS
360*29492bb7SDavid van Moolenbroek AcpiUnloadParentTable (
361*29492bb7SDavid van Moolenbroek     ACPI_HANDLE             Object)
362*29492bb7SDavid van Moolenbroek {
363*29492bb7SDavid van Moolenbroek     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Object);
364*29492bb7SDavid van Moolenbroek     ACPI_STATUS             Status = AE_NOT_EXIST;
365*29492bb7SDavid van Moolenbroek     ACPI_OWNER_ID           OwnerId;
366*29492bb7SDavid van Moolenbroek     UINT32                  i;
367*29492bb7SDavid van Moolenbroek 
368*29492bb7SDavid van Moolenbroek 
369*29492bb7SDavid van Moolenbroek     ACPI_FUNCTION_TRACE (AcpiUnloadParentTable);
370*29492bb7SDavid van Moolenbroek 
371*29492bb7SDavid van Moolenbroek 
372*29492bb7SDavid van Moolenbroek     /* Parameter validation */
373*29492bb7SDavid van Moolenbroek 
374*29492bb7SDavid van Moolenbroek     if (!Object)
375*29492bb7SDavid van Moolenbroek     {
376*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (AE_BAD_PARAMETER);
377*29492bb7SDavid van Moolenbroek     }
378*29492bb7SDavid van Moolenbroek 
379*29492bb7SDavid van Moolenbroek     /*
380*29492bb7SDavid van Moolenbroek      * The node OwnerId is currently the same as the parent table ID.
381*29492bb7SDavid van Moolenbroek      * However, this could change in the future.
382*29492bb7SDavid van Moolenbroek      */
383*29492bb7SDavid van Moolenbroek     OwnerId = Node->OwnerId;
384*29492bb7SDavid van Moolenbroek     if (!OwnerId)
385*29492bb7SDavid van Moolenbroek     {
386*29492bb7SDavid van Moolenbroek         /* OwnerId==0 means DSDT is the owner. DSDT cannot be unloaded */
387*29492bb7SDavid van Moolenbroek 
388*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (AE_TYPE);
389*29492bb7SDavid van Moolenbroek     }
390*29492bb7SDavid van Moolenbroek 
391*29492bb7SDavid van Moolenbroek     /* Must acquire the interpreter lock during this operation */
392*29492bb7SDavid van Moolenbroek 
393*29492bb7SDavid van Moolenbroek     Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
394*29492bb7SDavid van Moolenbroek     if (ACPI_FAILURE (Status))
395*29492bb7SDavid van Moolenbroek     {
396*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (Status);
397*29492bb7SDavid van Moolenbroek     }
398*29492bb7SDavid van Moolenbroek 
399*29492bb7SDavid van Moolenbroek     /* Find the table in the global table list */
400*29492bb7SDavid van Moolenbroek 
401*29492bb7SDavid van Moolenbroek     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
402*29492bb7SDavid van Moolenbroek     {
403*29492bb7SDavid van Moolenbroek         if (OwnerId != AcpiGbl_RootTableList.Tables[i].OwnerId)
404*29492bb7SDavid van Moolenbroek         {
405*29492bb7SDavid van Moolenbroek             continue;
406*29492bb7SDavid van Moolenbroek         }
407*29492bb7SDavid van Moolenbroek 
408*29492bb7SDavid van Moolenbroek         /*
409*29492bb7SDavid van Moolenbroek          * Allow unload of SSDT and OEMx tables only. Do not allow unload
410*29492bb7SDavid van Moolenbroek          * of the DSDT. No other types of tables should get here, since
411*29492bb7SDavid van Moolenbroek          * only these types can contain AML and thus are the only types
412*29492bb7SDavid van Moolenbroek          * that can create namespace objects.
413*29492bb7SDavid van Moolenbroek          */
414*29492bb7SDavid van Moolenbroek         if (ACPI_COMPARE_NAME (
415*29492bb7SDavid van Moolenbroek             AcpiGbl_RootTableList.Tables[i].Signature.Ascii,
416*29492bb7SDavid van Moolenbroek             ACPI_SIG_DSDT))
417*29492bb7SDavid van Moolenbroek         {
418*29492bb7SDavid van Moolenbroek             Status = AE_TYPE;
419*29492bb7SDavid van Moolenbroek             break;
420*29492bb7SDavid van Moolenbroek         }
421*29492bb7SDavid van Moolenbroek 
422*29492bb7SDavid van Moolenbroek         /* Ensure the table is actually loaded */
423*29492bb7SDavid van Moolenbroek 
424*29492bb7SDavid van Moolenbroek         if (!AcpiTbIsTableLoaded (i))
425*29492bb7SDavid van Moolenbroek         {
426*29492bb7SDavid van Moolenbroek             Status = AE_NOT_EXIST;
427*29492bb7SDavid van Moolenbroek             break;
428*29492bb7SDavid van Moolenbroek         }
429*29492bb7SDavid van Moolenbroek 
430*29492bb7SDavid van Moolenbroek         /* Invoke table handler if present */
431*29492bb7SDavid van Moolenbroek 
432*29492bb7SDavid van Moolenbroek         if (AcpiGbl_TableHandler)
433*29492bb7SDavid van Moolenbroek         {
434*29492bb7SDavid van Moolenbroek             (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD,
435*29492bb7SDavid van Moolenbroek                         AcpiGbl_RootTableList.Tables[i].Pointer,
436*29492bb7SDavid van Moolenbroek                         AcpiGbl_TableHandlerContext);
437*29492bb7SDavid van Moolenbroek         }
438*29492bb7SDavid van Moolenbroek 
439*29492bb7SDavid van Moolenbroek         /*
440*29492bb7SDavid van Moolenbroek          * Delete all namespace objects owned by this table. Note that
441*29492bb7SDavid van Moolenbroek          * these objects can appear anywhere in the namespace by virtue
442*29492bb7SDavid van Moolenbroek          * of the AML "Scope" operator. Thus, we need to track ownership
443*29492bb7SDavid van Moolenbroek          * by an ID, not simply a position within the hierarchy.
444*29492bb7SDavid van Moolenbroek          */
445*29492bb7SDavid van Moolenbroek         Status = AcpiTbDeleteNamespaceByOwner (i);
446*29492bb7SDavid van Moolenbroek         if (ACPI_FAILURE (Status))
447*29492bb7SDavid van Moolenbroek         {
448*29492bb7SDavid van Moolenbroek             break;
449*29492bb7SDavid van Moolenbroek         }
450*29492bb7SDavid van Moolenbroek 
451*29492bb7SDavid van Moolenbroek         Status = AcpiTbReleaseOwnerId (i);
452*29492bb7SDavid van Moolenbroek         AcpiTbSetTableLoadedFlag (i, FALSE);
453*29492bb7SDavid van Moolenbroek         break;
454*29492bb7SDavid van Moolenbroek     }
455*29492bb7SDavid van Moolenbroek 
456*29492bb7SDavid van Moolenbroek     (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
457*29492bb7SDavid van Moolenbroek     return_ACPI_STATUS (Status);
458*29492bb7SDavid van Moolenbroek }
459*29492bb7SDavid van Moolenbroek 
460*29492bb7SDavid van Moolenbroek ACPI_EXPORT_SYMBOL (AcpiUnloadParentTable)
461