xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/aslload.c (revision 2c7d7e3ca2e4f0b675c6c58e614f6aede66c678e)
128c506b8Sjruoho /******************************************************************************
228c506b8Sjruoho  *
3f5b481b3Schristos  * Module Name: aslload - compiler namespace load callbacks
428c506b8Sjruoho  *
528c506b8Sjruoho  *****************************************************************************/
628c506b8Sjruoho 
7124f4c82Sjruoho /*
8*2c7d7e3cSchristos  * Copyright (C) 2000 - 2023, Intel Corp.
928c506b8Sjruoho  * All rights reserved.
1028c506b8Sjruoho  *
11124f4c82Sjruoho  * Redistribution and use in source and binary forms, with or without
12124f4c82Sjruoho  * modification, are permitted provided that the following conditions
13124f4c82Sjruoho  * are met:
14124f4c82Sjruoho  * 1. Redistributions of source code must retain the above copyright
15124f4c82Sjruoho  *    notice, this list of conditions, and the following disclaimer,
16124f4c82Sjruoho  *    without modification.
17124f4c82Sjruoho  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18124f4c82Sjruoho  *    substantially similar to the "NO WARRANTY" disclaimer below
19124f4c82Sjruoho  *    ("Disclaimer") and any redistribution must be conditioned upon
20124f4c82Sjruoho  *    including a substantially similar Disclaimer requirement for further
21124f4c82Sjruoho  *    binary redistribution.
22124f4c82Sjruoho  * 3. Neither the names of the above-listed copyright holders nor the names
23124f4c82Sjruoho  *    of any contributors may be used to endorse or promote products derived
24124f4c82Sjruoho  *    from this software without specific prior written permission.
2528c506b8Sjruoho  *
26124f4c82Sjruoho  * Alternatively, this software may be distributed under the terms of the
27124f4c82Sjruoho  * GNU General Public License ("GPL") version 2 as published by the Free
28124f4c82Sjruoho  * Software Foundation.
2928c506b8Sjruoho  *
30124f4c82Sjruoho  * NO WARRANTY
31124f4c82Sjruoho  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32124f4c82Sjruoho  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3398244dcfSchristos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34124f4c82Sjruoho  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35124f4c82Sjruoho  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36124f4c82Sjruoho  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37124f4c82Sjruoho  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38124f4c82Sjruoho  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39124f4c82Sjruoho  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40124f4c82Sjruoho  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41124f4c82Sjruoho  * POSSIBILITY OF SUCH DAMAGES.
42124f4c82Sjruoho  */
4328c506b8Sjruoho 
4428c506b8Sjruoho #include "aslcompiler.h"
4528c506b8Sjruoho #include "amlcode.h"
4628c506b8Sjruoho #include "acdispat.h"
4728c506b8Sjruoho #include "acnamesp.h"
48a40a9998Schristos #include "acparser.h"
4928c506b8Sjruoho #include "aslcompiler.y.h"
5028c506b8Sjruoho 
51a40a9998Schristos 
5228c506b8Sjruoho #define _COMPONENT          ACPI_COMPILER
5328c506b8Sjruoho         ACPI_MODULE_NAME    ("aslload")
5428c506b8Sjruoho 
5528c506b8Sjruoho /* Local prototypes */
5628c506b8Sjruoho 
5728c506b8Sjruoho static ACPI_STATUS
5828c506b8Sjruoho LdLoadFieldElements (
597ab6b89bSchristos     UINT32                  AmlType,
6028c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
6128c506b8Sjruoho     ACPI_WALK_STATE         *WalkState);
6228c506b8Sjruoho 
6328c506b8Sjruoho static ACPI_STATUS
6428c506b8Sjruoho LdLoadResourceElements (
6528c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
6628c506b8Sjruoho     ACPI_WALK_STATE         *WalkState);
6728c506b8Sjruoho 
6828c506b8Sjruoho static ACPI_STATUS
6928c506b8Sjruoho LdNamespace1Begin (
7028c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
7128c506b8Sjruoho     UINT32                  Level,
7228c506b8Sjruoho     void                    *Context);
7328c506b8Sjruoho 
7428c506b8Sjruoho static ACPI_STATUS
7528c506b8Sjruoho LdNamespace2Begin (
7628c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
7728c506b8Sjruoho     UINT32                  Level,
7828c506b8Sjruoho     void                    *Context);
7928c506b8Sjruoho 
8028c506b8Sjruoho static ACPI_STATUS
8128c506b8Sjruoho LdCommonNamespaceEnd (
8228c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
8328c506b8Sjruoho     UINT32                  Level,
8428c506b8Sjruoho     void                    *Context);
8528c506b8Sjruoho 
867ab6b89bSchristos static void
877ab6b89bSchristos LdCheckSpecialNames (
887ab6b89bSchristos     ACPI_NAMESPACE_NODE     *Node,
897ab6b89bSchristos     ACPI_PARSE_OBJECT       *Op);
9028c506b8Sjruoho 
919ddb8508Schristos static ACPI_STATUS
929ddb8508Schristos LdAnalyzeExternals (
939ddb8508Schristos     ACPI_NAMESPACE_NODE     *Node,
949ddb8508Schristos     ACPI_PARSE_OBJECT       *Op,
959ddb8508Schristos     ACPI_OBJECT_TYPE        ExternalOpType,
969ddb8508Schristos     ACPI_WALK_STATE         *WalkState);
979ddb8508Schristos 
989ddb8508Schristos 
9928c506b8Sjruoho /*******************************************************************************
10028c506b8Sjruoho  *
10128c506b8Sjruoho  * FUNCTION:    LdLoadNamespace
10228c506b8Sjruoho  *
10328c506b8Sjruoho  * PARAMETERS:  RootOp      - Root of the parse tree
10428c506b8Sjruoho  *
10528c506b8Sjruoho  * RETURN:      Status
10628c506b8Sjruoho  *
10728c506b8Sjruoho  * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the
10828c506b8Sjruoho  *              named ASL/AML objects into the namespace. The namespace is
10928c506b8Sjruoho  *              constructed in order to resolve named references and references
11028c506b8Sjruoho  *              to named fields within resource templates/descriptors.
11128c506b8Sjruoho  *
11228c506b8Sjruoho  ******************************************************************************/
11328c506b8Sjruoho 
11428c506b8Sjruoho ACPI_STATUS
LdLoadNamespace(ACPI_PARSE_OBJECT * RootOp)11528c506b8Sjruoho LdLoadNamespace (
11628c506b8Sjruoho     ACPI_PARSE_OBJECT       *RootOp)
11728c506b8Sjruoho {
11828c506b8Sjruoho     ACPI_WALK_STATE         *WalkState;
11928c506b8Sjruoho 
12028c506b8Sjruoho 
12128c506b8Sjruoho     /* Create a new walk state */
12228c506b8Sjruoho 
12328c506b8Sjruoho     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
12428c506b8Sjruoho     if (!WalkState)
12528c506b8Sjruoho     {
126ff4a156dSchristos         return (AE_NO_MEMORY);
12728c506b8Sjruoho     }
12828c506b8Sjruoho 
12928c506b8Sjruoho     /* Walk the entire parse tree, first pass */
13028c506b8Sjruoho 
13128c506b8Sjruoho     TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin,
13228c506b8Sjruoho         LdCommonNamespaceEnd, WalkState);
13328c506b8Sjruoho 
13428c506b8Sjruoho     /* Second pass to handle forward references */
13528c506b8Sjruoho 
13628c506b8Sjruoho     TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin,
13728c506b8Sjruoho         LdCommonNamespaceEnd, WalkState);
13828c506b8Sjruoho 
13928c506b8Sjruoho     /* Dump the namespace if debug is enabled */
14028c506b8Sjruoho 
141a147b75fSchristos     if (AcpiDbgLevel & ACPI_LV_TABLES)
142a147b75fSchristos     {
14328c506b8Sjruoho         AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX);
144a147b75fSchristos     }
145a147b75fSchristos 
146414ef032Schristos     ACPI_FREE (WalkState);
147ff4a156dSchristos     return (AE_OK);
14828c506b8Sjruoho }
14928c506b8Sjruoho 
15028c506b8Sjruoho 
15128c506b8Sjruoho /*******************************************************************************
15228c506b8Sjruoho  *
15328c506b8Sjruoho  * FUNCTION:    LdLoadFieldElements
15428c506b8Sjruoho  *
1557ab6b89bSchristos  * PARAMETERS:  AmlType         - Type to search
1567ab6b89bSchristos  *              Op              - Parent node (Field)
15728c506b8Sjruoho  *              WalkState       - Current walk state
15828c506b8Sjruoho  *
15928c506b8Sjruoho  * RETURN:      Status
16028c506b8Sjruoho  *
16128c506b8Sjruoho  * DESCRIPTION: Enter the named elements of the field (children of the parent)
16228c506b8Sjruoho  *              into the namespace.
16328c506b8Sjruoho  *
16428c506b8Sjruoho  ******************************************************************************/
16528c506b8Sjruoho 
16628c506b8Sjruoho static ACPI_STATUS
LdLoadFieldElements(UINT32 AmlType,ACPI_PARSE_OBJECT * Op,ACPI_WALK_STATE * WalkState)16728c506b8Sjruoho LdLoadFieldElements (
1687ab6b89bSchristos     UINT32                  AmlType,
16928c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
17028c506b8Sjruoho     ACPI_WALK_STATE         *WalkState)
17128c506b8Sjruoho {
17228c506b8Sjruoho     ACPI_PARSE_OBJECT       *Child = NULL;
1737ab6b89bSchristos     ACPI_PARSE_OBJECT       *SourceRegion;
17428c506b8Sjruoho     ACPI_NAMESPACE_NODE     *Node;
17528c506b8Sjruoho     ACPI_STATUS             Status;
1769ddb8508Schristos     char                    *ExternalPath;
17728c506b8Sjruoho 
17828c506b8Sjruoho 
1797ab6b89bSchristos     SourceRegion = UtGetArg (Op, 0);
1807ab6b89bSchristos     if (SourceRegion)
1817ab6b89bSchristos     {
1827ab6b89bSchristos         Status = AcpiNsLookup (WalkState->ScopeInfo,
1839ddb8508Schristos             SourceRegion->Asl.Value.String, AmlType, ACPI_IMODE_EXECUTE,
1849ddb8508Schristos             ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
1857ab6b89bSchristos         if (Status == AE_NOT_FOUND)
1867ab6b89bSchristos         {
1877ab6b89bSchristos             /*
1887ab6b89bSchristos              * If the named object is not found, it means that it is either a
1897ab6b89bSchristos              * forward reference or the named object does not exist.
1907ab6b89bSchristos              */
1917ab6b89bSchristos             SourceRegion->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD;
1927ab6b89bSchristos         }
1937ab6b89bSchristos     }
1947ab6b89bSchristos 
19528c506b8Sjruoho     /* Get the first named field element */
19628c506b8Sjruoho 
19728c506b8Sjruoho     switch (Op->Asl.AmlOpcode)
19828c506b8Sjruoho     {
19928c506b8Sjruoho     case AML_BANK_FIELD_OP:
20028c506b8Sjruoho 
20128c506b8Sjruoho         Child = UtGetArg (Op, 6);
20228c506b8Sjruoho         break;
20328c506b8Sjruoho 
20428c506b8Sjruoho     case AML_INDEX_FIELD_OP:
20528c506b8Sjruoho 
20628c506b8Sjruoho         Child = UtGetArg (Op, 5);
20728c506b8Sjruoho         break;
20828c506b8Sjruoho 
20928c506b8Sjruoho     case AML_FIELD_OP:
21028c506b8Sjruoho 
21128c506b8Sjruoho         Child = UtGetArg (Op, 4);
21228c506b8Sjruoho         break;
21328c506b8Sjruoho 
21428c506b8Sjruoho     default:
215ff4a156dSchristos 
21628c506b8Sjruoho         /* No other opcodes should arrive here */
217ff4a156dSchristos 
21828c506b8Sjruoho         return (AE_BAD_PARAMETER);
21928c506b8Sjruoho     }
22028c506b8Sjruoho 
22128c506b8Sjruoho     /* Enter all elements into the namespace */
22228c506b8Sjruoho 
22328c506b8Sjruoho     while (Child)
22428c506b8Sjruoho     {
22528c506b8Sjruoho         switch (Child->Asl.AmlOpcode)
22628c506b8Sjruoho         {
22728c506b8Sjruoho         case AML_INT_RESERVEDFIELD_OP:
22828c506b8Sjruoho         case AML_INT_ACCESSFIELD_OP:
229ff4a156dSchristos         case AML_INT_CONNECTION_OP:
23028c506b8Sjruoho             break;
23128c506b8Sjruoho 
23228c506b8Sjruoho         default:
23328c506b8Sjruoho 
23428c506b8Sjruoho             Status = AcpiNsLookup (WalkState->ScopeInfo,
23528c506b8Sjruoho                 Child->Asl.Value.String,
23628c506b8Sjruoho                 ACPI_TYPE_LOCAL_REGION_FIELD,
23728c506b8Sjruoho                 ACPI_IMODE_LOAD_PASS1,
23828c506b8Sjruoho                 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
23981bd9c9cSchristos                     ACPI_NS_ERROR_IF_FOUND, NULL, &Node);
24028c506b8Sjruoho             if (ACPI_FAILURE (Status))
24128c506b8Sjruoho             {
24228c506b8Sjruoho                 if (Status != AE_ALREADY_EXISTS)
24328c506b8Sjruoho                 {
24428c506b8Sjruoho                     AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child,
24528c506b8Sjruoho                         Child->Asl.Value.String);
24628c506b8Sjruoho                     return (Status);
24728c506b8Sjruoho                 }
248ae01dbf5Schristos                 else if (Status == AE_ALREADY_EXISTS &&
249a147b75fSchristos                     (Node->Flags & ANOBJ_IS_EXTERNAL))
250ae01dbf5Schristos                 {
251ae01dbf5Schristos                     Node->Type = (UINT8) ACPI_TYPE_LOCAL_REGION_FIELD;
2525b948c02Schristos                     Node->Flags &= ~ANOBJ_IS_EXTERNAL;
253ae01dbf5Schristos                 }
254ae01dbf5Schristos                 else
255ae01dbf5Schristos                 {
25628c506b8Sjruoho                     /*
25728c506b8Sjruoho                      * The name already exists in this scope
25828c506b8Sjruoho                      * But continue processing the elements
25928c506b8Sjruoho                      */
2609ddb8508Schristos                     ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);
2619ddb8508Schristos 
2621c663068Schristos                     AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,
2639ddb8508Schristos                         ExternalPath, ASL_MSG_FOUND_HERE, Node->Op,
2649ddb8508Schristos                         ExternalPath);
2659ddb8508Schristos 
2669ddb8508Schristos                     if (ExternalPath)
2679ddb8508Schristos                     {
2689ddb8508Schristos                         ACPI_FREE (ExternalPath);
2699ddb8508Schristos                     }
27028c506b8Sjruoho                 }
271ae01dbf5Schristos             }
27228c506b8Sjruoho             else
27328c506b8Sjruoho             {
27428c506b8Sjruoho                 Child->Asl.Node = Node;
27528c506b8Sjruoho                 Node->Op = Child;
27628c506b8Sjruoho             }
27728c506b8Sjruoho             break;
27828c506b8Sjruoho         }
279ff4a156dSchristos 
28028c506b8Sjruoho         Child = Child->Asl.Next;
28128c506b8Sjruoho     }
282ff4a156dSchristos 
28328c506b8Sjruoho     return (AE_OK);
28428c506b8Sjruoho }
28528c506b8Sjruoho 
28628c506b8Sjruoho 
28728c506b8Sjruoho /*******************************************************************************
28828c506b8Sjruoho  *
28928c506b8Sjruoho  * FUNCTION:    LdLoadResourceElements
29028c506b8Sjruoho  *
29128c506b8Sjruoho  * PARAMETERS:  Op              - Parent node (Resource Descriptor)
29228c506b8Sjruoho  *              WalkState       - Current walk state
29328c506b8Sjruoho  *
29428c506b8Sjruoho  * RETURN:      Status
29528c506b8Sjruoho  *
29628c506b8Sjruoho  * DESCRIPTION: Enter the named elements of the resource descriptor (children
29728c506b8Sjruoho  *              of the parent) into the namespace.
29828c506b8Sjruoho  *
29928c506b8Sjruoho  * NOTE: In the real AML namespace, these named elements never exist. But
30028c506b8Sjruoho  *       we simply use the namespace here as a symbol table so we can look
30128c506b8Sjruoho  *       them up as they are referenced.
30228c506b8Sjruoho  *
30328c506b8Sjruoho  ******************************************************************************/
30428c506b8Sjruoho 
30528c506b8Sjruoho static ACPI_STATUS
LdLoadResourceElements(ACPI_PARSE_OBJECT * Op,ACPI_WALK_STATE * WalkState)30628c506b8Sjruoho LdLoadResourceElements (
30728c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
30828c506b8Sjruoho     ACPI_WALK_STATE         *WalkState)
30928c506b8Sjruoho {
31028c506b8Sjruoho     ACPI_PARSE_OBJECT       *InitializerOp = NULL;
31128c506b8Sjruoho     ACPI_NAMESPACE_NODE     *Node;
31228c506b8Sjruoho     ACPI_STATUS             Status;
3139ddb8508Schristos     char                    *ExternalPath;
31428c506b8Sjruoho 
31528c506b8Sjruoho 
31628c506b8Sjruoho     /*
31728c506b8Sjruoho      * Enter the resource name into the namespace. Name must not already exist.
31828c506b8Sjruoho      * This opens a scope, so later field names are guaranteed to be new/unique.
31928c506b8Sjruoho      */
32028c506b8Sjruoho     Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath,
32128c506b8Sjruoho         ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1,
32228c506b8Sjruoho         ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND,
32328c506b8Sjruoho         WalkState, &Node);
32428c506b8Sjruoho     if (ACPI_FAILURE (Status))
32528c506b8Sjruoho     {
32628c506b8Sjruoho         if (Status == AE_ALREADY_EXISTS)
32728c506b8Sjruoho         {
32828c506b8Sjruoho             /* Actual node causing the error was saved in ParentMethod */
32928c506b8Sjruoho 
3309ddb8508Schristos             ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);
3319ddb8508Schristos 
33225666a51Schristos             AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS,
33325666a51Schristos                 (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod,
3349ddb8508Schristos                 ExternalPath, ASL_MSG_FOUND_HERE, Node->Op,
3359ddb8508Schristos                 ExternalPath);
3369ddb8508Schristos 
3379ddb8508Schristos             if (ExternalPath)
3389ddb8508Schristos             {
3399ddb8508Schristos                 ACPI_FREE (ExternalPath);
3409ddb8508Schristos             }
34128c506b8Sjruoho             return (AE_OK);
34228c506b8Sjruoho         }
34328c506b8Sjruoho         return (Status);
34428c506b8Sjruoho     }
34528c506b8Sjruoho 
34628c506b8Sjruoho     Node->Value = (UINT32) Op->Asl.Value.Integer;
34728c506b8Sjruoho     Node->Op = Op;
34828c506b8Sjruoho     Op->Asl.Node = Node;
34928c506b8Sjruoho 
35028c506b8Sjruoho     /*
35128c506b8Sjruoho      * Now enter the predefined fields, for easy lookup when referenced
35228c506b8Sjruoho      * by the source ASL
35328c506b8Sjruoho      */
35428c506b8Sjruoho     InitializerOp = ASL_GET_CHILD_NODE (Op);
35528c506b8Sjruoho     while (InitializerOp)
35628c506b8Sjruoho     {
35728c506b8Sjruoho         if (InitializerOp->Asl.ExternalName)
35828c506b8Sjruoho         {
35928c506b8Sjruoho             Status = AcpiNsLookup (WalkState->ScopeInfo,
36028c506b8Sjruoho                 InitializerOp->Asl.ExternalName,
3617efa3256Schristos                 ACPI_TYPE_LOCAL_RESOURCE_FIELD, ACPI_IMODE_LOAD_PASS1,
3627efa3256Schristos                 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
36328c506b8Sjruoho             if (ACPI_FAILURE (Status))
36428c506b8Sjruoho             {
36528c506b8Sjruoho                 return (Status);
36628c506b8Sjruoho             }
36728c506b8Sjruoho 
36828c506b8Sjruoho             /*
369ff4a156dSchristos              * Store the field offset and length in the namespace node
370ff4a156dSchristos              * so it can be used when the field is referenced
37128c506b8Sjruoho              */
372ff4a156dSchristos             Node->Value = InitializerOp->Asl.Value.Tag.BitOffset;
373ff4a156dSchristos             Node->Length = InitializerOp->Asl.Value.Tag.BitLength;
37428c506b8Sjruoho             InitializerOp->Asl.Node = Node;
37528c506b8Sjruoho             Node->Op = InitializerOp;
37628c506b8Sjruoho         }
377ff4a156dSchristos 
37828c506b8Sjruoho         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
37928c506b8Sjruoho     }
38028c506b8Sjruoho 
38128c506b8Sjruoho     return (AE_OK);
38228c506b8Sjruoho }
38328c506b8Sjruoho 
38428c506b8Sjruoho 
38528c506b8Sjruoho /*******************************************************************************
38628c506b8Sjruoho  *
38728c506b8Sjruoho  * FUNCTION:    LdNamespace1Begin
38828c506b8Sjruoho  *
38928c506b8Sjruoho  * PARAMETERS:  ASL_WALK_CALLBACK
39028c506b8Sjruoho  *
39128c506b8Sjruoho  * RETURN:      Status
39228c506b8Sjruoho  *
39328c506b8Sjruoho  * DESCRIPTION: Descending callback used during the parse tree walk. If this
39428c506b8Sjruoho  *              is a named AML opcode, enter into the namespace
39528c506b8Sjruoho  *
39628c506b8Sjruoho  ******************************************************************************/
39728c506b8Sjruoho 
39828c506b8Sjruoho static ACPI_STATUS
LdNamespace1Begin(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)39928c506b8Sjruoho LdNamespace1Begin (
40028c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
40128c506b8Sjruoho     UINT32                  Level,
40228c506b8Sjruoho     void                    *Context)
40328c506b8Sjruoho {
40428c506b8Sjruoho     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
40528c506b8Sjruoho     ACPI_NAMESPACE_NODE     *Node;
40681bd9c9cSchristos     ACPI_PARSE_OBJECT       *MethodOp;
40728c506b8Sjruoho     ACPI_STATUS             Status;
40828c506b8Sjruoho     ACPI_OBJECT_TYPE        ObjectType;
40928c506b8Sjruoho     char                    *Path;
41028c506b8Sjruoho     UINT32                  Flags = ACPI_NS_NO_UPSEARCH;
41128c506b8Sjruoho     ACPI_PARSE_OBJECT       *Arg;
41228c506b8Sjruoho     UINT32                  i;
41328c506b8Sjruoho     BOOLEAN                 ForceNewScope = FALSE;
414a40a9998Schristos     const ACPI_OPCODE_INFO  *OpInfo;
415a40a9998Schristos     ACPI_PARSE_OBJECT       *ParentOp;
4169ddb8508Schristos     char                    *ExternalPath;
41728c506b8Sjruoho 
41828c506b8Sjruoho 
41928c506b8Sjruoho     ACPI_FUNCTION_NAME (LdNamespace1Begin);
420a40a9998Schristos 
421a40a9998Schristos 
42228c506b8Sjruoho     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
42328c506b8Sjruoho         Op, Op->Asl.ParseOpName));
42428c506b8Sjruoho 
42528c506b8Sjruoho     /*
42628c506b8Sjruoho      * We are only interested in opcodes that have an associated name
42728c506b8Sjruoho      * (or multiple names)
42828c506b8Sjruoho      */
42928c506b8Sjruoho     switch (Op->Asl.AmlOpcode)
43028c506b8Sjruoho     {
43128c506b8Sjruoho     case AML_INDEX_FIELD_OP:
4327ab6b89bSchristos 
4337ab6b89bSchristos         Status = LdLoadFieldElements (ACPI_TYPE_LOCAL_REGION_FIELD, Op, WalkState);
4347ab6b89bSchristos         return (Status);
4357ab6b89bSchristos 
4367ab6b89bSchristos     case AML_BANK_FIELD_OP:
43728c506b8Sjruoho     case AML_FIELD_OP:
43828c506b8Sjruoho 
4397ab6b89bSchristos         Status = LdLoadFieldElements (ACPI_TYPE_REGION, Op, WalkState);
4407ab6b89bSchristos         return (Status);
44128c506b8Sjruoho 
442414ef032Schristos     case AML_INT_CONNECTION_OP:
443414ef032Schristos 
444414ef032Schristos         if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)
445414ef032Schristos         {
446414ef032Schristos             break;
447414ef032Schristos         }
448414ef032Schristos 
4491c663068Schristos         Arg = Op->Asl.Child;
450414ef032Schristos         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName,
451414ef032Schristos             ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
452414ef032Schristos             WalkState, &Node);
453414ef032Schristos         if (ACPI_FAILURE (Status))
454414ef032Schristos         {
455414ef032Schristos             break;
456414ef032Schristos         }
457414ef032Schristos 
458414ef032Schristos         break;
459414ef032Schristos 
46028c506b8Sjruoho     default:
46128c506b8Sjruoho 
46228c506b8Sjruoho         /* All other opcodes go below */
463ff4a156dSchristos 
46428c506b8Sjruoho         break;
46528c506b8Sjruoho     }
46628c506b8Sjruoho 
46728c506b8Sjruoho     /* Check if this object has already been installed in the namespace */
46828c506b8Sjruoho 
46928c506b8Sjruoho     if (Op->Asl.Node)
47028c506b8Sjruoho     {
47128c506b8Sjruoho         return (AE_OK);
47228c506b8Sjruoho     }
47328c506b8Sjruoho 
474a40a9998Schristos     /* Check for a possible illegal forward reference */
475a40a9998Schristos 
476a40a9998Schristos     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
4779ddb8508Schristos         (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
4789ddb8508Schristos         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
479a40a9998Schristos     {
480a40a9998Schristos         /*
481a40a9998Schristos          * Op->Asl.Namepath will be NULL for these opcodes.
482a40a9998Schristos          * These opcodes are guaranteed to have a parent.
483a40a9998Schristos          * Examine the parent opcode.
484a40a9998Schristos          */
485a40a9998Schristos         ParentOp = Op->Asl.Parent;
486a40a9998Schristos         OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Asl.AmlOpcode);
487a40a9998Schristos 
488a40a9998Schristos         /*
489a40a9998Schristos          * Exclude all operators that actually declare a new name:
490a40a9998Schristos          *      Name (ABCD, 1) -> Ignore (AML_CLASS_NAMED_OBJECT)
491a40a9998Schristos          * We only want references to named objects:
492a40a9998Schristos          *      Store (2, WXYZ) -> Attempt to resolve the name
493a40a9998Schristos          */
4949ddb8508Schristos         if ((Op->Asl.ParseOpcode != PARSEOP_METHODCALL) &&
4959ddb8508Schristos             (OpInfo->Class == AML_CLASS_NAMED_OBJECT))
496a40a9998Schristos         {
497a40a9998Schristos             return (AE_OK);
498a40a9998Schristos         }
499a40a9998Schristos 
500a40a9998Schristos         /*
501a40a9998Schristos          * Check if the referenced object exists at this point during
502a40a9998Schristos          * the load:
503a40a9998Schristos          * 1) If it exists, then this cannot be a forward reference.
504a40a9998Schristos          * 2) If it does not exist, it could be a forward reference or
505a40a9998Schristos          * it truly does not exist (and no external declaration).
506a40a9998Schristos          */
507a40a9998Schristos         Status = AcpiNsLookup (WalkState->ScopeInfo,
508a40a9998Schristos             Op->Asl.Value.Name, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
509a40a9998Schristos             ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
510a40a9998Schristos             WalkState, &Node);
511a40a9998Schristos         if (Status == AE_NOT_FOUND)
512a40a9998Schristos         {
513a40a9998Schristos             /*
5145b948c02Schristos              * This is either a forward reference or the object truly
515a40a9998Schristos              * does not exist. The two cases can only be differentiated
516a40a9998Schristos              * during the cross-reference stage later. Mark the Op/Name
517a40a9998Schristos              * as not-found for now to indicate the need for further
518a40a9998Schristos              * processing.
519a40a9998Schristos              *
520a40a9998Schristos              * Special case: Allow forward references from elements of
521a40a9998Schristos              * Package objects. This provides compatibility with other
522a40a9998Schristos              * ACPI implementations. To correctly implement this, the
523a40a9998Schristos              * ACPICA table load defers package resolution until the entire
524a40a9998Schristos              * namespace has been loaded.
525a40a9998Schristos              */
526a40a9998Schristos             if ((ParentOp->Asl.ParseOpcode != PARSEOP_PACKAGE) &&
527a40a9998Schristos                 (ParentOp->Asl.ParseOpcode != PARSEOP_VAR_PACKAGE))
528a40a9998Schristos             {
529a40a9998Schristos                 Op->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD;
530a40a9998Schristos             }
531a40a9998Schristos 
532a40a9998Schristos             return (AE_OK);
533a40a9998Schristos         }
534a40a9998Schristos 
535a40a9998Schristos         return (Status);
536a40a9998Schristos     }
537a40a9998Schristos 
53828c506b8Sjruoho     Path = Op->Asl.Namepath;
53928c506b8Sjruoho     if (!Path)
54028c506b8Sjruoho     {
54128c506b8Sjruoho         return (AE_OK);
54228c506b8Sjruoho     }
54328c506b8Sjruoho 
54428c506b8Sjruoho     /* Map the raw opcode into an internal object type */
54528c506b8Sjruoho 
54628c506b8Sjruoho     switch (Op->Asl.ParseOpcode)
54728c506b8Sjruoho     {
54828c506b8Sjruoho     case PARSEOP_NAME:
54928c506b8Sjruoho 
55028c506b8Sjruoho         Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
55128c506b8Sjruoho         Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
55228c506b8Sjruoho 
55328c506b8Sjruoho         /*
55428c506b8Sjruoho          * If this name refers to a ResourceTemplate, we will need to open
55528c506b8Sjruoho          * a new scope so that the resource subfield names can be entered into
55628c506b8Sjruoho          * the namespace underneath this name
55728c506b8Sjruoho          */
558ae01dbf5Schristos         if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
55928c506b8Sjruoho         {
56028c506b8Sjruoho             ForceNewScope = TRUE;
56128c506b8Sjruoho         }
56228c506b8Sjruoho 
56328c506b8Sjruoho         /* Get the data type associated with the named object, not the name itself */
56428c506b8Sjruoho 
56528c506b8Sjruoho         /* Log2 loop to convert from Btype (binary) to Etype (encoded) */
56628c506b8Sjruoho 
56728c506b8Sjruoho         ObjectType = 1;
56828c506b8Sjruoho         for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2)
56928c506b8Sjruoho         {
57028c506b8Sjruoho             ObjectType++;
57128c506b8Sjruoho         }
57228c506b8Sjruoho         break;
57328c506b8Sjruoho 
57428c506b8Sjruoho     case PARSEOP_EXTERNAL:
57528c506b8Sjruoho         /*
57628c506b8Sjruoho          * "External" simply enters a name and type into the namespace.
57728c506b8Sjruoho          * We must be careful to not open a new scope, however, no matter
57828c506b8Sjruoho          * what type the external name refers to (e.g., a method)
57928c506b8Sjruoho          *
58028c506b8Sjruoho          * first child is name, next child is ObjectType
58128c506b8Sjruoho          */
582f5b481b3Schristos         ObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer;
58328c506b8Sjruoho 
58428c506b8Sjruoho         /*
58528c506b8Sjruoho          * We will mark every new node along the path as "External". This
58628c506b8Sjruoho          * allows some or all of the nodes to be created later in the ASL
58728c506b8Sjruoho          * code. Handles cases like this:
58828c506b8Sjruoho          *
58928c506b8Sjruoho          *   External (\_SB_.PCI0.ABCD, IntObj)
59028c506b8Sjruoho          *   Scope (_SB_)
59128c506b8Sjruoho          *   {
59228c506b8Sjruoho          *       Device (PCI0)
59328c506b8Sjruoho          *       {
59428c506b8Sjruoho          *       }
59528c506b8Sjruoho          *   }
59628c506b8Sjruoho          *   Method (X)
59728c506b8Sjruoho          *   {
59828c506b8Sjruoho          *       Store (\_SB_.PCI0.ABCD, Local0)
59928c506b8Sjruoho          *   }
60028c506b8Sjruoho          */
601f5b481b3Schristos         Flags |= ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE;
60228c506b8Sjruoho         break;
60328c506b8Sjruoho 
60428c506b8Sjruoho     case PARSEOP_DEFAULT_ARG:
60528c506b8Sjruoho 
606ae01dbf5Schristos         if (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC)
60728c506b8Sjruoho         {
60828c506b8Sjruoho             Status = LdLoadResourceElements (Op, WalkState);
60928c506b8Sjruoho             return_ACPI_STATUS (Status);
61028c506b8Sjruoho         }
61128c506b8Sjruoho 
61228c506b8Sjruoho         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
61328c506b8Sjruoho         break;
61428c506b8Sjruoho 
61528c506b8Sjruoho     case PARSEOP_SCOPE:
61628c506b8Sjruoho         /*
61728c506b8Sjruoho          * The name referenced by Scope(Name) must already exist at this point.
61828c506b8Sjruoho          * In other words, forward references for Scope() are not supported.
61928c506b8Sjruoho          * The only real reason for this is that the MS interpreter cannot
62028c506b8Sjruoho          * handle this case. Perhaps someday this case can go away.
62128c506b8Sjruoho          */
62228c506b8Sjruoho         Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
6237efa3256Schristos             ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &Node);
62428c506b8Sjruoho         if (ACPI_FAILURE (Status))
62528c506b8Sjruoho         {
62628c506b8Sjruoho             if (Status == AE_NOT_FOUND)
62728c506b8Sjruoho             {
62828c506b8Sjruoho                 /* The name was not found, go ahead and create it */
62928c506b8Sjruoho 
63028c506b8Sjruoho                 Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
6317efa3256Schristos                     ACPI_TYPE_LOCAL_SCOPE, ACPI_IMODE_LOAD_PASS1,
6327efa3256Schristos                     Flags, WalkState, &Node);
633ff4a156dSchristos                 if (ACPI_FAILURE (Status))
634ff4a156dSchristos                 {
635ff4a156dSchristos                     return_ACPI_STATUS (Status);
636ff4a156dSchristos                 }
63728c506b8Sjruoho 
6387efa3256Schristos                 /* However, this is an error -- operand to Scope must exist */
6397efa3256Schristos 
6405b948c02Schristos                 if (strlen (Op->Asl.ExternalName) == ACPI_NAMESEG_SIZE)
6417efa3256Schristos                 {
64228c506b8Sjruoho                     AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
64328c506b8Sjruoho                         Op->Asl.ExternalName);
6447efa3256Schristos                 }
6457efa3256Schristos                 else
6467efa3256Schristos                 {
6477efa3256Schristos                     AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
64828c506b8Sjruoho                         Op->Asl.ExternalName);
6497efa3256Schristos                 }
6507efa3256Schristos 
65128c506b8Sjruoho                 goto FinishNode;
65228c506b8Sjruoho             }
65328c506b8Sjruoho 
65428c506b8Sjruoho             AslCoreSubsystemError (Op, Status,
65528c506b8Sjruoho                 "Failure from namespace lookup", FALSE);
65628c506b8Sjruoho 
65728c506b8Sjruoho             return_ACPI_STATUS (Status);
65828c506b8Sjruoho         }
65981bd9c9cSchristos         else /* Status AE_OK */
66081bd9c9cSchristos         {
66181bd9c9cSchristos             /*
66281bd9c9cSchristos              * Do not allow references to external scopes from the DSDT.
66381bd9c9cSchristos              * This is because the DSDT is always loaded first, and the
66481bd9c9cSchristos              * external reference cannot be resolved -- causing a runtime
66581bd9c9cSchristos              * error because Scope() must be resolved immediately.
66681bd9c9cSchristos              * 10/2015.
66781bd9c9cSchristos              */
66881bd9c9cSchristos             if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
6695b948c02Schristos                 (ACPI_COMPARE_NAMESEG (AslGbl_TableSignature, "DSDT")))
67081bd9c9cSchristos             {
67181bd9c9cSchristos                 /* However, allowed if the reference is within a method */
67281bd9c9cSchristos 
67381bd9c9cSchristos                 MethodOp = Op->Asl.Parent;
67481bd9c9cSchristos                 while (MethodOp &&
67581bd9c9cSchristos                       (MethodOp->Asl.ParseOpcode != PARSEOP_METHOD))
67681bd9c9cSchristos                 {
67781bd9c9cSchristos                     MethodOp = MethodOp->Asl.Parent;
67881bd9c9cSchristos                 }
67981bd9c9cSchristos 
68081bd9c9cSchristos                 if (!MethodOp)
68181bd9c9cSchristos                 {
68281bd9c9cSchristos                     /* Not in a control method, error */
68381bd9c9cSchristos 
68481bd9c9cSchristos                     AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL);
68581bd9c9cSchristos                 }
68681bd9c9cSchristos             }
68781bd9c9cSchristos         }
68828c506b8Sjruoho 
68928c506b8Sjruoho         /* We found a node with this name, now check the type */
69028c506b8Sjruoho 
69128c506b8Sjruoho         switch (Node->Type)
69228c506b8Sjruoho         {
69328c506b8Sjruoho         case ACPI_TYPE_LOCAL_SCOPE:
69428c506b8Sjruoho         case ACPI_TYPE_DEVICE:
69528c506b8Sjruoho         case ACPI_TYPE_POWER:
69628c506b8Sjruoho         case ACPI_TYPE_PROCESSOR:
69728c506b8Sjruoho         case ACPI_TYPE_THERMAL:
69828c506b8Sjruoho 
69928c506b8Sjruoho             /* These are acceptable types - they all open a new scope */
70028c506b8Sjruoho             break;
70128c506b8Sjruoho 
70228c506b8Sjruoho         case ACPI_TYPE_INTEGER:
70328c506b8Sjruoho         case ACPI_TYPE_STRING:
70428c506b8Sjruoho         case ACPI_TYPE_BUFFER:
70528c506b8Sjruoho             /*
70628c506b8Sjruoho              * These types we will allow, but we will change the type.
70728c506b8Sjruoho              * This enables some existing code of the form:
70828c506b8Sjruoho              *
70928c506b8Sjruoho              *  Name (DEB, 0)
71028c506b8Sjruoho              *  Scope (DEB) { ... }
71128c506b8Sjruoho              *
71228c506b8Sjruoho              * Which is used to workaround the fact that the MS interpreter
71328c506b8Sjruoho              * does not allow Scope() forward references.
71428c506b8Sjruoho              */
7157efa3256Schristos             snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s [%s], changing type to [Scope]",
71628c506b8Sjruoho                 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
7177efa3256Schristos             AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);
71828c506b8Sjruoho 
71928c506b8Sjruoho             /* Switch the type to scope, open the new scope */
72028c506b8Sjruoho 
72128c506b8Sjruoho             Node->Type = ACPI_TYPE_LOCAL_SCOPE;
72228c506b8Sjruoho             Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
72328c506b8Sjruoho                 WalkState);
72428c506b8Sjruoho             if (ACPI_FAILURE (Status))
72528c506b8Sjruoho             {
72628c506b8Sjruoho                 return_ACPI_STATUS (Status);
72728c506b8Sjruoho             }
72828c506b8Sjruoho             break;
72928c506b8Sjruoho 
73028c506b8Sjruoho         default:
73128c506b8Sjruoho 
73228c506b8Sjruoho             /* All other types are an error */
73328c506b8Sjruoho 
7347efa3256Schristos             snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s [%s]", Op->Asl.ExternalName,
73528c506b8Sjruoho                 AcpiUtGetTypeName (Node->Type));
7367efa3256Schristos             AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);
73728c506b8Sjruoho 
73828c506b8Sjruoho             /*
73928c506b8Sjruoho              * However, switch the type to be an actual scope so
74028c506b8Sjruoho              * that compilation can continue without generating a whole
74128c506b8Sjruoho              * cascade of additional errors. Open the new scope.
74228c506b8Sjruoho              */
74328c506b8Sjruoho             Node->Type = ACPI_TYPE_LOCAL_SCOPE;
74428c506b8Sjruoho             Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
74528c506b8Sjruoho                 WalkState);
74628c506b8Sjruoho             if (ACPI_FAILURE (Status))
74728c506b8Sjruoho             {
74828c506b8Sjruoho                 return_ACPI_STATUS (Status);
74928c506b8Sjruoho             }
75028c506b8Sjruoho             break;
75128c506b8Sjruoho         }
75228c506b8Sjruoho 
75328c506b8Sjruoho         Status = AE_OK;
75428c506b8Sjruoho         goto FinishNode;
75528c506b8Sjruoho 
75628c506b8Sjruoho     default:
75728c506b8Sjruoho 
75828c506b8Sjruoho         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
75928c506b8Sjruoho         break;
76028c506b8Sjruoho     }
76128c506b8Sjruoho 
76228c506b8Sjruoho     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n",
76328c506b8Sjruoho         Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType)));
76428c506b8Sjruoho 
76528c506b8Sjruoho     /* The name must not already exist */
76628c506b8Sjruoho 
76728c506b8Sjruoho     Flags |= ACPI_NS_ERROR_IF_FOUND;
76828c506b8Sjruoho 
76928c506b8Sjruoho     /*
7707efa3256Schristos      * For opcodes that enter new names into the namespace,
7717efa3256Schristos      * all prefix NameSegs must exist.
7727efa3256Schristos      */
7737efa3256Schristos     WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
7747efa3256Schristos     if (((WalkState->OpInfo->Flags & AML_NAMED) ||
7757efa3256Schristos         (WalkState->OpInfo->Flags & AML_CREATE)) &&
7767efa3256Schristos         (Op->Asl.AmlOpcode != AML_EXTERNAL_OP))
7777efa3256Schristos     {
7787efa3256Schristos         Flags |= ACPI_NS_PREFIX_MUST_EXIST;
7797efa3256Schristos     }
7807efa3256Schristos 
7817efa3256Schristos     /*
78228c506b8Sjruoho      * Enter the named type into the internal namespace. We enter the name
78328c506b8Sjruoho      * as we go downward in the parse tree. Any necessary subobjects that
78428c506b8Sjruoho      * involve arguments to the opcode must be created as we go back up the
78528c506b8Sjruoho      * parse tree later.
78628c506b8Sjruoho      */
78728c506b8Sjruoho     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
78828c506b8Sjruoho         ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
78928c506b8Sjruoho     if (ACPI_FAILURE (Status))
79028c506b8Sjruoho     {
79128c506b8Sjruoho         if (Status == AE_ALREADY_EXISTS)
79228c506b8Sjruoho         {
79328c506b8Sjruoho             /* The name already exists in this scope */
79428c506b8Sjruoho 
79528c506b8Sjruoho             if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
79628c506b8Sjruoho             {
79728c506b8Sjruoho                 /* Allow multiple references to the same scope */
79828c506b8Sjruoho 
79928c506b8Sjruoho                 Node->Type = (UINT8) ObjectType;
80028c506b8Sjruoho                 Status = AE_OK;
80128c506b8Sjruoho             }
8029ddb8508Schristos             else if ((Node->Flags & ANOBJ_IS_EXTERNAL) ||
80381bd9c9cSchristos                      (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
80481bd9c9cSchristos             {
805f5b481b3Schristos                 Status = LdAnalyzeExternals (Node, Op, ObjectType, WalkState);
8069ddb8508Schristos                 if (ACPI_FAILURE (Status))
8079ddb8508Schristos                 {
8089ddb8508Schristos                     if (Status == AE_ERROR)
8099ddb8508Schristos                     {
81081bd9c9cSchristos                         /*
8119ddb8508Schristos                          * The use of AE_ERROR here indicates that there was a
8129ddb8508Schristos                          * compiler error emitted in LdAnalyzeExternals which
8139ddb8508Schristos                          * means that the caller should proceed to the next Op
8149ddb8508Schristos                          * for analysis of subsequent parse objects.
81581bd9c9cSchristos                          */
81628c506b8Sjruoho                         Status = AE_OK;
81728c506b8Sjruoho                     }
8189ddb8508Schristos                     return_ACPI_STATUS (Status);
81949c2f1f4Schristos                 }
820f5b481b3Schristos 
821f5b481b3Schristos                 if (!(Node->Flags & ANOBJ_IS_EXTERNAL) &&
822f5b481b3Schristos                      (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
823f5b481b3Schristos                 {
824f5b481b3Schristos                     /*
825f5b481b3Schristos                      * If we get to here, it means that an actual definition of
826f5b481b3Schristos                      * the object declared external exists. Meaning that Op
827f5b481b3Schristos                      * loading this this Op should have no change to the ACPI
828f5b481b3Schristos                      * namespace. By going to FinishNode, we skip the
829f5b481b3Schristos                      * assignment of Node->Op = Op.
830f5b481b3Schristos                      */
831f5b481b3Schristos                     goto FinishNode;
832f5b481b3Schristos                 }
83349c2f1f4Schristos             }
83428c506b8Sjruoho             else
83528c506b8Sjruoho             {
83628c506b8Sjruoho                 /* Valid error, object already exists */
83728c506b8Sjruoho 
8389ddb8508Schristos                 ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);
8399ddb8508Schristos 
84025666a51Schristos                 AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
8419ddb8508Schristos                     ExternalPath, ASL_MSG_FOUND_HERE, Node->Op,
8429ddb8508Schristos                     ExternalPath);
8439ddb8508Schristos 
8449ddb8508Schristos                 if (ExternalPath)
8459ddb8508Schristos                 {
8469ddb8508Schristos                     ACPI_FREE (ExternalPath);
8479ddb8508Schristos                 }
84828c506b8Sjruoho                 return_ACPI_STATUS (AE_OK);
84928c506b8Sjruoho             }
85028c506b8Sjruoho         }
8517efa3256Schristos         else if (AE_NOT_FOUND)
8527efa3256Schristos         {
8537efa3256Schristos             /*
8547efa3256Schristos              * One or more prefix NameSegs of the NamePath do not exist
8557efa3256Schristos              * (all of them must exist). Attempt to continue compilation
8567efa3256Schristos              * by setting the current scope to the root.
8577efa3256Schristos              */
8587efa3256Schristos             Node = AcpiGbl_RootNode;
8597efa3256Schristos             Status = AE_OK;
8607efa3256Schristos         }
86128c506b8Sjruoho         else
86228c506b8Sjruoho         {
8637efa3256Schristos             /* Flag all other errors as coming from the ACPICA core */
8647efa3256Schristos 
86528c506b8Sjruoho             AslCoreSubsystemError (Op, Status,
86628c506b8Sjruoho                 "Failure from namespace lookup", FALSE);
86728c506b8Sjruoho             return_ACPI_STATUS (Status);
86828c506b8Sjruoho         }
86928c506b8Sjruoho     }
87028c506b8Sjruoho 
8717ab6b89bSchristos     /* Check special names like _WAK and _PTS */
8727ab6b89bSchristos 
8737ab6b89bSchristos     LdCheckSpecialNames (Node, Op);
8747ab6b89bSchristos 
87528c506b8Sjruoho     if (ForceNewScope)
87628c506b8Sjruoho     {
87728c506b8Sjruoho         Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
87828c506b8Sjruoho         if (ACPI_FAILURE (Status))
87928c506b8Sjruoho         {
88028c506b8Sjruoho             return_ACPI_STATUS (Status);
88128c506b8Sjruoho         }
88228c506b8Sjruoho     }
88328c506b8Sjruoho 
884f5b481b3Schristos     /* Point the Node back to the original Parse node */
885f5b481b3Schristos 
88628c506b8Sjruoho     Node->Op = Op;
88728c506b8Sjruoho 
888f5b481b3Schristos FinishNode:
889f5b481b3Schristos 
890f5b481b3Schristos     /* Point the parse node to the new namespace node */
891f5b481b3Schristos 
892f5b481b3Schristos     Op->Asl.Node = Node;
89328c506b8Sjruoho 
89428c506b8Sjruoho     if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
89528c506b8Sjruoho     {
89628c506b8Sjruoho         /*
89728c506b8Sjruoho          * Get the method argument count from "Extra" and save
89828c506b8Sjruoho          * it in the namespace node
89928c506b8Sjruoho          */
90028c506b8Sjruoho         Node->Value = (UINT32) Op->Asl.Extra;
90128c506b8Sjruoho     }
902f5b481b3Schristos     else if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL &&
903f5b481b3Schristos         Node->Type == ACPI_TYPE_METHOD &&
904f5b481b3Schristos         (Node->Flags & ANOBJ_IS_EXTERNAL))
905f5b481b3Schristos     {
906f5b481b3Schristos         Node->Value =
907f5b481b3Schristos             (UINT32) Op->Asl.Child->Asl.Next->Asl.Next->Asl.Value.Integer;
908f5b481b3Schristos     }
90928c506b8Sjruoho 
91028c506b8Sjruoho     return_ACPI_STATUS (Status);
91128c506b8Sjruoho }
91228c506b8Sjruoho 
91328c506b8Sjruoho 
91428c506b8Sjruoho /*******************************************************************************
91528c506b8Sjruoho  *
916f5b481b3Schristos  * FUNCTION:    LdMatchExternType
9179ddb8508Schristos  *
9189ddb8508Schristos  * PARAMETERS:  Type1
9199ddb8508Schristos  *              Type2
9209ddb8508Schristos  *
9219ddb8508Schristos  * RETURN:      BOOLEAN
9229ddb8508Schristos  *
9239ddb8508Schristos  * DESCRIPTION: Match Type1 and Type2 with the assumption that one might be
9249ddb8508Schristos  *              using external types and another might be using local types.
9259ddb8508Schristos  *              This should be used to compare the types found in external
9269ddb8508Schristos  *              declarations with types found in other external declarations or
9279ddb8508Schristos  *              named object declaration. This should not be used to match two
9289ddb8508Schristos  *              object type declarations.
9299ddb8508Schristos  *
9309ddb8508Schristos  ******************************************************************************/
9319ddb8508Schristos 
9329ddb8508Schristos static BOOLEAN
LdMatchExternType(ACPI_OBJECT_TYPE Type1,ACPI_OBJECT_TYPE Type2)933f5b481b3Schristos LdMatchExternType (
9349ddb8508Schristos     ACPI_OBJECT_TYPE        Type1,
9359ddb8508Schristos     ACPI_OBJECT_TYPE        Type2)
9369ddb8508Schristos {
9379ddb8508Schristos     BOOLEAN                 Type1IsLocal = Type1 > ACPI_TYPE_EXTERNAL_MAX;
9389ddb8508Schristos     BOOLEAN                 Type2IsLocal = Type2 > ACPI_TYPE_EXTERNAL_MAX;
9399ddb8508Schristos     ACPI_OBJECT_TYPE        ExternalType;
9409ddb8508Schristos     ACPI_OBJECT_TYPE        LocalType;
9419ddb8508Schristos 
9429ddb8508Schristos 
9439ddb8508Schristos     /*
9449ddb8508Schristos      * The inputs could represent types that are local to ACPICA or types that
9459ddb8508Schristos      * are known externally. Some local types, such as the OperationRegion
9469ddb8508Schristos      * field units, are defined with more granularity than ACPICA local types.
9479ddb8508Schristos      *
9489ddb8508Schristos      * Therefore, map the local types to the external types before matching.
9499ddb8508Schristos      */
9509ddb8508Schristos     if (Type1IsLocal && !Type2IsLocal)
9519ddb8508Schristos     {
9529ddb8508Schristos         LocalType = Type1;
9539ddb8508Schristos         ExternalType = Type2;
9549ddb8508Schristos     }
9559ddb8508Schristos     else if (!Type1IsLocal && Type2IsLocal)
9569ddb8508Schristos     {
9579ddb8508Schristos         LocalType = Type2;
9589ddb8508Schristos         ExternalType = Type1;
9599ddb8508Schristos     }
9609ddb8508Schristos     else
9619ddb8508Schristos     {
9629ddb8508Schristos         return (Type1 == Type2);
9639ddb8508Schristos     }
9649ddb8508Schristos 
9659ddb8508Schristos     switch (LocalType)
9669ddb8508Schristos     {
9679ddb8508Schristos         case ACPI_TYPE_LOCAL_REGION_FIELD:
9689ddb8508Schristos         case ACPI_TYPE_LOCAL_BANK_FIELD:
9699ddb8508Schristos         case ACPI_TYPE_LOCAL_INDEX_FIELD:
9709ddb8508Schristos 
9719ddb8508Schristos             LocalType = ACPI_TYPE_FIELD_UNIT;
9729ddb8508Schristos             break;
9739ddb8508Schristos 
9749ddb8508Schristos         default:
9759ddb8508Schristos             break;
9769ddb8508Schristos     }
9779ddb8508Schristos 
9789ddb8508Schristos     return (LocalType == ExternalType);
9799ddb8508Schristos }
9809ddb8508Schristos 
9819ddb8508Schristos 
9829ddb8508Schristos /*******************************************************************************
9839ddb8508Schristos  *
9849ddb8508Schristos  * FUNCTION:    LdAnalyzeExternals
9859ddb8508Schristos  *
9869ddb8508Schristos  * PARAMETERS:  Node            - Node that represents the named object
9879ddb8508Schristos  *              Op              - Named object declaring this named object
9889ddb8508Schristos  *              ExternalOpType  - Type of ExternalOp
9899ddb8508Schristos  *              WalkState       - Current WalkState
9909ddb8508Schristos  *
9919ddb8508Schristos  * RETURN:      Status
9929ddb8508Schristos  *
9939ddb8508Schristos  * DESCRIPTION: Node and Op represents an identically named object declaration
9949ddb8508Schristos  *              that is either declared by the ASL external keyword or declared
9959ddb8508Schristos  *              by operators that declare named objects (i.e. Name, Device,
9969ddb8508Schristos  *              OperationRegion, and etc.). This function ensures that the
9979ddb8508Schristos  *              declarations do not contradict each other.
9989ddb8508Schristos  *
9999ddb8508Schristos  ******************************************************************************/
10009ddb8508Schristos 
10019ddb8508Schristos static ACPI_STATUS
LdAnalyzeExternals(ACPI_NAMESPACE_NODE * Node,ACPI_PARSE_OBJECT * Op,ACPI_OBJECT_TYPE ExternalOpType,ACPI_WALK_STATE * WalkState)10029ddb8508Schristos LdAnalyzeExternals (
10039ddb8508Schristos     ACPI_NAMESPACE_NODE     *Node,
10049ddb8508Schristos     ACPI_PARSE_OBJECT       *Op,
10059ddb8508Schristos     ACPI_OBJECT_TYPE        ExternalOpType,
10069ddb8508Schristos     ACPI_WALK_STATE         *WalkState)
10079ddb8508Schristos {
10089ddb8508Schristos     ACPI_STATUS             Status = AE_OK;
10099ddb8508Schristos     ACPI_OBJECT_TYPE        ActualExternalOpType;
10109ddb8508Schristos     ACPI_OBJECT_TYPE        ActualOpType;
10119ddb8508Schristos     ACPI_PARSE_OBJECT       *ExternalOp;
10129ddb8508Schristos     ACPI_PARSE_OBJECT       *ActualOp;
10139ddb8508Schristos 
10149ddb8508Schristos 
10159ddb8508Schristos     /*
10169ddb8508Schristos      * The declaration represented by Node and Op must have the same type.
10179ddb8508Schristos      * The type of the external Op is represented by ExternalOpType. However,
10189ddb8508Schristos      * the type of the pre-existing declaration depends on whether if Op
10199ddb8508Schristos      * is an external declaration or an actual declaration.
10209ddb8508Schristos      */
10219ddb8508Schristos     if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)
10229ddb8508Schristos     {
10239ddb8508Schristos         ActualExternalOpType = ExternalOpType;
10249ddb8508Schristos         ActualOpType = Node->Type;
10259ddb8508Schristos     }
10269ddb8508Schristos     else
10279ddb8508Schristos     {
10289ddb8508Schristos         ActualExternalOpType = Node->Type;
1029f5b481b3Schristos         ActualOpType = ExternalOpType;
10309ddb8508Schristos     }
10319ddb8508Schristos 
10329ddb8508Schristos     if ((ActualOpType != ACPI_TYPE_ANY) &&
10339ddb8508Schristos         (ActualExternalOpType != ACPI_TYPE_ANY) &&
1034f5b481b3Schristos         !LdMatchExternType (ActualExternalOpType, ActualOpType))
10359ddb8508Schristos     {
10369ddb8508Schristos         if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL &&
10379ddb8508Schristos             Node->Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)
10389ddb8508Schristos         {
10399ddb8508Schristos             AslDualParseOpError (ASL_WARNING,
10409ddb8508Schristos                 ASL_MSG_DUPLICATE_EXTERN_MISMATCH, Op, NULL,
10419ddb8508Schristos                 ASL_MSG_DUPLICATE_EXTERN_FOUND_HERE, Node->Op, NULL);
10429ddb8508Schristos         }
10439ddb8508Schristos         else
10449ddb8508Schristos         {
10459ddb8508Schristos             if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL &&
10469ddb8508Schristos                 Node->Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)
10479ddb8508Schristos             {
10489ddb8508Schristos                 ExternalOp = Op;
10499ddb8508Schristos                 ActualOp = Node->Op;
10509ddb8508Schristos             }
10519ddb8508Schristos             else
10529ddb8508Schristos             {
10539ddb8508Schristos                 ExternalOp = Node->Op;
10549ddb8508Schristos                 ActualOp = Op;
10559ddb8508Schristos             }
10569ddb8508Schristos             AslDualParseOpError (ASL_WARNING,
10579ddb8508Schristos                 ASL_MSG_DECLARATION_TYPE_MISMATCH, ExternalOp, NULL,
10589ddb8508Schristos                 ASL_MSG_TYPE_MISMATCH_FOUND_HERE, ActualOp, NULL);
10599ddb8508Schristos         }
10609ddb8508Schristos     }
10619ddb8508Schristos 
1062f5b481b3Schristos     /* Set the object type of the external */
1063f5b481b3Schristos 
10649ddb8508Schristos     if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
10659ddb8508Schristos         (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
10669ddb8508Schristos     {
10679ddb8508Schristos         /*
10689ddb8508Schristos          * Allow one create on an object or segment that was
10699ddb8508Schristos          * previously declared External
10709ddb8508Schristos          */
10719ddb8508Schristos         Node->Flags &= ~ANOBJ_IS_EXTERNAL;
1072531a0538Schristos         Node->Type = (UINT8) ActualOpType;
10739ddb8508Schristos 
10749ddb8508Schristos         /* Just retyped a node, probably will need to open a scope */
10759ddb8508Schristos 
1076531a0538Schristos         if (AcpiNsOpensScope (ActualOpType))
10779ddb8508Schristos         {
1078531a0538Schristos             Status = AcpiDsScopeStackPush (Node, ActualOpType, WalkState);
10799ddb8508Schristos             if (ACPI_FAILURE (Status))
10809ddb8508Schristos             {
10819ddb8508Schristos                 return (Status);
10829ddb8508Schristos             }
10839ddb8508Schristos         }
10849ddb8508Schristos 
10859ddb8508Schristos         Status = AE_OK;
10869ddb8508Schristos     }
10879ddb8508Schristos     else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) &&
10889ddb8508Schristos              (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
10899ddb8508Schristos     {
10909ddb8508Schristos         /*
10919ddb8508Schristos          * Allow externals in same scope as the definition of the
10929ddb8508Schristos          * actual object. Similar to C. Allows multiple definition
10939ddb8508Schristos          * blocks that refer to each other in the same file.
10949ddb8508Schristos          */
10959ddb8508Schristos         Status = AE_OK;
10969ddb8508Schristos     }
10979ddb8508Schristos     else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
10989ddb8508Schristos              (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) &&
1099531a0538Schristos              (ActualOpType == ACPI_TYPE_ANY))
11009ddb8508Schristos     {
11019ddb8508Schristos         /* Allow update of externals of unknown type. */
11029ddb8508Schristos 
1103531a0538Schristos         Node->Type = (UINT8) ActualExternalOpType;
11049ddb8508Schristos         Status = AE_OK;
11059ddb8508Schristos     }
11069ddb8508Schristos 
11079ddb8508Schristos     return (Status);
11089ddb8508Schristos }
11099ddb8508Schristos 
11109ddb8508Schristos 
11119ddb8508Schristos /*******************************************************************************
11129ddb8508Schristos  *
11137ab6b89bSchristos  * FUNCTION:    LdCheckSpecialNames
11147ab6b89bSchristos  *
11157ab6b89bSchristos  * PARAMETERS:  Node        - Node that represents the named object
11167ab6b89bSchristos  *              Op          - Named object declaring this named object
11177ab6b89bSchristos  *
11187ab6b89bSchristos  * RETURN:      None
11197ab6b89bSchristos  *
11207ab6b89bSchristos  * DESCRIPTION: Check if certain named objects are declared in the incorrect
11217ab6b89bSchristos  *              scope. Special named objects are listed in
11227ab6b89bSchristos  *              AslGbl_SpecialNamedObjects and can only be declared at the root
11237ab6b89bSchristos  *              scope. _UID inside of a processor declaration must not be a
11247ab6b89bSchristos  *              string.
11257ab6b89bSchristos  *
11267ab6b89bSchristos  ******************************************************************************/
11277ab6b89bSchristos 
11287ab6b89bSchristos static void
LdCheckSpecialNames(ACPI_NAMESPACE_NODE * Node,ACPI_PARSE_OBJECT * Op)11297ab6b89bSchristos LdCheckSpecialNames (
11307ab6b89bSchristos     ACPI_NAMESPACE_NODE     *Node,
11317ab6b89bSchristos     ACPI_PARSE_OBJECT       *Op)
11327ab6b89bSchristos {
11337ab6b89bSchristos     UINT32                  i;
11347ab6b89bSchristos 
11357ab6b89bSchristos 
11367ab6b89bSchristos     for (i = 0; i < MAX_SPECIAL_NAMES; i++)
11377ab6b89bSchristos     {
11387ab6b89bSchristos         if (ACPI_COMPARE_NAMESEG(Node->Name.Ascii, AslGbl_SpecialNamedObjects[i]) &&
11397ab6b89bSchristos             Node->Parent != AcpiGbl_RootNode)
11407ab6b89bSchristos         {
11417ab6b89bSchristos             AslError (ASL_ERROR, ASL_MSG_INVALID_SPECIAL_NAME, Op, Op->Asl.ExternalName);
11427ab6b89bSchristos             return;
11437ab6b89bSchristos         }
11447ab6b89bSchristos     }
11457ab6b89bSchristos 
11467ab6b89bSchristos     if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, "_UID") &&
11477ab6b89bSchristos         Node->Parent->Type == ACPI_TYPE_PROCESSOR &&
11487ab6b89bSchristos         Node->Type == ACPI_TYPE_STRING)
11497ab6b89bSchristos     {
11507ab6b89bSchristos         AslError (ASL_ERROR, ASL_MSG_INVALID_PROCESSOR_UID , Op, "found a string");
11517ab6b89bSchristos     }
11527ab6b89bSchristos }
11537ab6b89bSchristos 
11547ab6b89bSchristos 
11557ab6b89bSchristos /*******************************************************************************
11567ab6b89bSchristos  *
115728c506b8Sjruoho  * FUNCTION:    LdNamespace2Begin
115828c506b8Sjruoho  *
115928c506b8Sjruoho  * PARAMETERS:  ASL_WALK_CALLBACK
116028c506b8Sjruoho  *
116128c506b8Sjruoho  * RETURN:      Status
116228c506b8Sjruoho  *
116328c506b8Sjruoho  * DESCRIPTION: Descending callback used during the pass 2 parse tree walk.
116428c506b8Sjruoho  *              Second pass resolves some forward references.
116528c506b8Sjruoho  *
116628c506b8Sjruoho  * Notes:
116728c506b8Sjruoho  * Currently only needs to handle the Alias operator.
116828c506b8Sjruoho  * Could be used to allow forward references from the Scope() operator, but
116928c506b8Sjruoho  * the MS interpreter does not allow this, so this compiler does not either.
117028c506b8Sjruoho  *
117128c506b8Sjruoho  ******************************************************************************/
117228c506b8Sjruoho 
117328c506b8Sjruoho static ACPI_STATUS
LdNamespace2Begin(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)117428c506b8Sjruoho LdNamespace2Begin (
117528c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
117628c506b8Sjruoho     UINT32                  Level,
117728c506b8Sjruoho     void                    *Context)
117828c506b8Sjruoho {
117928c506b8Sjruoho     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
118028c506b8Sjruoho     ACPI_STATUS             Status;
118128c506b8Sjruoho     ACPI_NAMESPACE_NODE     *Node;
118228c506b8Sjruoho     ACPI_OBJECT_TYPE        ObjectType;
118328c506b8Sjruoho     BOOLEAN                 ForceNewScope = FALSE;
118428c506b8Sjruoho     ACPI_PARSE_OBJECT       *Arg;
118528c506b8Sjruoho     char                    *Path;
118628c506b8Sjruoho     ACPI_NAMESPACE_NODE     *TargetNode;
118728c506b8Sjruoho 
118828c506b8Sjruoho 
118928c506b8Sjruoho     ACPI_FUNCTION_NAME (LdNamespace2Begin);
119028c506b8Sjruoho     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
119128c506b8Sjruoho         Op, Op->Asl.ParseOpName));
119228c506b8Sjruoho 
119328c506b8Sjruoho 
119428c506b8Sjruoho     /* Ignore Ops with no namespace node */
119528c506b8Sjruoho 
119628c506b8Sjruoho     Node = Op->Asl.Node;
119728c506b8Sjruoho     if (!Node)
119828c506b8Sjruoho     {
119928c506b8Sjruoho         return (AE_OK);
120028c506b8Sjruoho     }
120128c506b8Sjruoho 
120228c506b8Sjruoho     /* Get the type to determine if we should push the scope */
120328c506b8Sjruoho 
120428c506b8Sjruoho     if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
1205ae01dbf5Schristos         (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC))
120628c506b8Sjruoho     {
120728c506b8Sjruoho         ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
120828c506b8Sjruoho     }
120928c506b8Sjruoho     else
121028c506b8Sjruoho     {
121128c506b8Sjruoho         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
121228c506b8Sjruoho     }
121328c506b8Sjruoho 
121428c506b8Sjruoho     /* Push scope for Resource Templates */
121528c506b8Sjruoho 
121628c506b8Sjruoho     if (Op->Asl.ParseOpcode == PARSEOP_NAME)
121728c506b8Sjruoho     {
1218ae01dbf5Schristos         if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
121928c506b8Sjruoho         {
122028c506b8Sjruoho             ForceNewScope = TRUE;
122128c506b8Sjruoho         }
122228c506b8Sjruoho     }
122328c506b8Sjruoho 
122428c506b8Sjruoho     /* Push the scope stack */
122528c506b8Sjruoho 
122628c506b8Sjruoho     if (ForceNewScope || AcpiNsOpensScope (ObjectType))
122728c506b8Sjruoho     {
122828c506b8Sjruoho         Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
122928c506b8Sjruoho         if (ACPI_FAILURE (Status))
123028c506b8Sjruoho         {
123128c506b8Sjruoho             return_ACPI_STATUS (Status);
123228c506b8Sjruoho         }
123328c506b8Sjruoho     }
123428c506b8Sjruoho 
123528c506b8Sjruoho     if (Op->Asl.ParseOpcode == PARSEOP_ALIAS)
123628c506b8Sjruoho     {
12377efa3256Schristos         /*
12387efa3256Schristos          * Complete the alias node by getting and saving the target node.
12397efa3256Schristos          * First child is the alias target
12407efa3256Schristos          */
124128c506b8Sjruoho         Arg = Op->Asl.Child;
124228c506b8Sjruoho 
124328c506b8Sjruoho         /* Get the target pathname */
124428c506b8Sjruoho 
124528c506b8Sjruoho         Path = Arg->Asl.Namepath;
124628c506b8Sjruoho         if (!Path)
124728c506b8Sjruoho         {
124828c506b8Sjruoho             Status = UtInternalizeName (Arg->Asl.ExternalName, &Path);
124928c506b8Sjruoho             if (ACPI_FAILURE (Status))
125028c506b8Sjruoho             {
125128c506b8Sjruoho                 return (Status);
125228c506b8Sjruoho             }
125328c506b8Sjruoho         }
125428c506b8Sjruoho 
125528c506b8Sjruoho         /* Get the NS node associated with the target. It must exist. */
125628c506b8Sjruoho 
125728c506b8Sjruoho         Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
125828c506b8Sjruoho             ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
125928c506b8Sjruoho             WalkState, &TargetNode);
126028c506b8Sjruoho         if (ACPI_FAILURE (Status))
126128c506b8Sjruoho         {
126228c506b8Sjruoho             if (Status == AE_NOT_FOUND)
126328c506b8Sjruoho             {
12647efa3256Schristos                 /* Standalone NameSeg vs. NamePath */
126528c506b8Sjruoho 
12665b948c02Schristos                 if (strlen (Arg->Asl.ExternalName) == ACPI_NAMESEG_SIZE)
12677efa3256Schristos                 {
12687efa3256Schristos                     AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
12697efa3256Schristos                         Arg->Asl.ExternalName);
12707efa3256Schristos                 }
12717efa3256Schristos                 else
12727efa3256Schristos                 {
12737efa3256Schristos                     AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
12747efa3256Schristos                         Arg->Asl.ExternalName);
12757efa3256Schristos                 }
12767efa3256Schristos 
12777efa3256Schristos #if 0
12787efa3256Schristos /*
12797efa3256Schristos  * NOTE: Removed 10/2018 to enhance compiler error reporting. No
12807efa3256Schristos  * regressions seen.
12817efa3256Schristos  */
128228c506b8Sjruoho                 /*
128328c506b8Sjruoho                  * The name was not found, go ahead and create it.
128428c506b8Sjruoho                  * This prevents more errors later.
128528c506b8Sjruoho                  */
128628c506b8Sjruoho                 Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
12877efa3256Schristos                     ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
12887efa3256Schristos                     ACPI_NS_NO_UPSEARCH, WalkState, &Node);
12897efa3256Schristos #endif
12907efa3256Schristos                 return (Status);
12917efa3256Schristos /* Removed: return (AE_OK)*/
129228c506b8Sjruoho             }
129328c506b8Sjruoho 
129428c506b8Sjruoho             AslCoreSubsystemError (Op, Status,
129528c506b8Sjruoho                 "Failure from namespace lookup", FALSE);
129628c506b8Sjruoho             return (AE_OK);
129728c506b8Sjruoho         }
129828c506b8Sjruoho 
1299b558e860Schristos         /* Save the target node within the alias node as well as type information */
130028c506b8Sjruoho 
130128c506b8Sjruoho         Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
1302b558e860Schristos         Node->Type = TargetNode->Type;
1303b558e860Schristos         if (Node->Type == ACPI_TYPE_METHOD)
1304b558e860Schristos         {
1305b558e860Schristos             /* Save the parameter count for methods */
1306b558e860Schristos 
1307b558e860Schristos             Node->Value = TargetNode->Value;
1308b558e860Schristos         }
130928c506b8Sjruoho     }
131028c506b8Sjruoho 
131128c506b8Sjruoho     return (AE_OK);
131228c506b8Sjruoho }
131328c506b8Sjruoho 
131428c506b8Sjruoho 
131528c506b8Sjruoho /*******************************************************************************
131628c506b8Sjruoho  *
131728c506b8Sjruoho  * FUNCTION:    LdCommonNamespaceEnd
131828c506b8Sjruoho  *
131928c506b8Sjruoho  * PARAMETERS:  ASL_WALK_CALLBACK
132028c506b8Sjruoho  *
132128c506b8Sjruoho  * RETURN:      Status
132228c506b8Sjruoho  *
132328c506b8Sjruoho  * DESCRIPTION: Ascending callback used during the loading of the namespace,
132428c506b8Sjruoho  *              We only need to worry about managing the scope stack here.
132528c506b8Sjruoho  *
132628c506b8Sjruoho  ******************************************************************************/
132728c506b8Sjruoho 
132828c506b8Sjruoho static ACPI_STATUS
LdCommonNamespaceEnd(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)132928c506b8Sjruoho LdCommonNamespaceEnd (
133028c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
133128c506b8Sjruoho     UINT32                  Level,
133228c506b8Sjruoho     void                    *Context)
133328c506b8Sjruoho {
133428c506b8Sjruoho     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
133528c506b8Sjruoho     ACPI_OBJECT_TYPE        ObjectType;
133628c506b8Sjruoho     BOOLEAN                 ForceNewScope = FALSE;
133728c506b8Sjruoho 
133828c506b8Sjruoho 
133928c506b8Sjruoho     ACPI_FUNCTION_NAME (LdCommonNamespaceEnd);
134028c506b8Sjruoho 
134128c506b8Sjruoho 
134228c506b8Sjruoho     /* We are only interested in opcodes that have an associated name */
134328c506b8Sjruoho 
134428c506b8Sjruoho     if (!Op->Asl.Namepath)
134528c506b8Sjruoho     {
134628c506b8Sjruoho         return (AE_OK);
134728c506b8Sjruoho     }
134828c506b8Sjruoho 
134928c506b8Sjruoho     /* Get the type to determine if we should pop the scope */
135028c506b8Sjruoho 
135128c506b8Sjruoho     if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
1352ae01dbf5Schristos         (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC))
135328c506b8Sjruoho     {
135428c506b8Sjruoho         /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */
135528c506b8Sjruoho 
135628c506b8Sjruoho         ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
135728c506b8Sjruoho     }
135828c506b8Sjruoho     else
135928c506b8Sjruoho     {
136028c506b8Sjruoho         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
136128c506b8Sjruoho     }
136228c506b8Sjruoho 
136328c506b8Sjruoho     /* Pop scope that was pushed for Resource Templates */
136428c506b8Sjruoho 
136528c506b8Sjruoho     if (Op->Asl.ParseOpcode == PARSEOP_NAME)
136628c506b8Sjruoho     {
1367ae01dbf5Schristos         if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
136828c506b8Sjruoho         {
136928c506b8Sjruoho             ForceNewScope = TRUE;
137028c506b8Sjruoho         }
137128c506b8Sjruoho     }
137228c506b8Sjruoho 
137328c506b8Sjruoho     /* Pop the scope stack */
137428c506b8Sjruoho 
137528c506b8Sjruoho     if (ForceNewScope || AcpiNsOpensScope (ObjectType))
137628c506b8Sjruoho     {
137728c506b8Sjruoho         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
137828c506b8Sjruoho             "(%s): Popping scope for Op [%s] %p\n",
137928c506b8Sjruoho             AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op));
138028c506b8Sjruoho 
138128c506b8Sjruoho         (void) AcpiDsScopeStackPop (WalkState);
138228c506b8Sjruoho     }
138328c506b8Sjruoho 
138428c506b8Sjruoho     return (AE_OK);
138528c506b8Sjruoho }
1386