xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/aslload.c (revision 9ddb8508240c7c9f35a5772bb7feb5968eb419e8)
128c506b8Sjruoho /******************************************************************************
228c506b8Sjruoho  *
328c506b8Sjruoho  * Module Name: dswload - Dispatcher namespace load callbacks
428c506b8Sjruoho  *
528c506b8Sjruoho  *****************************************************************************/
628c506b8Sjruoho 
7124f4c82Sjruoho /*
8*9ddb8508Schristos  * Copyright (C) 2000 - 2020, 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
33124f4c82Sjruoho  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY 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 
91*9ddb8508Schristos static ACPI_STATUS
92*9ddb8508Schristos LdAnalyzeExternals (
93*9ddb8508Schristos     ACPI_NAMESPACE_NODE     *Node,
94*9ddb8508Schristos     ACPI_PARSE_OBJECT       *Op,
95*9ddb8508Schristos     ACPI_OBJECT_TYPE        ExternalOpType,
96*9ddb8508Schristos     ACPI_OBJECT_TYPE        ObjectType,
97*9ddb8508Schristos     ACPI_WALK_STATE         *WalkState);
98*9ddb8508Schristos 
99*9ddb8508Schristos 
10028c506b8Sjruoho /*******************************************************************************
10128c506b8Sjruoho  *
10228c506b8Sjruoho  * FUNCTION:    LdLoadNamespace
10328c506b8Sjruoho  *
10428c506b8Sjruoho  * PARAMETERS:  RootOp      - Root of the parse tree
10528c506b8Sjruoho  *
10628c506b8Sjruoho  * RETURN:      Status
10728c506b8Sjruoho  *
10828c506b8Sjruoho  * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the
10928c506b8Sjruoho  *              named ASL/AML objects into the namespace. The namespace is
11028c506b8Sjruoho  *              constructed in order to resolve named references and references
11128c506b8Sjruoho  *              to named fields within resource templates/descriptors.
11228c506b8Sjruoho  *
11328c506b8Sjruoho  ******************************************************************************/
11428c506b8Sjruoho 
11528c506b8Sjruoho ACPI_STATUS
11628c506b8Sjruoho LdLoadNamespace (
11728c506b8Sjruoho     ACPI_PARSE_OBJECT       *RootOp)
11828c506b8Sjruoho {
11928c506b8Sjruoho     ACPI_WALK_STATE         *WalkState;
12028c506b8Sjruoho 
12128c506b8Sjruoho 
12228c506b8Sjruoho     /* Create a new walk state */
12328c506b8Sjruoho 
12428c506b8Sjruoho     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
12528c506b8Sjruoho     if (!WalkState)
12628c506b8Sjruoho     {
127ff4a156dSchristos         return (AE_NO_MEMORY);
12828c506b8Sjruoho     }
12928c506b8Sjruoho 
13028c506b8Sjruoho     /* Walk the entire parse tree, first pass */
13128c506b8Sjruoho 
13228c506b8Sjruoho     TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin,
13328c506b8Sjruoho         LdCommonNamespaceEnd, WalkState);
13428c506b8Sjruoho 
13528c506b8Sjruoho     /* Second pass to handle forward references */
13628c506b8Sjruoho 
13728c506b8Sjruoho     TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin,
13828c506b8Sjruoho         LdCommonNamespaceEnd, WalkState);
13928c506b8Sjruoho 
14028c506b8Sjruoho     /* Dump the namespace if debug is enabled */
14128c506b8Sjruoho 
142a147b75fSchristos     if (AcpiDbgLevel & ACPI_LV_TABLES)
143a147b75fSchristos     {
14428c506b8Sjruoho         AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX);
145a147b75fSchristos     }
146a147b75fSchristos 
147414ef032Schristos     ACPI_FREE (WalkState);
148ff4a156dSchristos     return (AE_OK);
14928c506b8Sjruoho }
15028c506b8Sjruoho 
15128c506b8Sjruoho 
15228c506b8Sjruoho /*******************************************************************************
15328c506b8Sjruoho  *
15428c506b8Sjruoho  * FUNCTION:    LdLoadFieldElements
15528c506b8Sjruoho  *
1567ab6b89bSchristos  * PARAMETERS:  AmlType         - Type to search
1577ab6b89bSchristos  *              Op              - Parent node (Field)
15828c506b8Sjruoho  *              WalkState       - Current walk state
15928c506b8Sjruoho  *
16028c506b8Sjruoho  * RETURN:      Status
16128c506b8Sjruoho  *
16228c506b8Sjruoho  * DESCRIPTION: Enter the named elements of the field (children of the parent)
16328c506b8Sjruoho  *              into the namespace.
16428c506b8Sjruoho  *
16528c506b8Sjruoho  ******************************************************************************/
16628c506b8Sjruoho 
16728c506b8Sjruoho static ACPI_STATUS
16828c506b8Sjruoho LdLoadFieldElements (
1697ab6b89bSchristos     UINT32                  AmlType,
17028c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
17128c506b8Sjruoho     ACPI_WALK_STATE         *WalkState)
17228c506b8Sjruoho {
17328c506b8Sjruoho     ACPI_PARSE_OBJECT       *Child = NULL;
1747ab6b89bSchristos     ACPI_PARSE_OBJECT       *SourceRegion;
17528c506b8Sjruoho     ACPI_NAMESPACE_NODE     *Node;
17628c506b8Sjruoho     ACPI_STATUS             Status;
177*9ddb8508Schristos     char                    *ExternalPath;
17828c506b8Sjruoho 
17928c506b8Sjruoho 
1807ab6b89bSchristos     SourceRegion = UtGetArg (Op, 0);
1817ab6b89bSchristos     if (SourceRegion)
1827ab6b89bSchristos     {
1837ab6b89bSchristos         Status = AcpiNsLookup (WalkState->ScopeInfo,
184*9ddb8508Schristos             SourceRegion->Asl.Value.String, AmlType, ACPI_IMODE_EXECUTE,
185*9ddb8508Schristos             ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
1867ab6b89bSchristos         if (Status == AE_NOT_FOUND)
1877ab6b89bSchristos         {
1887ab6b89bSchristos             /*
1897ab6b89bSchristos              * If the named object is not found, it means that it is either a
1907ab6b89bSchristos              * forward reference or the named object does not exist.
1917ab6b89bSchristos              */
1927ab6b89bSchristos             SourceRegion->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD;
1937ab6b89bSchristos         }
1947ab6b89bSchristos     }
1957ab6b89bSchristos 
19628c506b8Sjruoho     /* Get the first named field element */
19728c506b8Sjruoho 
19828c506b8Sjruoho     switch (Op->Asl.AmlOpcode)
19928c506b8Sjruoho     {
20028c506b8Sjruoho     case AML_BANK_FIELD_OP:
20128c506b8Sjruoho 
20228c506b8Sjruoho         Child = UtGetArg (Op, 6);
20328c506b8Sjruoho         break;
20428c506b8Sjruoho 
20528c506b8Sjruoho     case AML_INDEX_FIELD_OP:
20628c506b8Sjruoho 
20728c506b8Sjruoho         Child = UtGetArg (Op, 5);
20828c506b8Sjruoho         break;
20928c506b8Sjruoho 
21028c506b8Sjruoho     case AML_FIELD_OP:
21128c506b8Sjruoho 
21228c506b8Sjruoho         Child = UtGetArg (Op, 4);
21328c506b8Sjruoho         break;
21428c506b8Sjruoho 
21528c506b8Sjruoho     default:
216ff4a156dSchristos 
21728c506b8Sjruoho         /* No other opcodes should arrive here */
218ff4a156dSchristos 
21928c506b8Sjruoho         return (AE_BAD_PARAMETER);
22028c506b8Sjruoho     }
22128c506b8Sjruoho 
22228c506b8Sjruoho     /* Enter all elements into the namespace */
22328c506b8Sjruoho 
22428c506b8Sjruoho     while (Child)
22528c506b8Sjruoho     {
22628c506b8Sjruoho         switch (Child->Asl.AmlOpcode)
22728c506b8Sjruoho         {
22828c506b8Sjruoho         case AML_INT_RESERVEDFIELD_OP:
22928c506b8Sjruoho         case AML_INT_ACCESSFIELD_OP:
230ff4a156dSchristos         case AML_INT_CONNECTION_OP:
23128c506b8Sjruoho             break;
23228c506b8Sjruoho 
23328c506b8Sjruoho         default:
23428c506b8Sjruoho 
23528c506b8Sjruoho             Status = AcpiNsLookup (WalkState->ScopeInfo,
23628c506b8Sjruoho                 Child->Asl.Value.String,
23728c506b8Sjruoho                 ACPI_TYPE_LOCAL_REGION_FIELD,
23828c506b8Sjruoho                 ACPI_IMODE_LOAD_PASS1,
23928c506b8Sjruoho                 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
24081bd9c9cSchristos                     ACPI_NS_ERROR_IF_FOUND, NULL, &Node);
24128c506b8Sjruoho             if (ACPI_FAILURE (Status))
24228c506b8Sjruoho             {
24328c506b8Sjruoho                 if (Status != AE_ALREADY_EXISTS)
24428c506b8Sjruoho                 {
24528c506b8Sjruoho                     AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child,
24628c506b8Sjruoho                         Child->Asl.Value.String);
24728c506b8Sjruoho                     return (Status);
24828c506b8Sjruoho                 }
249ae01dbf5Schristos                 else if (Status == AE_ALREADY_EXISTS &&
250a147b75fSchristos                     (Node->Flags & ANOBJ_IS_EXTERNAL))
251ae01dbf5Schristos                 {
252ae01dbf5Schristos                     Node->Type = (UINT8) ACPI_TYPE_LOCAL_REGION_FIELD;
2535b948c02Schristos                     Node->Flags &= ~ANOBJ_IS_EXTERNAL;
254ae01dbf5Schristos                 }
255ae01dbf5Schristos                 else
256ae01dbf5Schristos                 {
25728c506b8Sjruoho                     /*
25828c506b8Sjruoho                      * The name already exists in this scope
25928c506b8Sjruoho                      * But continue processing the elements
26028c506b8Sjruoho                      */
261*9ddb8508Schristos                     ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);
262*9ddb8508Schristos 
2631c663068Schristos                     AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,
264*9ddb8508Schristos                         ExternalPath, ASL_MSG_FOUND_HERE, Node->Op,
265*9ddb8508Schristos                         ExternalPath);
266*9ddb8508Schristos 
267*9ddb8508Schristos                     if (ExternalPath)
268*9ddb8508Schristos                     {
269*9ddb8508Schristos                         ACPI_FREE (ExternalPath);
270*9ddb8508Schristos                     }
27128c506b8Sjruoho                 }
272ae01dbf5Schristos             }
27328c506b8Sjruoho             else
27428c506b8Sjruoho             {
27528c506b8Sjruoho                 Child->Asl.Node = Node;
27628c506b8Sjruoho                 Node->Op = Child;
27728c506b8Sjruoho             }
27828c506b8Sjruoho             break;
27928c506b8Sjruoho         }
280ff4a156dSchristos 
28128c506b8Sjruoho         Child = Child->Asl.Next;
28228c506b8Sjruoho     }
283ff4a156dSchristos 
28428c506b8Sjruoho     return (AE_OK);
28528c506b8Sjruoho }
28628c506b8Sjruoho 
28728c506b8Sjruoho 
28828c506b8Sjruoho /*******************************************************************************
28928c506b8Sjruoho  *
29028c506b8Sjruoho  * FUNCTION:    LdLoadResourceElements
29128c506b8Sjruoho  *
29228c506b8Sjruoho  * PARAMETERS:  Op              - Parent node (Resource Descriptor)
29328c506b8Sjruoho  *              WalkState       - Current walk state
29428c506b8Sjruoho  *
29528c506b8Sjruoho  * RETURN:      Status
29628c506b8Sjruoho  *
29728c506b8Sjruoho  * DESCRIPTION: Enter the named elements of the resource descriptor (children
29828c506b8Sjruoho  *              of the parent) into the namespace.
29928c506b8Sjruoho  *
30028c506b8Sjruoho  * NOTE: In the real AML namespace, these named elements never exist. But
30128c506b8Sjruoho  *       we simply use the namespace here as a symbol table so we can look
30228c506b8Sjruoho  *       them up as they are referenced.
30328c506b8Sjruoho  *
30428c506b8Sjruoho  ******************************************************************************/
30528c506b8Sjruoho 
30628c506b8Sjruoho static ACPI_STATUS
30728c506b8Sjruoho LdLoadResourceElements (
30828c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
30928c506b8Sjruoho     ACPI_WALK_STATE         *WalkState)
31028c506b8Sjruoho {
31128c506b8Sjruoho     ACPI_PARSE_OBJECT       *InitializerOp = NULL;
31228c506b8Sjruoho     ACPI_NAMESPACE_NODE     *Node;
31328c506b8Sjruoho     ACPI_STATUS             Status;
314*9ddb8508Schristos     char                    *ExternalPath;
31528c506b8Sjruoho 
31628c506b8Sjruoho 
31728c506b8Sjruoho     /*
31828c506b8Sjruoho      * Enter the resource name into the namespace. Name must not already exist.
31928c506b8Sjruoho      * This opens a scope, so later field names are guaranteed to be new/unique.
32028c506b8Sjruoho      */
32128c506b8Sjruoho     Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath,
32228c506b8Sjruoho         ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1,
32328c506b8Sjruoho         ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND,
32428c506b8Sjruoho         WalkState, &Node);
32528c506b8Sjruoho     if (ACPI_FAILURE (Status))
32628c506b8Sjruoho     {
32728c506b8Sjruoho         if (Status == AE_ALREADY_EXISTS)
32828c506b8Sjruoho         {
32928c506b8Sjruoho             /* Actual node causing the error was saved in ParentMethod */
33028c506b8Sjruoho 
331*9ddb8508Schristos             ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);
332*9ddb8508Schristos 
33325666a51Schristos             AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS,
33425666a51Schristos                 (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod,
335*9ddb8508Schristos                 ExternalPath, ASL_MSG_FOUND_HERE, Node->Op,
336*9ddb8508Schristos                 ExternalPath);
337*9ddb8508Schristos 
338*9ddb8508Schristos             if (ExternalPath)
339*9ddb8508Schristos             {
340*9ddb8508Schristos                 ACPI_FREE (ExternalPath);
341*9ddb8508Schristos             }
34228c506b8Sjruoho             return (AE_OK);
34328c506b8Sjruoho         }
34428c506b8Sjruoho         return (Status);
34528c506b8Sjruoho     }
34628c506b8Sjruoho 
34728c506b8Sjruoho     Node->Value = (UINT32) Op->Asl.Value.Integer;
34828c506b8Sjruoho     Node->Op = Op;
34928c506b8Sjruoho     Op->Asl.Node = Node;
35028c506b8Sjruoho 
35128c506b8Sjruoho     /*
35228c506b8Sjruoho      * Now enter the predefined fields, for easy lookup when referenced
35328c506b8Sjruoho      * by the source ASL
35428c506b8Sjruoho      */
35528c506b8Sjruoho     InitializerOp = ASL_GET_CHILD_NODE (Op);
35628c506b8Sjruoho     while (InitializerOp)
35728c506b8Sjruoho     {
35828c506b8Sjruoho         if (InitializerOp->Asl.ExternalName)
35928c506b8Sjruoho         {
36028c506b8Sjruoho             Status = AcpiNsLookup (WalkState->ScopeInfo,
36128c506b8Sjruoho                 InitializerOp->Asl.ExternalName,
3627efa3256Schristos                 ACPI_TYPE_LOCAL_RESOURCE_FIELD, ACPI_IMODE_LOAD_PASS1,
3637efa3256Schristos                 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
36428c506b8Sjruoho             if (ACPI_FAILURE (Status))
36528c506b8Sjruoho             {
36628c506b8Sjruoho                 return (Status);
36728c506b8Sjruoho             }
36828c506b8Sjruoho 
36928c506b8Sjruoho             /*
370ff4a156dSchristos              * Store the field offset and length in the namespace node
371ff4a156dSchristos              * so it can be used when the field is referenced
37228c506b8Sjruoho              */
373ff4a156dSchristos             Node->Value = InitializerOp->Asl.Value.Tag.BitOffset;
374ff4a156dSchristos             Node->Length = InitializerOp->Asl.Value.Tag.BitLength;
37528c506b8Sjruoho             InitializerOp->Asl.Node = Node;
37628c506b8Sjruoho             Node->Op = InitializerOp;
37728c506b8Sjruoho         }
378ff4a156dSchristos 
37928c506b8Sjruoho         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
38028c506b8Sjruoho     }
38128c506b8Sjruoho 
38228c506b8Sjruoho     return (AE_OK);
38328c506b8Sjruoho }
38428c506b8Sjruoho 
38528c506b8Sjruoho 
38628c506b8Sjruoho /*******************************************************************************
38728c506b8Sjruoho  *
38828c506b8Sjruoho  * FUNCTION:    LdNamespace1Begin
38928c506b8Sjruoho  *
39028c506b8Sjruoho  * PARAMETERS:  ASL_WALK_CALLBACK
39128c506b8Sjruoho  *
39228c506b8Sjruoho  * RETURN:      Status
39328c506b8Sjruoho  *
39428c506b8Sjruoho  * DESCRIPTION: Descending callback used during the parse tree walk. If this
39528c506b8Sjruoho  *              is a named AML opcode, enter into the namespace
39628c506b8Sjruoho  *
39728c506b8Sjruoho  ******************************************************************************/
39828c506b8Sjruoho 
39928c506b8Sjruoho static ACPI_STATUS
40028c506b8Sjruoho LdNamespace1Begin (
40128c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
40228c506b8Sjruoho     UINT32                  Level,
40328c506b8Sjruoho     void                    *Context)
40428c506b8Sjruoho {
40528c506b8Sjruoho     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
40628c506b8Sjruoho     ACPI_NAMESPACE_NODE     *Node;
40781bd9c9cSchristos     ACPI_PARSE_OBJECT       *MethodOp;
40828c506b8Sjruoho     ACPI_STATUS             Status;
40928c506b8Sjruoho     ACPI_OBJECT_TYPE        ObjectType;
41028c506b8Sjruoho     ACPI_OBJECT_TYPE        ActualObjectType = ACPI_TYPE_ANY;
41128c506b8Sjruoho     char                    *Path;
41228c506b8Sjruoho     UINT32                  Flags = ACPI_NS_NO_UPSEARCH;
41328c506b8Sjruoho     ACPI_PARSE_OBJECT       *Arg;
41428c506b8Sjruoho     UINT32                  i;
41528c506b8Sjruoho     BOOLEAN                 ForceNewScope = FALSE;
416a40a9998Schristos     const ACPI_OPCODE_INFO  *OpInfo;
417a40a9998Schristos     ACPI_PARSE_OBJECT       *ParentOp;
418*9ddb8508Schristos     char                    *ExternalPath;
41928c506b8Sjruoho 
42028c506b8Sjruoho 
42128c506b8Sjruoho     ACPI_FUNCTION_NAME (LdNamespace1Begin);
422a40a9998Schristos 
423a40a9998Schristos 
42428c506b8Sjruoho     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
42528c506b8Sjruoho         Op, Op->Asl.ParseOpName));
42628c506b8Sjruoho 
42728c506b8Sjruoho     /*
42828c506b8Sjruoho      * We are only interested in opcodes that have an associated name
42928c506b8Sjruoho      * (or multiple names)
43028c506b8Sjruoho      */
43128c506b8Sjruoho     switch (Op->Asl.AmlOpcode)
43228c506b8Sjruoho     {
43328c506b8Sjruoho     case AML_INDEX_FIELD_OP:
4347ab6b89bSchristos 
4357ab6b89bSchristos         Status = LdLoadFieldElements (ACPI_TYPE_LOCAL_REGION_FIELD, Op, WalkState);
4367ab6b89bSchristos         return (Status);
4377ab6b89bSchristos 
4387ab6b89bSchristos     case AML_BANK_FIELD_OP:
43928c506b8Sjruoho     case AML_FIELD_OP:
44028c506b8Sjruoho 
4417ab6b89bSchristos         Status = LdLoadFieldElements (ACPI_TYPE_REGION, Op, WalkState);
4427ab6b89bSchristos         return (Status);
44328c506b8Sjruoho 
444414ef032Schristos     case AML_INT_CONNECTION_OP:
445414ef032Schristos 
446414ef032Schristos         if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)
447414ef032Schristos         {
448414ef032Schristos             break;
449414ef032Schristos         }
450414ef032Schristos 
4511c663068Schristos         Arg = Op->Asl.Child;
452414ef032Schristos         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName,
453414ef032Schristos             ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
454414ef032Schristos             WalkState, &Node);
455414ef032Schristos         if (ACPI_FAILURE (Status))
456414ef032Schristos         {
457414ef032Schristos             break;
458414ef032Schristos         }
459414ef032Schristos 
460414ef032Schristos         break;
461414ef032Schristos 
46228c506b8Sjruoho     default:
46328c506b8Sjruoho 
46428c506b8Sjruoho         /* All other opcodes go below */
465ff4a156dSchristos 
46628c506b8Sjruoho         break;
46728c506b8Sjruoho     }
46828c506b8Sjruoho 
46928c506b8Sjruoho     /* Check if this object has already been installed in the namespace */
47028c506b8Sjruoho 
47128c506b8Sjruoho     if (Op->Asl.Node)
47228c506b8Sjruoho     {
47328c506b8Sjruoho         return (AE_OK);
47428c506b8Sjruoho     }
47528c506b8Sjruoho 
476a40a9998Schristos     /* Check for a possible illegal forward reference */
477a40a9998Schristos 
478a40a9998Schristos     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
479*9ddb8508Schristos         (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
480*9ddb8508Schristos         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
481a40a9998Schristos     {
482a40a9998Schristos         /*
483a40a9998Schristos          * Op->Asl.Namepath will be NULL for these opcodes.
484a40a9998Schristos          * These opcodes are guaranteed to have a parent.
485a40a9998Schristos          * Examine the parent opcode.
486a40a9998Schristos          */
487a40a9998Schristos         ParentOp = Op->Asl.Parent;
488a40a9998Schristos         OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Asl.AmlOpcode);
489a40a9998Schristos 
490a40a9998Schristos         /*
491a40a9998Schristos          * Exclude all operators that actually declare a new name:
492a40a9998Schristos          *      Name (ABCD, 1) -> Ignore (AML_CLASS_NAMED_OBJECT)
493a40a9998Schristos          * We only want references to named objects:
494a40a9998Schristos          *      Store (2, WXYZ) -> Attempt to resolve the name
495a40a9998Schristos          */
496*9ddb8508Schristos         if ((Op->Asl.ParseOpcode != PARSEOP_METHODCALL) &&
497*9ddb8508Schristos             (OpInfo->Class == AML_CLASS_NAMED_OBJECT))
498a40a9998Schristos         {
499a40a9998Schristos             return (AE_OK);
500a40a9998Schristos         }
501a40a9998Schristos 
502a40a9998Schristos         /*
503a40a9998Schristos          * Check if the referenced object exists at this point during
504a40a9998Schristos          * the load:
505a40a9998Schristos          * 1) If it exists, then this cannot be a forward reference.
506a40a9998Schristos          * 2) If it does not exist, it could be a forward reference or
507a40a9998Schristos          * it truly does not exist (and no external declaration).
508a40a9998Schristos          */
509a40a9998Schristos         Status = AcpiNsLookup (WalkState->ScopeInfo,
510a40a9998Schristos             Op->Asl.Value.Name, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
511a40a9998Schristos             ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
512a40a9998Schristos             WalkState, &Node);
513a40a9998Schristos         if (Status == AE_NOT_FOUND)
514a40a9998Schristos         {
515a40a9998Schristos             /*
5165b948c02Schristos              * This is either a forward reference or the object truly
517a40a9998Schristos              * does not exist. The two cases can only be differentiated
518a40a9998Schristos              * during the cross-reference stage later. Mark the Op/Name
519a40a9998Schristos              * as not-found for now to indicate the need for further
520a40a9998Schristos              * processing.
521a40a9998Schristos              *
522a40a9998Schristos              * Special case: Allow forward references from elements of
523a40a9998Schristos              * Package objects. This provides compatibility with other
524a40a9998Schristos              * ACPI implementations. To correctly implement this, the
525a40a9998Schristos              * ACPICA table load defers package resolution until the entire
526a40a9998Schristos              * namespace has been loaded.
527a40a9998Schristos              */
528a40a9998Schristos             if ((ParentOp->Asl.ParseOpcode != PARSEOP_PACKAGE) &&
529a40a9998Schristos                 (ParentOp->Asl.ParseOpcode != PARSEOP_VAR_PACKAGE))
530a40a9998Schristos             {
531a40a9998Schristos                 Op->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD;
532a40a9998Schristos             }
533a40a9998Schristos 
534a40a9998Schristos             return (AE_OK);
535a40a9998Schristos         }
536a40a9998Schristos 
537a40a9998Schristos         return (Status);
538a40a9998Schristos     }
539a40a9998Schristos 
54028c506b8Sjruoho     Path = Op->Asl.Namepath;
54128c506b8Sjruoho     if (!Path)
54228c506b8Sjruoho     {
54328c506b8Sjruoho         return (AE_OK);
54428c506b8Sjruoho     }
54528c506b8Sjruoho 
54628c506b8Sjruoho     /* Map the raw opcode into an internal object type */
54728c506b8Sjruoho 
54828c506b8Sjruoho     switch (Op->Asl.ParseOpcode)
54928c506b8Sjruoho     {
55028c506b8Sjruoho     case PARSEOP_NAME:
55128c506b8Sjruoho 
55228c506b8Sjruoho         Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
55328c506b8Sjruoho         Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
55428c506b8Sjruoho 
55528c506b8Sjruoho         /*
55628c506b8Sjruoho          * If this name refers to a ResourceTemplate, we will need to open
55728c506b8Sjruoho          * a new scope so that the resource subfield names can be entered into
55828c506b8Sjruoho          * the namespace underneath this name
55928c506b8Sjruoho          */
560ae01dbf5Schristos         if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
56128c506b8Sjruoho         {
56228c506b8Sjruoho             ForceNewScope = TRUE;
56328c506b8Sjruoho         }
56428c506b8Sjruoho 
56528c506b8Sjruoho         /* Get the data type associated with the named object, not the name itself */
56628c506b8Sjruoho 
56728c506b8Sjruoho         /* Log2 loop to convert from Btype (binary) to Etype (encoded) */
56828c506b8Sjruoho 
56928c506b8Sjruoho         ObjectType = 1;
57028c506b8Sjruoho         for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2)
57128c506b8Sjruoho         {
57228c506b8Sjruoho             ObjectType++;
57328c506b8Sjruoho         }
57428c506b8Sjruoho         break;
57528c506b8Sjruoho 
57628c506b8Sjruoho     case PARSEOP_EXTERNAL:
57728c506b8Sjruoho         /*
57828c506b8Sjruoho          * "External" simply enters a name and type into the namespace.
57928c506b8Sjruoho          * We must be careful to not open a new scope, however, no matter
58028c506b8Sjruoho          * what type the external name refers to (e.g., a method)
58128c506b8Sjruoho          *
58228c506b8Sjruoho          * first child is name, next child is ObjectType
58328c506b8Sjruoho          */
58428c506b8Sjruoho         ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer;
58528c506b8Sjruoho         ObjectType = ACPI_TYPE_ANY;
58628c506b8Sjruoho 
58728c506b8Sjruoho         /*
58828c506b8Sjruoho          * We will mark every new node along the path as "External". This
58928c506b8Sjruoho          * allows some or all of the nodes to be created later in the ASL
59028c506b8Sjruoho          * code. Handles cases like this:
59128c506b8Sjruoho          *
59228c506b8Sjruoho          *   External (\_SB_.PCI0.ABCD, IntObj)
59328c506b8Sjruoho          *   Scope (_SB_)
59428c506b8Sjruoho          *   {
59528c506b8Sjruoho          *       Device (PCI0)
59628c506b8Sjruoho          *       {
59728c506b8Sjruoho          *       }
59828c506b8Sjruoho          *   }
59928c506b8Sjruoho          *   Method (X)
60028c506b8Sjruoho          *   {
60128c506b8Sjruoho          *       Store (\_SB_.PCI0.ABCD, Local0)
60228c506b8Sjruoho          *   }
60328c506b8Sjruoho          */
60428c506b8Sjruoho         Flags |= ACPI_NS_EXTERNAL;
60528c506b8Sjruoho         break;
60628c506b8Sjruoho 
60728c506b8Sjruoho     case PARSEOP_DEFAULT_ARG:
60828c506b8Sjruoho 
609ae01dbf5Schristos         if (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC)
61028c506b8Sjruoho         {
61128c506b8Sjruoho             Status = LdLoadResourceElements (Op, WalkState);
61228c506b8Sjruoho             return_ACPI_STATUS (Status);
61328c506b8Sjruoho         }
61428c506b8Sjruoho 
61528c506b8Sjruoho         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
61628c506b8Sjruoho         break;
61728c506b8Sjruoho 
61828c506b8Sjruoho     case PARSEOP_SCOPE:
61928c506b8Sjruoho         /*
62028c506b8Sjruoho          * The name referenced by Scope(Name) must already exist at this point.
62128c506b8Sjruoho          * In other words, forward references for Scope() are not supported.
62228c506b8Sjruoho          * The only real reason for this is that the MS interpreter cannot
62328c506b8Sjruoho          * handle this case. Perhaps someday this case can go away.
62428c506b8Sjruoho          */
62528c506b8Sjruoho         Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
6267efa3256Schristos             ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &Node);
62728c506b8Sjruoho         if (ACPI_FAILURE (Status))
62828c506b8Sjruoho         {
62928c506b8Sjruoho             if (Status == AE_NOT_FOUND)
63028c506b8Sjruoho             {
63128c506b8Sjruoho                 /* The name was not found, go ahead and create it */
63228c506b8Sjruoho 
63328c506b8Sjruoho                 Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
6347efa3256Schristos                     ACPI_TYPE_LOCAL_SCOPE, ACPI_IMODE_LOAD_PASS1,
6357efa3256Schristos                     Flags, WalkState, &Node);
636ff4a156dSchristos                 if (ACPI_FAILURE (Status))
637ff4a156dSchristos                 {
638ff4a156dSchristos                     return_ACPI_STATUS (Status);
639ff4a156dSchristos                 }
64028c506b8Sjruoho 
6417efa3256Schristos                 /* However, this is an error -- operand to Scope must exist */
6427efa3256Schristos 
6435b948c02Schristos                 if (strlen (Op->Asl.ExternalName) == ACPI_NAMESEG_SIZE)
6447efa3256Schristos                 {
64528c506b8Sjruoho                     AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
64628c506b8Sjruoho                         Op->Asl.ExternalName);
6477efa3256Schristos                 }
6487efa3256Schristos                 else
6497efa3256Schristos                 {
6507efa3256Schristos                     AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
65128c506b8Sjruoho                         Op->Asl.ExternalName);
6527efa3256Schristos                 }
6537efa3256Schristos 
65428c506b8Sjruoho                 goto FinishNode;
65528c506b8Sjruoho             }
65628c506b8Sjruoho 
65728c506b8Sjruoho             AslCoreSubsystemError (Op, Status,
65828c506b8Sjruoho                 "Failure from namespace lookup", FALSE);
65928c506b8Sjruoho 
66028c506b8Sjruoho             return_ACPI_STATUS (Status);
66128c506b8Sjruoho         }
66281bd9c9cSchristos         else /* Status AE_OK */
66381bd9c9cSchristos         {
66481bd9c9cSchristos             /*
66581bd9c9cSchristos              * Do not allow references to external scopes from the DSDT.
66681bd9c9cSchristos              * This is because the DSDT is always loaded first, and the
66781bd9c9cSchristos              * external reference cannot be resolved -- causing a runtime
66881bd9c9cSchristos              * error because Scope() must be resolved immediately.
66981bd9c9cSchristos              * 10/2015.
67081bd9c9cSchristos              */
67181bd9c9cSchristos             if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
6725b948c02Schristos                 (ACPI_COMPARE_NAMESEG (AslGbl_TableSignature, "DSDT")))
67381bd9c9cSchristos             {
67481bd9c9cSchristos                 /* However, allowed if the reference is within a method */
67581bd9c9cSchristos 
67681bd9c9cSchristos                 MethodOp = Op->Asl.Parent;
67781bd9c9cSchristos                 while (MethodOp &&
67881bd9c9cSchristos                       (MethodOp->Asl.ParseOpcode != PARSEOP_METHOD))
67981bd9c9cSchristos                 {
68081bd9c9cSchristos                     MethodOp = MethodOp->Asl.Parent;
68181bd9c9cSchristos                 }
68281bd9c9cSchristos 
68381bd9c9cSchristos                 if (!MethodOp)
68481bd9c9cSchristos                 {
68581bd9c9cSchristos                     /* Not in a control method, error */
68681bd9c9cSchristos 
68781bd9c9cSchristos                     AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL);
68881bd9c9cSchristos                 }
68981bd9c9cSchristos             }
69081bd9c9cSchristos         }
69128c506b8Sjruoho 
69228c506b8Sjruoho         /* We found a node with this name, now check the type */
69328c506b8Sjruoho 
69428c506b8Sjruoho         switch (Node->Type)
69528c506b8Sjruoho         {
69628c506b8Sjruoho         case ACPI_TYPE_LOCAL_SCOPE:
69728c506b8Sjruoho         case ACPI_TYPE_DEVICE:
69828c506b8Sjruoho         case ACPI_TYPE_POWER:
69928c506b8Sjruoho         case ACPI_TYPE_PROCESSOR:
70028c506b8Sjruoho         case ACPI_TYPE_THERMAL:
70128c506b8Sjruoho 
70228c506b8Sjruoho             /* These are acceptable types - they all open a new scope */
70328c506b8Sjruoho             break;
70428c506b8Sjruoho 
70528c506b8Sjruoho         case ACPI_TYPE_INTEGER:
70628c506b8Sjruoho         case ACPI_TYPE_STRING:
70728c506b8Sjruoho         case ACPI_TYPE_BUFFER:
70828c506b8Sjruoho             /*
70928c506b8Sjruoho              * These types we will allow, but we will change the type.
71028c506b8Sjruoho              * This enables some existing code of the form:
71128c506b8Sjruoho              *
71228c506b8Sjruoho              *  Name (DEB, 0)
71328c506b8Sjruoho              *  Scope (DEB) { ... }
71428c506b8Sjruoho              *
71528c506b8Sjruoho              * Which is used to workaround the fact that the MS interpreter
71628c506b8Sjruoho              * does not allow Scope() forward references.
71728c506b8Sjruoho              */
7187efa3256Schristos             snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s [%s], changing type to [Scope]",
71928c506b8Sjruoho                 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
7207efa3256Schristos             AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);
72128c506b8Sjruoho 
72228c506b8Sjruoho             /* Switch the type to scope, open the new scope */
72328c506b8Sjruoho 
72428c506b8Sjruoho             Node->Type = ACPI_TYPE_LOCAL_SCOPE;
72528c506b8Sjruoho             Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
72628c506b8Sjruoho                 WalkState);
72728c506b8Sjruoho             if (ACPI_FAILURE (Status))
72828c506b8Sjruoho             {
72928c506b8Sjruoho                 return_ACPI_STATUS (Status);
73028c506b8Sjruoho             }
73128c506b8Sjruoho             break;
73228c506b8Sjruoho 
73328c506b8Sjruoho         default:
73428c506b8Sjruoho 
73528c506b8Sjruoho             /* All other types are an error */
73628c506b8Sjruoho 
7377efa3256Schristos             snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s [%s]", Op->Asl.ExternalName,
73828c506b8Sjruoho                 AcpiUtGetTypeName (Node->Type));
7397efa3256Schristos             AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);
74028c506b8Sjruoho 
74128c506b8Sjruoho             /*
74228c506b8Sjruoho              * However, switch the type to be an actual scope so
74328c506b8Sjruoho              * that compilation can continue without generating a whole
74428c506b8Sjruoho              * cascade of additional errors. Open the new scope.
74528c506b8Sjruoho              */
74628c506b8Sjruoho             Node->Type = ACPI_TYPE_LOCAL_SCOPE;
74728c506b8Sjruoho             Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
74828c506b8Sjruoho                 WalkState);
74928c506b8Sjruoho             if (ACPI_FAILURE (Status))
75028c506b8Sjruoho             {
75128c506b8Sjruoho                 return_ACPI_STATUS (Status);
75228c506b8Sjruoho             }
75328c506b8Sjruoho             break;
75428c506b8Sjruoho         }
75528c506b8Sjruoho 
75628c506b8Sjruoho         Status = AE_OK;
75728c506b8Sjruoho         goto FinishNode;
75828c506b8Sjruoho 
75928c506b8Sjruoho     default:
76028c506b8Sjruoho 
76128c506b8Sjruoho         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
76228c506b8Sjruoho         break;
76328c506b8Sjruoho     }
76428c506b8Sjruoho 
76528c506b8Sjruoho     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n",
76628c506b8Sjruoho         Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType)));
76728c506b8Sjruoho 
76828c506b8Sjruoho     /* The name must not already exist */
76928c506b8Sjruoho 
77028c506b8Sjruoho     Flags |= ACPI_NS_ERROR_IF_FOUND;
77128c506b8Sjruoho 
77228c506b8Sjruoho     /*
7737efa3256Schristos      * For opcodes that enter new names into the namespace,
7747efa3256Schristos      * all prefix NameSegs must exist.
7757efa3256Schristos      */
7767efa3256Schristos     WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
7777efa3256Schristos     if (((WalkState->OpInfo->Flags & AML_NAMED) ||
7787efa3256Schristos         (WalkState->OpInfo->Flags & AML_CREATE)) &&
7797efa3256Schristos         (Op->Asl.AmlOpcode != AML_EXTERNAL_OP))
7807efa3256Schristos     {
7817efa3256Schristos         Flags |= ACPI_NS_PREFIX_MUST_EXIST;
7827efa3256Schristos     }
7837efa3256Schristos 
7847efa3256Schristos     /*
78528c506b8Sjruoho      * Enter the named type into the internal namespace. We enter the name
78628c506b8Sjruoho      * as we go downward in the parse tree. Any necessary subobjects that
78728c506b8Sjruoho      * involve arguments to the opcode must be created as we go back up the
78828c506b8Sjruoho      * parse tree later.
78928c506b8Sjruoho      */
79028c506b8Sjruoho     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
79128c506b8Sjruoho         ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
79228c506b8Sjruoho     if (ACPI_FAILURE (Status))
79328c506b8Sjruoho     {
79428c506b8Sjruoho         if (Status == AE_ALREADY_EXISTS)
79528c506b8Sjruoho         {
79628c506b8Sjruoho             /* The name already exists in this scope */
79728c506b8Sjruoho 
79828c506b8Sjruoho             if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
79928c506b8Sjruoho             {
80028c506b8Sjruoho                 /* Allow multiple references to the same scope */
80128c506b8Sjruoho 
80228c506b8Sjruoho                 Node->Type = (UINT8) ObjectType;
80328c506b8Sjruoho                 Status = AE_OK;
80428c506b8Sjruoho             }
805*9ddb8508Schristos             else if ((Node->Flags & ANOBJ_IS_EXTERNAL) ||
80681bd9c9cSchristos                      (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
80781bd9c9cSchristos             {
808*9ddb8508Schristos                 Status = LdAnalyzeExternals (Node, Op, ActualObjectType,
809*9ddb8508Schristos                     ObjectType, WalkState);
810*9ddb8508Schristos                 if (ACPI_FAILURE (Status))
811*9ddb8508Schristos                 {
812*9ddb8508Schristos                     if (Status == AE_ERROR)
813*9ddb8508Schristos                     {
81481bd9c9cSchristos                         /*
815*9ddb8508Schristos                          * The use of AE_ERROR here indicates that there was a
816*9ddb8508Schristos                          * compiler error emitted in LdAnalyzeExternals which
817*9ddb8508Schristos                          * means that the caller should proceed to the next Op
818*9ddb8508Schristos                          * for analysis of subsequent parse objects.
81981bd9c9cSchristos                          */
82028c506b8Sjruoho                         Status = AE_OK;
82128c506b8Sjruoho                     }
822*9ddb8508Schristos                     return_ACPI_STATUS (Status);
82349c2f1f4Schristos                 }
82449c2f1f4Schristos             }
82528c506b8Sjruoho             else
82628c506b8Sjruoho             {
82728c506b8Sjruoho                 /* Valid error, object already exists */
82828c506b8Sjruoho 
829*9ddb8508Schristos                 ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);
830*9ddb8508Schristos 
83125666a51Schristos                 AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
832*9ddb8508Schristos                     ExternalPath, ASL_MSG_FOUND_HERE, Node->Op,
833*9ddb8508Schristos                     ExternalPath);
834*9ddb8508Schristos 
835*9ddb8508Schristos                 if (ExternalPath)
836*9ddb8508Schristos                 {
837*9ddb8508Schristos                     ACPI_FREE (ExternalPath);
838*9ddb8508Schristos                 }
83928c506b8Sjruoho                 return_ACPI_STATUS (AE_OK);
84028c506b8Sjruoho             }
84128c506b8Sjruoho         }
8427efa3256Schristos         else if (AE_NOT_FOUND)
8437efa3256Schristos         {
8447efa3256Schristos             /*
8457efa3256Schristos              * One or more prefix NameSegs of the NamePath do not exist
8467efa3256Schristos              * (all of them must exist). Attempt to continue compilation
8477efa3256Schristos              * by setting the current scope to the root.
8487efa3256Schristos              */
8497efa3256Schristos             Node = AcpiGbl_RootNode;
8507efa3256Schristos             Status = AE_OK;
8517efa3256Schristos         }
85228c506b8Sjruoho         else
85328c506b8Sjruoho         {
8547efa3256Schristos             /* Flag all other errors as coming from the ACPICA core */
8557efa3256Schristos 
85628c506b8Sjruoho             AslCoreSubsystemError (Op, Status,
85728c506b8Sjruoho                 "Failure from namespace lookup", FALSE);
85828c506b8Sjruoho             return_ACPI_STATUS (Status);
85928c506b8Sjruoho         }
86028c506b8Sjruoho     }
86128c506b8Sjruoho 
8627ab6b89bSchristos     /* Check special names like _WAK and _PTS */
8637ab6b89bSchristos 
8647ab6b89bSchristos     LdCheckSpecialNames (Node, Op);
8657ab6b89bSchristos 
86628c506b8Sjruoho     if (ForceNewScope)
86728c506b8Sjruoho     {
86828c506b8Sjruoho         Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
86928c506b8Sjruoho         if (ACPI_FAILURE (Status))
87028c506b8Sjruoho         {
87128c506b8Sjruoho             return_ACPI_STATUS (Status);
87228c506b8Sjruoho         }
87328c506b8Sjruoho     }
87428c506b8Sjruoho 
87528c506b8Sjruoho FinishNode:
87628c506b8Sjruoho     /*
87728c506b8Sjruoho      * Point the parse node to the new namespace node, and point
87828c506b8Sjruoho      * the Node back to the original Parse node
87928c506b8Sjruoho      */
88028c506b8Sjruoho     Op->Asl.Node = Node;
88128c506b8Sjruoho     Node->Op = Op;
88228c506b8Sjruoho 
8831c663068Schristos     /*
8841c663068Schristos      * Set the actual data type if appropriate (EXTERNAL term only)
8851c663068Schristos      * As of 11/19/2019, ASL External() does not support parameter
8861c663068Schristos      * counts. When an External method is loaded, the parameter count is
887*9ddb8508Schristos      * recorded in the external's arg count parameter. The parameter count may
888*9ddb8508Schristos      * or may not be known in the declaration. If the value of this node turns
889*9ddb8508Schristos      * out to be ASL_EXTERNAL_METHOD_UNKNOWN_PARAMS, it indicates that
890*9ddb8508Schristos      * we do not know the parameter count and that we must look at the usage of
891*9ddb8508Schristos      * the External method call to get this information.
8921c663068Schristos      */
89328c506b8Sjruoho     if (ActualObjectType != ACPI_TYPE_ANY)
89428c506b8Sjruoho     {
89528c506b8Sjruoho         Node->Type = (UINT8) ActualObjectType;
896*9ddb8508Schristos         Node->Value = (UINT32)
897*9ddb8508Schristos             Op->Asl.Child->Asl.Next->Asl.Next->Asl.Value.Integer;
89828c506b8Sjruoho     }
89928c506b8Sjruoho 
90028c506b8Sjruoho     if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
90128c506b8Sjruoho     {
90228c506b8Sjruoho         /*
90328c506b8Sjruoho          * Get the method argument count from "Extra" and save
90428c506b8Sjruoho          * it in the namespace node
90528c506b8Sjruoho          */
90628c506b8Sjruoho         Node->Value = (UINT32) Op->Asl.Extra;
90728c506b8Sjruoho     }
90828c506b8Sjruoho 
90928c506b8Sjruoho     return_ACPI_STATUS (Status);
91028c506b8Sjruoho }
91128c506b8Sjruoho 
91228c506b8Sjruoho 
91328c506b8Sjruoho /*******************************************************************************
91428c506b8Sjruoho  *
915*9ddb8508Schristos  * FUNCTION:    LdAnalyzeExternals
916*9ddb8508Schristos  *
917*9ddb8508Schristos  * PARAMETERS:  Type1
918*9ddb8508Schristos  *              Type2
919*9ddb8508Schristos  *
920*9ddb8508Schristos  * RETURN:      BOOLEAN
921*9ddb8508Schristos  *
922*9ddb8508Schristos  * DESCRIPTION: Match Type1 and Type2 with the assumption that one might be
923*9ddb8508Schristos  *              using external types and another might be using local types.
924*9ddb8508Schristos  *              This should be used to compare the types found in external
925*9ddb8508Schristos  *              declarations with types found in other external declarations or
926*9ddb8508Schristos  *              named object declaration. This should not be used to match two
927*9ddb8508Schristos  *              object type declarations.
928*9ddb8508Schristos  *
929*9ddb8508Schristos  ******************************************************************************/
930*9ddb8508Schristos 
931*9ddb8508Schristos static BOOLEAN
932*9ddb8508Schristos LdTypesMatchExternType (
933*9ddb8508Schristos     ACPI_OBJECT_TYPE        Type1,
934*9ddb8508Schristos     ACPI_OBJECT_TYPE        Type2)
935*9ddb8508Schristos {
936*9ddb8508Schristos     BOOLEAN                 Type1IsLocal = Type1 > ACPI_TYPE_EXTERNAL_MAX;
937*9ddb8508Schristos     BOOLEAN                 Type2IsLocal = Type2 > ACPI_TYPE_EXTERNAL_MAX;
938*9ddb8508Schristos     ACPI_OBJECT_TYPE        ExternalType;
939*9ddb8508Schristos     ACPI_OBJECT_TYPE        LocalType;
940*9ddb8508Schristos 
941*9ddb8508Schristos 
942*9ddb8508Schristos     /*
943*9ddb8508Schristos      * The inputs could represent types that are local to ACPICA or types that
944*9ddb8508Schristos      * are known externally. Some local types, such as the OperationRegion
945*9ddb8508Schristos      * field units, are defined with more granularity than ACPICA local types.
946*9ddb8508Schristos      *
947*9ddb8508Schristos      * Therefore, map the local types to the external types before matching.
948*9ddb8508Schristos      */
949*9ddb8508Schristos     if (Type1IsLocal && !Type2IsLocal)
950*9ddb8508Schristos     {
951*9ddb8508Schristos         LocalType = Type1;
952*9ddb8508Schristos         ExternalType = Type2;
953*9ddb8508Schristos     }
954*9ddb8508Schristos     else if (!Type1IsLocal && Type2IsLocal)
955*9ddb8508Schristos     {
956*9ddb8508Schristos         LocalType = Type2;
957*9ddb8508Schristos         ExternalType = Type1;
958*9ddb8508Schristos     }
959*9ddb8508Schristos     else
960*9ddb8508Schristos     {
961*9ddb8508Schristos         return (Type1 == Type2);
962*9ddb8508Schristos     }
963*9ddb8508Schristos 
964*9ddb8508Schristos     switch (LocalType)
965*9ddb8508Schristos     {
966*9ddb8508Schristos         case ACPI_TYPE_LOCAL_REGION_FIELD:
967*9ddb8508Schristos         case ACPI_TYPE_LOCAL_BANK_FIELD:
968*9ddb8508Schristos         case ACPI_TYPE_LOCAL_INDEX_FIELD:
969*9ddb8508Schristos 
970*9ddb8508Schristos             LocalType = ACPI_TYPE_FIELD_UNIT;
971*9ddb8508Schristos             break;
972*9ddb8508Schristos 
973*9ddb8508Schristos         default:
974*9ddb8508Schristos             break;
975*9ddb8508Schristos     }
976*9ddb8508Schristos 
977*9ddb8508Schristos     return (LocalType == ExternalType);
978*9ddb8508Schristos }
979*9ddb8508Schristos 
980*9ddb8508Schristos 
981*9ddb8508Schristos /*******************************************************************************
982*9ddb8508Schristos  *
983*9ddb8508Schristos  * FUNCTION:    LdAnalyzeExternals
984*9ddb8508Schristos  *
985*9ddb8508Schristos  * PARAMETERS:  Node            - Node that represents the named object
986*9ddb8508Schristos  *              Op              - Named object declaring this named object
987*9ddb8508Schristos  *              ExternalOpType  - Type of ExternalOp
988*9ddb8508Schristos  *              ObjectType      - Type of Declared object
989*9ddb8508Schristos  *              WalkState       - Current WalkState
990*9ddb8508Schristos  *
991*9ddb8508Schristos  * RETURN:      Status
992*9ddb8508Schristos  *
993*9ddb8508Schristos  * DESCRIPTION: Node and Op represents an identically named object declaration
994*9ddb8508Schristos  *              that is either declared by the ASL external keyword or declared
995*9ddb8508Schristos  *              by operators that declare named objects (i.e. Name, Device,
996*9ddb8508Schristos  *              OperationRegion, and etc.). This function ensures that the
997*9ddb8508Schristos  *              declarations do not contradict each other.
998*9ddb8508Schristos  *
999*9ddb8508Schristos  ******************************************************************************/
1000*9ddb8508Schristos 
1001*9ddb8508Schristos static ACPI_STATUS
1002*9ddb8508Schristos LdAnalyzeExternals (
1003*9ddb8508Schristos     ACPI_NAMESPACE_NODE     *Node,
1004*9ddb8508Schristos     ACPI_PARSE_OBJECT       *Op,
1005*9ddb8508Schristos     ACPI_OBJECT_TYPE        ExternalOpType,
1006*9ddb8508Schristos     ACPI_OBJECT_TYPE        ObjectType,
1007*9ddb8508Schristos     ACPI_WALK_STATE         *WalkState)
1008*9ddb8508Schristos {
1009*9ddb8508Schristos     ACPI_STATUS             Status = AE_OK;
1010*9ddb8508Schristos     ACPI_OBJECT_TYPE        ActualExternalOpType;
1011*9ddb8508Schristos     ACPI_OBJECT_TYPE        ActualOpType;
1012*9ddb8508Schristos     ACPI_PARSE_OBJECT       *ExternalOp;
1013*9ddb8508Schristos     ACPI_PARSE_OBJECT       *ActualOp;
1014*9ddb8508Schristos 
1015*9ddb8508Schristos 
1016*9ddb8508Schristos     /*
1017*9ddb8508Schristos      * The declaration represented by Node and Op must have the same type.
1018*9ddb8508Schristos      * The type of the external Op is represented by ExternalOpType. However,
1019*9ddb8508Schristos      * the type of the pre-existing declaration depends on whether if Op
1020*9ddb8508Schristos      * is an external declaration or an actual declaration.
1021*9ddb8508Schristos      */
1022*9ddb8508Schristos     if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)
1023*9ddb8508Schristos     {
1024*9ddb8508Schristos         ActualExternalOpType = ExternalOpType;
1025*9ddb8508Schristos         ActualOpType = Node->Type;
1026*9ddb8508Schristos     }
1027*9ddb8508Schristos     else
1028*9ddb8508Schristos     {
1029*9ddb8508Schristos         ActualExternalOpType = Node->Type;
1030*9ddb8508Schristos         ActualOpType = ObjectType;
1031*9ddb8508Schristos     }
1032*9ddb8508Schristos 
1033*9ddb8508Schristos     if ((ActualOpType != ACPI_TYPE_ANY) &&
1034*9ddb8508Schristos         (ActualExternalOpType != ACPI_TYPE_ANY) &&
1035*9ddb8508Schristos         !LdTypesMatchExternType (ActualExternalOpType, ActualOpType))
1036*9ddb8508Schristos     {
1037*9ddb8508Schristos         if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL &&
1038*9ddb8508Schristos             Node->Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)
1039*9ddb8508Schristos         {
1040*9ddb8508Schristos             AslDualParseOpError (ASL_WARNING,
1041*9ddb8508Schristos                 ASL_MSG_DUPLICATE_EXTERN_MISMATCH, Op, NULL,
1042*9ddb8508Schristos                 ASL_MSG_DUPLICATE_EXTERN_FOUND_HERE, Node->Op, NULL);
1043*9ddb8508Schristos         }
1044*9ddb8508Schristos         else
1045*9ddb8508Schristos         {
1046*9ddb8508Schristos             if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL &&
1047*9ddb8508Schristos                 Node->Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)
1048*9ddb8508Schristos             {
1049*9ddb8508Schristos                 ExternalOp = Op;
1050*9ddb8508Schristos                 ActualOp = Node->Op;
1051*9ddb8508Schristos             }
1052*9ddb8508Schristos             else
1053*9ddb8508Schristos             {
1054*9ddb8508Schristos                 ExternalOp = Node->Op;
1055*9ddb8508Schristos                 ActualOp = Op;
1056*9ddb8508Schristos             }
1057*9ddb8508Schristos             AslDualParseOpError (ASL_WARNING,
1058*9ddb8508Schristos                 ASL_MSG_DECLARATION_TYPE_MISMATCH, ExternalOp, NULL,
1059*9ddb8508Schristos                 ASL_MSG_TYPE_MISMATCH_FOUND_HERE, ActualOp, NULL);
1060*9ddb8508Schristos         }
1061*9ddb8508Schristos     }
1062*9ddb8508Schristos 
1063*9ddb8508Schristos     if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
1064*9ddb8508Schristos         (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
1065*9ddb8508Schristos     {
1066*9ddb8508Schristos         /*
1067*9ddb8508Schristos          * Allow one create on an object or segment that was
1068*9ddb8508Schristos          * previously declared External
1069*9ddb8508Schristos          */
1070*9ddb8508Schristos         Node->Flags &= ~ANOBJ_IS_EXTERNAL;
1071*9ddb8508Schristos         Node->Type = (UINT8) ObjectType;
1072*9ddb8508Schristos 
1073*9ddb8508Schristos         /* Just retyped a node, probably will need to open a scope */
1074*9ddb8508Schristos 
1075*9ddb8508Schristos         if (AcpiNsOpensScope (ObjectType))
1076*9ddb8508Schristos         {
1077*9ddb8508Schristos             Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
1078*9ddb8508Schristos             if (ACPI_FAILURE (Status))
1079*9ddb8508Schristos             {
1080*9ddb8508Schristos                 return (Status);
1081*9ddb8508Schristos             }
1082*9ddb8508Schristos         }
1083*9ddb8508Schristos 
1084*9ddb8508Schristos         Status = AE_OK;
1085*9ddb8508Schristos     }
1086*9ddb8508Schristos     else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) &&
1087*9ddb8508Schristos              (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
1088*9ddb8508Schristos     {
1089*9ddb8508Schristos         /*
1090*9ddb8508Schristos          * Allow externals in same scope as the definition of the
1091*9ddb8508Schristos          * actual object. Similar to C. Allows multiple definition
1092*9ddb8508Schristos          * blocks that refer to each other in the same file.
1093*9ddb8508Schristos          */
1094*9ddb8508Schristos         Status = AE_OK;
1095*9ddb8508Schristos     }
1096*9ddb8508Schristos     else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
1097*9ddb8508Schristos              (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) &&
1098*9ddb8508Schristos              (ObjectType == ACPI_TYPE_ANY))
1099*9ddb8508Schristos     {
1100*9ddb8508Schristos         /* Allow update of externals of unknown type. */
1101*9ddb8508Schristos 
1102*9ddb8508Schristos         Node->Type = (UINT8) ExternalOpType;
1103*9ddb8508Schristos         Status = AE_OK;
1104*9ddb8508Schristos     }
1105*9ddb8508Schristos 
1106*9ddb8508Schristos     return (Status);
1107*9ddb8508Schristos }
1108*9ddb8508Schristos 
1109*9ddb8508Schristos 
1110*9ddb8508Schristos /*******************************************************************************
1111*9ddb8508Schristos  *
11127ab6b89bSchristos  * FUNCTION:    LdCheckSpecialNames
11137ab6b89bSchristos  *
11147ab6b89bSchristos  * PARAMETERS:  Node        - Node that represents the named object
11157ab6b89bSchristos  *              Op          - Named object declaring this named object
11167ab6b89bSchristos  *
11177ab6b89bSchristos  * RETURN:      None
11187ab6b89bSchristos  *
11197ab6b89bSchristos  * DESCRIPTION: Check if certain named objects are declared in the incorrect
11207ab6b89bSchristos  *              scope. Special named objects are listed in
11217ab6b89bSchristos  *              AslGbl_SpecialNamedObjects and can only be declared at the root
11227ab6b89bSchristos  *              scope. _UID inside of a processor declaration must not be a
11237ab6b89bSchristos  *              string.
11247ab6b89bSchristos  *
11257ab6b89bSchristos  ******************************************************************************/
11267ab6b89bSchristos 
11277ab6b89bSchristos static void
11287ab6b89bSchristos LdCheckSpecialNames (
11297ab6b89bSchristos     ACPI_NAMESPACE_NODE     *Node,
11307ab6b89bSchristos     ACPI_PARSE_OBJECT       *Op)
11317ab6b89bSchristos {
11327ab6b89bSchristos     UINT32                  i;
11337ab6b89bSchristos 
11347ab6b89bSchristos 
11357ab6b89bSchristos     for (i = 0; i < MAX_SPECIAL_NAMES; i++)
11367ab6b89bSchristos     {
11377ab6b89bSchristos         if (ACPI_COMPARE_NAMESEG(Node->Name.Ascii, AslGbl_SpecialNamedObjects[i]) &&
11387ab6b89bSchristos             Node->Parent != AcpiGbl_RootNode)
11397ab6b89bSchristos         {
11407ab6b89bSchristos             AslError (ASL_ERROR, ASL_MSG_INVALID_SPECIAL_NAME, Op, Op->Asl.ExternalName);
11417ab6b89bSchristos             return;
11427ab6b89bSchristos         }
11437ab6b89bSchristos     }
11447ab6b89bSchristos 
11457ab6b89bSchristos     if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, "_UID") &&
11467ab6b89bSchristos         Node->Parent->Type == ACPI_TYPE_PROCESSOR &&
11477ab6b89bSchristos         Node->Type == ACPI_TYPE_STRING)
11487ab6b89bSchristos     {
11497ab6b89bSchristos         AslError (ASL_ERROR, ASL_MSG_INVALID_PROCESSOR_UID , Op, "found a string");
11507ab6b89bSchristos     }
11517ab6b89bSchristos }
11527ab6b89bSchristos 
11537ab6b89bSchristos 
11547ab6b89bSchristos /*******************************************************************************
11557ab6b89bSchristos  *
115628c506b8Sjruoho  * FUNCTION:    LdNamespace2Begin
115728c506b8Sjruoho  *
115828c506b8Sjruoho  * PARAMETERS:  ASL_WALK_CALLBACK
115928c506b8Sjruoho  *
116028c506b8Sjruoho  * RETURN:      Status
116128c506b8Sjruoho  *
116228c506b8Sjruoho  * DESCRIPTION: Descending callback used during the pass 2 parse tree walk.
116328c506b8Sjruoho  *              Second pass resolves some forward references.
116428c506b8Sjruoho  *
116528c506b8Sjruoho  * Notes:
116628c506b8Sjruoho  * Currently only needs to handle the Alias operator.
116728c506b8Sjruoho  * Could be used to allow forward references from the Scope() operator, but
116828c506b8Sjruoho  * the MS interpreter does not allow this, so this compiler does not either.
116928c506b8Sjruoho  *
117028c506b8Sjruoho  ******************************************************************************/
117128c506b8Sjruoho 
117228c506b8Sjruoho static ACPI_STATUS
117328c506b8Sjruoho LdNamespace2Begin (
117428c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
117528c506b8Sjruoho     UINT32                  Level,
117628c506b8Sjruoho     void                    *Context)
117728c506b8Sjruoho {
117828c506b8Sjruoho     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
117928c506b8Sjruoho     ACPI_STATUS             Status;
118028c506b8Sjruoho     ACPI_NAMESPACE_NODE     *Node;
118128c506b8Sjruoho     ACPI_OBJECT_TYPE        ObjectType;
118228c506b8Sjruoho     BOOLEAN                 ForceNewScope = FALSE;
118328c506b8Sjruoho     ACPI_PARSE_OBJECT       *Arg;
118428c506b8Sjruoho     char                    *Path;
118528c506b8Sjruoho     ACPI_NAMESPACE_NODE     *TargetNode;
118628c506b8Sjruoho 
118728c506b8Sjruoho 
118828c506b8Sjruoho     ACPI_FUNCTION_NAME (LdNamespace2Begin);
118928c506b8Sjruoho     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
119028c506b8Sjruoho         Op, Op->Asl.ParseOpName));
119128c506b8Sjruoho 
119228c506b8Sjruoho 
119328c506b8Sjruoho     /* Ignore Ops with no namespace node */
119428c506b8Sjruoho 
119528c506b8Sjruoho     Node = Op->Asl.Node;
119628c506b8Sjruoho     if (!Node)
119728c506b8Sjruoho     {
119828c506b8Sjruoho         return (AE_OK);
119928c506b8Sjruoho     }
120028c506b8Sjruoho 
120128c506b8Sjruoho     /* Get the type to determine if we should push the scope */
120228c506b8Sjruoho 
120328c506b8Sjruoho     if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
1204ae01dbf5Schristos         (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC))
120528c506b8Sjruoho     {
120628c506b8Sjruoho         ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
120728c506b8Sjruoho     }
120828c506b8Sjruoho     else
120928c506b8Sjruoho     {
121028c506b8Sjruoho         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
121128c506b8Sjruoho     }
121228c506b8Sjruoho 
121328c506b8Sjruoho     /* Push scope for Resource Templates */
121428c506b8Sjruoho 
121528c506b8Sjruoho     if (Op->Asl.ParseOpcode == PARSEOP_NAME)
121628c506b8Sjruoho     {
1217ae01dbf5Schristos         if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
121828c506b8Sjruoho         {
121928c506b8Sjruoho             ForceNewScope = TRUE;
122028c506b8Sjruoho         }
122128c506b8Sjruoho     }
122228c506b8Sjruoho 
122328c506b8Sjruoho     /* Push the scope stack */
122428c506b8Sjruoho 
122528c506b8Sjruoho     if (ForceNewScope || AcpiNsOpensScope (ObjectType))
122628c506b8Sjruoho     {
122728c506b8Sjruoho         Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
122828c506b8Sjruoho         if (ACPI_FAILURE (Status))
122928c506b8Sjruoho         {
123028c506b8Sjruoho             return_ACPI_STATUS (Status);
123128c506b8Sjruoho         }
123228c506b8Sjruoho     }
123328c506b8Sjruoho 
123428c506b8Sjruoho     if (Op->Asl.ParseOpcode == PARSEOP_ALIAS)
123528c506b8Sjruoho     {
12367efa3256Schristos         /*
12377efa3256Schristos          * Complete the alias node by getting and saving the target node.
12387efa3256Schristos          * First child is the alias target
12397efa3256Schristos          */
124028c506b8Sjruoho         Arg = Op->Asl.Child;
124128c506b8Sjruoho 
124228c506b8Sjruoho         /* Get the target pathname */
124328c506b8Sjruoho 
124428c506b8Sjruoho         Path = Arg->Asl.Namepath;
124528c506b8Sjruoho         if (!Path)
124628c506b8Sjruoho         {
124728c506b8Sjruoho             Status = UtInternalizeName (Arg->Asl.ExternalName, &Path);
124828c506b8Sjruoho             if (ACPI_FAILURE (Status))
124928c506b8Sjruoho             {
125028c506b8Sjruoho                 return (Status);
125128c506b8Sjruoho             }
125228c506b8Sjruoho         }
125328c506b8Sjruoho 
125428c506b8Sjruoho         /* Get the NS node associated with the target. It must exist. */
125528c506b8Sjruoho 
125628c506b8Sjruoho         Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
125728c506b8Sjruoho             ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
125828c506b8Sjruoho             WalkState, &TargetNode);
125928c506b8Sjruoho         if (ACPI_FAILURE (Status))
126028c506b8Sjruoho         {
126128c506b8Sjruoho             if (Status == AE_NOT_FOUND)
126228c506b8Sjruoho             {
12637efa3256Schristos                 /* Standalone NameSeg vs. NamePath */
126428c506b8Sjruoho 
12655b948c02Schristos                 if (strlen (Arg->Asl.ExternalName) == ACPI_NAMESEG_SIZE)
12667efa3256Schristos                 {
12677efa3256Schristos                     AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
12687efa3256Schristos                         Arg->Asl.ExternalName);
12697efa3256Schristos                 }
12707efa3256Schristos                 else
12717efa3256Schristos                 {
12727efa3256Schristos                     AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
12737efa3256Schristos                         Arg->Asl.ExternalName);
12747efa3256Schristos                 }
12757efa3256Schristos 
12767efa3256Schristos #if 0
12777efa3256Schristos /*
12787efa3256Schristos  * NOTE: Removed 10/2018 to enhance compiler error reporting. No
12797efa3256Schristos  * regressions seen.
12807efa3256Schristos  */
128128c506b8Sjruoho                 /*
128228c506b8Sjruoho                  * The name was not found, go ahead and create it.
128328c506b8Sjruoho                  * This prevents more errors later.
128428c506b8Sjruoho                  */
128528c506b8Sjruoho                 Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
12867efa3256Schristos                     ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
12877efa3256Schristos                     ACPI_NS_NO_UPSEARCH, WalkState, &Node);
12887efa3256Schristos #endif
12897efa3256Schristos                 return (Status);
12907efa3256Schristos /* Removed: return (AE_OK)*/
129128c506b8Sjruoho             }
129228c506b8Sjruoho 
129328c506b8Sjruoho             AslCoreSubsystemError (Op, Status,
129428c506b8Sjruoho                 "Failure from namespace lookup", FALSE);
129528c506b8Sjruoho             return (AE_OK);
129628c506b8Sjruoho         }
129728c506b8Sjruoho 
129828c506b8Sjruoho         /* Save the target node within the alias node */
129928c506b8Sjruoho 
130028c506b8Sjruoho         Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
130128c506b8Sjruoho     }
130228c506b8Sjruoho 
130328c506b8Sjruoho     return (AE_OK);
130428c506b8Sjruoho }
130528c506b8Sjruoho 
130628c506b8Sjruoho 
130728c506b8Sjruoho /*******************************************************************************
130828c506b8Sjruoho  *
130928c506b8Sjruoho  * FUNCTION:    LdCommonNamespaceEnd
131028c506b8Sjruoho  *
131128c506b8Sjruoho  * PARAMETERS:  ASL_WALK_CALLBACK
131228c506b8Sjruoho  *
131328c506b8Sjruoho  * RETURN:      Status
131428c506b8Sjruoho  *
131528c506b8Sjruoho  * DESCRIPTION: Ascending callback used during the loading of the namespace,
131628c506b8Sjruoho  *              We only need to worry about managing the scope stack here.
131728c506b8Sjruoho  *
131828c506b8Sjruoho  ******************************************************************************/
131928c506b8Sjruoho 
132028c506b8Sjruoho static ACPI_STATUS
132128c506b8Sjruoho LdCommonNamespaceEnd (
132228c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
132328c506b8Sjruoho     UINT32                  Level,
132428c506b8Sjruoho     void                    *Context)
132528c506b8Sjruoho {
132628c506b8Sjruoho     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
132728c506b8Sjruoho     ACPI_OBJECT_TYPE        ObjectType;
132828c506b8Sjruoho     BOOLEAN                 ForceNewScope = FALSE;
132928c506b8Sjruoho 
133028c506b8Sjruoho 
133128c506b8Sjruoho     ACPI_FUNCTION_NAME (LdCommonNamespaceEnd);
133228c506b8Sjruoho 
133328c506b8Sjruoho 
133428c506b8Sjruoho     /* We are only interested in opcodes that have an associated name */
133528c506b8Sjruoho 
133628c506b8Sjruoho     if (!Op->Asl.Namepath)
133728c506b8Sjruoho     {
133828c506b8Sjruoho         return (AE_OK);
133928c506b8Sjruoho     }
134028c506b8Sjruoho 
134128c506b8Sjruoho     /* Get the type to determine if we should pop the scope */
134228c506b8Sjruoho 
134328c506b8Sjruoho     if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
1344ae01dbf5Schristos         (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC))
134528c506b8Sjruoho     {
134628c506b8Sjruoho         /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */
134728c506b8Sjruoho 
134828c506b8Sjruoho         ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
134928c506b8Sjruoho     }
135028c506b8Sjruoho     else
135128c506b8Sjruoho     {
135228c506b8Sjruoho         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
135328c506b8Sjruoho     }
135428c506b8Sjruoho 
135528c506b8Sjruoho     /* Pop scope that was pushed for Resource Templates */
135628c506b8Sjruoho 
135728c506b8Sjruoho     if (Op->Asl.ParseOpcode == PARSEOP_NAME)
135828c506b8Sjruoho     {
1359ae01dbf5Schristos         if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
136028c506b8Sjruoho         {
136128c506b8Sjruoho             ForceNewScope = TRUE;
136228c506b8Sjruoho         }
136328c506b8Sjruoho     }
136428c506b8Sjruoho 
136528c506b8Sjruoho     /* Pop the scope stack */
136628c506b8Sjruoho 
136728c506b8Sjruoho     if (ForceNewScope || AcpiNsOpensScope (ObjectType))
136828c506b8Sjruoho     {
136928c506b8Sjruoho         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
137028c506b8Sjruoho             "(%s): Popping scope for Op [%s] %p\n",
137128c506b8Sjruoho             AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op));
137228c506b8Sjruoho 
137328c506b8Sjruoho         (void) AcpiDsScopeStackPop (WalkState);
137428c506b8Sjruoho     }
137528c506b8Sjruoho 
137628c506b8Sjruoho     return (AE_OK);
137728c506b8Sjruoho }
1378