ReactOS 0.4.16-dev-329-g9223134
dsutils.c
Go to the documentation of this file.
1/*******************************************************************************
2 *
3 * Module Name: dsutils - Dispatcher utilities
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2022, 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 MERCHANTABILITY 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 "acpi.h"
45#include "accommon.h"
46#include "acparser.h"
47#include "amlcode.h"
48#include "acdispat.h"
49#include "acinterp.h"
50#include "acnamesp.h"
51#include "acdebug.h"
52
53#define _COMPONENT ACPI_DISPATCHER
54 ACPI_MODULE_NAME ("dsutils")
55
56
57/*******************************************************************************
58 *
59 * FUNCTION: AcpiDsClearImplicitReturn
60 *
61 * PARAMETERS: WalkState - Current State
62 *
63 * RETURN: None.
64 *
65 * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
66 * to delete "stale" return values (if enabled, the return value
67 * from every operator is saved at least momentarily, in case the
68 * parent method exits.)
69 *
70 ******************************************************************************/
71
72void
74 ACPI_WALK_STATE *WalkState)
75{
76 ACPI_FUNCTION_NAME (DsClearImplicitReturn);
77
78
79 /*
80 * Slack must be enabled for this feature
81 */
82 if (!AcpiGbl_EnableInterpreterSlack)
83 {
84 return;
85 }
86
87 if (WalkState->ImplicitReturnObj)
88 {
89 /*
90 * Delete any "stale" implicit return. However, in
91 * complex statements, the implicit return value can be
92 * bubbled up several levels.
93 */
95 "Removing reference on stale implicit return obj %p\n",
96 WalkState->ImplicitReturnObj));
97
98 AcpiUtRemoveReference (WalkState->ImplicitReturnObj);
99 WalkState->ImplicitReturnObj = NULL;
100 }
101}
102
103
104/*******************************************************************************
105 *
106 * FUNCTION: AcpiDsDoImplicitReturn
107 *
108 * PARAMETERS: ReturnDesc - The return value
109 * WalkState - Current State
110 * AddReference - True if a reference should be added to the
111 * return object
112 *
113 * RETURN: TRUE if implicit return enabled, FALSE otherwise
114 *
115 * DESCRIPTION: Implements the optional "implicit return". We save the result
116 * of every ASL operator and control method invocation in case the
117 * parent method exit. Before storing a new return value, we
118 * delete the previous return value.
119 *
120 ******************************************************************************/
121
124 ACPI_OPERAND_OBJECT *ReturnDesc,
125 ACPI_WALK_STATE *WalkState,
126 BOOLEAN AddReference)
127{
128 ACPI_FUNCTION_NAME (DsDoImplicitReturn);
129
130
131 /*
132 * Slack must be enabled for this feature, and we must
133 * have a valid return object
134 */
135 if ((!AcpiGbl_EnableInterpreterSlack) ||
136 (!ReturnDesc))
137 {
138 return (FALSE);
139 }
140
142 "Result %p will be implicitly returned; Prev=%p\n",
143 ReturnDesc,
144 WalkState->ImplicitReturnObj));
145
146 /*
147 * Delete any "stale" implicit return value first. However, in
148 * complex statements, the implicit return value can be
149 * bubbled up several levels, so we don't clear the value if it
150 * is the same as the ReturnDesc.
151 */
152 if (WalkState->ImplicitReturnObj)
153 {
154 if (WalkState->ImplicitReturnObj == ReturnDesc)
155 {
156 return (TRUE);
157 }
158 AcpiDsClearImplicitReturn (WalkState);
159 }
160
161 /* Save the implicit return value, add a reference if requested */
162
163 WalkState->ImplicitReturnObj = ReturnDesc;
164 if (AddReference)
165 {
166 AcpiUtAddReference (ReturnDesc);
167 }
168
169 return (TRUE);
170}
171
172
173/*******************************************************************************
174 *
175 * FUNCTION: AcpiDsIsResultUsed
176 *
177 * PARAMETERS: Op - Current Op
178 * WalkState - Current State
179 *
180 * RETURN: TRUE if result is used, FALSE otherwise
181 *
182 * DESCRIPTION: Check if a result object will be used by the parent
183 *
184 ******************************************************************************/
185
189 ACPI_WALK_STATE *WalkState)
190{
191 const ACPI_OPCODE_INFO *ParentInfo;
192
193 ACPI_FUNCTION_TRACE_PTR (DsIsResultUsed, Op);
194
195
196 /* Must have both an Op and a Result Object */
197
198 if (!Op)
199 {
200 ACPI_ERROR ((AE_INFO, "Null Op"));
202 }
203
204 /*
205 * We know that this operator is not a
206 * Return() operator (would not come here.) The following code is the
207 * optional support for a so-called "implicit return". Some AML code
208 * assumes that the last value of the method is "implicitly" returned
209 * to the caller. Just save the last result as the return value.
210 * NOTE: this is optional because the ASL language does not actually
211 * support this behavior.
212 */
213 (void) AcpiDsDoImplicitReturn (WalkState->ResultObj, WalkState, TRUE);
214
215 /*
216 * Now determine if the parent will use the result
217 *
218 * If there is no parent, or the parent is a ScopeOp, we are executing
219 * at the method level. An executing method typically has no parent,
220 * since each method is parsed separately. A method invoked externally
221 * via ExecuteControlMethod has a ScopeOp as the parent.
222 */
223 if ((!Op->Common.Parent) ||
224 (Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP))
225 {
226 /* No parent, the return value cannot possibly be used */
227
229 "At Method level, result of [%s] not used\n",
230 AcpiPsGetOpcodeName (Op->Common.AmlOpcode)));
232 }
233
234 /* Get info on the parent. The RootOp is AML_SCOPE */
235
236 ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode);
237 if (ParentInfo->Class == AML_CLASS_UNKNOWN)
238 {
240 "Unknown parent opcode Op=%p", Op));
242 }
243
244 /*
245 * Decide what to do with the result based on the parent. If
246 * the parent opcode will not use the result, delete the object.
247 * Otherwise leave it as is, it will be deleted when it is used
248 * as an operand later.
249 */
250 switch (ParentInfo->Class)
251 {
253
254 switch (Op->Common.Parent->Common.AmlOpcode)
255 {
256 case AML_RETURN_OP:
257
258 /* Never delete the return value associated with a return opcode */
259
260 goto ResultUsed;
261
262 case AML_IF_OP:
263 case AML_WHILE_OP:
264 /*
265 * If we are executing the predicate AND this is the predicate op,
266 * we will use the return value
267 */
268 if ((WalkState->ControlState->Common.State ==
270 (WalkState->ControlState->Control.PredicateOp == Op))
271 {
272 goto ResultUsed;
273 }
274 break;
275
276 default:
277
278 /* Ignore other control opcodes */
279
280 break;
281 }
282
283 /* The general control opcode returns no result */
284
285 goto ResultNotUsed;
286
287 case AML_CLASS_CREATE:
288 /*
289 * These opcodes allow TermArg(s) as operands and therefore
290 * the operands can be method calls. The result is used.
291 */
292 goto ResultUsed;
293
295
296 if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP) ||
297 (Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP) ||
298 (Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
299 (Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP) ||
300 (Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP) ||
301 (Op->Common.Parent->Common.AmlOpcode == AML_INT_EVAL_SUBTREE_OP) ||
302 (Op->Common.Parent->Common.AmlOpcode == AML_BANK_FIELD_OP))
303 {
304 /*
305 * These opcodes allow TermArg(s) as operands and therefore
306 * the operands can be method calls. The result is used.
307 */
308 goto ResultUsed;
309 }
310
311 goto ResultNotUsed;
312
313 default:
314 /*
315 * In all other cases. the parent will actually use the return
316 * object, so keep it.
317 */
318 goto ResultUsed;
319 }
320
321
322ResultUsed:
324 "Result of [%s] used by Parent [%s] Op=%p\n",
325 AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
326 AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
327
329
330
331ResultNotUsed:
333 "Result of [%s] not used by Parent [%s] Op=%p\n",
334 AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
335 AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
336
338}
339
340
341/*******************************************************************************
342 *
343 * FUNCTION: AcpiDsDeleteResultIfNotUsed
344 *
345 * PARAMETERS: Op - Current parse Op
346 * ResultObj - Result of the operation
347 * WalkState - Current state
348 *
349 * RETURN: Status
350 *
351 * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
352 * result descriptor, check if the parent opcode will actually use
353 * this result. If not, delete the result now so that it will
354 * not become orphaned.
355 *
356 ******************************************************************************/
357
358void
361 ACPI_OPERAND_OBJECT *ResultObj,
362 ACPI_WALK_STATE *WalkState)
363{
364 ACPI_OPERAND_OBJECT *ObjDesc;
366
367
368 ACPI_FUNCTION_TRACE_PTR (DsDeleteResultIfNotUsed, ResultObj);
369
370
371 if (!Op)
372 {
373 ACPI_ERROR ((AE_INFO, "Null Op"));
375 }
376
377 if (!ResultObj)
378 {
380 }
381
382 if (!AcpiDsIsResultUsed (Op, WalkState))
383 {
384 /* Must pop the result stack (ObjDesc should be equal to ResultObj) */
385
386 Status = AcpiDsResultPop (&ObjDesc, WalkState);
387 if (ACPI_SUCCESS (Status))
388 {
389 AcpiUtRemoveReference (ResultObj);
390 }
391 }
392
394}
395
396
397/*******************************************************************************
398 *
399 * FUNCTION: AcpiDsResolveOperands
400 *
401 * PARAMETERS: WalkState - Current walk state with operands on stack
402 *
403 * RETURN: Status
404 *
405 * DESCRIPTION: Resolve all operands to their values. Used to prepare
406 * arguments to a control method invocation (a call from one
407 * method to another.)
408 *
409 ******************************************************************************/
410
413 ACPI_WALK_STATE *WalkState)
414{
415 UINT32 i;
417
418
419 ACPI_FUNCTION_TRACE_PTR (DsResolveOperands, WalkState);
420
421
422 /*
423 * Attempt to resolve each of the valid operands
424 * Method arguments are passed by reference, not by value. This means
425 * that the actual objects are passed, not copies of the objects.
426 */
427 for (i = 0; i < WalkState->NumOperands; i++)
428 {
429 Status = AcpiExResolveToValue (&WalkState->Operands[i], WalkState);
430 if (ACPI_FAILURE (Status))
431 {
432 break;
433 }
434 }
435
437}
438
439
440/*******************************************************************************
441 *
442 * FUNCTION: AcpiDsClearOperands
443 *
444 * PARAMETERS: WalkState - Current walk state with operands on stack
445 *
446 * RETURN: None
447 *
448 * DESCRIPTION: Clear all operands on the current walk state operand stack.
449 *
450 ******************************************************************************/
451
452void
454 ACPI_WALK_STATE *WalkState)
455{
456 UINT32 i;
457
458
459 ACPI_FUNCTION_TRACE_PTR (DsClearOperands, WalkState);
460
461
462 /* Remove a reference on each operand on the stack */
463
464 for (i = 0; i < WalkState->NumOperands; i++)
465 {
466 /*
467 * Remove a reference to all operands, including both
468 * "Arguments" and "Targets".
469 */
470 AcpiUtRemoveReference (WalkState->Operands[i]);
471 WalkState->Operands[i] = NULL;
472 }
473
474 WalkState->NumOperands = 0;
476}
477
478
479/*******************************************************************************
480 *
481 * FUNCTION: AcpiDsCreateOperand
482 *
483 * PARAMETERS: WalkState - Current walk state
484 * Arg - Parse object for the argument
485 * ArgIndex - Which argument (zero based)
486 *
487 * RETURN: Status
488 *
489 * DESCRIPTION: Translate a parse tree object that is an argument to an AML
490 * opcode to the equivalent interpreter object. This may include
491 * looking up a name or entering a new name into the internal
492 * namespace.
493 *
494 ******************************************************************************/
495
498 ACPI_WALK_STATE *WalkState,
500 UINT32 ArgIndex)
501{
503 char *NameString;
504 UINT32 NameLength;
505 ACPI_OPERAND_OBJECT *ObjDesc;
506 ACPI_PARSE_OBJECT *ParentOp;
508 ACPI_INTERPRETER_MODE InterpreterMode;
509 const ACPI_OPCODE_INFO *OpInfo;
510
511
512 ACPI_FUNCTION_TRACE_PTR (DsCreateOperand, Arg);
513
514
515 /* A valid name must be looked up in the namespace */
516
517 if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
518 (Arg->Common.Value.String) &&
519 !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
520 {
521 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", Arg));
522
523 /* Get the entire name string from the AML stream */
524
526 Arg->Common.Value.Buffer, &NameString, &NameLength);
527
528 if (ACPI_FAILURE (Status))
529 {
531 }
532
533 /* All prefixes have been handled, and the name is in NameString */
534
535 /*
536 * Special handling for BufferField declarations. This is a deferred
537 * opcode that unfortunately defines the field name as the last
538 * parameter instead of the first. We get here when we are performing
539 * the deferred execution, so the actual name of the field is already
540 * in the namespace. We don't want to attempt to look it up again
541 * because we may be executing in a different scope than where the
542 * actual opcode exists.
543 */
544 if ((WalkState->DeferredNode) &&
545 (WalkState->DeferredNode->Type == ACPI_TYPE_BUFFER_FIELD) &&
546 (ArgIndex == (UINT32)
547 ((WalkState->Opcode == AML_CREATE_FIELD_OP) ? 3 : 2)))
548 {
549 ObjDesc = ACPI_CAST_PTR (
551 Status = AE_OK;
552 }
553 else /* All other opcodes */
554 {
555 /*
556 * Differentiate between a namespace "create" operation
557 * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
558 * IMODE_EXECUTE) in order to support the creation of
559 * namespace objects during the execution of control methods.
560 */
561 ParentOp = Arg->Common.Parent;
562 OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
563
564 if ((OpInfo->Flags & AML_NSNODE) &&
565 (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
566 (ParentOp->Common.AmlOpcode != AML_REGION_OP) &&
567 (ParentOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
568 {
569 /* Enter name into namespace if not found */
570
571 InterpreterMode = ACPI_IMODE_LOAD_PASS2;
572 }
573 else
574 {
575 /* Return a failure if name not found */
576
577 InterpreterMode = ACPI_IMODE_EXECUTE;
578 }
579
580 Status = AcpiNsLookup (WalkState->ScopeInfo, NameString,
581 ACPI_TYPE_ANY, InterpreterMode,
584 /*
585 * The only case where we pass through (ignore) a NOT_FOUND
586 * error is for the CondRefOf opcode.
587 */
588 if (Status == AE_NOT_FOUND)
589 {
590 if (ParentOp->Common.AmlOpcode == AML_CONDITIONAL_REF_OF_OP)
591 {
592 /*
593 * For the Conditional Reference op, it's OK if
594 * the name is not found; We just need a way to
595 * indicate this to the interpreter, set the
596 * object to the root
597 */
598 ObjDesc = ACPI_CAST_PTR (
599 ACPI_OPERAND_OBJECT, AcpiGbl_RootNode);
600 Status = AE_OK;
601 }
602 else if (ParentOp->Common.AmlOpcode == AML_EXTERNAL_OP)
603 {
604 /*
605 * This opcode should never appear here. It is used only
606 * by AML disassemblers and is surrounded by an If(0)
607 * by the ASL compiler.
608 *
609 * Therefore, if we see it here, it is a serious error.
610 */
612 }
613 else
614 {
615 /*
616 * We just plain didn't find it -- which is a
617 * very serious error at this point
618 */
620 }
621 }
622
623 if (ACPI_FAILURE (Status))
624 {
626 NameString, Status);
627 }
628 }
629
630 /* Free the namestring created above */
631
632 ACPI_FREE (NameString);
633
634 /* Check status from the lookup */
635
636 if (ACPI_FAILURE (Status))
637 {
639 }
640
641 /* Put the resulting object onto the current object stack */
642
643 Status = AcpiDsObjStackPush (ObjDesc, WalkState);
644 if (ACPI_FAILURE (Status))
645 {
647 }
648
649 AcpiDbDisplayArgumentObject (ObjDesc, WalkState);
650 }
651 else
652 {
653 /* Check for null name case */
654
655 if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
656 !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
657 {
658 /*
659 * If the name is null, this means that this is an
660 * optional result parameter that was not specified
661 * in the original ASL. Create a Zero Constant for a
662 * placeholder. (Store to a constant is a Noop.)
663 */
664 Opcode = AML_ZERO_OP; /* Has no arguments! */
665
667 "Null namepath: Arg=%p\n", Arg));
668 }
669 else
670 {
671 Opcode = Arg->Common.AmlOpcode;
672 }
673
674 /* Get the object type of the argument */
675
676 OpInfo = AcpiPsGetOpcodeInfo (Opcode);
677 if (OpInfo->ObjectType == ACPI_TYPE_INVALID)
678 {
680 }
681
682 if ((OpInfo->Flags & AML_HAS_RETVAL) ||
683 (Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
684 {
685 /*
686 * Use value that was already previously returned
687 * by the evaluation of this argument
688 */
689 Status = AcpiDsResultPop (&ObjDesc, WalkState);
690 if (ACPI_FAILURE (Status))
691 {
692 /*
693 * Only error is underflow, and this indicates
694 * a missing or null operand!
695 */
697 "Missing or null operand"));
699 }
700 }
701 else
702 {
703 /* Create an ACPI_INTERNAL_OBJECT for the argument */
704
705 ObjDesc = AcpiUtCreateInternalObject (OpInfo->ObjectType);
706 if (!ObjDesc)
707 {
709 }
710
711 /* Initialize the new object */
712
714 WalkState, Arg, Opcode, &ObjDesc);
715 if (ACPI_FAILURE (Status))
716 {
717 AcpiUtDeleteObjectDesc (ObjDesc);
719 }
720 }
721
722 /* Put the operand object on the object stack */
723
724 Status = AcpiDsObjStackPush (ObjDesc, WalkState);
725 if (ACPI_FAILURE (Status))
726 {
728 }
729
730 AcpiDbDisplayArgumentObject (ObjDesc, WalkState);
731 }
732
734}
735
736
737/*******************************************************************************
738 *
739 * FUNCTION: AcpiDsCreateOperands
740 *
741 * PARAMETERS: WalkState - Current state
742 * FirstArg - First argument of a parser argument tree
743 *
744 * RETURN: Status
745 *
746 * DESCRIPTION: Convert an operator's arguments from a parse tree format to
747 * namespace objects and place those argument object on the object
748 * stack in preparation for evaluation by the interpreter.
749 *
750 ******************************************************************************/
751
754 ACPI_WALK_STATE *WalkState,
755 ACPI_PARSE_OBJECT *FirstArg)
756{
760 UINT32 ArgCount = 0;
761 UINT32 Index = WalkState->NumOperands;
762 UINT32 i;
763
764
765 ACPI_FUNCTION_TRACE_PTR (DsCreateOperands, FirstArg);
766
767
768 /* Get all arguments in the list */
769
770 Arg = FirstArg;
771 while (Arg)
772 {
774 {
776 }
777
778 Arguments[Index] = Arg;
779 WalkState->Operands [Index] = NULL;
780
781 /* Move on to next argument, if any */
782
783 Arg = Arg->Common.Next;
784 ArgCount++;
785 Index++;
786 }
787
789 "NumOperands %d, ArgCount %d, Index %d\n",
790 WalkState->NumOperands, ArgCount, Index));
791
792 /* Create the interpreter arguments, in reverse order */
793
794 Index--;
795 for (i = 0; i < ArgCount; i++)
796 {
797 Arg = Arguments[Index];
798 WalkState->OperandIndex = (UINT8) Index;
799
800 Status = AcpiDsCreateOperand (WalkState, Arg, Index);
801 if (ACPI_FAILURE (Status))
802 {
803 goto Cleanup;
804 }
805
807 "Created Arg #%u (%p) %u args total\n",
808 Index, Arg, ArgCount));
809 Index--;
810 }
811
813
814
815Cleanup:
816 /*
817 * We must undo everything done above; meaning that we must
818 * pop everything off of the operand stack and delete those
819 * objects
820 */
821 AcpiDsObjStackPopAndDelete (ArgCount, WalkState);
822
823 ACPI_EXCEPTION ((AE_INFO, Status, "While creating Arg %u", Index));
825}
826
827
828/*****************************************************************************
829 *
830 * FUNCTION: AcpiDsEvaluateNamePath
831 *
832 * PARAMETERS: WalkState - Current state of the parse tree walk,
833 * the opcode of current operation should be
834 * AML_INT_NAMEPATH_OP
835 *
836 * RETURN: Status
837 *
838 * DESCRIPTION: Translate the -NamePath- parse tree object to the equivalent
839 * interpreter object, convert it to value, if needed, duplicate
840 * it, if needed, and push it onto the current result stack.
841 *
842 ****************************************************************************/
843
846 ACPI_WALK_STATE *WalkState)
847{
849 ACPI_PARSE_OBJECT *Op = WalkState->Op;
850 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
851 ACPI_OPERAND_OBJECT *NewObjDesc;
852 UINT8 Type;
853
854
855 ACPI_FUNCTION_TRACE_PTR (DsEvaluateNamePath, WalkState);
856
857
858 if (!Op->Common.Parent)
859 {
860 /* This happens after certain exception processing */
861
862 goto Exit;
863 }
864
865 if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
866 (Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP) ||
867 (Op->Common.Parent->Common.AmlOpcode == AML_REF_OF_OP))
868 {
869 /* TBD: Should we specify this feature as a bit of OpInfo->Flags of these opcodes? */
870
871 goto Exit;
872 }
873
874 Status = AcpiDsCreateOperand (WalkState, Op, 0);
875 if (ACPI_FAILURE (Status))
876 {
877 goto Exit;
878 }
879
880 if (Op->Common.Flags & ACPI_PARSEOP_TARGET)
881 {
882 NewObjDesc = *Operand;
883 goto PushResult;
884 }
885
886 Type = (*Operand)->Common.Type;
887
888 Status = AcpiExResolveToValue (Operand, WalkState);
889 if (ACPI_FAILURE (Status))
890 {
891 goto Exit;
892 }
893
894 if (Type == ACPI_TYPE_INTEGER)
895 {
896 /* It was incremented by AcpiExResolveToValue */
897
898 AcpiUtRemoveReference (*Operand);
899
901 *Operand, &NewObjDesc, WalkState);
902 if (ACPI_FAILURE (Status))
903 {
904 goto Exit;
905 }
906 }
907 else
908 {
909 /*
910 * The object either was anew created or is
911 * a Namespace node - don't decrement it.
912 */
913 NewObjDesc = *Operand;
914 }
915
916 /* Cleanup for name-path operand */
917
918 Status = AcpiDsObjStackPop (1, WalkState);
919 if (ACPI_FAILURE (Status))
920 {
921 WalkState->ResultObj = NewObjDesc;
922 goto Exit;
923 }
924
925PushResult:
926
927 WalkState->ResultObj = NewObjDesc;
928
929 Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
930 if (ACPI_SUCCESS (Status))
931 {
932 /* Force to take it from stack */
933
934 Op->Common.Flags |= ACPI_PARSEOP_IN_STACK;
935 }
936
937Exit:
938
940}
unsigned short UINT16
unsigned char BOOLEAN
unsigned char UINT8
unsigned int UINT32
Type
Definition: Type.h:7
#define AE_BAD_DATA
Definition: acexcep.h:154
#define AE_NOT_IMPLEMENTED
Definition: acexcep.h:122
#define AE_AML_NAME_NOT_FOUND
Definition: acexcep.h:193
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define AE_AML_BAD_OPCODE
Definition: acexcep.h:180
#define AE_NOT_FOUND
Definition: acexcep.h:113
#define AE_NO_MEMORY
Definition: acexcep.h:112
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
#define AE_OK
Definition: acexcep.h:97
#define ACPI_PARSEOP_TARGET
Definition: aclocal.h:1122
#define ACPI_PARSEOP_IN_STACK
Definition: aclocal.h:1121
ACPI_INTERPRETER_MODE
Definition: aclocal.h:166
@ ACPI_IMODE_EXECUTE
Definition: aclocal.h:169
@ ACPI_IMODE_LOAD_PASS2
Definition: aclocal.h:168
#define ACPI_CONTROL_PREDICATE_EXECUTING
Definition: aclocal.h:671
#define ACPI_ERROR_NAMESPACE(s, p, e)
Definition: acmacros.h:462
ACPI_STATUS AcpiNsLookup(ACPI_GENERIC_STATE *ScopeInfo, char *Name, ACPI_OBJECT_TYPE Type, ACPI_INTERPRETER_MODE InterpreterMode, UINT32 Flags, ACPI_WALK_STATE *WalkState, ACPI_NAMESPACE_NODE **RetNode)
Definition: nsaccess.c:328
#define ACPI_NS_DONT_OPEN_SCOPE
Definition: acnamesp.h:64
#define ACPI_NS_SEARCH_PARENT
Definition: acnamesp.h:63
#define ACPI_DB_DISPATCH
Definition: acoutput.h:163
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
#define return_UINT8(s)
Definition: acoutput.h:500
#define ACPI_EXCEPTION(plist)
Definition: acoutput.h:239
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
#define ACPI_FUNCTION_TRACE_PTR(a, b)
Definition: acoutput.h:481
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define AE_INFO
Definition: acoutput.h:230
#define return_VOID
Definition: acoutput.h:495
#define ACPI_FUNCTION_NAME(a)
Definition: acoutput.h:479
const char * AcpiPsGetOpcodeName(UINT16 Opcode)
Definition: psopinfo.c:169
const ACPI_OPCODE_INFO * AcpiPsGetOpcodeInfo(UINT16 Opcode)
Definition: psopinfo.c:72
#define ACPI_TYPE_BUFFER_FIELD
Definition: actypes.h:701
#define ACPI_CAST_INDIRECT_PTR(t, p)
Definition: actypes.h:545
#define ACPI_FREE(a)
Definition: actypes.h:386
#define ACPI_TYPE_INTEGER
Definition: actypes.h:688
#define ACPI_TYPE_ANY
Definition: actypes.h:687
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_TYPE_INVALID
Definition: actypes.h:742
#define ACPI_CAST_PTR(t, p)
Definition: actypes.h:544
#define AcpiUtCreateInternalObject(t)
Definition: acutils.h:681
void AcpiUtRemoveReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:790
void AcpiUtDeleteObjectDesc(ACPI_OPERAND_OBJECT *Object)
Definition: utobject.c:473
void AcpiUtAddReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:752
ACPI_STATUS AcpiUtCopyIobjectToIobject(ACPI_OPERAND_OBJECT *SourceDesc, ACPI_OPERAND_OBJECT **DestDesc, ACPI_WALK_STATE *WalkState)
Definition: utcopy.c:1037
#define AML_RETURN_OP
Definition: amlcode.h:138
#define AML_VARIABLE_PACKAGE_OP
Definition: amlcode.h:63
#define AML_REF_OF_OP
Definition: amlcode.h:89
#define AML_REGION_OP
Definition: amlcode.h:180
#define AML_NSNODE
Definition: amlcode.h:324
#define AML_HAS_RETVAL
Definition: amlcode.h:327
#define AML_BANK_FIELD_OP
Definition: amlcode.h:187
#define AML_CLASS_NAMED_OBJECT
Definition: amlcode.h:403
#define AML_INT_EVAL_SUBTREE_OP
Definition: amlcode.h:212
#define AML_EXTERNAL_OP
Definition: amlcode.h:65
#define AML_INT_METHODCALL_OP
Definition: amlcode.h:210
#define AML_CONDITIONAL_REF_OF_OP
Definition: amlcode.h:162
#define AML_DATA_REGION_OP
Definition: amlcode.h:188
#define AML_CLASS_CREATE
Definition: amlcode.h:401
#define AML_BUFFER_OP
Definition: amlcode.h:61
#define AML_ZERO_OP
Definition: amlcode.h:51
#define AML_CLASS_CONTROL
Definition: amlcode.h:404
#define AML_IF_OP
Definition: amlcode.h:134
#define AML_PACKAGE_OP
Definition: amlcode.h:62
#define AML_SCOPE_OP
Definition: amlcode.h:60
#define AML_INT_NAMEPATH_OP
Definition: amlcode.h:205
#define AML_CLASS_UNKNOWN
Definition: amlcode.h:410
#define AML_CREATE_FIELD_OP
Definition: amlcode.h:163
#define AML_WHILE_OP
Definition: amlcode.h:136
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR Cleanup[]
Definition: register.c:80
#define ACPI_OBJ_NUM_OPERANDS
Definition: acconfig.h:172
ACPI_STATUS AcpiDsInitObjectFromOp(ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op, UINT16 Opcode, ACPI_OPERAND_OBJECT **RetObjDesc)
Definition: dsobject.c:373
void AcpiDsDeleteResultIfNotUsed(ACPI_PARSE_OBJECT *Op, ACPI_OPERAND_OBJECT *ResultObj, ACPI_WALK_STATE *WalkState)
Definition: dsutils.c:359
void AcpiDsClearOperands(ACPI_WALK_STATE *WalkState)
Definition: dsutils.c:453
void AcpiDsClearImplicitReturn(ACPI_WALK_STATE *WalkState)
Definition: dsutils.c:73
ACPI_STATUS AcpiDsCreateOperands(ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *FirstArg)
Definition: dsutils.c:753
ACPI_STATUS AcpiDsCreateOperand(ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Arg, UINT32 ArgIndex)
Definition: dsutils.c:497
BOOLEAN AcpiDsDoImplicitReturn(ACPI_OPERAND_OBJECT *ReturnDesc, ACPI_WALK_STATE *WalkState, BOOLEAN AddReference)
Definition: dsutils.c:123
ACPI_STATUS AcpiDsResolveOperands(ACPI_WALK_STATE *WalkState)
Definition: dsutils.c:412
ACPI_STATUS AcpiDsEvaluateNamePath(ACPI_WALK_STATE *WalkState)
Definition: dsutils.c:845
BOOLEAN AcpiDsIsResultUsed(ACPI_PARSE_OBJECT *Op, ACPI_WALK_STATE *WalkState)
Definition: dsutils.c:187
void AcpiDsObjStackPopAndDelete(UINT32 PopCount, ACPI_WALK_STATE *WalkState)
Definition: dswstate.c:441
ACPI_STATUS AcpiDsResultPop(ACPI_OPERAND_OBJECT **Object, ACPI_WALK_STATE *WalkState)
Definition: dswstate.c:78
ACPI_STATUS AcpiDsObjStackPush(void *Object, ACPI_WALK_STATE *WalkState)
Definition: dswstate.c:342
ACPI_STATUS AcpiDsObjStackPop(UINT32 PopCount, ACPI_WALK_STATE *WalkState)
Definition: dswstate.c:391
ACPI_STATUS AcpiDsResultPush(ACPI_OPERAND_OBJECT *Object, ACPI_WALK_STATE *WalkState)
Definition: dswstate.c:160
ACPI_STATUS AcpiExGetNameString(ACPI_OBJECT_TYPE DataType, UINT8 *InAmlAddress, char **OutNameString, UINT32 *OutNameLength)
Definition: exnames.c:278
ACPI_STATUS AcpiExResolveToValue(ACPI_OPERAND_OBJECT **StackPtr, ACPI_WALK_STATE *WalkState)
Definition: exresolv.c:79
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_In_ PVOID _In_ ULONG Opcode
Definition: hubbusif.h:331
static void Exit(void)
Definition: sock.c:1330
union acpi_parse_object * PredicateOp
Definition: aclocal.h:726
UINT16 Flags
Definition: aclocal.h:873
UINT8 ObjectType
Definition: aclocal.h:874
union acpi_operand_object * ImplicitReturnObj
Definition: acstruct.h:112
union acpi_operand_object * Operands[ACPI_OBJ_NUM_OPERANDS+1]
Definition: acstruct.h:105
ACPI_PARSE_OBJECT * Op
Definition: acstruct.h:118
UINT8 OperandIndex
Definition: acstruct.h:81
union acpi_operand_object * ResultObj
Definition: acstruct.h:121
ACPI_GENERIC_STATE * ScopeInfo
Definition: acstruct.h:124
UINT16 Opcode
Definition: acstruct.h:78
ACPI_GENERIC_STATE * ControlState
Definition: acstruct.h:110
UINT8 NumOperands
Definition: acstruct.h:80
struct acpi_namespace_node * DeferredNode
Definition: acstruct.h:111
ACPI_COMMON_STATE Common
Definition: aclocal.h:822
ACPI_CONTROL_STATE Control
Definition: aclocal.h:823
ACPI_OBJECT_COMMON Common
Definition: acobject.h:519
ACPI_PARSE_OBJ_COMMON Common
Definition: aclocal.h:1078
_In_ WDFCOLLECTION _In_ ULONG Index