xref: /freebsd/sys/contrib/dev/acpica/compiler/aslload.c (revision a009b7dcabdc27aa3fdde1f2c6dd08d4fe5a3170)
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      UINT32                  AmlType,
168      ACPI_PARSE_OBJECT       *Op,
169      ACPI_WALK_STATE         *WalkState);
170  
171  static ACPI_STATUS
172  LdLoadResourceElements (
173      ACPI_PARSE_OBJECT       *Op,
174      ACPI_WALK_STATE         *WalkState);
175  
176  static ACPI_STATUS
177  LdNamespace1Begin (
178      ACPI_PARSE_OBJECT       *Op,
179      UINT32                  Level,
180      void                    *Context);
181  
182  static ACPI_STATUS
183  LdNamespace2Begin (
184      ACPI_PARSE_OBJECT       *Op,
185      UINT32                  Level,
186      void                    *Context);
187  
188  static ACPI_STATUS
189  LdCommonNamespaceEnd (
190      ACPI_PARSE_OBJECT       *Op,
191      UINT32                  Level,
192      void                    *Context);
193  
194  static void
195  LdCheckSpecialNames (
196      ACPI_NAMESPACE_NODE     *Node,
197      ACPI_PARSE_OBJECT       *Op);
198  
199  /*******************************************************************************
200   *
201   * FUNCTION:    LdLoadNamespace
202   *
203   * PARAMETERS:  RootOp      - Root of the parse tree
204   *
205   * RETURN:      Status
206   *
207   * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the
208   *              named ASL/AML objects into the namespace. The namespace is
209   *              constructed in order to resolve named references and references
210   *              to named fields within resource templates/descriptors.
211   *
212   ******************************************************************************/
213  
214  ACPI_STATUS
215  LdLoadNamespace (
216      ACPI_PARSE_OBJECT       *RootOp)
217  {
218      ACPI_WALK_STATE         *WalkState;
219  
220  
221      /* Create a new walk state */
222  
223      WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
224      if (!WalkState)
225      {
226          return (AE_NO_MEMORY);
227      }
228  
229      /* Walk the entire parse tree, first pass */
230  
231      TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin,
232          LdCommonNamespaceEnd, WalkState);
233  
234      /* Second pass to handle forward references */
235  
236      TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin,
237          LdCommonNamespaceEnd, WalkState);
238  
239      /* Dump the namespace if debug is enabled */
240  
241      if (AcpiDbgLevel & ACPI_LV_TABLES)
242      {
243          AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX);
244      }
245  
246      ACPI_FREE (WalkState);
247      return (AE_OK);
248  }
249  
250  
251  /*******************************************************************************
252   *
253   * FUNCTION:    LdLoadFieldElements
254   *
255   * PARAMETERS:  AmlType         - Type to search
256   *              Op              - Parent node (Field)
257   *              WalkState       - Current walk state
258   *
259   * RETURN:      Status
260   *
261   * DESCRIPTION: Enter the named elements of the field (children of the parent)
262   *              into the namespace.
263   *
264   ******************************************************************************/
265  
266  static ACPI_STATUS
267  LdLoadFieldElements (
268      UINT32                  AmlType,
269      ACPI_PARSE_OBJECT       *Op,
270      ACPI_WALK_STATE         *WalkState)
271  {
272      ACPI_PARSE_OBJECT       *Child = NULL;
273      ACPI_PARSE_OBJECT       *SourceRegion;
274      ACPI_NAMESPACE_NODE     *Node;
275      ACPI_STATUS             Status;
276  
277  
278      SourceRegion = UtGetArg (Op, 0);
279      if (SourceRegion)
280      {
281          Status = AcpiNsLookup (WalkState->ScopeInfo,
282              SourceRegion->Asl.Value.String,
283              AmlType, ACPI_IMODE_EXECUTE,
284              ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
285          if (Status == AE_NOT_FOUND)
286          {
287              /*
288               * If the named object is not found, it means that it is either a
289               * forward reference or the named object does not exist.
290               */
291              SourceRegion->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD;
292          }
293      }
294  
295      /* Get the first named field element */
296  
297      switch (Op->Asl.AmlOpcode)
298      {
299      case AML_BANK_FIELD_OP:
300  
301          Child = UtGetArg (Op, 6);
302          break;
303  
304      case AML_INDEX_FIELD_OP:
305  
306          Child = UtGetArg (Op, 5);
307          break;
308  
309      case AML_FIELD_OP:
310  
311          Child = UtGetArg (Op, 4);
312          break;
313  
314      default:
315  
316          /* No other opcodes should arrive here */
317  
318          return (AE_BAD_PARAMETER);
319      }
320  
321      /* Enter all elements into the namespace */
322  
323      while (Child)
324      {
325          switch (Child->Asl.AmlOpcode)
326          {
327          case AML_INT_RESERVEDFIELD_OP:
328          case AML_INT_ACCESSFIELD_OP:
329          case AML_INT_CONNECTION_OP:
330              break;
331  
332          default:
333  
334              Status = AcpiNsLookup (WalkState->ScopeInfo,
335                  Child->Asl.Value.String,
336                  ACPI_TYPE_LOCAL_REGION_FIELD,
337                  ACPI_IMODE_LOAD_PASS1,
338                  ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
339                      ACPI_NS_ERROR_IF_FOUND, NULL, &Node);
340              if (ACPI_FAILURE (Status))
341              {
342                  if (Status != AE_ALREADY_EXISTS)
343                  {
344                      AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child,
345                          Child->Asl.Value.String);
346                      return (Status);
347                  }
348                  else if (Status == AE_ALREADY_EXISTS &&
349                      (Node->Flags & ANOBJ_IS_EXTERNAL))
350                  {
351                      Node->Type = (UINT8) ACPI_TYPE_LOCAL_REGION_FIELD;
352                      Node->Flags &= ~ANOBJ_IS_EXTERNAL;
353                  }
354                  else
355                  {
356                      /*
357                       * The name already exists in this scope
358                       * But continue processing the elements
359                       */
360                      AslDualParseOpError (ASL_WARNING, ASL_MSG_NAME_EXISTS, Child,
361                          Child->Asl.Value.String, ASL_MSG_FOUND_HERE, Node->Op,
362                          Node->Op->Asl.ExternalName);
363                  }
364              }
365              else
366              {
367                  Child->Asl.Node = Node;
368                  Node->Op = Child;
369              }
370              break;
371          }
372  
373          Child = Child->Asl.Next;
374      }
375  
376      return (AE_OK);
377  }
378  
379  
380  /*******************************************************************************
381   *
382   * FUNCTION:    LdLoadResourceElements
383   *
384   * PARAMETERS:  Op              - Parent node (Resource Descriptor)
385   *              WalkState       - Current walk state
386   *
387   * RETURN:      Status
388   *
389   * DESCRIPTION: Enter the named elements of the resource descriptor (children
390   *              of the parent) into the namespace.
391   *
392   * NOTE: In the real AML namespace, these named elements never exist. But
393   *       we simply use the namespace here as a symbol table so we can look
394   *       them up as they are referenced.
395   *
396   ******************************************************************************/
397  
398  static ACPI_STATUS
399  LdLoadResourceElements (
400      ACPI_PARSE_OBJECT       *Op,
401      ACPI_WALK_STATE         *WalkState)
402  {
403      ACPI_PARSE_OBJECT       *InitializerOp = NULL;
404      ACPI_NAMESPACE_NODE     *Node;
405      ACPI_STATUS             Status;
406  
407  
408      /*
409       * Enter the resource name into the namespace. Name must not already exist.
410       * This opens a scope, so later field names are guaranteed to be new/unique.
411       */
412      Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath,
413          ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1,
414          ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND,
415          WalkState, &Node);
416      if (ACPI_FAILURE (Status))
417      {
418          if (Status == AE_ALREADY_EXISTS)
419          {
420              /* Actual node causing the error was saved in ParentMethod */
421  
422              AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS,
423                  (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod,
424                  Op->Asl.Namepath, ASL_MSG_FOUND_HERE, Node->Op,
425                  Node->Op->Asl.ExternalName);
426              return (AE_OK);
427          }
428          return (Status);
429      }
430  
431      Node->Value = (UINT32) Op->Asl.Value.Integer;
432      Node->Op = Op;
433      Op->Asl.Node = Node;
434  
435      /*
436       * Now enter the predefined fields, for easy lookup when referenced
437       * by the source ASL
438       */
439      InitializerOp = ASL_GET_CHILD_NODE (Op);
440      while (InitializerOp)
441      {
442          if (InitializerOp->Asl.ExternalName)
443          {
444              Status = AcpiNsLookup (WalkState->ScopeInfo,
445                  InitializerOp->Asl.ExternalName,
446                  ACPI_TYPE_LOCAL_RESOURCE_FIELD, ACPI_IMODE_LOAD_PASS1,
447                  ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
448              if (ACPI_FAILURE (Status))
449              {
450                  return (Status);
451              }
452  
453              /*
454               * Store the field offset and length in the namespace node
455               * so it can be used when the field is referenced
456               */
457              Node->Value = InitializerOp->Asl.Value.Tag.BitOffset;
458              Node->Length = InitializerOp->Asl.Value.Tag.BitLength;
459              InitializerOp->Asl.Node = Node;
460              Node->Op = InitializerOp;
461          }
462  
463          InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
464      }
465  
466      return (AE_OK);
467  }
468  
469  
470  /*******************************************************************************
471   *
472   * FUNCTION:    LdNamespace1Begin
473   *
474   * PARAMETERS:  ASL_WALK_CALLBACK
475   *
476   * RETURN:      Status
477   *
478   * DESCRIPTION: Descending callback used during the parse tree walk. If this
479   *              is a named AML opcode, enter into the namespace
480   *
481   ******************************************************************************/
482  
483  static ACPI_STATUS
484  LdNamespace1Begin (
485      ACPI_PARSE_OBJECT       *Op,
486      UINT32                  Level,
487      void                    *Context)
488  {
489      ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
490      ACPI_NAMESPACE_NODE     *Node;
491      ACPI_PARSE_OBJECT       *MethodOp;
492      ACPI_STATUS             Status;
493      ACPI_OBJECT_TYPE        ObjectType;
494      ACPI_OBJECT_TYPE        ActualObjectType = ACPI_TYPE_ANY;
495      char                    *Path;
496      UINT32                  Flags = ACPI_NS_NO_UPSEARCH;
497      ACPI_PARSE_OBJECT       *Arg;
498      UINT32                  i;
499      BOOLEAN                 ForceNewScope = FALSE;
500      const ACPI_OPCODE_INFO  *OpInfo;
501      ACPI_PARSE_OBJECT       *ParentOp;
502  
503  
504      ACPI_FUNCTION_NAME (LdNamespace1Begin);
505  
506  
507      ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
508          Op, Op->Asl.ParseOpName));
509  
510      /*
511       * We are only interested in opcodes that have an associated name
512       * (or multiple names)
513       */
514      switch (Op->Asl.AmlOpcode)
515      {
516      case AML_INDEX_FIELD_OP:
517  
518          Status = LdLoadFieldElements (ACPI_TYPE_LOCAL_REGION_FIELD, Op, WalkState);
519          return (Status);
520  
521      case AML_BANK_FIELD_OP:
522      case AML_FIELD_OP:
523  
524          Status = LdLoadFieldElements (ACPI_TYPE_REGION, Op, WalkState);
525          return (Status);
526  
527      case AML_INT_CONNECTION_OP:
528  
529          if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)
530          {
531              break;
532          }
533  
534          Arg = Op->Asl.Child;
535          Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName,
536              ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
537              WalkState, &Node);
538          if (ACPI_FAILURE (Status))
539          {
540              break;
541          }
542  
543          break;
544  
545      default:
546  
547          /* All other opcodes go below */
548  
549          break;
550      }
551  
552      /* Check if this object has already been installed in the namespace */
553  
554      if (Op->Asl.Node)
555      {
556          return (AE_OK);
557      }
558  
559      /* Check for a possible illegal forward reference */
560  
561      if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
562          (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
563      {
564          /*
565           * Op->Asl.Namepath will be NULL for these opcodes.
566           * These opcodes are guaranteed to have a parent.
567           * Examine the parent opcode.
568           */
569          ParentOp = Op->Asl.Parent;
570          OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Asl.AmlOpcode);
571  
572          /*
573           * Exclude all operators that actually declare a new name:
574           *      Name (ABCD, 1) -> Ignore (AML_CLASS_NAMED_OBJECT)
575           * We only want references to named objects:
576           *      Store (2, WXYZ) -> Attempt to resolve the name
577           */
578          if (OpInfo->Class == AML_CLASS_NAMED_OBJECT)
579          {
580              return (AE_OK);
581          }
582  
583          /*
584           * Check if the referenced object exists at this point during
585           * the load:
586           * 1) If it exists, then this cannot be a forward reference.
587           * 2) If it does not exist, it could be a forward reference or
588           * it truly does not exist (and no external declaration).
589           */
590          Status = AcpiNsLookup (WalkState->ScopeInfo,
591              Op->Asl.Value.Name, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
592              ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
593              WalkState, &Node);
594          if (Status == AE_NOT_FOUND)
595          {
596              /*
597               * This is either a forward reference or the object truly
598               * does not exist. The two cases can only be differentiated
599               * during the cross-reference stage later. Mark the Op/Name
600               * as not-found for now to indicate the need for further
601               * processing.
602               *
603               * Special case: Allow forward references from elements of
604               * Package objects. This provides compatibility with other
605               * ACPI implementations. To correctly implement this, the
606               * ACPICA table load defers package resolution until the entire
607               * namespace has been loaded.
608               */
609              if ((ParentOp->Asl.ParseOpcode != PARSEOP_PACKAGE) &&
610                  (ParentOp->Asl.ParseOpcode != PARSEOP_VAR_PACKAGE))
611              {
612                  Op->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD;
613              }
614  
615              return (AE_OK);
616          }
617  
618          return (Status);
619      }
620  
621      Path = Op->Asl.Namepath;
622      if (!Path)
623      {
624          return (AE_OK);
625      }
626  
627      /* Map the raw opcode into an internal object type */
628  
629      switch (Op->Asl.ParseOpcode)
630      {
631      case PARSEOP_NAME:
632  
633          Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
634          Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
635  
636          /*
637           * If this name refers to a ResourceTemplate, we will need to open
638           * a new scope so that the resource subfield names can be entered into
639           * the namespace underneath this name
640           */
641          if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
642          {
643              ForceNewScope = TRUE;
644          }
645  
646          /* Get the data type associated with the named object, not the name itself */
647  
648          /* Log2 loop to convert from Btype (binary) to Etype (encoded) */
649  
650          ObjectType = 1;
651          for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2)
652          {
653              ObjectType++;
654          }
655          break;
656  
657      case PARSEOP_EXTERNAL:
658          /*
659           * "External" simply enters a name and type into the namespace.
660           * We must be careful to not open a new scope, however, no matter
661           * what type the external name refers to (e.g., a method)
662           *
663           * first child is name, next child is ObjectType
664           */
665          ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer;
666          ObjectType = ACPI_TYPE_ANY;
667  
668          /*
669           * We will mark every new node along the path as "External". This
670           * allows some or all of the nodes to be created later in the ASL
671           * code. Handles cases like this:
672           *
673           *   External (\_SB_.PCI0.ABCD, IntObj)
674           *   Scope (_SB_)
675           *   {
676           *       Device (PCI0)
677           *       {
678           *       }
679           *   }
680           *   Method (X)
681           *   {
682           *       Store (\_SB_.PCI0.ABCD, Local0)
683           *   }
684           */
685          Flags |= ACPI_NS_EXTERNAL;
686          break;
687  
688      case PARSEOP_DEFAULT_ARG:
689  
690          if (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC)
691          {
692              Status = LdLoadResourceElements (Op, WalkState);
693              return_ACPI_STATUS (Status);
694          }
695  
696          ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
697          break;
698  
699      case PARSEOP_SCOPE:
700          /*
701           * The name referenced by Scope(Name) must already exist at this point.
702           * In other words, forward references for Scope() are not supported.
703           * The only real reason for this is that the MS interpreter cannot
704           * handle this case. Perhaps someday this case can go away.
705           */
706          Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
707              ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &Node);
708          if (ACPI_FAILURE (Status))
709          {
710              if (Status == AE_NOT_FOUND)
711              {
712                  /* The name was not found, go ahead and create it */
713  
714                  Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
715                      ACPI_TYPE_LOCAL_SCOPE, ACPI_IMODE_LOAD_PASS1,
716                      Flags, WalkState, &Node);
717                  if (ACPI_FAILURE (Status))
718                  {
719                      return_ACPI_STATUS (Status);
720                  }
721  
722                  /* However, this is an error -- operand to Scope must exist */
723  
724                  if (strlen (Op->Asl.ExternalName) == ACPI_NAMESEG_SIZE)
725                  {
726                      AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
727                          Op->Asl.ExternalName);
728                  }
729                  else
730                  {
731                      AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
732                          Op->Asl.ExternalName);
733                  }
734  
735                  goto FinishNode;
736              }
737  
738              AslCoreSubsystemError (Op, Status,
739                  "Failure from namespace lookup", FALSE);
740  
741              return_ACPI_STATUS (Status);
742          }
743          else /* Status AE_OK */
744          {
745              /*
746               * Do not allow references to external scopes from the DSDT.
747               * This is because the DSDT is always loaded first, and the
748               * external reference cannot be resolved -- causing a runtime
749               * error because Scope() must be resolved immediately.
750               * 10/2015.
751               */
752              if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
753                  (ACPI_COMPARE_NAMESEG (AslGbl_TableSignature, "DSDT")))
754              {
755                  /* However, allowed if the reference is within a method */
756  
757                  MethodOp = Op->Asl.Parent;
758                  while (MethodOp &&
759                        (MethodOp->Asl.ParseOpcode != PARSEOP_METHOD))
760                  {
761                      MethodOp = MethodOp->Asl.Parent;
762                  }
763  
764                  if (!MethodOp)
765                  {
766                      /* Not in a control method, error */
767  
768                      AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL);
769                  }
770              }
771          }
772  
773          /* We found a node with this name, now check the type */
774  
775          switch (Node->Type)
776          {
777          case ACPI_TYPE_LOCAL_SCOPE:
778          case ACPI_TYPE_DEVICE:
779          case ACPI_TYPE_POWER:
780          case ACPI_TYPE_PROCESSOR:
781          case ACPI_TYPE_THERMAL:
782  
783              /* These are acceptable types - they all open a new scope */
784              break;
785  
786          case ACPI_TYPE_INTEGER:
787          case ACPI_TYPE_STRING:
788          case ACPI_TYPE_BUFFER:
789              /*
790               * These types we will allow, but we will change the type.
791               * This enables some existing code of the form:
792               *
793               *  Name (DEB, 0)
794               *  Scope (DEB) { ... }
795               *
796               * Which is used to workaround the fact that the MS interpreter
797               * does not allow Scope() forward references.
798               */
799              sprintf (AslGbl_MsgBuffer, "%s [%s], changing type to [Scope]",
800                  Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
801              AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);
802  
803              /* Switch the type to scope, open the new scope */
804  
805              Node->Type = ACPI_TYPE_LOCAL_SCOPE;
806              Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
807                  WalkState);
808              if (ACPI_FAILURE (Status))
809              {
810                  return_ACPI_STATUS (Status);
811              }
812              break;
813  
814          default:
815  
816              /* All other types are an error */
817  
818              sprintf (AslGbl_MsgBuffer, "%s [%s]", Op->Asl.ExternalName,
819                  AcpiUtGetTypeName (Node->Type));
820              AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);
821  
822              /*
823               * However, switch the type to be an actual scope so
824               * that compilation can continue without generating a whole
825               * cascade of additional errors. Open the new scope.
826               */
827              Node->Type = ACPI_TYPE_LOCAL_SCOPE;
828              Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
829                  WalkState);
830              if (ACPI_FAILURE (Status))
831              {
832                  return_ACPI_STATUS (Status);
833              }
834              break;
835          }
836  
837          Status = AE_OK;
838          goto FinishNode;
839  
840      default:
841  
842          ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
843          break;
844      }
845  
846      ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n",
847          Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType)));
848  
849      /* The name must not already exist */
850  
851      Flags |= ACPI_NS_ERROR_IF_FOUND;
852  
853      /*
854       * For opcodes that enter new names into the namespace,
855       * all prefix NameSegs must exist.
856       */
857      WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
858      if (((WalkState->OpInfo->Flags & AML_NAMED) ||
859          (WalkState->OpInfo->Flags & AML_CREATE)) &&
860          (Op->Asl.AmlOpcode != AML_EXTERNAL_OP))
861      {
862          Flags |= ACPI_NS_PREFIX_MUST_EXIST;
863      }
864  
865      /*
866       * Enter the named type into the internal namespace. We enter the name
867       * as we go downward in the parse tree. Any necessary subobjects that
868       * involve arguments to the opcode must be created as we go back up the
869       * parse tree later.
870       */
871      Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
872          ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
873      if (ACPI_FAILURE (Status))
874      {
875          if (Status == AE_ALREADY_EXISTS)
876          {
877              /* The name already exists in this scope */
878  
879              if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
880              {
881                  /* Allow multiple references to the same scope */
882  
883                  Node->Type = (UINT8) ObjectType;
884                  Status = AE_OK;
885              }
886              else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
887                       (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
888              {
889                  /*
890                   * Allow one create on an object or segment that was
891                   * previously declared External
892                   */
893                  Node->Flags &= ~ANOBJ_IS_EXTERNAL;
894                  Node->Type = (UINT8) ObjectType;
895  
896                  /* Just retyped a node, probably will need to open a scope */
897  
898                  if (AcpiNsOpensScope (ObjectType))
899                  {
900                      Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
901                      if (ACPI_FAILURE (Status))
902                      {
903                          return_ACPI_STATUS (Status);
904                      }
905                  }
906  
907                  Status = AE_OK;
908              }
909              else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) &&
910                       (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
911              {
912                  /*
913                   * Allow externals in same scope as the definition of the
914                   * actual object. Similar to C. Allows multiple definition
915                   * blocks that refer to each other in the same file.
916                   */
917                  Status = AE_OK;
918              }
919              else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
920                       (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) &&
921                       (ObjectType == ACPI_TYPE_ANY))
922              {
923                  /* Allow update of externals of unknown type. */
924  
925                  if (AcpiNsOpensScope (ActualObjectType))
926                  {
927                      Node->Type = (UINT8) ActualObjectType;
928                      Status = AE_OK;
929                  }
930                  else
931                  {
932                      sprintf (AslGbl_MsgBuffer, "%s [%s]", Op->Asl.ExternalName,
933                          AcpiUtGetTypeName (Node->Type));
934                      AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);
935                      return_ACPI_STATUS (AE_OK);
936                  }
937              }
938              else
939              {
940                  /* Valid error, object already exists */
941  
942                  AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
943                      Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op,
944                      Node->Op->Asl.ExternalName);
945                  return_ACPI_STATUS (AE_OK);
946              }
947          }
948          else if (AE_NOT_FOUND)
949          {
950              /*
951               * One or more prefix NameSegs of the NamePath do not exist
952               * (all of them must exist). Attempt to continue compilation
953               * by setting the current scope to the root.
954               */
955              Node = AcpiGbl_RootNode;
956              Status = AE_OK;
957          }
958          else
959          {
960              /* Flag all other errors as coming from the ACPICA core */
961  
962              AslCoreSubsystemError (Op, Status,
963                  "Failure from namespace lookup", FALSE);
964              return_ACPI_STATUS (Status);
965          }
966      }
967  
968      /* Check special names like _WAK and _PTS */
969  
970      LdCheckSpecialNames (Node, Op);
971  
972      if (ForceNewScope)
973      {
974          Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
975          if (ACPI_FAILURE (Status))
976          {
977              return_ACPI_STATUS (Status);
978          }
979      }
980  
981  FinishNode:
982      /*
983       * Point the parse node to the new namespace node, and point
984       * the Node back to the original Parse node
985       */
986      Op->Asl.Node = Node;
987      Node->Op = Op;
988  
989      /* Set the actual data type if appropriate (EXTERNAL term only) */
990  
991      if (ActualObjectType != ACPI_TYPE_ANY)
992      {
993          Node->Type = (UINT8) ActualObjectType;
994          Node->Value = ASL_EXTERNAL_METHOD;
995      }
996  
997      if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
998      {
999          /*
1000           * Get the method argument count from "Extra" and save
1001           * it in the namespace node
1002           */
1003          Node->Value = (UINT32) Op->Asl.Extra;
1004      }
1005  
1006      return_ACPI_STATUS (Status);
1007  }
1008  
1009  
1010  /*******************************************************************************
1011   *
1012   * FUNCTION:    LdCheckSpecialNames
1013   *
1014   * PARAMETERS:  Node        - Node that represents the named object
1015   *              Op          - Named object declaring this named object
1016   *
1017   * RETURN:      None
1018   *
1019   * DESCRIPTION: Check if certain named objects are declared in the incorrect
1020   *              scope. Special named objects are listed in
1021   *              AslGbl_SpecialNamedObjects and can only be declared at the root
1022   *              scope. _UID inside of a processor declaration must not be a
1023   *              string.
1024   *
1025   ******************************************************************************/
1026  
1027  static void
1028  LdCheckSpecialNames (
1029      ACPI_NAMESPACE_NODE     *Node,
1030      ACPI_PARSE_OBJECT       *Op)
1031  {
1032      UINT32                  i;
1033  
1034  
1035      for (i = 0; i < MAX_SPECIAL_NAMES; i++)
1036      {
1037          if (ACPI_COMPARE_NAMESEG(Node->Name.Ascii, AslGbl_SpecialNamedObjects[i]) &&
1038              Node->Parent != AcpiGbl_RootNode)
1039          {
1040              AslError (ASL_ERROR, ASL_MSG_INVALID_SPECIAL_NAME, Op, Op->Asl.ExternalName);
1041              return;
1042          }
1043      }
1044  
1045      if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, "_UID") &&
1046          Node->Parent->Type == ACPI_TYPE_PROCESSOR &&
1047          Node->Type == ACPI_TYPE_STRING)
1048      {
1049          AslError (ASL_ERROR, ASL_MSG_INVALID_PROCESSOR_UID , Op, "found a string");
1050      }
1051  }
1052  
1053  
1054  /*******************************************************************************
1055   *
1056   * FUNCTION:    LdNamespace2Begin
1057   *
1058   * PARAMETERS:  ASL_WALK_CALLBACK
1059   *
1060   * RETURN:      Status
1061   *
1062   * DESCRIPTION: Descending callback used during the pass 2 parse tree walk.
1063   *              Second pass resolves some forward references.
1064   *
1065   * Notes:
1066   * Currently only needs to handle the Alias operator.
1067   * Could be used to allow forward references from the Scope() operator, but
1068   * the MS interpreter does not allow this, so this compiler does not either.
1069   *
1070   ******************************************************************************/
1071  
1072  static ACPI_STATUS
1073  LdNamespace2Begin (
1074      ACPI_PARSE_OBJECT       *Op,
1075      UINT32                  Level,
1076      void                    *Context)
1077  {
1078      ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
1079      ACPI_STATUS             Status;
1080      ACPI_NAMESPACE_NODE     *Node;
1081      ACPI_OBJECT_TYPE        ObjectType;
1082      BOOLEAN                 ForceNewScope = FALSE;
1083      ACPI_PARSE_OBJECT       *Arg;
1084      char                    *Path;
1085      ACPI_NAMESPACE_NODE     *TargetNode;
1086  
1087  
1088      ACPI_FUNCTION_NAME (LdNamespace2Begin);
1089      ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
1090          Op, Op->Asl.ParseOpName));
1091  
1092  
1093      /* Ignore Ops with no namespace node */
1094  
1095      Node = Op->Asl.Node;
1096      if (!Node)
1097      {
1098          return (AE_OK);
1099      }
1100  
1101      /* Get the type to determine if we should push the scope */
1102  
1103      if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
1104          (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC))
1105      {
1106          ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
1107      }
1108      else
1109      {
1110          ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
1111      }
1112  
1113      /* Push scope for Resource Templates */
1114  
1115      if (Op->Asl.ParseOpcode == PARSEOP_NAME)
1116      {
1117          if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
1118          {
1119              ForceNewScope = TRUE;
1120          }
1121      }
1122  
1123      /* Push the scope stack */
1124  
1125      if (ForceNewScope || AcpiNsOpensScope (ObjectType))
1126      {
1127          Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
1128          if (ACPI_FAILURE (Status))
1129          {
1130              return_ACPI_STATUS (Status);
1131          }
1132      }
1133  
1134      if (Op->Asl.ParseOpcode == PARSEOP_ALIAS)
1135      {
1136          /*
1137           * Complete the alias node by getting and saving the target node.
1138           * First child is the alias target
1139           */
1140          Arg = Op->Asl.Child;
1141  
1142          /* Get the target pathname */
1143  
1144          Path = Arg->Asl.Namepath;
1145          if (!Path)
1146          {
1147              Status = UtInternalizeName (Arg->Asl.ExternalName, &Path);
1148              if (ACPI_FAILURE (Status))
1149              {
1150                  return (Status);
1151              }
1152          }
1153  
1154          /* Get the NS node associated with the target. It must exist. */
1155  
1156          Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
1157              ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
1158              WalkState, &TargetNode);
1159          if (ACPI_FAILURE (Status))
1160          {
1161              if (Status == AE_NOT_FOUND)
1162              {
1163                  /* Standalone NameSeg vs. NamePath */
1164  
1165                  if (strlen (Arg->Asl.ExternalName) == ACPI_NAMESEG_SIZE)
1166                  {
1167                      AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
1168                          Arg->Asl.ExternalName);
1169                  }
1170                  else
1171                  {
1172                      AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
1173                          Arg->Asl.ExternalName);
1174                  }
1175  
1176  #if 0
1177  /*
1178   * NOTE: Removed 10/2018 to enhance compiler error reporting. No
1179   * regressions seen.
1180   */
1181                  /*
1182                   * The name was not found, go ahead and create it.
1183                   * This prevents more errors later.
1184                   */
1185                  Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
1186                      ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
1187                      ACPI_NS_NO_UPSEARCH, WalkState, &Node);
1188  #endif
1189                  return (Status);
1190  /* Removed: return (AE_OK)*/
1191              }
1192  
1193              AslCoreSubsystemError (Op, Status,
1194                  "Failure from namespace lookup", FALSE);
1195              return (AE_OK);
1196          }
1197  
1198          /* Save the target node within the alias node */
1199  
1200          Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
1201      }
1202  
1203      return (AE_OK);
1204  }
1205  
1206  
1207  /*******************************************************************************
1208   *
1209   * FUNCTION:    LdCommonNamespaceEnd
1210   *
1211   * PARAMETERS:  ASL_WALK_CALLBACK
1212   *
1213   * RETURN:      Status
1214   *
1215   * DESCRIPTION: Ascending callback used during the loading of the namespace,
1216   *              We only need to worry about managing the scope stack here.
1217   *
1218   ******************************************************************************/
1219  
1220  static ACPI_STATUS
1221  LdCommonNamespaceEnd (
1222      ACPI_PARSE_OBJECT       *Op,
1223      UINT32                  Level,
1224      void                    *Context)
1225  {
1226      ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
1227      ACPI_OBJECT_TYPE        ObjectType;
1228      BOOLEAN                 ForceNewScope = FALSE;
1229  
1230  
1231      ACPI_FUNCTION_NAME (LdCommonNamespaceEnd);
1232  
1233  
1234      /* We are only interested in opcodes that have an associated name */
1235  
1236      if (!Op->Asl.Namepath)
1237      {
1238          return (AE_OK);
1239      }
1240  
1241      /* Get the type to determine if we should pop the scope */
1242  
1243      if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
1244          (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC))
1245      {
1246          /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */
1247  
1248          ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
1249      }
1250      else
1251      {
1252          ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
1253      }
1254  
1255      /* Pop scope that was pushed for Resource Templates */
1256  
1257      if (Op->Asl.ParseOpcode == PARSEOP_NAME)
1258      {
1259          if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
1260          {
1261              ForceNewScope = TRUE;
1262          }
1263      }
1264  
1265      /* Pop the scope stack */
1266  
1267      if (ForceNewScope || AcpiNsOpensScope (ObjectType))
1268      {
1269          ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1270              "(%s): Popping scope for Op [%s] %p\n",
1271              AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op));
1272  
1273          (void) AcpiDsScopeStackPop (WalkState);
1274      }
1275  
1276      return (AE_OK);
1277  }
1278