nsload.c revision 117521
1/******************************************************************************
2 *
3 * Module Name: nsload - namespace loading/expanding/contracting procedures
4 *              $Revision: 66 $
5 *
6 *****************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp.
13 * All rights reserved.
14 *
15 * 2. License
16 *
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights.  You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
20 * property rights.
21 *
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
28 *
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code.  No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
37 *
38 * The above copyright and patent license is granted only if the following
39 * conditions are met:
40 *
41 * 3. Conditions
42 *
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision.  In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change.  Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee.  Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
54 *
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution.  In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
65 * make.
66 *
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3.4. Intel retains all right, title, and interest in and to the Original
74 * Intel Code.
75 *
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
80 *
81 * 4. Disclaimer and Export Compliance
82 *
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 * PARTICULAR PURPOSE.
90 *
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 * LIMITED REMEDY.
99 *
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government.  In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************/
116
117#define __NSLOAD_C__
118
119#include "acpi.h"
120#include "acnamesp.h"
121#include "acdispat.h"
122
123
124#define _COMPONENT          ACPI_NAMESPACE
125        ACPI_MODULE_NAME    ("nsload")
126
127
128#ifndef ACPI_NO_METHOD_EXECUTION
129
130/*******************************************************************************
131 *
132 * FUNCTION:    AcpiNsLoadTable
133 *
134 * PARAMETERS:  TableDesc       - Descriptor for table to be loaded
135 *              Node            - Owning NS node
136 *
137 * RETURN:      Status
138 *
139 * DESCRIPTION: Load one ACPI table into the namespace
140 *
141 ******************************************************************************/
142
143ACPI_STATUS
144AcpiNsLoadTable (
145    ACPI_TABLE_DESC         *TableDesc,
146    ACPI_NAMESPACE_NODE     *Node)
147{
148    ACPI_STATUS             Status;
149
150
151    ACPI_FUNCTION_TRACE ("NsLoadTable");
152
153
154    /* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */
155
156    if (!(AcpiGbl_TableData[TableDesc->Type].Flags & ACPI_TABLE_EXECUTABLE))
157    {
158        /* Just ignore this table */
159
160        return_ACPI_STATUS (AE_OK);
161    }
162
163    /* Check validity of the AML start and length */
164
165    if (!TableDesc->AmlStart)
166    {
167        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null AML pointer\n"));
168        return_ACPI_STATUS (AE_BAD_PARAMETER);
169    }
170
171    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "AML block at %p\n", TableDesc->AmlStart));
172
173    /* Ignore table if there is no AML contained within */
174
175    if (!TableDesc->AmlLength)
176    {
177        ACPI_REPORT_WARNING (("Zero-length AML block in table [%4.4s]\n", TableDesc->Pointer->Signature));
178        return_ACPI_STATUS (AE_OK);
179    }
180
181    /*
182     * Parse the table and load the namespace with all named
183     * objects found within.  Control methods are NOT parsed
184     * at this time.  In fact, the control methods cannot be
185     * parsed until the entire namespace is loaded, because
186     * if a control method makes a forward reference (call)
187     * to another control method, we can't continue parsing
188     * because we don't know how many arguments to parse next!
189     */
190    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Loading table into namespace ****\n"));
191
192    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
193    if (ACPI_FAILURE (Status))
194    {
195        return_ACPI_STATUS (Status);
196    }
197
198    Status = AcpiNsParseTable (TableDesc, Node->Child);
199    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
200
201    if (ACPI_FAILURE (Status))
202    {
203        return_ACPI_STATUS (Status);
204    }
205
206    /*
207     * Now we can parse the control methods.  We always parse
208     * them here for a sanity check, and if configured for
209     * just-in-time parsing, we delete the control method
210     * parse trees.
211     */
212    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
213        "**** Begin Table Method Parsing and Object Initialization ****\n"));
214
215    Status = AcpiDsInitializeObjects (TableDesc, Node);
216
217    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
218        "**** Completed Table Method Parsing and Object Initialization ****\n"));
219
220    return_ACPI_STATUS (Status);
221}
222
223
224/*******************************************************************************
225 *
226 * FUNCTION:    AcpiNsLoadTableByType
227 *
228 * PARAMETERS:  TableType           - Id of the table type to load
229 *
230 * RETURN:      Status
231 *
232 * DESCRIPTION: Load an ACPI table or tables into the namespace.  All tables
233 *              of the given type are loaded.  The mechanism allows this
234 *              routine to be called repeatedly.
235 *
236 ******************************************************************************/
237
238ACPI_STATUS
239AcpiNsLoadTableByType (
240    ACPI_TABLE_TYPE         TableType)
241{
242    UINT32                  i;
243    ACPI_STATUS             Status;
244    ACPI_TABLE_DESC         *TableDesc;
245
246
247    ACPI_FUNCTION_TRACE ("NsLoadTableByType");
248
249
250    Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
251    if (ACPI_FAILURE (Status))
252    {
253        return_ACPI_STATUS (Status);
254    }
255
256    /*
257     * Table types supported are:
258     * DSDT (one), SSDT/PSDT (multiple)
259     */
260    switch (TableType)
261    {
262    case ACPI_TABLE_DSDT:
263
264        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading DSDT\n"));
265
266        TableDesc = AcpiGbl_TableLists[ACPI_TABLE_DSDT].Next;
267
268        /* If table already loaded into namespace, just return */
269
270        if (TableDesc->LoadedIntoNamespace)
271        {
272            goto UnlockAndExit;
273        }
274
275        /* Now load the single DSDT */
276
277        Status = AcpiNsLoadTable (TableDesc, AcpiGbl_RootNode);
278        if (ACPI_SUCCESS (Status))
279        {
280            TableDesc->LoadedIntoNamespace = TRUE;
281        }
282
283        break;
284
285
286    case ACPI_TABLE_SSDT:
287
288        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d SSDTs\n",
289            AcpiGbl_TableLists[ACPI_TABLE_SSDT].Count));
290
291        /*
292         * Traverse list of SSDT tables
293         */
294        TableDesc = AcpiGbl_TableLists[ACPI_TABLE_SSDT].Next;
295        for (i = 0; i < AcpiGbl_TableLists[ACPI_TABLE_SSDT].Count; i++)
296        {
297            /*
298             * Only attempt to load table if it is not
299             * already loaded!
300             */
301            if (!TableDesc->LoadedIntoNamespace)
302            {
303                Status = AcpiNsLoadTable (TableDesc, AcpiGbl_RootNode);
304                if (ACPI_FAILURE (Status))
305                {
306                    break;
307                }
308
309                TableDesc->LoadedIntoNamespace = TRUE;
310            }
311
312            TableDesc = TableDesc->Next;
313        }
314        break;
315
316
317    case ACPI_TABLE_PSDT:
318
319        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d PSDTs\n",
320            AcpiGbl_TableLists[ACPI_TABLE_PSDT].Count));
321
322        /*
323         * Traverse list of PSDT tables
324         */
325        TableDesc = AcpiGbl_TableLists[ACPI_TABLE_PSDT].Next;
326
327        for (i = 0; i < AcpiGbl_TableLists[ACPI_TABLE_PSDT].Count; i++)
328        {
329            /* Only attempt to load table if it is not already loaded! */
330
331            if (!TableDesc->LoadedIntoNamespace)
332            {
333                Status = AcpiNsLoadTable (TableDesc, AcpiGbl_RootNode);
334                if (ACPI_FAILURE (Status))
335                {
336                    break;
337                }
338
339                TableDesc->LoadedIntoNamespace = TRUE;
340            }
341
342            TableDesc = TableDesc->Next;
343        }
344
345        break;
346
347
348    default:
349        Status = AE_SUPPORT;
350        break;
351    }
352
353
354UnlockAndExit:
355    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
356    return_ACPI_STATUS (Status);
357}
358
359
360/*******************************************************************************
361 *
362 * FUNCTION:    AcpiLoadNamespace
363 *
364 * PARAMETERS:  None
365 *
366 * RETURN:      Status
367 *
368 * DESCRIPTION: Load the name space from what ever is pointed to by DSDT.
369 *              (DSDT points to either the BIOS or a buffer.)
370 *
371 ******************************************************************************/
372
373ACPI_STATUS
374AcpiNsLoadNamespace (
375    void)
376{
377    ACPI_STATUS             Status;
378
379
380    ACPI_FUNCTION_TRACE ("AcpiLoadNameSpace");
381
382
383    /* There must be at least a DSDT installed */
384
385    if (AcpiGbl_DSDT == NULL)
386    {
387        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "DSDT is not in memory\n"));
388        return_ACPI_STATUS (AE_NO_ACPI_TABLES);
389    }
390
391    /*
392     * Load the namespace.  The DSDT is required,
393     * but the SSDT and PSDT tables are optional.
394     */
395    Status = AcpiNsLoadTableByType (ACPI_TABLE_DSDT);
396    if (ACPI_FAILURE (Status))
397    {
398        return_ACPI_STATUS (Status);
399    }
400
401    /* Ignore exceptions from these */
402
403    (void) AcpiNsLoadTableByType (ACPI_TABLE_SSDT);
404    (void) AcpiNsLoadTableByType (ACPI_TABLE_PSDT);
405
406    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
407        "ACPI Namespace successfully loaded at root %p\n",
408        AcpiGbl_RootNode));
409
410    return_ACPI_STATUS (Status);
411}
412
413
414/*******************************************************************************
415 *
416 * FUNCTION:    AcpiNsDeleteSubtree
417 *
418 * PARAMETERS:  StartHandle         - Handle in namespace where search begins
419 *
420 * RETURNS      Status
421 *
422 * DESCRIPTION: Walks the namespace starting at the given handle and deletes
423 *              all objects, entries, and scopes in the entire subtree.
424 *
425 *              Namespace/Interpreter should be locked or the subsystem should
426 *              be in shutdown before this routine is called.
427 *
428 ******************************************************************************/
429
430ACPI_STATUS
431AcpiNsDeleteSubtree (
432    ACPI_HANDLE             StartHandle)
433{
434    ACPI_STATUS             Status;
435    ACPI_HANDLE             ChildHandle;
436    ACPI_HANDLE             ParentHandle;
437    ACPI_HANDLE             NextChildHandle;
438    ACPI_HANDLE             Dummy;
439    UINT32                  Level;
440
441
442    ACPI_FUNCTION_TRACE ("NsDeleteSubtree");
443
444
445    ParentHandle = StartHandle;
446    ChildHandle  = 0;
447    Level        = 1;
448
449    /*
450     * Traverse the tree of objects until we bubble back up
451     * to where we started.
452     */
453    while (Level > 0)
454    {
455        /* Attempt to get the next object in this scope */
456
457        Status = AcpiGetNextObject (ACPI_TYPE_ANY, ParentHandle,
458                                    ChildHandle, &NextChildHandle);
459
460        ChildHandle = NextChildHandle;
461
462        /* Did we get a new object? */
463
464        if (ACPI_SUCCESS (Status))
465        {
466            /* Check if this object has any children */
467
468            if (ACPI_SUCCESS (AcpiGetNextObject (ACPI_TYPE_ANY, ChildHandle,
469                                    0, &Dummy)))
470            {
471                /*
472                 * There is at least one child of this object,
473                 * visit the object
474                 */
475                Level++;
476                ParentHandle = ChildHandle;
477                ChildHandle  = 0;
478            }
479        }
480        else
481        {
482            /*
483             * No more children in this object, go back up to
484             * the object's parent
485             */
486            Level--;
487
488            /* Delete all children now */
489
490            AcpiNsDeleteChildren (ChildHandle);
491
492            ChildHandle = ParentHandle;
493            Status = AcpiGetParent (ParentHandle, &ParentHandle);
494            if (ACPI_FAILURE (Status))
495            {
496                return_ACPI_STATUS (Status);
497            }
498        }
499    }
500
501    /* Now delete the starting object, and we are done */
502
503    AcpiNsDeleteNode (ChildHandle);
504
505    return_ACPI_STATUS (AE_OK);
506}
507
508
509/*******************************************************************************
510 *
511 *  FUNCTION:       AcpiNsUnloadNameSpace
512 *
513 *  PARAMETERS:     Handle          - Root of namespace subtree to be deleted
514 *
515 *  RETURN:         Status
516 *
517 *  DESCRIPTION:    Shrinks the namespace, typically in response to an undocking
518 *                  event.  Deletes an entire subtree starting from (and
519 *                  including) the given handle.
520 *
521 ******************************************************************************/
522
523ACPI_STATUS
524AcpiNsUnloadNamespace (
525    ACPI_HANDLE             Handle)
526{
527    ACPI_STATUS             Status;
528
529
530    ACPI_FUNCTION_TRACE ("NsUnloadNameSpace");
531
532
533    /* Parameter validation */
534
535    if (!AcpiGbl_RootNode)
536    {
537        return_ACPI_STATUS (AE_NO_NAMESPACE);
538    }
539
540    if (!Handle)
541    {
542        return_ACPI_STATUS (AE_BAD_PARAMETER);
543    }
544
545    /* This function does the real work */
546
547    Status = AcpiNsDeleteSubtree (Handle);
548
549    return_ACPI_STATUS (Status);
550}
551
552#endif
553
554