xref: /freebsd/sys/contrib/dev/acpica/compiler/aslload.c (revision 030a1f8ba2e2873195454e5fbd4da6123b0b57a0)
1  /******************************************************************************
2   *
3   * Module Name: dswload - Dispatcher namespace load callbacks
4   *
5   *****************************************************************************/
6  
7  /******************************************************************************
8   *
9   * 1. Copyright Notice
10   *
11   * Some or all of this work - Copyright (c) 1999 - 2019, Intel Corp.
12   * All rights reserved.
13   *
14   * 2. License
15   *
16   * 2.1. This is your license from Intel Corp. under its intellectual property
17   * rights. You may have additional license terms from the party that provided
18   * you this software, covering your right to use that party's intellectual
19   * property rights.
20   *
21   * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22   * copy of the source code appearing in this file ("Covered Code") an
23   * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24   * base code distributed originally by Intel ("Original Intel Code") to copy,
25   * make derivatives, distribute, use and display any portion of the Covered
26   * Code in any form, with the right to sublicense such rights; and
27   *
28   * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29   * license (with the right to sublicense), under only those claims of Intel
30   * patents that are infringed by the Original Intel Code, to make, use, sell,
31   * offer to sell, and import the Covered Code and derivative works thereof
32   * solely to the minimum extent necessary to exercise the above copyright
33   * license, and in no event shall the patent license extend to any additions
34   * to or modifications of the Original Intel Code. No other license or right
35   * is granted directly or by implication, estoppel or otherwise;
36   *
37   * The above copyright and patent license is granted only if the following
38   * conditions are met:
39   *
40   * 3. Conditions
41   *
42   * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43   * Redistribution of source code of any substantial portion of the Covered
44   * Code or modification with rights to further distribute source must include
45   * the above Copyright Notice, the above License, this list of Conditions,
46   * and the following Disclaimer and Export Compliance provision. In addition,
47   * Licensee must cause all Covered Code to which Licensee contributes to
48   * contain a file documenting the changes Licensee made to create that Covered
49   * Code and the date of any change. Licensee must include in that file the
50   * documentation of any changes made by any predecessor Licensee. Licensee
51   * must include a prominent statement that the modification is derived,
52   * directly or indirectly, from Original Intel Code.
53   *
54   * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55   * Redistribution of source code of any substantial portion of the Covered
56   * Code or modification without rights to further distribute source must
57   * include the following Disclaimer and Export Compliance provision in the
58   * documentation and/or other materials provided with distribution. In
59   * addition, Licensee may not authorize further sublicense of source of any
60   * portion of the Covered Code, and must include terms to the effect that the
61   * license from Licensee to its licensee is limited to the intellectual
62   * property embodied in the software Licensee provides to its licensee, and
63   * not to intellectual property embodied in modifications its licensee may
64   * make.
65   *
66   * 3.3. Redistribution of Executable. Redistribution in executable form of any
67   * substantial portion of the Covered Code or modification must reproduce the
68   * above Copyright Notice, and the following Disclaimer and Export Compliance
69   * provision in the documentation and/or other materials provided with the
70   * distribution.
71   *
72   * 3.4. Intel retains all right, title, and interest in and to the Original
73   * Intel Code.
74   *
75   * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76   * Intel shall be used in advertising or otherwise to promote the sale, use or
77   * other dealings in products derived from or relating to the Covered Code
78   * without prior written authorization from Intel.
79   *
80   * 4. Disclaimer and Export Compliance
81   *
82   * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83   * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84   * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85   * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86   * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87   * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88   * PARTICULAR PURPOSE.
89   *
90   * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91   * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92   * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93   * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94   * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95   * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96   * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97   * LIMITED REMEDY.
98   *
99   * 4.3. Licensee shall not export, either directly or indirectly, any of this
100   * software or system incorporating such software without first obtaining any
101   * required license or other approval from the U. S. Department of Commerce or
102   * any other agency or department of the United States Government. In the
103   * event Licensee exports any such software from the United States or
104   * re-exports any such software from a foreign destination, Licensee shall
105   * ensure that the distribution and export/re-export of the software is in
106   * compliance with all laws, regulations, orders, or other restrictions of the
107   * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108   * any of its subsidiaries will export/re-export any technical data, process,
109   * software, or service, directly or indirectly, to any country for which the
110   * United States government or any agency thereof requires an export license,
111   * other governmental approval, or letter of assurance, without first obtaining
112   * such license, approval or letter.
113   *
114   *****************************************************************************
115   *
116   * Alternatively, you may choose to be licensed under the terms of the
117   * following license:
118   *
119   * Redistribution and use in source and binary forms, with or without
120   * modification, are permitted provided that the following conditions
121   * are met:
122   * 1. Redistributions of source code must retain the above copyright
123   *    notice, this list of conditions, and the following disclaimer,
124   *    without modification.
125   * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126   *    substantially similar to the "NO WARRANTY" disclaimer below
127   *    ("Disclaimer") and any redistribution must be conditioned upon
128   *    including a substantially similar Disclaimer requirement for further
129   *    binary redistribution.
130   * 3. Neither the names of the above-listed copyright holders nor the names
131   *    of any contributors may be used to endorse or promote products derived
132   *    from this software without specific prior written permission.
133   *
134   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138   * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145   *
146   * Alternatively, you may choose to be licensed under the terms of the
147   * GNU General Public License ("GPL") version 2 as published by the Free
148   * Software Foundation.
149   *
150   *****************************************************************************/
151  
152  #include <contrib/dev/acpica/compiler/aslcompiler.h>
153  #include <contrib/dev/acpica/include/amlcode.h>
154  #include <contrib/dev/acpica/include/acdispat.h>
155  #include <contrib/dev/acpica/include/acnamesp.h>
156  #include <contrib/dev/acpica/include/acparser.h>
157  #include "aslcompiler.y.h"
158  
159  
160  #define _COMPONENT          ACPI_COMPILER
161          ACPI_MODULE_NAME    ("aslload")
162  
163  /* Local prototypes */
164  
165  static ACPI_STATUS
166  LdLoadFieldElements (
167      ACPI_PARSE_OBJECT       *Op,
168      ACPI_WALK_STATE         *WalkState);
169  
170  static ACPI_STATUS
171  LdLoadResourceElements (
172      ACPI_PARSE_OBJECT       *Op,
173      ACPI_WALK_STATE         *WalkState);
174  
175  static ACPI_STATUS
176  LdNamespace1Begin (
177      ACPI_PARSE_OBJECT       *Op,
178      UINT32                  Level,
179      void                    *Context);
180  
181  static ACPI_STATUS
182  LdNamespace2Begin (
183      ACPI_PARSE_OBJECT       *Op,
184      UINT32                  Level,
185      void                    *Context);
186  
187  static ACPI_STATUS
188  LdCommonNamespaceEnd (
189      ACPI_PARSE_OBJECT       *Op,
190      UINT32                  Level,
191      void                    *Context);
192  
193  
194  /*******************************************************************************
195   *
196   * FUNCTION:    LdLoadNamespace
197   *
198   * PARAMETERS:  RootOp      - Root of the parse tree
199   *
200   * RETURN:      Status
201   *
202   * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the
203   *              named ASL/AML objects into the namespace. The namespace is
204   *              constructed in order to resolve named references and references
205   *              to named fields within resource templates/descriptors.
206   *
207   ******************************************************************************/
208  
209  ACPI_STATUS
210  LdLoadNamespace (
211      ACPI_PARSE_OBJECT       *RootOp)
212  {
213      ACPI_WALK_STATE         *WalkState;
214  
215  
216      /* Create a new walk state */
217  
218      WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
219      if (!WalkState)
220      {
221          return (AE_NO_MEMORY);
222      }
223  
224      /* Walk the entire parse tree, first pass */
225  
226      TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin,
227          LdCommonNamespaceEnd, WalkState);
228  
229      /* Second pass to handle forward references */
230  
231      TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin,
232          LdCommonNamespaceEnd, WalkState);
233  
234      /* Dump the namespace if debug is enabled */
235  
236      if (AcpiDbgLevel & ACPI_LV_TABLES)
237      {
238          AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX);
239      }
240  
241      ACPI_FREE (WalkState);
242      return (AE_OK);
243  }
244  
245  
246  /*******************************************************************************
247   *
248   * FUNCTION:    LdLoadFieldElements
249   *
250   * PARAMETERS:  Op              - Parent node (Field)
251   *              WalkState       - Current walk state
252   *
253   * RETURN:      Status
254   *
255   * DESCRIPTION: Enter the named elements of the field (children of the parent)
256   *              into the namespace.
257   *
258   ******************************************************************************/
259  
260  static ACPI_STATUS
261  LdLoadFieldElements (
262      ACPI_PARSE_OBJECT       *Op,
263      ACPI_WALK_STATE         *WalkState)
264  {
265      ACPI_PARSE_OBJECT       *Child = NULL;
266      ACPI_NAMESPACE_NODE     *Node;
267      ACPI_STATUS             Status;
268  
269  
270      /* Get the first named field element */
271  
272      switch (Op->Asl.AmlOpcode)
273      {
274      case AML_BANK_FIELD_OP:
275  
276          Child = UtGetArg (Op, 6);
277          break;
278  
279      case AML_INDEX_FIELD_OP:
280  
281          Child = UtGetArg (Op, 5);
282          break;
283  
284      case AML_FIELD_OP:
285  
286          Child = UtGetArg (Op, 4);
287          break;
288  
289      default:
290  
291          /* No other opcodes should arrive here */
292  
293          return (AE_BAD_PARAMETER);
294      }
295  
296      /* Enter all elements into the namespace */
297  
298      while (Child)
299      {
300          switch (Child->Asl.AmlOpcode)
301          {
302          case AML_INT_RESERVEDFIELD_OP:
303          case AML_INT_ACCESSFIELD_OP:
304          case AML_INT_CONNECTION_OP:
305              break;
306  
307          default:
308  
309              Status = AcpiNsLookup (WalkState->ScopeInfo,
310                  Child->Asl.Value.String,
311                  ACPI_TYPE_LOCAL_REGION_FIELD,
312                  ACPI_IMODE_LOAD_PASS1,
313                  ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
314                      ACPI_NS_ERROR_IF_FOUND, NULL, &Node);
315              if (ACPI_FAILURE (Status))
316              {
317                  if (Status != AE_ALREADY_EXISTS)
318                  {
319                      AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child,
320                          Child->Asl.Value.String);
321                      return (Status);
322                  }
323                  else if (Status == AE_ALREADY_EXISTS &&
324                      (Node->Flags & ANOBJ_IS_EXTERNAL))
325                  {
326                      Node->Type = (UINT8) ACPI_TYPE_LOCAL_REGION_FIELD;
327                  }
328                  else
329                  {
330                      /*
331                       * The name already exists in this scope
332                       * But continue processing the elements
333                       */
334                      AslDualParseOpError (ASL_WARNING, ASL_MSG_EXTERN_COLLISION, Child,
335                          Child->Asl.Value.String, ASL_MSG_EXTERN_FOUND_HERE, Node->Op,
336                          Node->Op->Asl.ExternalName);
337                  }
338              }
339              else
340              {
341                  Child->Asl.Node = Node;
342                  Node->Op = Child;
343              }
344              break;
345          }
346  
347          Child = Child->Asl.Next;
348      }
349  
350      return (AE_OK);
351  }
352  
353  
354  /*******************************************************************************
355   *
356   * FUNCTION:    LdLoadResourceElements
357   *
358   * PARAMETERS:  Op              - Parent node (Resource Descriptor)
359   *              WalkState       - Current walk state
360   *
361   * RETURN:      Status
362   *
363   * DESCRIPTION: Enter the named elements of the resource descriptor (children
364   *              of the parent) into the namespace.
365   *
366   * NOTE: In the real AML namespace, these named elements never exist. But
367   *       we simply use the namespace here as a symbol table so we can look
368   *       them up as they are referenced.
369   *
370   ******************************************************************************/
371  
372  static ACPI_STATUS
373  LdLoadResourceElements (
374      ACPI_PARSE_OBJECT       *Op,
375      ACPI_WALK_STATE         *WalkState)
376  {
377      ACPI_PARSE_OBJECT       *InitializerOp = NULL;
378      ACPI_NAMESPACE_NODE     *Node;
379      ACPI_STATUS             Status;
380  
381  
382      /*
383       * Enter the resource name into the namespace. Name must not already exist.
384       * This opens a scope, so later field names are guaranteed to be new/unique.
385       */
386      Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath,
387          ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1,
388          ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND,
389          WalkState, &Node);
390      if (ACPI_FAILURE (Status))
391      {
392          if (Status == AE_ALREADY_EXISTS)
393          {
394              /* Actual node causing the error was saved in ParentMethod */
395  
396              AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS,
397                  (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod,
398                  Op->Asl.Namepath, ASL_MSG_FOUND_HERE, Node->Op,
399                  Node->Op->Asl.ExternalName);
400              return (AE_OK);
401          }
402          return (Status);
403      }
404  
405      Node->Value = (UINT32) Op->Asl.Value.Integer;
406      Node->Op = Op;
407      Op->Asl.Node = Node;
408  
409      /*
410       * Now enter the predefined fields, for easy lookup when referenced
411       * by the source ASL
412       */
413      InitializerOp = ASL_GET_CHILD_NODE (Op);
414      while (InitializerOp)
415      {
416          if (InitializerOp->Asl.ExternalName)
417          {
418              Status = AcpiNsLookup (WalkState->ScopeInfo,
419                  InitializerOp->Asl.ExternalName,
420                  ACPI_TYPE_LOCAL_RESOURCE_FIELD, ACPI_IMODE_LOAD_PASS1,
421                  ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
422              if (ACPI_FAILURE (Status))
423              {
424                  return (Status);
425              }
426  
427              /*
428               * Store the field offset and length in the namespace node
429               * so it can be used when the field is referenced
430               */
431              Node->Value = InitializerOp->Asl.Value.Tag.BitOffset;
432              Node->Length = InitializerOp->Asl.Value.Tag.BitLength;
433              InitializerOp->Asl.Node = Node;
434              Node->Op = InitializerOp;
435          }
436  
437          InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
438      }
439  
440      return (AE_OK);
441  }
442  
443  
444  /*******************************************************************************
445   *
446   * FUNCTION:    LdNamespace1Begin
447   *
448   * PARAMETERS:  ASL_WALK_CALLBACK
449   *
450   * RETURN:      Status
451   *
452   * DESCRIPTION: Descending callback used during the parse tree walk. If this
453   *              is a named AML opcode, enter into the namespace
454   *
455   ******************************************************************************/
456  
457  static ACPI_STATUS
458  LdNamespace1Begin (
459      ACPI_PARSE_OBJECT       *Op,
460      UINT32                  Level,
461      void                    *Context)
462  {
463      ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
464      ACPI_NAMESPACE_NODE     *Node;
465      ACPI_PARSE_OBJECT       *MethodOp;
466      ACPI_STATUS             Status;
467      ACPI_OBJECT_TYPE        ObjectType;
468      ACPI_OBJECT_TYPE        ActualObjectType = ACPI_TYPE_ANY;
469      char                    *Path;
470      UINT32                  Flags = ACPI_NS_NO_UPSEARCH;
471      ACPI_PARSE_OBJECT       *Arg;
472      UINT32                  i;
473      BOOLEAN                 ForceNewScope = FALSE;
474      const ACPI_OPCODE_INFO  *OpInfo;
475      ACPI_PARSE_OBJECT       *ParentOp;
476  
477  
478      ACPI_FUNCTION_NAME (LdNamespace1Begin);
479  
480  
481      ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
482          Op, Op->Asl.ParseOpName));
483  
484      /*
485       * We are only interested in opcodes that have an associated name
486       * (or multiple names)
487       */
488      switch (Op->Asl.AmlOpcode)
489      {
490      case AML_BANK_FIELD_OP:
491      case AML_INDEX_FIELD_OP:
492      case AML_FIELD_OP:
493  
494          Status = LdLoadFieldElements (Op, WalkState);
495          return (Status);
496  
497      case AML_INT_CONNECTION_OP:
498  
499  
500          if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)
501          {
502              break;
503          }
504          Arg = Op->Asl.Child;
505  
506          Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName,
507              ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
508              WalkState, &Node);
509          if (ACPI_FAILURE (Status))
510          {
511              break;
512          }
513  
514          if (Node->Type == ACPI_TYPE_BUFFER)
515          {
516              Arg->Asl.Node = Node;
517  
518              Arg = Node->Op->Asl.Child;  /* Get namepath */
519              Arg = Arg->Asl.Next;        /* Get actual buffer */
520              Arg = Arg->Asl.Child;       /* Buffer length */
521              Arg = Arg->Asl.Next;        /* RAW_DATA buffer */
522          }
523          break;
524  
525      default:
526  
527          /* All other opcodes go below */
528  
529          break;
530      }
531  
532      /* Check if this object has already been installed in the namespace */
533  
534      if (Op->Asl.Node)
535      {
536          return (AE_OK);
537      }
538  
539      /* Check for a possible illegal forward reference */
540  
541      if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
542          (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
543      {
544          /*
545           * Op->Asl.Namepath will be NULL for these opcodes.
546           * These opcodes are guaranteed to have a parent.
547           * Examine the parent opcode.
548           */
549          Status = AE_OK;
550          ParentOp = Op->Asl.Parent;
551          OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Asl.AmlOpcode);
552  
553          /*
554           * Exclude all operators that actually declare a new name:
555           *      Name (ABCD, 1) -> Ignore (AML_CLASS_NAMED_OBJECT)
556           * We only want references to named objects:
557           *      Store (2, WXYZ) -> Attempt to resolve the name
558           */
559          if (OpInfo->Class == AML_CLASS_NAMED_OBJECT)
560          {
561              return (AE_OK);
562          }
563  
564          /*
565           * Check if the referenced object exists at this point during
566           * the load:
567           * 1) If it exists, then this cannot be a forward reference.
568           * 2) If it does not exist, it could be a forward reference or
569           * it truly does not exist (and no external declaration).
570           */
571          Status = AcpiNsLookup (WalkState->ScopeInfo,
572              Op->Asl.Value.Name, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
573              ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
574              WalkState, &Node);
575          if (Status == AE_NOT_FOUND)
576          {
577              /*
578               * This is either a foward reference or the object truly
579               * does not exist. The two cases can only be differentiated
580               * during the cross-reference stage later. Mark the Op/Name
581               * as not-found for now to indicate the need for further
582               * processing.
583               *
584               * Special case: Allow forward references from elements of
585               * Package objects. This provides compatibility with other
586               * ACPI implementations. To correctly implement this, the
587               * ACPICA table load defers package resolution until the entire
588               * namespace has been loaded.
589               */
590              if ((ParentOp->Asl.ParseOpcode != PARSEOP_PACKAGE) &&
591                  (ParentOp->Asl.ParseOpcode != PARSEOP_VAR_PACKAGE))
592              {
593                  Op->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD;
594              }
595  
596              return (AE_OK);
597          }
598  
599          return (Status);
600      }
601  
602      Path = Op->Asl.Namepath;
603      if (!Path)
604      {
605          return (AE_OK);
606      }
607  
608      /* Map the raw opcode into an internal object type */
609  
610      switch (Op->Asl.ParseOpcode)
611      {
612      case PARSEOP_NAME:
613  
614          Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
615          Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
616  
617          /*
618           * If this name refers to a ResourceTemplate, we will need to open
619           * a new scope so that the resource subfield names can be entered into
620           * the namespace underneath this name
621           */
622          if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
623          {
624              ForceNewScope = TRUE;
625          }
626  
627          /* Get the data type associated with the named object, not the name itself */
628  
629          /* Log2 loop to convert from Btype (binary) to Etype (encoded) */
630  
631          ObjectType = 1;
632          for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2)
633          {
634              ObjectType++;
635          }
636          break;
637  
638      case PARSEOP_EXTERNAL:
639          /*
640           * "External" simply enters a name and type into the namespace.
641           * We must be careful to not open a new scope, however, no matter
642           * what type the external name refers to (e.g., a method)
643           *
644           * first child is name, next child is ObjectType
645           */
646          ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer;
647          ObjectType = ACPI_TYPE_ANY;
648  
649          /*
650           * We will mark every new node along the path as "External". This
651           * allows some or all of the nodes to be created later in the ASL
652           * code. Handles cases like this:
653           *
654           *   External (\_SB_.PCI0.ABCD, IntObj)
655           *   Scope (_SB_)
656           *   {
657           *       Device (PCI0)
658           *       {
659           *       }
660           *   }
661           *   Method (X)
662           *   {
663           *       Store (\_SB_.PCI0.ABCD, Local0)
664           *   }
665           */
666          Flags |= ACPI_NS_EXTERNAL;
667          break;
668  
669      case PARSEOP_DEFAULT_ARG:
670  
671          if (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC)
672          {
673              Status = LdLoadResourceElements (Op, WalkState);
674              return_ACPI_STATUS (Status);
675          }
676  
677          ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
678          break;
679  
680      case PARSEOP_SCOPE:
681          /*
682           * The name referenced by Scope(Name) must already exist at this point.
683           * In other words, forward references for Scope() are not supported.
684           * The only real reason for this is that the MS interpreter cannot
685           * handle this case. Perhaps someday this case can go away.
686           */
687          Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
688              ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &Node);
689          if (ACPI_FAILURE (Status))
690          {
691              if (Status == AE_NOT_FOUND)
692              {
693                  /* The name was not found, go ahead and create it */
694  
695                  Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
696                      ACPI_TYPE_LOCAL_SCOPE, ACPI_IMODE_LOAD_PASS1,
697                      Flags, WalkState, &Node);
698                  if (ACPI_FAILURE (Status))
699                  {
700                      return_ACPI_STATUS (Status);
701                  }
702  
703                  /* However, this is an error -- operand to Scope must exist */
704  
705                  if (strlen (Op->Asl.ExternalName) == ACPI_NAME_SIZE)
706                  {
707                      AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
708                          Op->Asl.ExternalName);
709                  }
710                  else
711                  {
712                      AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
713                          Op->Asl.ExternalName);
714                  }
715  
716                  goto FinishNode;
717              }
718  
719              AslCoreSubsystemError (Op, Status,
720                  "Failure from namespace lookup", FALSE);
721  
722              return_ACPI_STATUS (Status);
723          }
724          else /* Status AE_OK */
725          {
726              /*
727               * Do not allow references to external scopes from the DSDT.
728               * This is because the DSDT is always loaded first, and the
729               * external reference cannot be resolved -- causing a runtime
730               * error because Scope() must be resolved immediately.
731               * 10/2015.
732               */
733              if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
734                  (ACPI_COMPARE_NAME (AslGbl_TableSignature, "DSDT")))
735              {
736                  /* However, allowed if the reference is within a method */
737  
738                  MethodOp = Op->Asl.Parent;
739                  while (MethodOp &&
740                        (MethodOp->Asl.ParseOpcode != PARSEOP_METHOD))
741                  {
742                      MethodOp = MethodOp->Asl.Parent;
743                  }
744  
745                  if (!MethodOp)
746                  {
747                      /* Not in a control method, error */
748  
749                      AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL);
750                  }
751              }
752          }
753  
754          /* We found a node with this name, now check the type */
755  
756          switch (Node->Type)
757          {
758          case ACPI_TYPE_LOCAL_SCOPE:
759          case ACPI_TYPE_DEVICE:
760          case ACPI_TYPE_POWER:
761          case ACPI_TYPE_PROCESSOR:
762          case ACPI_TYPE_THERMAL:
763  
764              /* These are acceptable types - they all open a new scope */
765              break;
766  
767          case ACPI_TYPE_INTEGER:
768          case ACPI_TYPE_STRING:
769          case ACPI_TYPE_BUFFER:
770              /*
771               * These types we will allow, but we will change the type.
772               * This enables some existing code of the form:
773               *
774               *  Name (DEB, 0)
775               *  Scope (DEB) { ... }
776               *
777               * Which is used to workaround the fact that the MS interpreter
778               * does not allow Scope() forward references.
779               */
780              sprintf (AslGbl_MsgBuffer, "%s [%s], changing type to [Scope]",
781                  Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
782              AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);
783  
784              /* Switch the type to scope, open the new scope */
785  
786              Node->Type = ACPI_TYPE_LOCAL_SCOPE;
787              Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
788                  WalkState);
789              if (ACPI_FAILURE (Status))
790              {
791                  return_ACPI_STATUS (Status);
792              }
793              break;
794  
795          default:
796  
797              /* All other types are an error */
798  
799              sprintf (AslGbl_MsgBuffer, "%s [%s]", Op->Asl.ExternalName,
800                  AcpiUtGetTypeName (Node->Type));
801              AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);
802  
803              /*
804               * However, switch the type to be an actual scope so
805               * that compilation can continue without generating a whole
806               * cascade of additional errors. Open the new scope.
807               */
808              Node->Type = ACPI_TYPE_LOCAL_SCOPE;
809              Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
810                  WalkState);
811              if (ACPI_FAILURE (Status))
812              {
813                  return_ACPI_STATUS (Status);
814              }
815              break;
816          }
817  
818          Status = AE_OK;
819          goto FinishNode;
820  
821      default:
822  
823          ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
824          break;
825      }
826  
827      ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n",
828          Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType)));
829  
830      /* The name must not already exist */
831  
832      Flags |= ACPI_NS_ERROR_IF_FOUND;
833  
834      /*
835       * For opcodes that enter new names into the namespace,
836       * all prefix NameSegs must exist.
837       */
838      WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
839      if (((WalkState->OpInfo->Flags & AML_NAMED) ||
840          (WalkState->OpInfo->Flags & AML_CREATE)) &&
841          (Op->Asl.AmlOpcode != AML_EXTERNAL_OP))
842      {
843          Flags |= ACPI_NS_PREFIX_MUST_EXIST;
844      }
845  
846      /*
847       * Enter the named type into the internal namespace. We enter the name
848       * as we go downward in the parse tree. Any necessary subobjects that
849       * involve arguments to the opcode must be created as we go back up the
850       * parse tree later.
851       */
852      Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
853          ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
854      if (ACPI_FAILURE (Status))
855      {
856          if (Status == AE_ALREADY_EXISTS)
857          {
858              /* The name already exists in this scope */
859  
860              if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
861              {
862                  /* Allow multiple references to the same scope */
863  
864                  Node->Type = (UINT8) ObjectType;
865                  Status = AE_OK;
866              }
867              else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
868                       (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
869              {
870                  /*
871                   * Allow one create on an object or segment that was
872                   * previously declared External
873                   */
874                  Node->Flags &= ~ANOBJ_IS_EXTERNAL;
875                  Node->Type = (UINT8) ObjectType;
876  
877                  /* Just retyped a node, probably will need to open a scope */
878  
879                  if (AcpiNsOpensScope (ObjectType))
880                  {
881                      Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
882                      if (ACPI_FAILURE (Status))
883                      {
884                          return_ACPI_STATUS (Status);
885                      }
886                  }
887  
888                  Status = AE_OK;
889              }
890              else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) &&
891                       (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
892              {
893                  /*
894                   * Allow externals in same scope as the definition of the
895                   * actual object. Similar to C. Allows multiple definition
896                   * blocks that refer to each other in the same file.
897                   */
898                  Status = AE_OK;
899              }
900              else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
901                       (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) &&
902                       (ObjectType == ACPI_TYPE_ANY))
903              {
904                  /* Allow update of externals of unknown type. */
905  
906                  if (AcpiNsOpensScope (ActualObjectType))
907                  {
908                      Node->Type = (UINT8) ActualObjectType;
909                      Status = AE_OK;
910                  }
911                  else
912                  {
913                      sprintf (AslGbl_MsgBuffer, "%s [%s]", Op->Asl.ExternalName,
914                          AcpiUtGetTypeName (Node->Type));
915                      AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);
916                      return_ACPI_STATUS (AE_OK);
917                  }
918              }
919              else
920              {
921                  /* Valid error, object already exists */
922  
923                  AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
924                      Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op,
925                      Node->Op->Asl.ExternalName);
926                  return_ACPI_STATUS (AE_OK);
927              }
928          }
929          else if (AE_NOT_FOUND)
930          {
931              /*
932               * One or more prefix NameSegs of the NamePath do not exist
933               * (all of them must exist). Attempt to continue compilation
934               * by setting the current scope to the root.
935               */
936              Node = AcpiGbl_RootNode;
937              Status = AE_OK;
938          }
939          else
940          {
941              /* Flag all other errors as coming from the ACPICA core */
942  
943              AslCoreSubsystemError (Op, Status,
944                  "Failure from namespace lookup", FALSE);
945              return_ACPI_STATUS (Status);
946          }
947      }
948  
949      if (ForceNewScope)
950      {
951          Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
952          if (ACPI_FAILURE (Status))
953          {
954              return_ACPI_STATUS (Status);
955          }
956      }
957  
958  FinishNode:
959      /*
960       * Point the parse node to the new namespace node, and point
961       * the Node back to the original Parse node
962       */
963      Op->Asl.Node = Node;
964      Node->Op = Op;
965  
966      /* Set the actual data type if appropriate (EXTERNAL term only) */
967  
968      if (ActualObjectType != ACPI_TYPE_ANY)
969      {
970          Node->Type = (UINT8) ActualObjectType;
971          Node->Value = ASL_EXTERNAL_METHOD;
972      }
973  
974      if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
975      {
976          /*
977           * Get the method argument count from "Extra" and save
978           * it in the namespace node
979           */
980          Node->Value = (UINT32) Op->Asl.Extra;
981      }
982  
983      return_ACPI_STATUS (Status);
984  }
985  
986  
987  /*******************************************************************************
988   *
989   * FUNCTION:    LdNamespace2Begin
990   *
991   * PARAMETERS:  ASL_WALK_CALLBACK
992   *
993   * RETURN:      Status
994   *
995   * DESCRIPTION: Descending callback used during the pass 2 parse tree walk.
996   *              Second pass resolves some forward references.
997   *
998   * Notes:
999   * Currently only needs to handle the Alias operator.
1000   * Could be used to allow forward references from the Scope() operator, but
1001   * the MS interpreter does not allow this, so this compiler does not either.
1002   *
1003   ******************************************************************************/
1004  
1005  static ACPI_STATUS
1006  LdNamespace2Begin (
1007      ACPI_PARSE_OBJECT       *Op,
1008      UINT32                  Level,
1009      void                    *Context)
1010  {
1011      ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
1012      ACPI_STATUS             Status;
1013      ACPI_NAMESPACE_NODE     *Node;
1014      ACPI_OBJECT_TYPE        ObjectType;
1015      BOOLEAN                 ForceNewScope = FALSE;
1016      ACPI_PARSE_OBJECT       *Arg;
1017      char                    *Path;
1018      ACPI_NAMESPACE_NODE     *TargetNode;
1019  
1020  
1021      ACPI_FUNCTION_NAME (LdNamespace2Begin);
1022      ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
1023          Op, Op->Asl.ParseOpName));
1024  
1025  
1026      /* Ignore Ops with no namespace node */
1027  
1028      Node = Op->Asl.Node;
1029      if (!Node)
1030      {
1031          return (AE_OK);
1032      }
1033  
1034      /* Get the type to determine if we should push the scope */
1035  
1036      if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
1037          (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC))
1038      {
1039          ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
1040      }
1041      else
1042      {
1043          ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
1044      }
1045  
1046      /* Push scope for Resource Templates */
1047  
1048      if (Op->Asl.ParseOpcode == PARSEOP_NAME)
1049      {
1050          if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
1051          {
1052              ForceNewScope = TRUE;
1053          }
1054      }
1055  
1056      /* Push the scope stack */
1057  
1058      if (ForceNewScope || AcpiNsOpensScope (ObjectType))
1059      {
1060          Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
1061          if (ACPI_FAILURE (Status))
1062          {
1063              return_ACPI_STATUS (Status);
1064          }
1065      }
1066  
1067      if (Op->Asl.ParseOpcode == PARSEOP_ALIAS)
1068      {
1069          /*
1070           * Complete the alias node by getting and saving the target node.
1071           * First child is the alias target
1072           */
1073          Arg = Op->Asl.Child;
1074  
1075          /* Get the target pathname */
1076  
1077          Path = Arg->Asl.Namepath;
1078          if (!Path)
1079          {
1080              Status = UtInternalizeName (Arg->Asl.ExternalName, &Path);
1081              if (ACPI_FAILURE (Status))
1082              {
1083                  return (Status);
1084              }
1085          }
1086  
1087          /* Get the NS node associated with the target. It must exist. */
1088  
1089          Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
1090              ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
1091              WalkState, &TargetNode);
1092          if (ACPI_FAILURE (Status))
1093          {
1094              if (Status == AE_NOT_FOUND)
1095              {
1096                  /* Standalone NameSeg vs. NamePath */
1097  
1098                  if (strlen (Arg->Asl.ExternalName) == ACPI_NAME_SIZE)
1099                  {
1100                      AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
1101                          Arg->Asl.ExternalName);
1102                  }
1103                  else
1104                  {
1105                      AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
1106                          Arg->Asl.ExternalName);
1107                  }
1108  
1109  #if 0
1110  /*
1111   * NOTE: Removed 10/2018 to enhance compiler error reporting. No
1112   * regressions seen.
1113   */
1114                  /*
1115                   * The name was not found, go ahead and create it.
1116                   * This prevents more errors later.
1117                   */
1118                  Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
1119                      ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
1120                      ACPI_NS_NO_UPSEARCH, WalkState, &Node);
1121  #endif
1122                  return (Status);
1123  /* Removed: return (AE_OK)*/
1124              }
1125  
1126              AslCoreSubsystemError (Op, Status,
1127                  "Failure from namespace lookup", FALSE);
1128              return (AE_OK);
1129          }
1130  
1131          /* Save the target node within the alias node */
1132  
1133          Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
1134      }
1135  
1136      return (AE_OK);
1137  }
1138  
1139  
1140  /*******************************************************************************
1141   *
1142   * FUNCTION:    LdCommonNamespaceEnd
1143   *
1144   * PARAMETERS:  ASL_WALK_CALLBACK
1145   *
1146   * RETURN:      Status
1147   *
1148   * DESCRIPTION: Ascending callback used during the loading of the namespace,
1149   *              We only need to worry about managing the scope stack here.
1150   *
1151   ******************************************************************************/
1152  
1153  static ACPI_STATUS
1154  LdCommonNamespaceEnd (
1155      ACPI_PARSE_OBJECT       *Op,
1156      UINT32                  Level,
1157      void                    *Context)
1158  {
1159      ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
1160      ACPI_OBJECT_TYPE        ObjectType;
1161      BOOLEAN                 ForceNewScope = FALSE;
1162  
1163  
1164      ACPI_FUNCTION_NAME (LdCommonNamespaceEnd);
1165  
1166  
1167      /* We are only interested in opcodes that have an associated name */
1168  
1169      if (!Op->Asl.Namepath)
1170      {
1171          return (AE_OK);
1172      }
1173  
1174      /* Get the type to determine if we should pop the scope */
1175  
1176      if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
1177          (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC))
1178      {
1179          /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */
1180  
1181          ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
1182      }
1183      else
1184      {
1185          ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
1186      }
1187  
1188      /* Pop scope that was pushed for Resource Templates */
1189  
1190      if (Op->Asl.ParseOpcode == PARSEOP_NAME)
1191      {
1192          if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
1193          {
1194              ForceNewScope = TRUE;
1195          }
1196      }
1197  
1198      /* Pop the scope stack */
1199  
1200      if (ForceNewScope || AcpiNsOpensScope (ObjectType))
1201      {
1202          ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1203              "(%s): Popping scope for Op [%s] %p\n",
1204              AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op));
1205  
1206          (void) AcpiDsScopeStackPop (WalkState);
1207      }
1208  
1209      return (AE_OK);
1210  }
1211