1 /******************************************************************************
2 *
3 * Module Name: dswload - Dispatcher namespace load callbacks
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2014, 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 "aslcompiler.h"
47 #include "amlcode.h"
48 #include "acdispat.h"
49 #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 }