nsload.c revision 151600
1/******************************************************************************
2 *
3 * Module Name: nsload - namespace loading/expanding/contracting procedures
4 *              $Revision: 69 $
5 *
6 *****************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2004, 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 <contrib/dev/acpica/acpi.h>
120#include <contrib/dev/acpica/acnamesp.h>
121#include <contrib/dev/acpica/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",
172        TableDesc->AmlStart));
173
174    /* Ignore table if there is no AML contained within */
175
176    if (!TableDesc->AmlLength)
177    {
178        ACPI_REPORT_WARNING (("Zero-length AML block in table [%4.4s]\n",
179            TableDesc->Pointer->Signature));
180        return_ACPI_STATUS (AE_OK);
181    }
182
183    /*
184     * Parse the table and load the namespace with all named
185     * objects found within.  Control methods are NOT parsed
186     * at this time.  In fact, the control methods cannot be
187     * parsed until the entire namespace is loaded, because
188     * if a control method makes a forward reference (call)
189     * to another control method, we can't continue parsing
190     * because we don't know how many arguments to parse next!
191     */
192    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
193        "**** Loading table into namespace ****\n"));
194
195    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
196    if (ACPI_FAILURE (Status))
197    {
198        return_ACPI_STATUS (Status);
199    }
200
201    Status = AcpiNsParseTable (TableDesc, Node->Child);
202    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
203
204    if (ACPI_FAILURE (Status))
205    {
206        return_ACPI_STATUS (Status);
207    }
208
209    /*
210     * Now we can parse the control methods.  We always parse
211     * them here for a sanity check, and if configured for
212     * just-in-time parsing, we delete the control method
213     * parse trees.
214     */
215    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
216        "**** Begin Table Method Parsing and Object Initialization ****\n"));
217
218    Status = AcpiDsInitializeObjects (TableDesc, Node);
219
220    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
221        "**** Completed Table Method Parsing and Object Initialization ****\n"));
222
223    return_ACPI_STATUS (Status);
224}
225
226
227/*******************************************************************************
228 *
229 * FUNCTION:    AcpiNsLoadTableByType
230 *
231 * PARAMETERS:  TableType           - Id of the table type to load
232 *
233 * RETURN:      Status
234 *
235 * DESCRIPTION: Load an ACPI table or tables into the namespace.  All tables
236 *              of the given type are loaded.  The mechanism allows this
237 *              routine to be called repeatedly.
238 *
239 ******************************************************************************/
240
241ACPI_STATUS
242AcpiNsLoadTableByType (
243    ACPI_TABLE_TYPE         TableType)
244{
245    UINT32                  i;
246    ACPI_STATUS             Status;
247    ACPI_TABLE_DESC         *TableDesc;
248
249
250    ACPI_FUNCTION_TRACE ("NsLoadTableByType");
251
252
253    Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
254    if (ACPI_FAILURE (Status))
255    {
256        return_ACPI_STATUS (Status);
257    }
258
259    /*
260     * Table types supported are:
261     * DSDT (one), SSDT/PSDT (multiple)
262     */
263    switch (TableType)
264    {
265    case ACPI_TABLE_DSDT:
266
267        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading DSDT\n"));
268
269        TableDesc = AcpiGbl_TableLists[ACPI_TABLE_DSDT].Next;
270
271        /* If table already loaded into namespace, just return */
272
273        if (TableDesc->LoadedIntoNamespace)
274        {
275            goto UnlockAndExit;
276        }
277
278        /* Now load the single DSDT */
279
280        Status = AcpiNsLoadTable (TableDesc, AcpiGbl_RootNode);
281        if (ACPI_SUCCESS (Status))
282        {
283            TableDesc->LoadedIntoNamespace = TRUE;
284        }
285        break;
286
287
288    case ACPI_TABLE_SSDT:
289
290        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d SSDTs\n",
291            AcpiGbl_TableLists[ACPI_TABLE_SSDT].Count));
292
293        /*
294         * Traverse list of SSDT tables
295         */
296        TableDesc = AcpiGbl_TableLists[ACPI_TABLE_SSDT].Next;
297        for (i = 0; i < AcpiGbl_TableLists[ACPI_TABLE_SSDT].Count; i++)
298        {
299            /*
300             * Only attempt to load table if it is not
301             * already loaded!
302             */
303            if (!TableDesc->LoadedIntoNamespace)
304            {
305                Status = AcpiNsLoadTable (TableDesc, AcpiGbl_RootNode);
306                if (ACPI_FAILURE (Status))
307                {
308                    break;
309                }
310
311                TableDesc->LoadedIntoNamespace = TRUE;
312            }
313
314            TableDesc = TableDesc->Next;
315        }
316        break;
317
318
319    case ACPI_TABLE_PSDT:
320
321        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d PSDTs\n",
322            AcpiGbl_TableLists[ACPI_TABLE_PSDT].Count));
323
324        /*
325         * Traverse list of PSDT tables
326         */
327        TableDesc = AcpiGbl_TableLists[ACPI_TABLE_PSDT].Next;
328
329        for (i = 0; i < AcpiGbl_TableLists[ACPI_TABLE_PSDT].Count; i++)
330        {
331            /* Only attempt to load table if it is not already loaded! */
332
333            if (!TableDesc->LoadedIntoNamespace)
334            {
335                Status = AcpiNsLoadTable (TableDesc, AcpiGbl_RootNode);
336                if (ACPI_FAILURE (Status))
337                {
338                    break;
339                }
340
341                TableDesc->LoadedIntoNamespace = TRUE;
342            }
343
344            TableDesc = TableDesc->Next;
345        }
346        break;
347
348
349    default:
350        Status = AE_SUPPORT;
351        break;
352    }
353
354
355UnlockAndExit:
356    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
357    return_ACPI_STATUS (Status);
358}
359
360
361/*******************************************************************************
362 *
363 * FUNCTION:    AcpiLoadNamespace
364 *
365 * PARAMETERS:  None
366 *
367 * RETURN:      Status
368 *
369 * DESCRIPTION: Load the name space from what ever is pointed to by DSDT.
370 *              (DSDT points to either the BIOS or a buffer.)
371 *
372 ******************************************************************************/
373
374ACPI_STATUS
375AcpiNsLoadNamespace (
376    void)
377{
378    ACPI_STATUS             Status;
379
380
381    ACPI_FUNCTION_TRACE ("AcpiLoadNameSpace");
382
383
384    /* There must be at least a DSDT installed */
385
386    if (AcpiGbl_DSDT == NULL)
387    {
388        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "DSDT is not in memory\n"));
389        return_ACPI_STATUS (AE_NO_ACPI_TABLES);
390    }
391
392    /*
393     * Load the namespace.  The DSDT is required,
394     * but the SSDT and PSDT tables are optional.
395     */
396    Status = AcpiNsLoadTableByType (ACPI_TABLE_DSDT);
397    if (ACPI_FAILURE (Status))
398    {
399        return_ACPI_STATUS (Status);
400    }
401
402    /* Ignore exceptions from these */
403
404    (void) AcpiNsLoadTableByType (ACPI_TABLE_SSDT);
405    (void) AcpiNsLoadTableByType (ACPI_TABLE_PSDT);
406
407    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
408        "ACPI Namespace successfully loaded at root %p\n",
409        AcpiGbl_RootNode));
410
411    return_ACPI_STATUS (Status);
412}
413
414
415/*******************************************************************************
416 *
417 * FUNCTION:    AcpiNsDeleteSubtree
418 *
419 * PARAMETERS:  StartHandle         - Handle in namespace where search begins
420 *
421 * RETURNS      Status
422 *
423 * DESCRIPTION: Walks the namespace starting at the given handle and deletes
424 *              all objects, entries, and scopes in the entire subtree.
425 *
426 *              Namespace/Interpreter should be locked or the subsystem should
427 *              be in shutdown before this routine is called.
428 *
429 ******************************************************************************/
430
431ACPI_STATUS
432AcpiNsDeleteSubtree (
433    ACPI_HANDLE             StartHandle)
434{
435    ACPI_STATUS             Status;
436    ACPI_HANDLE             ChildHandle;
437    ACPI_HANDLE             ParentHandle;
438    ACPI_HANDLE             NextChildHandle;
439    ACPI_HANDLE             Dummy;
440    UINT32                  Level;
441
442
443    ACPI_FUNCTION_TRACE ("NsDeleteSubtree");
444
445
446    ParentHandle = StartHandle;
447    ChildHandle  = NULL;
448    Level        = 1;
449
450    /*
451     * Traverse the tree of objects until we bubble back up
452     * to where we started.
453     */
454    while (Level > 0)
455    {
456        /* Attempt to get the next object in this scope */
457
458        Status = AcpiGetNextObject (ACPI_TYPE_ANY, ParentHandle,
459                                    ChildHandle, &NextChildHandle);
460
461        ChildHandle = NextChildHandle;
462
463        /* Did we get a new object? */
464
465        if (ACPI_SUCCESS (Status))
466        {
467            /* Check if this object has any children */
468
469            if (ACPI_SUCCESS (AcpiGetNextObject (ACPI_TYPE_ANY, ChildHandle,
470                                    NULL, &Dummy)))
471            {
472                /*
473                 * There is at least one child of this object,
474                 * visit the object
475                 */
476                Level++;
477                ParentHandle = ChildHandle;
478                ChildHandle  = NULL;
479            }
480        }
481        else
482        {
483            /*
484             * No more children in this object, go back up to
485             * the object's parent
486             */
487            Level--;
488
489            /* Delete all children now */
490
491            AcpiNsDeleteChildren (ChildHandle);
492
493            ChildHandle = ParentHandle;
494            Status = AcpiGetParent (ParentHandle, &ParentHandle);
495            if (ACPI_FAILURE (Status))
496            {
497                return_ACPI_STATUS (Status);
498            }
499        }
500    }
501
502    /* Now delete the starting object, and we are done */
503
504    AcpiNsDeleteNode (ChildHandle);
505
506    return_ACPI_STATUS (AE_OK);
507}
508
509
510/*******************************************************************************
511 *
512 *  FUNCTION:       AcpiNsUnloadNameSpace
513 *
514 *  PARAMETERS:     Handle          - Root of namespace subtree to be deleted
515 *
516 *  RETURN:         Status
517 *
518 *  DESCRIPTION:    Shrinks the namespace, typically in response to an undocking
519 *                  event.  Deletes an entire subtree starting from (and
520 *                  including) the given handle.
521 *
522 ******************************************************************************/
523
524ACPI_STATUS
525AcpiNsUnloadNamespace (
526    ACPI_HANDLE             Handle)
527{
528    ACPI_STATUS             Status;
529
530
531    ACPI_FUNCTION_TRACE ("NsUnloadNameSpace");
532
533
534    /* Parameter validation */
535
536    if (!AcpiGbl_RootNode)
537    {
538        return_ACPI_STATUS (AE_NO_NAMESPACE);
539    }
540
541    if (!Handle)
542    {
543        return_ACPI_STATUS (AE_BAD_PARAMETER);
544    }
545
546    /* This function does the real work */
547
548    Status = AcpiNsDeleteSubtree (Handle);
549
550    return_ACPI_STATUS (Status);
551}
552
553#endif
554
555