xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/tables/tbxfload.c (revision f2df0cfe93a902842f6f4629ff614f5b3f9bf687)
1 /******************************************************************************
2  *
3  * Module Name: tbxfload - Table load/unload external interfaces
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2016, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115 
116 #define EXPORT_ACPI_INTERFACES
117 
118 #include "acpi.h"
119 #include "accommon.h"
120 #include "acnamesp.h"
121 #include "actables.h"
122 
123 #define _COMPONENT          ACPI_TABLES
124         ACPI_MODULE_NAME    ("tbxfload")
125 
126 
127 /*******************************************************************************
128  *
129  * FUNCTION:    AcpiLoadTables
130  *
131  * PARAMETERS:  None
132  *
133  * RETURN:      Status
134  *
135  * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
136  *
137  ******************************************************************************/
138 
139 ACPI_STATUS
140 AcpiLoadTables (
141     void)
142 {
143     ACPI_STATUS             Status;
144 
145 
146     ACPI_FUNCTION_TRACE (AcpiLoadTables);
147 
148 
149     /* Load the namespace from the tables */
150 
151     Status = AcpiTbLoadNamespace ();
152 
153     /* Don't let single failures abort the load */
154 
155     if (Status == AE_CTRL_TERMINATE)
156     {
157         Status = AE_OK;
158     }
159 
160     if (ACPI_FAILURE (Status))
161     {
162         ACPI_EXCEPTION ((AE_INFO, Status,
163             "While loading namespace from ACPI tables"));
164     }
165 
166     return_ACPI_STATUS (Status);
167 }
168 
169 ACPI_EXPORT_SYMBOL_INIT (AcpiLoadTables)
170 
171 
172 /*******************************************************************************
173  *
174  * FUNCTION:    AcpiTbLoadNamespace
175  *
176  * PARAMETERS:  None
177  *
178  * RETURN:      Status
179  *
180  * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
181  *              the RSDT/XSDT.
182  *
183  ******************************************************************************/
184 
185 ACPI_STATUS
186 AcpiTbLoadNamespace (
187     void)
188 {
189     ACPI_STATUS             Status;
190     UINT32                  i;
191     ACPI_TABLE_HEADER       *NewDsdt;
192     ACPI_TABLE_DESC         *Table;
193     UINT32                  TablesLoaded = 0;
194     UINT32                  TablesFailed = 0;
195 
196 
197     ACPI_FUNCTION_TRACE (TbLoadNamespace);
198 
199 
200     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
201 
202     /*
203      * Load the namespace. The DSDT is required, but any SSDT and
204      * PSDT tables are optional. Verify the DSDT.
205      */
206     Table = &AcpiGbl_RootTableList.Tables[AcpiGbl_DsdtIndex];
207 
208     if (!AcpiGbl_RootTableList.CurrentTableCount ||
209         !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_DSDT) ||
210          ACPI_FAILURE (AcpiTbValidateTable (Table)))
211     {
212         Status = AE_NO_ACPI_TABLES;
213         goto UnlockAndExit;
214     }
215 
216     /*
217      * Save the DSDT pointer for simple access. This is the mapped memory
218      * address. We must take care here because the address of the .Tables
219      * array can change dynamically as tables are loaded at run-time. Note:
220      * .Pointer field is not validated until after call to AcpiTbValidateTable.
221      */
222     AcpiGbl_DSDT = Table->Pointer;
223 
224     /*
225      * Optionally copy the entire DSDT to local memory (instead of simply
226      * mapping it.) There are some BIOSs that corrupt or replace the original
227      * DSDT, creating the need for this option. Default is FALSE, do not copy
228      * the DSDT.
229      */
230     if (AcpiGbl_CopyDsdtLocally)
231     {
232         NewDsdt = AcpiTbCopyDsdt (AcpiGbl_DsdtIndex);
233         if (NewDsdt)
234         {
235             AcpiGbl_DSDT = NewDsdt;
236         }
237     }
238 
239     /*
240      * Save the original DSDT header for detection of table corruption
241      * and/or replacement of the DSDT from outside the OS.
242      */
243     memcpy (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
244         sizeof (ACPI_TABLE_HEADER));
245 
246     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
247 
248     /* Load and parse tables */
249 
250     Status = AcpiNsLoadTable (AcpiGbl_DsdtIndex, AcpiGbl_RootNode);
251     if (ACPI_FAILURE (Status))
252     {
253         ACPI_EXCEPTION ((AE_INFO, Status, "[DSDT] table load failed"));
254         TablesFailed++;
255     }
256     else
257     {
258         TablesLoaded++;
259     }
260 
261     /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
262 
263     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
264     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
265     {
266         Table = &AcpiGbl_RootTableList.Tables[i];
267 
268         if (!AcpiGbl_RootTableList.Tables[i].Address ||
269             (!ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_SSDT) &&
270              !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_PSDT) &&
271              !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_OSDT)) ||
272              ACPI_FAILURE (AcpiTbValidateTable (Table)))
273         {
274             continue;
275         }
276 
277         /* Ignore errors while loading tables, get as many as possible */
278 
279         (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
280         Status =  AcpiNsLoadTable (i, AcpiGbl_RootNode);
281         if (ACPI_FAILURE (Status))
282         {
283             ACPI_EXCEPTION ((AE_INFO, Status, "(%4.4s:%8.8s) while loading table",
284                 Table->Signature.Ascii, Table->Pointer->OemTableId));
285 
286             TablesFailed++;
287 
288             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
289                 "Table [%4.4s:%8.8s] (id FF) - Table namespace load failed\n\n",
290                 Table->Signature.Ascii, Table->Pointer->OemTableId));
291         }
292         else
293         {
294             TablesLoaded++;
295         }
296 
297         (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
298     }
299 
300     if (!TablesFailed)
301     {
302         ACPI_INFO ((AE_INFO,
303             "%u ACPI AML tables successfully acquired and loaded\n",
304             TablesLoaded));
305     }
306     else
307     {
308         ACPI_ERROR ((AE_INFO,
309             "%u table load failures, %u successful",
310             TablesFailed, TablesLoaded));
311 
312         /* Indicate at least one failure */
313 
314         Status = AE_CTRL_TERMINATE;
315     }
316 
317 UnlockAndExit:
318     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
319     return_ACPI_STATUS (Status);
320 }
321 
322 
323 /*******************************************************************************
324  *
325  * FUNCTION:    AcpiInstallTable
326  *
327  * PARAMETERS:  Address             - Address of the ACPI table to be installed.
328  *              Physical            - Whether the address is a physical table
329  *                                    address or not
330  *
331  * RETURN:      Status
332  *
333  * DESCRIPTION: Dynamically install an ACPI table.
334  *              Note: This function should only be invoked after
335  *                    AcpiInitializeTables() and before AcpiLoadTables().
336  *
337  ******************************************************************************/
338 
339 ACPI_STATUS
340 AcpiInstallTable (
341     ACPI_PHYSICAL_ADDRESS   Address,
342     BOOLEAN                 Physical)
343 {
344     ACPI_STATUS             Status;
345     UINT8                   Flags;
346     UINT32                  TableIndex;
347 
348 
349     ACPI_FUNCTION_TRACE (AcpiInstallTable);
350 
351 
352     if (Physical)
353     {
354         Flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL;
355     }
356     else
357     {
358         Flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL;
359     }
360 
361     Status = AcpiTbInstallStandardTable (Address, Flags,
362         FALSE, FALSE, &TableIndex);
363 
364     return_ACPI_STATUS (Status);
365 }
366 
367 ACPI_EXPORT_SYMBOL_INIT (AcpiInstallTable)
368 
369 
370 /*******************************************************************************
371  *
372  * FUNCTION:    AcpiLoadTable
373  *
374  * PARAMETERS:  Table               - Pointer to a buffer containing the ACPI
375  *                                    table to be loaded.
376  *
377  * RETURN:      Status
378  *
379  * DESCRIPTION: Dynamically load an ACPI table from the caller's buffer. Must
380  *              be a valid ACPI table with a valid ACPI table header.
381  *              Note1: Mainly intended to support hotplug addition of SSDTs.
382  *              Note2: Does not copy the incoming table. User is responsible
383  *              to ensure that the table is not deleted or unmapped.
384  *
385  ******************************************************************************/
386 
387 ACPI_STATUS
388 AcpiLoadTable (
389     ACPI_TABLE_HEADER       *Table)
390 {
391     ACPI_STATUS             Status;
392     UINT32                  TableIndex;
393 
394 
395     ACPI_FUNCTION_TRACE (AcpiLoadTable);
396 
397 
398     /* Parameter validation */
399 
400     if (!Table)
401     {
402         return_ACPI_STATUS (AE_BAD_PARAMETER);
403     }
404 
405     /* Must acquire the interpreter lock during this operation */
406 
407     Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
408     if (ACPI_FAILURE (Status))
409     {
410         return_ACPI_STATUS (Status);
411     }
412 
413     /* Install the table and load it into the namespace */
414 
415     ACPI_INFO ((AE_INFO, "Host-directed Dynamic ACPI Table Load:"));
416     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
417 
418     Status = AcpiTbInstallStandardTable (ACPI_PTR_TO_PHYSADDR (Table),
419         ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, TRUE, FALSE,
420         &TableIndex);
421 
422     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
423     if (ACPI_FAILURE (Status))
424     {
425         goto UnlockAndExit;
426     }
427 
428     /*
429      * Note: Now table is "INSTALLED", it must be validated before
430      * using.
431      */
432     Status = AcpiTbValidateTable (
433         &AcpiGbl_RootTableList.Tables[TableIndex]);
434     if (ACPI_FAILURE (Status))
435     {
436         goto UnlockAndExit;
437     }
438 
439     Status = AcpiNsLoadTable (TableIndex, AcpiGbl_RootNode);
440 
441     /* Invoke table handler if present */
442 
443     if (AcpiGbl_TableHandler)
444     {
445         (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
446             AcpiGbl_TableHandlerContext);
447     }
448 
449 UnlockAndExit:
450     (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
451     return_ACPI_STATUS (Status);
452 }
453 
454 ACPI_EXPORT_SYMBOL (AcpiLoadTable)
455 
456 
457 /*******************************************************************************
458  *
459  * FUNCTION:    AcpiUnloadParentTable
460  *
461  * PARAMETERS:  Object              - Handle to any namespace object owned by
462  *                                    the table to be unloaded
463  *
464  * RETURN:      Status
465  *
466  * DESCRIPTION: Via any namespace object within an SSDT or OEMx table, unloads
467  *              the table and deletes all namespace objects associated with
468  *              that table. Unloading of the DSDT is not allowed.
469  *              Note: Mainly intended to support hotplug removal of SSDTs.
470  *
471  ******************************************************************************/
472 
473 ACPI_STATUS
474 AcpiUnloadParentTable (
475     ACPI_HANDLE             Object)
476 {
477     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Object);
478     ACPI_STATUS             Status = AE_NOT_EXIST;
479     ACPI_OWNER_ID           OwnerId;
480     UINT32                  i;
481 
482 
483     ACPI_FUNCTION_TRACE (AcpiUnloadParentTable);
484 
485 
486     /* Parameter validation */
487 
488     if (!Object)
489     {
490         return_ACPI_STATUS (AE_BAD_PARAMETER);
491     }
492 
493     /*
494      * The node OwnerId is currently the same as the parent table ID.
495      * However, this could change in the future.
496      */
497     OwnerId = Node->OwnerId;
498     if (!OwnerId)
499     {
500         /* OwnerId==0 means DSDT is the owner. DSDT cannot be unloaded */
501 
502         return_ACPI_STATUS (AE_TYPE);
503     }
504 
505     /* Must acquire the interpreter lock during this operation */
506 
507     Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
508     if (ACPI_FAILURE (Status))
509     {
510         return_ACPI_STATUS (Status);
511     }
512 
513     /* Find the table in the global table list */
514 
515     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
516     {
517         if (OwnerId != AcpiGbl_RootTableList.Tables[i].OwnerId)
518         {
519             continue;
520         }
521 
522         /*
523          * Allow unload of SSDT and OEMx tables only. Do not allow unload
524          * of the DSDT. No other types of tables should get here, since
525          * only these types can contain AML and thus are the only types
526          * that can create namespace objects.
527          */
528         if (ACPI_COMPARE_NAME (
529                 AcpiGbl_RootTableList.Tables[i].Signature.Ascii,
530                 ACPI_SIG_DSDT))
531         {
532             Status = AE_TYPE;
533             break;
534         }
535 
536         /* Ensure the table is actually loaded */
537 
538         if (!AcpiTbIsTableLoaded (i))
539         {
540             Status = AE_NOT_EXIST;
541             break;
542         }
543 
544         /* Invoke table handler if present */
545 
546         if (AcpiGbl_TableHandler)
547         {
548             (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD,
549                 AcpiGbl_RootTableList.Tables[i].Pointer,
550                 AcpiGbl_TableHandlerContext);
551         }
552 
553         /*
554          * Delete all namespace objects owned by this table. Note that
555          * these objects can appear anywhere in the namespace by virtue
556          * of the AML "Scope" operator. Thus, we need to track ownership
557          * by an ID, not simply a position within the hierarchy.
558          */
559         Status = AcpiTbDeleteNamespaceByOwner (i);
560         if (ACPI_FAILURE (Status))
561         {
562             break;
563         }
564 
565         Status = AcpiTbReleaseOwnerId (i);
566         AcpiTbSetTableLoadedFlag (i, FALSE);
567         break;
568     }
569 
570     (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
571     return_ACPI_STATUS (Status);
572 }
573 
574 ACPI_EXPORT_SYMBOL (AcpiUnloadParentTable)
575