xref: /freebsd/sys/contrib/dev/acpica/compiler/aslload.c (revision b61949dd20826680c4dc0286aa7312b2e924ebea)
1  /******************************************************************************
2   *
3   * Module Name: dswload - Dispatcher namespace load callbacks
4   *
5   *****************************************************************************/
6  
7  /*
8   * Copyright (C) 2000 - 2013, Intel Corp.
9   * All rights reserved.
10   *
11   * Redistribution and use in source and binary forms, with or without
12   * modification, are permitted provided that the following conditions
13   * are met:
14   * 1. Redistributions of source code must retain the above copyright
15   *    notice, this list of conditions, and the following disclaimer,
16   *    without modification.
17   * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18   *    substantially similar to the "NO WARRANTY" disclaimer below
19   *    ("Disclaimer") and any redistribution must be conditioned upon
20   *    including a substantially similar Disclaimer requirement for further
21   *    binary redistribution.
22   * 3. Neither the names of the above-listed copyright holders nor the names
23   *    of any contributors may be used to endorse or promote products derived
24   *    from this software without specific prior written permission.
25   *
26   * Alternatively, this software may be distributed under the terms of the
27   * GNU General Public License ("GPL") version 2 as published by the Free
28   * Software Foundation.
29   *
30   * NO WARRANTY
31   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35   * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40   * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41   * POSSIBILITY OF SUCH DAMAGES.
42   */
43  
44  #define __ASLLOAD_C__
45  
46  #include <contrib/dev/acpica/compiler/aslcompiler.h>
47  #include <contrib/dev/acpica/include/amlcode.h>
48  #include <contrib/dev/acpica/include/acdispat.h>
49  #include <contrib/dev/acpica/include/acnamesp.h>
50  
51  #include "aslcompiler.y.h"
52  
53  #define _COMPONENT          ACPI_COMPILER
54          ACPI_MODULE_NAME    ("aslload")
55  
56  /* Local prototypes */
57  
58  static ACPI_STATUS
59  LdLoadFieldElements (
60      ACPI_PARSE_OBJECT       *Op,
61      ACPI_WALK_STATE         *WalkState);
62  
63  static ACPI_STATUS
64  LdLoadResourceElements (
65      ACPI_PARSE_OBJECT       *Op,
66      ACPI_WALK_STATE         *WalkState);
67  
68  static ACPI_STATUS
69  LdNamespace1Begin (
70      ACPI_PARSE_OBJECT       *Op,
71      UINT32                  Level,
72      void                    *Context);
73  
74  static ACPI_STATUS
75  LdNamespace2Begin (
76      ACPI_PARSE_OBJECT       *Op,
77      UINT32                  Level,
78      void                    *Context);
79  
80  static ACPI_STATUS
81  LdCommonNamespaceEnd (
82      ACPI_PARSE_OBJECT       *Op,
83      UINT32                  Level,
84      void                    *Context);
85  
86  
87  /*******************************************************************************
88   *
89   * FUNCTION:    LdLoadNamespace
90   *
91   * PARAMETERS:  RootOp      - Root of the parse tree
92   *
93   * RETURN:      Status
94   *
95   * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the
96   *              named ASL/AML objects into the namespace. The namespace is
97   *              constructed in order to resolve named references and references
98   *              to named fields within resource templates/descriptors.
99   *
100   ******************************************************************************/
101  
102  ACPI_STATUS
103  LdLoadNamespace (
104      ACPI_PARSE_OBJECT       *RootOp)
105  {
106      ACPI_WALK_STATE         *WalkState;
107  
108  
109      DbgPrint (ASL_DEBUG_OUTPUT, "\nCreating namespace\n\n");
110  
111      /* Create a new walk state */
112  
113      WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
114      if (!WalkState)
115      {
116          return (AE_NO_MEMORY);
117      }
118  
119      /* Walk the entire parse tree, first pass */
120  
121      TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin,
122          LdCommonNamespaceEnd, WalkState);
123  
124      /* Second pass to handle forward references */
125  
126      TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin,
127          LdCommonNamespaceEnd, WalkState);
128  
129      /* Dump the namespace if debug is enabled */
130  
131      AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX);
132      return (AE_OK);
133  }
134  
135  
136  /*******************************************************************************
137   *
138   * FUNCTION:    LdLoadFieldElements
139   *
140   * PARAMETERS:  Op              - Parent node (Field)
141   *              WalkState       - Current walk state
142   *
143   * RETURN:      Status
144   *
145   * DESCRIPTION: Enter the named elements of the field (children of the parent)
146   *              into the namespace.
147   *
148   ******************************************************************************/
149  
150  static ACPI_STATUS
151  LdLoadFieldElements (
152      ACPI_PARSE_OBJECT       *Op,
153      ACPI_WALK_STATE         *WalkState)
154  {
155      ACPI_PARSE_OBJECT       *Child = NULL;
156      ACPI_NAMESPACE_NODE     *Node;
157      ACPI_STATUS             Status;
158  
159  
160      /* Get the first named field element */
161  
162      switch (Op->Asl.AmlOpcode)
163      {
164      case AML_BANK_FIELD_OP:
165  
166          Child = UtGetArg (Op, 6);
167          break;
168  
169      case AML_INDEX_FIELD_OP:
170  
171          Child = UtGetArg (Op, 5);
172          break;
173  
174      case AML_FIELD_OP:
175  
176          Child = UtGetArg (Op, 4);
177          break;
178  
179      default:
180  
181          /* No other opcodes should arrive here */
182  
183          return (AE_BAD_PARAMETER);
184      }
185  
186      /* Enter all elements into the namespace */
187  
188      while (Child)
189      {
190          switch (Child->Asl.AmlOpcode)
191          {
192          case AML_INT_RESERVEDFIELD_OP:
193          case AML_INT_ACCESSFIELD_OP:
194          case AML_INT_CONNECTION_OP:
195              break;
196  
197          default:
198  
199              Status = AcpiNsLookup (WalkState->ScopeInfo,
200                          Child->Asl.Value.String,
201                          ACPI_TYPE_LOCAL_REGION_FIELD,
202                          ACPI_IMODE_LOAD_PASS1,
203                          ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
204                              ACPI_NS_ERROR_IF_FOUND,
205                          NULL, &Node);
206              if (ACPI_FAILURE (Status))
207              {
208                  if (Status != AE_ALREADY_EXISTS)
209                  {
210                      AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child,
211                          Child->Asl.Value.String);
212                      return (Status);
213                  }
214  
215                  /*
216                   * The name already exists in this scope
217                   * But continue processing the elements
218                   */
219                  AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,
220                      Child->Asl.Value.String);
221              }
222              else
223              {
224                  Child->Asl.Node = Node;
225                  Node->Op = Child;
226              }
227              break;
228          }
229  
230          Child = Child->Asl.Next;
231      }
232  
233      return (AE_OK);
234  }
235  
236  
237  /*******************************************************************************
238   *
239   * FUNCTION:    LdLoadResourceElements
240   *
241   * PARAMETERS:  Op              - Parent node (Resource Descriptor)
242   *              WalkState       - Current walk state
243   *
244   * RETURN:      Status
245   *
246   * DESCRIPTION: Enter the named elements of the resource descriptor (children
247   *              of the parent) into the namespace.
248   *
249   * NOTE: In the real AML namespace, these named elements never exist. But
250   *       we simply use the namespace here as a symbol table so we can look
251   *       them up as they are referenced.
252   *
253   ******************************************************************************/
254  
255  static ACPI_STATUS
256  LdLoadResourceElements (
257      ACPI_PARSE_OBJECT       *Op,
258      ACPI_WALK_STATE         *WalkState)
259  {
260      ACPI_PARSE_OBJECT       *InitializerOp = NULL;
261      ACPI_NAMESPACE_NODE     *Node;
262      ACPI_STATUS             Status;
263  
264  
265      /*
266       * Enter the resource name into the namespace. Name must not already exist.
267       * This opens a scope, so later field names are guaranteed to be new/unique.
268       */
269      Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath,
270                  ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1,
271                  ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND,
272                  WalkState, &Node);
273      if (ACPI_FAILURE (Status))
274      {
275          if (Status == AE_ALREADY_EXISTS)
276          {
277              /* Actual node causing the error was saved in ParentMethod */
278  
279              AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS,
280                  (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath);
281              return (AE_OK);
282          }
283          return (Status);
284      }
285  
286      Node->Value = (UINT32) Op->Asl.Value.Integer;
287      Node->Op = Op;
288      Op->Asl.Node = Node;
289  
290      /*
291       * Now enter the predefined fields, for easy lookup when referenced
292       * by the source ASL
293       */
294      InitializerOp = ASL_GET_CHILD_NODE (Op);
295      while (InitializerOp)
296      {
297          if (InitializerOp->Asl.ExternalName)
298          {
299              Status = AcpiNsLookup (WalkState->ScopeInfo,
300                          InitializerOp->Asl.ExternalName,
301                          ACPI_TYPE_LOCAL_RESOURCE_FIELD,
302                          ACPI_IMODE_LOAD_PASS1,
303                          ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE,
304                          NULL, &Node);
305              if (ACPI_FAILURE (Status))
306              {
307                  return (Status);
308              }
309  
310              /*
311               * Store the field offset and length in the namespace node
312               * so it can be used when the field is referenced
313               */
314              Node->Value = InitializerOp->Asl.Value.Tag.BitOffset;
315              Node->Length = InitializerOp->Asl.Value.Tag.BitLength;
316              InitializerOp->Asl.Node = Node;
317              Node->Op = InitializerOp;
318          }
319  
320          InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
321      }
322  
323      return (AE_OK);
324  }
325  
326  
327  /*******************************************************************************
328   *
329   * FUNCTION:    LdNamespace1Begin
330   *
331   * PARAMETERS:  ASL_WALK_CALLBACK
332   *
333   * RETURN:      Status
334   *
335   * DESCRIPTION: Descending callback used during the parse tree walk. If this
336   *              is a named AML opcode, enter into the namespace
337   *
338   ******************************************************************************/
339  
340  static ACPI_STATUS
341  LdNamespace1Begin (
342      ACPI_PARSE_OBJECT       *Op,
343      UINT32                  Level,
344      void                    *Context)
345  {
346      ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
347      ACPI_NAMESPACE_NODE     *Node;
348      ACPI_STATUS             Status;
349      ACPI_OBJECT_TYPE        ObjectType;
350      ACPI_OBJECT_TYPE        ActualObjectType = ACPI_TYPE_ANY;
351      char                    *Path;
352      UINT32                  Flags = ACPI_NS_NO_UPSEARCH;
353      ACPI_PARSE_OBJECT       *Arg;
354      UINT32                  i;
355      BOOLEAN                 ForceNewScope = FALSE;
356  
357  
358      ACPI_FUNCTION_NAME (LdNamespace1Begin);
359      ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
360          Op, Op->Asl.ParseOpName));
361  
362  
363      /*
364       * We are only interested in opcodes that have an associated name
365       * (or multiple names)
366       */
367      switch (Op->Asl.AmlOpcode)
368      {
369      case AML_BANK_FIELD_OP:
370      case AML_INDEX_FIELD_OP:
371      case AML_FIELD_OP:
372  
373          Status = LdLoadFieldElements (Op, WalkState);
374          return (Status);
375  
376      default:
377  
378          /* All other opcodes go below */
379  
380          break;
381      }
382  
383      /* Check if this object has already been installed in the namespace */
384  
385      if (Op->Asl.Node)
386      {
387          return (AE_OK);
388      }
389  
390      Path = Op->Asl.Namepath;
391      if (!Path)
392      {
393          return (AE_OK);
394      }
395  
396      /* Map the raw opcode into an internal object type */
397  
398      switch (Op->Asl.ParseOpcode)
399      {
400      case PARSEOP_NAME:
401  
402          Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
403          Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
404  
405          /*
406           * If this name refers to a ResourceTemplate, we will need to open
407           * a new scope so that the resource subfield names can be entered into
408           * the namespace underneath this name
409           */
410          if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
411          {
412              ForceNewScope = TRUE;
413          }
414  
415          /* Get the data type associated with the named object, not the name itself */
416  
417          /* Log2 loop to convert from Btype (binary) to Etype (encoded) */
418  
419          ObjectType = 1;
420          for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2)
421          {
422              ObjectType++;
423          }
424          break;
425  
426  
427      case PARSEOP_EXTERNAL:
428          /*
429           * "External" simply enters a name and type into the namespace.
430           * We must be careful to not open a new scope, however, no matter
431           * what type the external name refers to (e.g., a method)
432           *
433           * first child is name, next child is ObjectType
434           */
435          ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer;
436          ObjectType = ACPI_TYPE_ANY;
437  
438          /*
439           * We will mark every new node along the path as "External". This
440           * allows some or all of the nodes to be created later in the ASL
441           * code. Handles cases like this:
442           *
443           *   External (\_SB_.PCI0.ABCD, IntObj)
444           *   Scope (_SB_)
445           *   {
446           *       Device (PCI0)
447           *       {
448           *       }
449           *   }
450           *   Method (X)
451           *   {
452           *       Store (\_SB_.PCI0.ABCD, Local0)
453           *   }
454           */
455          Flags |= ACPI_NS_EXTERNAL;
456          break;
457  
458      case PARSEOP_DEFAULT_ARG:
459  
460          if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)
461          {
462              Status = LdLoadResourceElements (Op, WalkState);
463              return_ACPI_STATUS (Status);
464          }
465  
466          ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
467          break;
468  
469  
470      case PARSEOP_SCOPE:
471          /*
472           * The name referenced by Scope(Name) must already exist at this point.
473           * In other words, forward references for Scope() are not supported.
474           * The only real reason for this is that the MS interpreter cannot
475           * handle this case. Perhaps someday this case can go away.
476           */
477          Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
478                      ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
479                      WalkState, &(Node));
480          if (ACPI_FAILURE (Status))
481          {
482              if (Status == AE_NOT_FOUND)
483              {
484                  /* The name was not found, go ahead and create it */
485  
486                  Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
487                              ACPI_TYPE_LOCAL_SCOPE,
488                              ACPI_IMODE_LOAD_PASS1, Flags,
489                              WalkState, &(Node));
490                  if (ACPI_FAILURE (Status))
491                  {
492                      return_ACPI_STATUS (Status);
493                  }
494  
495                  /*
496                   * However, this is an error -- primarily because the MS
497                   * interpreter can't handle a forward reference from the
498                   * Scope() operator.
499                   */
500                  AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
501                      Op->Asl.ExternalName);
502                  AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op,
503                      Op->Asl.ExternalName);
504                  goto FinishNode;
505              }
506  
507              AslCoreSubsystemError (Op, Status,
508                  "Failure from namespace lookup", FALSE);
509  
510              return_ACPI_STATUS (Status);
511          }
512  
513          /* We found a node with this name, now check the type */
514  
515          switch (Node->Type)
516          {
517          case ACPI_TYPE_LOCAL_SCOPE:
518          case ACPI_TYPE_DEVICE:
519          case ACPI_TYPE_POWER:
520          case ACPI_TYPE_PROCESSOR:
521          case ACPI_TYPE_THERMAL:
522  
523              /* These are acceptable types - they all open a new scope */
524              break;
525  
526          case ACPI_TYPE_INTEGER:
527          case ACPI_TYPE_STRING:
528          case ACPI_TYPE_BUFFER:
529              /*
530               * These types we will allow, but we will change the type.
531               * This enables some existing code of the form:
532               *
533               *  Name (DEB, 0)
534               *  Scope (DEB) { ... }
535               *
536               * Which is used to workaround the fact that the MS interpreter
537               * does not allow Scope() forward references.
538               */
539              sprintf (MsgBuffer, "%s [%s], changing type to [Scope]",
540                  Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
541              AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
542  
543              /* Switch the type to scope, open the new scope */
544  
545              Node->Type = ACPI_TYPE_LOCAL_SCOPE;
546              Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
547                          WalkState);
548              if (ACPI_FAILURE (Status))
549              {
550                  return_ACPI_STATUS (Status);
551              }
552              break;
553  
554          default:
555  
556              /* All other types are an error */
557  
558              sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName,
559                  AcpiUtGetTypeName (Node->Type));
560              AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
561  
562              /*
563               * However, switch the type to be an actual scope so
564               * that compilation can continue without generating a whole
565               * cascade of additional errors. Open the new scope.
566               */
567              Node->Type = ACPI_TYPE_LOCAL_SCOPE;
568              Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
569                          WalkState);
570              if (ACPI_FAILURE (Status))
571              {
572                  return_ACPI_STATUS (Status);
573              }
574              break;
575          }
576  
577          Status = AE_OK;
578          goto FinishNode;
579  
580  
581      default:
582  
583          ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
584          break;
585      }
586  
587  
588      ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n",
589              Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType)));
590  
591      /* The name must not already exist */
592  
593      Flags |= ACPI_NS_ERROR_IF_FOUND;
594  
595      /*
596       * Enter the named type into the internal namespace. We enter the name
597       * as we go downward in the parse tree. Any necessary subobjects that
598       * involve arguments to the opcode must be created as we go back up the
599       * parse tree later.
600       */
601      Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
602                      ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
603      if (ACPI_FAILURE (Status))
604      {
605          if (Status == AE_ALREADY_EXISTS)
606          {
607              /* The name already exists in this scope */
608  
609              if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
610              {
611                  /* Allow multiple references to the same scope */
612  
613                  Node->Type = (UINT8) ObjectType;
614                  Status = AE_OK;
615              }
616              else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
617                       (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
618              {
619                  /*
620                   * Allow one create on an object or segment that was
621                   * previously declared External
622                   */
623                  Node->Flags &= ~ANOBJ_IS_EXTERNAL;
624                  Node->Type = (UINT8) ObjectType;
625  
626                  /* Just retyped a node, probably will need to open a scope */
627  
628                  if (AcpiNsOpensScope (ObjectType))
629                  {
630                      Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
631                      if (ACPI_FAILURE (Status))
632                      {
633                          return_ACPI_STATUS (Status);
634                      }
635                  }
636                  Status = AE_OK;
637              }
638              else
639              {
640                  /* Valid error, object already exists */
641  
642                  AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
643                      Op->Asl.ExternalName);
644                  return_ACPI_STATUS (AE_OK);
645              }
646          }
647          else
648          {
649              AslCoreSubsystemError (Op, Status,
650                  "Failure from namespace lookup", FALSE);
651              return_ACPI_STATUS (Status);
652          }
653      }
654  
655      if (ForceNewScope)
656      {
657          Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
658          if (ACPI_FAILURE (Status))
659          {
660              return_ACPI_STATUS (Status);
661          }
662      }
663  
664  FinishNode:
665      /*
666       * Point the parse node to the new namespace node, and point
667       * the Node back to the original Parse node
668       */
669      Op->Asl.Node = Node;
670      Node->Op = Op;
671  
672      /* Set the actual data type if appropriate (EXTERNAL term only) */
673  
674      if (ActualObjectType != ACPI_TYPE_ANY)
675      {
676          Node->Type = (UINT8) ActualObjectType;
677          Node->Value = ASL_EXTERNAL_METHOD;
678      }
679  
680      if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
681      {
682          /*
683           * Get the method argument count from "Extra" and save
684           * it in the namespace node
685           */
686          Node->Value = (UINT32) Op->Asl.Extra;
687      }
688  
689      return_ACPI_STATUS (Status);
690  }
691  
692  
693  /*******************************************************************************
694   *
695   * FUNCTION:    LdNamespace2Begin
696   *
697   * PARAMETERS:  ASL_WALK_CALLBACK
698   *
699   * RETURN:      Status
700   *
701   * DESCRIPTION: Descending callback used during the pass 2 parse tree walk.
702   *              Second pass resolves some forward references.
703   *
704   * Notes:
705   * Currently only needs to handle the Alias operator.
706   * Could be used to allow forward references from the Scope() operator, but
707   * the MS interpreter does not allow this, so this compiler does not either.
708   *
709   ******************************************************************************/
710  
711  static ACPI_STATUS
712  LdNamespace2Begin (
713      ACPI_PARSE_OBJECT       *Op,
714      UINT32                  Level,
715      void                    *Context)
716  {
717      ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
718      ACPI_STATUS             Status;
719      ACPI_NAMESPACE_NODE     *Node;
720      ACPI_OBJECT_TYPE        ObjectType;
721      BOOLEAN                 ForceNewScope = FALSE;
722      ACPI_PARSE_OBJECT       *Arg;
723      char                    *Path;
724      ACPI_NAMESPACE_NODE     *TargetNode;
725  
726  
727      ACPI_FUNCTION_NAME (LdNamespace2Begin);
728      ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
729          Op, Op->Asl.ParseOpName));
730  
731  
732      /* Ignore Ops with no namespace node */
733  
734      Node = Op->Asl.Node;
735      if (!Node)
736      {
737          return (AE_OK);
738      }
739  
740      /* Get the type to determine if we should push the scope */
741  
742      if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
743          (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
744      {
745          ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
746      }
747      else
748      {
749          ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
750      }
751  
752      /* Push scope for Resource Templates */
753  
754      if (Op->Asl.ParseOpcode == PARSEOP_NAME)
755      {
756          if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
757          {
758              ForceNewScope = TRUE;
759          }
760      }
761  
762      /* Push the scope stack */
763  
764      if (ForceNewScope || AcpiNsOpensScope (ObjectType))
765      {
766          Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
767          if (ACPI_FAILURE (Status))
768          {
769              return_ACPI_STATUS (Status);
770          }
771      }
772  
773      if (Op->Asl.ParseOpcode == PARSEOP_ALIAS)
774      {
775          /* Complete the alias node by getting and saving the target node */
776  
777          /* First child is the alias target */
778  
779          Arg = Op->Asl.Child;
780  
781          /* Get the target pathname */
782  
783          Path = Arg->Asl.Namepath;
784          if (!Path)
785          {
786              Status = UtInternalizeName (Arg->Asl.ExternalName, &Path);
787              if (ACPI_FAILURE (Status))
788              {
789                  return (Status);
790              }
791          }
792  
793          /* Get the NS node associated with the target. It must exist. */
794  
795          Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
796                      ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
797                      WalkState, &TargetNode);
798          if (ACPI_FAILURE (Status))
799          {
800              if (Status == AE_NOT_FOUND)
801              {
802                  AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
803                      Op->Asl.ExternalName);
804  
805                  /*
806                   * The name was not found, go ahead and create it.
807                   * This prevents more errors later.
808                   */
809                  Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
810                              ACPI_TYPE_ANY,
811                              ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH,
812                              WalkState, &(Node));
813                  return (AE_OK);
814              }
815  
816              AslCoreSubsystemError (Op, Status,
817                  "Failure from namespace lookup", FALSE);
818              return (AE_OK);
819          }
820  
821          /* Save the target node within the alias node */
822  
823          Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
824      }
825  
826      return (AE_OK);
827  }
828  
829  
830  /*******************************************************************************
831   *
832   * FUNCTION:    LdCommonNamespaceEnd
833   *
834   * PARAMETERS:  ASL_WALK_CALLBACK
835   *
836   * RETURN:      Status
837   *
838   * DESCRIPTION: Ascending callback used during the loading of the namespace,
839   *              We only need to worry about managing the scope stack here.
840   *
841   ******************************************************************************/
842  
843  static ACPI_STATUS
844  LdCommonNamespaceEnd (
845      ACPI_PARSE_OBJECT       *Op,
846      UINT32                  Level,
847      void                    *Context)
848  {
849      ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
850      ACPI_OBJECT_TYPE        ObjectType;
851      BOOLEAN                 ForceNewScope = FALSE;
852  
853  
854      ACPI_FUNCTION_NAME (LdCommonNamespaceEnd);
855  
856  
857      /* We are only interested in opcodes that have an associated name */
858  
859      if (!Op->Asl.Namepath)
860      {
861          return (AE_OK);
862      }
863  
864      /* Get the type to determine if we should pop the scope */
865  
866      if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
867          (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
868      {
869          /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */
870  
871          ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
872      }
873      else
874      {
875          ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
876      }
877  
878      /* Pop scope that was pushed for Resource Templates */
879  
880      if (Op->Asl.ParseOpcode == PARSEOP_NAME)
881      {
882          if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
883          {
884              ForceNewScope = TRUE;
885          }
886      }
887  
888      /* Pop the scope stack */
889  
890      if (ForceNewScope || AcpiNsOpensScope (ObjectType))
891      {
892          ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
893              "(%s): Popping scope for Op [%s] %p\n",
894              AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op));
895  
896          (void) AcpiDsScopeStackPop (WalkState);
897      }
898  
899      return (AE_OK);
900  }
901