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