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