xref: /freebsd/sys/contrib/dev/acpica/components/tables/tbinstal.c (revision 70e6ab8f6ba244da61ab222a5829207da1201d8f)
1a159c266SJung-uk Kim /******************************************************************************
2a159c266SJung-uk Kim  *
3a159c266SJung-uk Kim  * Module Name: tbinstal - ACPI table installation and removal
4a159c266SJung-uk Kim  *
5a159c266SJung-uk Kim  *****************************************************************************/
6a159c266SJung-uk Kim 
7a159c266SJung-uk Kim /*
81c0e1b6dSJung-uk Kim  * Copyright (C) 2000 - 2015, Intel Corp.
9a159c266SJung-uk Kim  * All rights reserved.
10a159c266SJung-uk Kim  *
11a159c266SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12a159c266SJung-uk Kim  * modification, are permitted provided that the following conditions
13a159c266SJung-uk Kim  * are met:
14a159c266SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15a159c266SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16a159c266SJung-uk Kim  *    without modification.
17a159c266SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18a159c266SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19a159c266SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20a159c266SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21a159c266SJung-uk Kim  *    binary redistribution.
22a159c266SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23a159c266SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24a159c266SJung-uk Kim  *    from this software without specific prior written permission.
25a159c266SJung-uk Kim  *
26a159c266SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27a159c266SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28a159c266SJung-uk Kim  * Software Foundation.
29a159c266SJung-uk Kim  *
30a159c266SJung-uk Kim  * NO WARRANTY
31a159c266SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32a159c266SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33a159c266SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34a159c266SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35a159c266SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36a159c266SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37a159c266SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38a159c266SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39a159c266SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40a159c266SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41a159c266SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42a159c266SJung-uk Kim  */
43a159c266SJung-uk Kim 
44a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
45a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
46a159c266SJung-uk Kim #include <contrib/dev/acpica/include/actables.h>
47a159c266SJung-uk Kim 
48a159c266SJung-uk Kim #define _COMPONENT          ACPI_TABLES
49a159c266SJung-uk Kim         ACPI_MODULE_NAME    ("tbinstal")
50a159c266SJung-uk Kim 
51313a0c13SJung-uk Kim /* Local prototypes */
52a159c266SJung-uk Kim 
53313a0c13SJung-uk Kim static BOOLEAN
54313a0c13SJung-uk Kim AcpiTbCompareTables (
55313a0c13SJung-uk Kim     ACPI_TABLE_DESC         *TableDesc,
56313a0c13SJung-uk Kim     UINT32                  TableIndex);
57313a0c13SJung-uk Kim 
58313a0c13SJung-uk Kim 
59313a0c13SJung-uk Kim /*******************************************************************************
60a159c266SJung-uk Kim  *
61313a0c13SJung-uk Kim  * FUNCTION:    AcpiTbCompareTables
62a159c266SJung-uk Kim  *
63313a0c13SJung-uk Kim  * PARAMETERS:  TableDesc           - Table 1 descriptor to be compared
64313a0c13SJung-uk Kim  *              TableIndex          - Index of table 2 to be compared
65313a0c13SJung-uk Kim  *
66313a0c13SJung-uk Kim  * RETURN:      TRUE if both tables are identical.
67313a0c13SJung-uk Kim  *
68313a0c13SJung-uk Kim  * DESCRIPTION: This function compares a table with another table that has
69313a0c13SJung-uk Kim  *              already been installed in the root table list.
70313a0c13SJung-uk Kim  *
71313a0c13SJung-uk Kim  ******************************************************************************/
72313a0c13SJung-uk Kim 
73313a0c13SJung-uk Kim static BOOLEAN
74313a0c13SJung-uk Kim AcpiTbCompareTables (
75313a0c13SJung-uk Kim     ACPI_TABLE_DESC         *TableDesc,
76313a0c13SJung-uk Kim     UINT32                  TableIndex)
77313a0c13SJung-uk Kim {
78313a0c13SJung-uk Kim     ACPI_STATUS             Status = AE_OK;
79313a0c13SJung-uk Kim     BOOLEAN                 IsIdentical;
80313a0c13SJung-uk Kim     ACPI_TABLE_HEADER       *Table;
81313a0c13SJung-uk Kim     UINT32                  TableLength;
82313a0c13SJung-uk Kim     UINT8                   TableFlags;
83313a0c13SJung-uk Kim 
84313a0c13SJung-uk Kim 
85313a0c13SJung-uk Kim     Status = AcpiTbAcquireTable (&AcpiGbl_RootTableList.Tables[TableIndex],
86313a0c13SJung-uk Kim                 &Table, &TableLength, &TableFlags);
87313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
88313a0c13SJung-uk Kim     {
89313a0c13SJung-uk Kim         return (FALSE);
90313a0c13SJung-uk Kim     }
91313a0c13SJung-uk Kim 
92313a0c13SJung-uk Kim     /*
93313a0c13SJung-uk Kim      * Check for a table match on the entire table length,
94313a0c13SJung-uk Kim      * not just the header.
95313a0c13SJung-uk Kim      */
96313a0c13SJung-uk Kim     IsIdentical = (BOOLEAN)((TableDesc->Length != TableLength ||
975ef50723SJung-uk Kim         memcmp (TableDesc->Pointer, Table, TableLength)) ?
98313a0c13SJung-uk Kim         FALSE : TRUE);
99313a0c13SJung-uk Kim 
100313a0c13SJung-uk Kim     /* Release the acquired table */
101313a0c13SJung-uk Kim 
102313a0c13SJung-uk Kim     AcpiTbReleaseTable (Table, TableLength, TableFlags);
103313a0c13SJung-uk Kim     return (IsIdentical);
104313a0c13SJung-uk Kim }
105313a0c13SJung-uk Kim 
106313a0c13SJung-uk Kim 
107313a0c13SJung-uk Kim /*******************************************************************************
108313a0c13SJung-uk Kim  *
109313a0c13SJung-uk Kim  * FUNCTION:    AcpiTbInstallTableWithOverride
110313a0c13SJung-uk Kim  *
111*70e6ab8fSJung-uk Kim  * PARAMETERS:  NewTableDesc            - New table descriptor to install
112313a0c13SJung-uk Kim  *              Override                - Whether override should be performed
113*70e6ab8fSJung-uk Kim  *              TableIndex              - Where the table index is returned
114313a0c13SJung-uk Kim  *
115313a0c13SJung-uk Kim  * RETURN:      None
116313a0c13SJung-uk Kim  *
117313a0c13SJung-uk Kim  * DESCRIPTION: Install an ACPI table into the global data structure. The
118313a0c13SJung-uk Kim  *              table override mechanism is called to allow the host
119313a0c13SJung-uk Kim  *              OS to replace any table before it is installed in the root
120313a0c13SJung-uk Kim  *              table array.
121313a0c13SJung-uk Kim  *
122313a0c13SJung-uk Kim  ******************************************************************************/
123313a0c13SJung-uk Kim 
124313a0c13SJung-uk Kim void
125313a0c13SJung-uk Kim AcpiTbInstallTableWithOverride (
126313a0c13SJung-uk Kim     ACPI_TABLE_DESC         *NewTableDesc,
127*70e6ab8fSJung-uk Kim     BOOLEAN                 Override,
128*70e6ab8fSJung-uk Kim     UINT32                  *TableIndex)
129313a0c13SJung-uk Kim {
130*70e6ab8fSJung-uk Kim     UINT32                  i;
131*70e6ab8fSJung-uk Kim     ACPI_STATUS             Status;
132313a0c13SJung-uk Kim 
133*70e6ab8fSJung-uk Kim 
134*70e6ab8fSJung-uk Kim     Status = AcpiTbGetNextTableDescriptor (&i, NULL);
135*70e6ab8fSJung-uk Kim     if (ACPI_FAILURE (Status))
136313a0c13SJung-uk Kim     {
137313a0c13SJung-uk Kim         return;
138313a0c13SJung-uk Kim     }
139313a0c13SJung-uk Kim 
140313a0c13SJung-uk Kim     /*
141313a0c13SJung-uk Kim      * ACPI Table Override:
142313a0c13SJung-uk Kim      *
143313a0c13SJung-uk Kim      * Before we install the table, let the host OS override it with a new
144313a0c13SJung-uk Kim      * one if desired. Any table within the RSDT/XSDT can be replaced,
145313a0c13SJung-uk Kim      * including the DSDT which is pointed to by the FADT.
146313a0c13SJung-uk Kim      */
147313a0c13SJung-uk Kim     if (Override)
148313a0c13SJung-uk Kim     {
149313a0c13SJung-uk Kim         AcpiTbOverrideTable (NewTableDesc);
150313a0c13SJung-uk Kim     }
151313a0c13SJung-uk Kim 
152*70e6ab8fSJung-uk Kim     AcpiTbInitTableDescriptor (&AcpiGbl_RootTableList.Tables[i],
153313a0c13SJung-uk Kim         NewTableDesc->Address, NewTableDesc->Flags, NewTableDesc->Pointer);
154313a0c13SJung-uk Kim 
155313a0c13SJung-uk Kim     AcpiTbPrintTableHeader (NewTableDesc->Address, NewTableDesc->Pointer);
156313a0c13SJung-uk Kim 
157*70e6ab8fSJung-uk Kim     /* This synchronizes AcpiGbl_DsdtIndex */
158*70e6ab8fSJung-uk Kim 
159*70e6ab8fSJung-uk Kim     *TableIndex = i;
160*70e6ab8fSJung-uk Kim 
161313a0c13SJung-uk Kim     /* Set the global integer width (based upon revision of the DSDT) */
162313a0c13SJung-uk Kim 
163*70e6ab8fSJung-uk Kim     if (i == AcpiGbl_DsdtIndex)
164313a0c13SJung-uk Kim     {
165313a0c13SJung-uk Kim         AcpiUtSetIntegerWidth (NewTableDesc->Pointer->Revision);
166313a0c13SJung-uk Kim     }
167313a0c13SJung-uk Kim }
168313a0c13SJung-uk Kim 
169313a0c13SJung-uk Kim 
170313a0c13SJung-uk Kim /*******************************************************************************
171313a0c13SJung-uk Kim  *
172313a0c13SJung-uk Kim  * FUNCTION:    AcpiTbInstallFixedTable
173313a0c13SJung-uk Kim  *
174313a0c13SJung-uk Kim  * PARAMETERS:  Address                 - Physical address of DSDT or FACS
175313a0c13SJung-uk Kim  *              Signature               - Table signature, NULL if no need to
176313a0c13SJung-uk Kim  *                                        match
177*70e6ab8fSJung-uk Kim  *              TableIndex              - Where the table index is returned
178a159c266SJung-uk Kim  *
179a159c266SJung-uk Kim  * RETURN:      Status
180a159c266SJung-uk Kim  *
181313a0c13SJung-uk Kim  * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data
182313a0c13SJung-uk Kim  *              structure.
183a159c266SJung-uk Kim  *
184313a0c13SJung-uk Kim  ******************************************************************************/
185a159c266SJung-uk Kim 
186a159c266SJung-uk Kim ACPI_STATUS
187313a0c13SJung-uk Kim AcpiTbInstallFixedTable (
188313a0c13SJung-uk Kim     ACPI_PHYSICAL_ADDRESS   Address,
189313a0c13SJung-uk Kim     char                    *Signature,
190*70e6ab8fSJung-uk Kim     UINT32                  *TableIndex)
191a159c266SJung-uk Kim {
192313a0c13SJung-uk Kim     ACPI_TABLE_DESC         NewTableDesc;
193313a0c13SJung-uk Kim     ACPI_STATUS             Status;
194a159c266SJung-uk Kim 
195a159c266SJung-uk Kim 
196313a0c13SJung-uk Kim     ACPI_FUNCTION_TRACE (TbInstallFixedTable);
197a159c266SJung-uk Kim 
198a159c266SJung-uk Kim 
199313a0c13SJung-uk Kim     if (!Address)
200a159c266SJung-uk Kim     {
201313a0c13SJung-uk Kim         ACPI_ERROR ((AE_INFO, "Null physical address for ACPI table [%s]",
202313a0c13SJung-uk Kim             Signature));
203313a0c13SJung-uk Kim         return (AE_NO_MEMORY);
204a159c266SJung-uk Kim     }
205a159c266SJung-uk Kim 
206313a0c13SJung-uk Kim     /* Fill a table descriptor for validation */
207313a0c13SJung-uk Kim 
208313a0c13SJung-uk Kim     Status = AcpiTbAcquireTempTable (&NewTableDesc, Address,
209313a0c13SJung-uk Kim                 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL);
210313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
211a159c266SJung-uk Kim     {
2127cf3e94aSJung-uk Kim         ACPI_ERROR ((AE_INFO, "Could not acquire table length at %8.8X%8.8X",
2137cf3e94aSJung-uk Kim             ACPI_FORMAT_UINT64 (Address)));
214313a0c13SJung-uk Kim         return_ACPI_STATUS (Status);
215a159c266SJung-uk Kim     }
216a159c266SJung-uk Kim 
217313a0c13SJung-uk Kim     /* Validate and verify a table before installation */
218a159c266SJung-uk Kim 
219313a0c13SJung-uk Kim     Status = AcpiTbVerifyTempTable (&NewTableDesc, Signature);
220313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
221313a0c13SJung-uk Kim     {
222313a0c13SJung-uk Kim         goto ReleaseAndExit;
223313a0c13SJung-uk Kim     }
224a159c266SJung-uk Kim 
225*70e6ab8fSJung-uk Kim     /* Add the table to the global root table list */
226*70e6ab8fSJung-uk Kim 
227*70e6ab8fSJung-uk Kim     AcpiTbInstallTableWithOverride (&NewTableDesc, TRUE, TableIndex);
228313a0c13SJung-uk Kim 
229313a0c13SJung-uk Kim ReleaseAndExit:
230313a0c13SJung-uk Kim 
231313a0c13SJung-uk Kim     /* Release the temporary table descriptor */
232313a0c13SJung-uk Kim 
233313a0c13SJung-uk Kim     AcpiTbReleaseTempTable (&NewTableDesc);
234a159c266SJung-uk Kim     return_ACPI_STATUS (Status);
235a159c266SJung-uk Kim }
236a159c266SJung-uk Kim 
237a159c266SJung-uk Kim 
238a159c266SJung-uk Kim /*******************************************************************************
239a159c266SJung-uk Kim  *
240313a0c13SJung-uk Kim  * FUNCTION:    AcpiTbInstallStandardTable
241a159c266SJung-uk Kim  *
242313a0c13SJung-uk Kim  * PARAMETERS:  Address             - Address of the table (might be a virtual
243313a0c13SJung-uk Kim  *                                    address depending on the TableFlags)
244313a0c13SJung-uk Kim  *              Flags               - Flags for the table
245313a0c13SJung-uk Kim  *              Reload              - Whether reload should be performed
246313a0c13SJung-uk Kim  *              Override            - Whether override should be performed
247a159c266SJung-uk Kim  *              TableIndex          - Where the table index is returned
248a159c266SJung-uk Kim  *
249a159c266SJung-uk Kim  * RETURN:      Status
250a159c266SJung-uk Kim  *
251313a0c13SJung-uk Kim  * DESCRIPTION: This function is called to install an ACPI table that is
252313a0c13SJung-uk Kim  *              neither DSDT nor FACS (a "standard" table.)
253313a0c13SJung-uk Kim  *              When this function is called by "Load" or "LoadTable" opcodes,
254313a0c13SJung-uk Kim  *              or by AcpiLoadTable() API, the "Reload" parameter is set.
255313a0c13SJung-uk Kim  *              After sucessfully returning from this function, table is
256313a0c13SJung-uk Kim  *              "INSTALLED" but not "VALIDATED".
257a159c266SJung-uk Kim  *
258a159c266SJung-uk Kim  ******************************************************************************/
259a159c266SJung-uk Kim 
260a159c266SJung-uk Kim ACPI_STATUS
261313a0c13SJung-uk Kim AcpiTbInstallStandardTable (
262313a0c13SJung-uk Kim     ACPI_PHYSICAL_ADDRESS   Address,
263313a0c13SJung-uk Kim     UINT8                   Flags,
264313a0c13SJung-uk Kim     BOOLEAN                 Reload,
265313a0c13SJung-uk Kim     BOOLEAN                 Override,
266a159c266SJung-uk Kim     UINT32                  *TableIndex)
267a159c266SJung-uk Kim {
268a159c266SJung-uk Kim     UINT32                  i;
269a159c266SJung-uk Kim     ACPI_STATUS             Status = AE_OK;
270313a0c13SJung-uk Kim     ACPI_TABLE_DESC         NewTableDesc;
271a159c266SJung-uk Kim 
272a159c266SJung-uk Kim 
273313a0c13SJung-uk Kim     ACPI_FUNCTION_TRACE (TbInstallStandardTable);
274a159c266SJung-uk Kim 
275a159c266SJung-uk Kim 
276313a0c13SJung-uk Kim     /* Acquire a temporary table descriptor for validation */
277313a0c13SJung-uk Kim 
278313a0c13SJung-uk Kim     Status = AcpiTbAcquireTempTable (&NewTableDesc, Address, Flags);
279313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
280a159c266SJung-uk Kim     {
2817cf3e94aSJung-uk Kim         ACPI_ERROR ((AE_INFO, "Could not acquire table length at %8.8X%8.8X",
2827cf3e94aSJung-uk Kim             ACPI_FORMAT_UINT64 (Address)));
283a159c266SJung-uk Kim         return_ACPI_STATUS (Status);
284a159c266SJung-uk Kim     }
285313a0c13SJung-uk Kim 
286313a0c13SJung-uk Kim     /*
287313a0c13SJung-uk Kim      * Optionally do not load any SSDTs from the RSDT/XSDT. This can
288313a0c13SJung-uk Kim      * be useful for debugging ACPI problems on some machines.
289313a0c13SJung-uk Kim      */
290313a0c13SJung-uk Kim     if (!Reload &&
291313a0c13SJung-uk Kim         AcpiGbl_DisableSsdtTableInstall &&
292313a0c13SJung-uk Kim         ACPI_COMPARE_NAME (&NewTableDesc.Signature, ACPI_SIG_SSDT))
293313a0c13SJung-uk Kim     {
2947cf3e94aSJung-uk Kim         ACPI_INFO ((AE_INFO, "Ignoring installation of %4.4s at %8.8X%8.8X",
2957cf3e94aSJung-uk Kim             NewTableDesc.Signature.Ascii, ACPI_FORMAT_UINT64 (Address)));
296313a0c13SJung-uk Kim         goto ReleaseAndExit;
297a159c266SJung-uk Kim     }
298a159c266SJung-uk Kim 
299313a0c13SJung-uk Kim     /* Validate and verify a table before installation */
300313a0c13SJung-uk Kim 
301313a0c13SJung-uk Kim     Status = AcpiTbVerifyTempTable (&NewTableDesc, NULL);
302313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
303313a0c13SJung-uk Kim     {
304313a0c13SJung-uk Kim         goto ReleaseAndExit;
305313a0c13SJung-uk Kim     }
306313a0c13SJung-uk Kim 
307313a0c13SJung-uk Kim     if (Reload)
308313a0c13SJung-uk Kim     {
309a159c266SJung-uk Kim         /*
310a159c266SJung-uk Kim          * Validate the incoming table signature.
311a159c266SJung-uk Kim          *
312a159c266SJung-uk Kim          * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
313a159c266SJung-uk Kim          * 2) We added support for OEMx tables, signature "OEM".
314a159c266SJung-uk Kim          * 3) Valid tables were encountered with a null signature, so we just
315a159c266SJung-uk Kim          *    gave up on validating the signature, (05/2008).
316a159c266SJung-uk Kim          * 4) We encountered non-AML tables such as the MADT, which caused
317a159c266SJung-uk Kim          *    interpreter errors and kernel faults. So now, we once again allow
318a159c266SJung-uk Kim          *    only "SSDT", "OEMx", and now, also a null signature. (05/2011).
319a159c266SJung-uk Kim          */
320313a0c13SJung-uk Kim         if ((NewTableDesc.Signature.Ascii[0] != 0x00) &&
321313a0c13SJung-uk Kim            (!ACPI_COMPARE_NAME (&NewTableDesc.Signature, ACPI_SIG_SSDT)) &&
3225ef50723SJung-uk Kim            (strncmp (NewTableDesc.Signature.Ascii, "OEM", 3)))
323a159c266SJung-uk Kim         {
324e8241eabSJung-uk Kim             ACPI_BIOS_ERROR ((AE_INFO,
325e8241eabSJung-uk Kim                 "Table has invalid signature [%4.4s] (0x%8.8X), "
326e8241eabSJung-uk Kim                 "must be SSDT or OEMx",
327313a0c13SJung-uk Kim                 AcpiUtValidAcpiName (NewTableDesc.Signature.Ascii) ?
328313a0c13SJung-uk Kim                     NewTableDesc.Signature.Ascii : "????",
329313a0c13SJung-uk Kim                 NewTableDesc.Signature.Integer));
330a159c266SJung-uk Kim 
331313a0c13SJung-uk Kim             Status = AE_BAD_SIGNATURE;
332313a0c13SJung-uk Kim             goto ReleaseAndExit;
333a159c266SJung-uk Kim         }
334a159c266SJung-uk Kim 
335a159c266SJung-uk Kim         /* Check if table is already registered */
336a159c266SJung-uk Kim 
337a159c266SJung-uk Kim         for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
338a159c266SJung-uk Kim         {
339a159c266SJung-uk Kim             /*
340a159c266SJung-uk Kim              * Check for a table match on the entire table length,
341a159c266SJung-uk Kim              * not just the header.
342a159c266SJung-uk Kim              */
343313a0c13SJung-uk Kim             if (!AcpiTbCompareTables (&NewTableDesc, i))
344a159c266SJung-uk Kim             {
345a159c266SJung-uk Kim                 continue;
346a159c266SJung-uk Kim             }
347a159c266SJung-uk Kim 
348a159c266SJung-uk Kim             /*
349a159c266SJung-uk Kim              * Note: the current mechanism does not unregister a table if it is
350a159c266SJung-uk Kim              * dynamically unloaded. The related namespace entries are deleted,
351a159c266SJung-uk Kim              * but the table remains in the root table list.
352a159c266SJung-uk Kim              *
353a159c266SJung-uk Kim              * The assumption here is that the number of different tables that
354a159c266SJung-uk Kim              * will be loaded is actually small, and there is minimal overhead
355a159c266SJung-uk Kim              * in just keeping the table in case it is needed again.
356a159c266SJung-uk Kim              *
357a159c266SJung-uk Kim              * If this assumption changes in the future (perhaps on large
358a159c266SJung-uk Kim              * machines with many table load/unload operations), tables will
359a159c266SJung-uk Kim              * need to be unregistered when they are unloaded, and slots in the
360a159c266SJung-uk Kim              * root table list should be reused when empty.
361a159c266SJung-uk Kim              */
362a159c266SJung-uk Kim             if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED)
363a159c266SJung-uk Kim             {
364a159c266SJung-uk Kim                 /* Table is still loaded, this is an error */
365a159c266SJung-uk Kim 
366a159c266SJung-uk Kim                 Status = AE_ALREADY_EXISTS;
367313a0c13SJung-uk Kim                 goto ReleaseAndExit;
368a159c266SJung-uk Kim             }
369a159c266SJung-uk Kim             else
370a159c266SJung-uk Kim             {
371a159c266SJung-uk Kim                 /*
372313a0c13SJung-uk Kim                  * Table was unloaded, allow it to be reloaded.
373313a0c13SJung-uk Kim                  * As we are going to return AE_OK to the caller, we should
374313a0c13SJung-uk Kim                  * take the responsibility of freeing the input descriptor.
375313a0c13SJung-uk Kim                  * Refill the input descriptor to ensure
376313a0c13SJung-uk Kim                  * AcpiTbInstallTableWithOverride() can be called again to
377313a0c13SJung-uk Kim                  * indicate the re-installation.
378a159c266SJung-uk Kim                  */
379313a0c13SJung-uk Kim                 AcpiTbUninstallTable (&NewTableDesc);
380313a0c13SJung-uk Kim                 *TableIndex = i;
381313a0c13SJung-uk Kim                 return_ACPI_STATUS (AE_OK);
382313a0c13SJung-uk Kim             }
383313a0c13SJung-uk Kim         }
384313a0c13SJung-uk Kim     }
385a159c266SJung-uk Kim 
386a159c266SJung-uk Kim     /* Add the table to the global root table list */
387a159c266SJung-uk Kim 
388*70e6ab8fSJung-uk Kim     AcpiTbInstallTableWithOverride (&NewTableDesc, Override, TableIndex);
389a159c266SJung-uk Kim 
390313a0c13SJung-uk Kim ReleaseAndExit:
391313a0c13SJung-uk Kim 
392313a0c13SJung-uk Kim     /* Release the temporary table descriptor */
393313a0c13SJung-uk Kim 
394313a0c13SJung-uk Kim     AcpiTbReleaseTempTable (&NewTableDesc);
395a159c266SJung-uk Kim     return_ACPI_STATUS (Status);
396a159c266SJung-uk Kim }
397a159c266SJung-uk Kim 
398a159c266SJung-uk Kim 
399a159c266SJung-uk Kim /*******************************************************************************
400a159c266SJung-uk Kim  *
401313a0c13SJung-uk Kim  * FUNCTION:    AcpiTbOverrideTable
402a159c266SJung-uk Kim  *
403313a0c13SJung-uk Kim  * PARAMETERS:  OldTableDesc        - Validated table descriptor to be
404313a0c13SJung-uk Kim  *                                    overridden
405a159c266SJung-uk Kim  *
406313a0c13SJung-uk Kim  * RETURN:      None
407a159c266SJung-uk Kim  *
408a159c266SJung-uk Kim  * DESCRIPTION: Attempt table override by calling the OSL override functions.
409a159c266SJung-uk Kim  *              Note: If the table is overridden, then the entire new table
410313a0c13SJung-uk Kim  *              is acquired and returned by this function.
411313a0c13SJung-uk Kim  *              Before/after invocation, the table descriptor is in a state
412313a0c13SJung-uk Kim  *              that is "VALIDATED".
413a159c266SJung-uk Kim  *
414a159c266SJung-uk Kim  ******************************************************************************/
415a159c266SJung-uk Kim 
416313a0c13SJung-uk Kim void
417313a0c13SJung-uk Kim AcpiTbOverrideTable (
418313a0c13SJung-uk Kim     ACPI_TABLE_DESC         *OldTableDesc)
419a159c266SJung-uk Kim {
420a159c266SJung-uk Kim     ACPI_STATUS             Status;
421a159c266SJung-uk Kim     char                    *OverrideType;
422313a0c13SJung-uk Kim     ACPI_TABLE_DESC         NewTableDesc;
423313a0c13SJung-uk Kim     ACPI_TABLE_HEADER       *Table;
424313a0c13SJung-uk Kim     ACPI_PHYSICAL_ADDRESS   Address;
425313a0c13SJung-uk Kim     UINT32                  Length;
426a159c266SJung-uk Kim 
427a159c266SJung-uk Kim 
428a159c266SJung-uk Kim     /* (1) Attempt logical override (returns a logical address) */
429a159c266SJung-uk Kim 
430313a0c13SJung-uk Kim     Status = AcpiOsTableOverride (OldTableDesc->Pointer, &Table);
431313a0c13SJung-uk Kim     if (ACPI_SUCCESS (Status) && Table)
432a159c266SJung-uk Kim     {
433313a0c13SJung-uk Kim         AcpiTbAcquireTempTable (&NewTableDesc, ACPI_PTR_TO_PHYSADDR (Table),
434313a0c13SJung-uk Kim             ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL);
435a159c266SJung-uk Kim         OverrideType = "Logical";
436a159c266SJung-uk Kim         goto FinishOverride;
437a159c266SJung-uk Kim     }
438a159c266SJung-uk Kim 
439a159c266SJung-uk Kim     /* (2) Attempt physical override (returns a physical address) */
440a159c266SJung-uk Kim 
441313a0c13SJung-uk Kim     Status = AcpiOsPhysicalTableOverride (OldTableDesc->Pointer,
442313a0c13SJung-uk Kim         &Address, &Length);
443313a0c13SJung-uk Kim     if (ACPI_SUCCESS (Status) && Address && Length)
444a159c266SJung-uk Kim     {
445313a0c13SJung-uk Kim         AcpiTbAcquireTempTable (&NewTableDesc, Address,
446313a0c13SJung-uk Kim             ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL);
447a159c266SJung-uk Kim         OverrideType = "Physical";
448a159c266SJung-uk Kim         goto FinishOverride;
449a159c266SJung-uk Kim     }
450a159c266SJung-uk Kim 
451313a0c13SJung-uk Kim     return; /* There was no override */
452a159c266SJung-uk Kim 
453a159c266SJung-uk Kim 
454a159c266SJung-uk Kim FinishOverride:
455a159c266SJung-uk Kim 
456313a0c13SJung-uk Kim     /* Validate and verify a table before overriding */
457a159c266SJung-uk Kim 
458313a0c13SJung-uk Kim     Status = AcpiTbVerifyTempTable (&NewTableDesc, NULL);
459313a0c13SJung-uk Kim     if (ACPI_FAILURE (Status))
460313a0c13SJung-uk Kim     {
461313a0c13SJung-uk Kim         return;
462a159c266SJung-uk Kim     }
463a159c266SJung-uk Kim 
4647cf3e94aSJung-uk Kim     ACPI_INFO ((AE_INFO, "%4.4s 0x%8.8X%8.8X"
4657cf3e94aSJung-uk Kim         " %s table override, new table: 0x%8.8X%8.8X",
466313a0c13SJung-uk Kim         OldTableDesc->Signature.Ascii,
4677cf3e94aSJung-uk Kim         ACPI_FORMAT_UINT64 (OldTableDesc->Address),
4687cf3e94aSJung-uk Kim         OverrideType, ACPI_FORMAT_UINT64 (NewTableDesc.Address)));
469a159c266SJung-uk Kim 
470313a0c13SJung-uk Kim     /* We can now uninstall the original table */
471a159c266SJung-uk Kim 
472313a0c13SJung-uk Kim     AcpiTbUninstallTable (OldTableDesc);
473a159c266SJung-uk Kim 
474313a0c13SJung-uk Kim     /*
475313a0c13SJung-uk Kim      * Replace the original table descriptor and keep its state as
476313a0c13SJung-uk Kim      * "VALIDATED".
477313a0c13SJung-uk Kim      */
478313a0c13SJung-uk Kim     AcpiTbInitTableDescriptor (OldTableDesc, NewTableDesc.Address,
479313a0c13SJung-uk Kim         NewTableDesc.Flags, NewTableDesc.Pointer);
480313a0c13SJung-uk Kim     AcpiTbValidateTempTable (OldTableDesc);
481a159c266SJung-uk Kim 
482313a0c13SJung-uk Kim     /* Release the temporary table descriptor */
483a159c266SJung-uk Kim 
484313a0c13SJung-uk Kim     AcpiTbReleaseTempTable (&NewTableDesc);
485a159c266SJung-uk Kim }
486a159c266SJung-uk Kim 
487a159c266SJung-uk Kim 
488a159c266SJung-uk Kim /*******************************************************************************
489a159c266SJung-uk Kim  *
490313a0c13SJung-uk Kim  * FUNCTION:    AcpiTbUninstallTable
491a159c266SJung-uk Kim  *
492313a0c13SJung-uk Kim  * PARAMETERS:  TableDesc           - Table descriptor
493a159c266SJung-uk Kim  *
494a159c266SJung-uk Kim  * RETURN:      None
495a159c266SJung-uk Kim  *
496a159c266SJung-uk Kim  * DESCRIPTION: Delete one internal ACPI table
497a159c266SJung-uk Kim  *
498a159c266SJung-uk Kim  ******************************************************************************/
499a159c266SJung-uk Kim 
500a159c266SJung-uk Kim void
501313a0c13SJung-uk Kim AcpiTbUninstallTable (
502a159c266SJung-uk Kim     ACPI_TABLE_DESC         *TableDesc)
503a159c266SJung-uk Kim {
504a159c266SJung-uk Kim 
505313a0c13SJung-uk Kim     ACPI_FUNCTION_TRACE (TbUninstallTable);
506a159c266SJung-uk Kim 
507313a0c13SJung-uk Kim 
508313a0c13SJung-uk Kim     /* Table must be installed */
509313a0c13SJung-uk Kim 
510313a0c13SJung-uk Kim     if (!TableDesc->Address)
511a159c266SJung-uk Kim     {
5128ef1a331SJung-uk Kim         return_VOID;
513a159c266SJung-uk Kim     }
514a159c266SJung-uk Kim 
515313a0c13SJung-uk Kim     AcpiTbInvalidateTable (TableDesc);
516a159c266SJung-uk Kim 
517313a0c13SJung-uk Kim     if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) ==
518313a0c13SJung-uk Kim         ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL)
519a159c266SJung-uk Kim     {
5207cf3e94aSJung-uk Kim         ACPI_FREE (ACPI_PHYSADDR_TO_PTR (TableDesc->Address));
521a159c266SJung-uk Kim     }
522a159c266SJung-uk Kim 
523313a0c13SJung-uk Kim     TableDesc->Address = ACPI_PTR_TO_PHYSADDR (NULL);
524313a0c13SJung-uk Kim     return_VOID;
525a159c266SJung-uk Kim }
526