ReactOS  0.4.15-dev-5452-g3c95c95
exoparg1.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Module Name: exoparg1 - AML execution - opcodes with 1 argument
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 "acdispat.h"
48 #include "acinterp.h"
49 #include "amlcode.h"
50 #include "acnamesp.h"
51 
52 
53 #define _COMPONENT ACPI_EXECUTER
54  ACPI_MODULE_NAME ("exoparg1")
55 
56 
57 
79 /*******************************************************************************
80  *
81  * FUNCTION: AcpiExOpcode_0A_0T_1R
82  *
83  * PARAMETERS: WalkState - Current state (contains AML opcode)
84  *
85  * RETURN: Status
86  *
87  * DESCRIPTION: Execute operator with no operands, one return value
88  *
89  ******************************************************************************/
90 
93  ACPI_WALK_STATE *WalkState)
94 {
96  ACPI_OPERAND_OBJECT *ReturnDesc = NULL;
97 
98 
99  ACPI_FUNCTION_TRACE_STR (ExOpcode_0A_0T_1R,
100  AcpiPsGetOpcodeName (WalkState->Opcode));
101 
102 
103  /* Examine the AML opcode */
104 
105  switch (WalkState->Opcode)
106  {
107  case AML_TIMER_OP: /* Timer () */
108 
109  /* Create a return object of type Integer */
110 
111  ReturnDesc = AcpiUtCreateIntegerObject (AcpiOsGetTimer ());
112  if (!ReturnDesc)
113  {
115  goto Cleanup;
116  }
117  break;
118 
119  default: /* Unknown opcode */
120 
121  ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
122  WalkState->Opcode));
124  break;
125  }
126 
127 Cleanup:
128 
129  /* Delete return object on error */
130 
131  if ((ACPI_FAILURE (Status)) || WalkState->ResultObj)
132  {
133  AcpiUtRemoveReference (ReturnDesc);
134  WalkState->ResultObj = NULL;
135  }
136  else
137  {
138  /* Save the return value */
139 
140  WalkState->ResultObj = ReturnDesc;
141  }
142 
144 }
145 
146 
147 /*******************************************************************************
148  *
149  * FUNCTION: AcpiExOpcode_1A_0T_0R
150  *
151  * PARAMETERS: WalkState - Current state (contains AML opcode)
152  *
153  * RETURN: Status
154  *
155  * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
156  * object stack
157  *
158  ******************************************************************************/
159 
162  ACPI_WALK_STATE *WalkState)
163 {
164  ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
166 
167 
168  ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_0R,
169  AcpiPsGetOpcodeName (WalkState->Opcode));
170 
171 
172  /* Examine the AML opcode */
173 
174  switch (WalkState->Opcode)
175  {
176  case AML_RELEASE_OP: /* Release (MutexObject) */
177 
178  Status = AcpiExReleaseMutex (Operand[0], WalkState);
179  break;
180 
181  case AML_RESET_OP: /* Reset (EventObject) */
182 
183  Status = AcpiExSystemResetEvent (Operand[0]);
184  break;
185 
186  case AML_SIGNAL_OP: /* Signal (EventObject) */
187 
188  Status = AcpiExSystemSignalEvent (Operand[0]);
189  break;
190 
191  case AML_SLEEP_OP: /* Sleep (MsecTime) */
192 
193  Status = AcpiExSystemDoSleep (Operand[0]->Integer.Value);
194  break;
195 
196  case AML_STALL_OP: /* Stall (UsecTime) */
197 
198  Status = AcpiExSystemDoStall ((UINT32) Operand[0]->Integer.Value);
199  break;
200 
201  case AML_UNLOAD_OP: /* Unload (Handle) */
202 
203  Status = AcpiExUnloadTable (Operand[0]);
204  break;
205 
206  default: /* Unknown opcode */
207 
208  ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
209  WalkState->Opcode));
211  break;
212  }
213 
215 }
216 
217 
218 #ifdef _OBSOLETE_CODE /* Was originally used for Load() operator */
219 /*******************************************************************************
220  *
221  * FUNCTION: AcpiExOpcode_1A_1T_0R
222  *
223  * PARAMETERS: WalkState - Current state (contains AML opcode)
224  *
225  * RETURN: Status
226  *
227  * DESCRIPTION: Execute opcode with one argument, one target, and no
228  * return value.
229  *
230  ******************************************************************************/
231 
234  ACPI_WALK_STATE *WalkState)
235 {
237  ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
238 
239 
240  ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_0R,
241  AcpiPsGetOpcodeName (WalkState->Opcode));
242 
243 
244  /* Examine the AML opcode */
245 
246  switch (WalkState->Opcode)
247  {
248 #ifdef _OBSOLETE_CODE
249  case AML_LOAD_OP:
250 
251  Status = AcpiExLoadOp (Operand[0], Operand[1], WalkState);
252  break;
253 #endif
254 
255  default: /* Unknown opcode */
256 
257  ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
258  WalkState->Opcode));
260  goto Cleanup;
261  }
262 
263 
264 Cleanup:
265 
267 }
268 #endif
269 
270 /*******************************************************************************
271  *
272  * FUNCTION: AcpiExOpcode_1A_1T_1R
273  *
274  * PARAMETERS: WalkState - Current state (contains AML opcode)
275  *
276  * RETURN: Status
277  *
278  * DESCRIPTION: Execute opcode with one argument, one target, and a
279  * return value.
280  * January 2022: Added Load operator, with new ACPI 6.4
281  * semantics.
282  *
283  ******************************************************************************/
284 
287  ACPI_WALK_STATE *WalkState)
288 {
290  ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
291  ACPI_OPERAND_OBJECT *ReturnDesc = NULL;
292  ACPI_OPERAND_OBJECT *ReturnDesc2 = NULL;
293  UINT32 Temp32;
294  UINT32 i;
295  UINT64 PowerOfTen;
296  UINT64 Digit;
297 
298 
299  ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_1R,
300  AcpiPsGetOpcodeName (WalkState->Opcode));
301 
302 
303  /* Examine the AML opcode */
304 
305  switch (WalkState->Opcode)
306  {
307  case AML_BIT_NOT_OP:
310  case AML_FROM_BCD_OP:
311  case AML_LOAD_OP:
312  case AML_TO_BCD_OP:
314 
315  /* Create a return object of type Integer for these opcodes */
316 
318  if (!ReturnDesc)
319  {
321  goto Cleanup;
322  }
323 
324  switch (WalkState->Opcode)
325  {
326  case AML_BIT_NOT_OP: /* Not (Operand, Result) */
327 
328  ReturnDesc->Integer.Value = ~Operand[0]->Integer.Value;
329  break;
330 
331  case AML_FIND_SET_LEFT_BIT_OP: /* FindSetLeftBit (Operand, Result) */
332 
333  ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
334 
335  /*
336  * Acpi specification describes Integer type as a little
337  * endian unsigned value, so this boundary condition is valid.
338  */
339  for (Temp32 = 0; ReturnDesc->Integer.Value &&
340  Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
341  {
342  ReturnDesc->Integer.Value >>= 1;
343  }
344 
345  ReturnDesc->Integer.Value = Temp32;
346  break;
347 
348  case AML_FIND_SET_RIGHT_BIT_OP: /* FindSetRightBit (Operand, Result) */
349 
350  ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
351 
352  /*
353  * The Acpi specification describes Integer type as a little
354  * endian unsigned value, so this boundary condition is valid.
355  */
356  for (Temp32 = 0; ReturnDesc->Integer.Value &&
357  Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
358  {
359  ReturnDesc->Integer.Value <<= 1;
360  }
361 
362  /* Since the bit position is one-based, subtract from 33 (65) */
363 
364  ReturnDesc->Integer.Value =
365  Temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - Temp32;
366  break;
367 
368  case AML_FROM_BCD_OP: /* FromBcd (BCDValue, Result) */
369  /*
370  * The 64-bit ACPI integer can hold 16 4-bit BCD characters
371  * (if table is 32-bit, integer can hold 8 BCD characters)
372  * Convert each 4-bit BCD value
373  */
374  PowerOfTen = 1;
375  ReturnDesc->Integer.Value = 0;
376  Digit = Operand[0]->Integer.Value;
377 
378  /* Convert each BCD digit (each is one nybble wide) */
379 
380  for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
381  {
382  /* Get the least significant 4-bit BCD digit */
383 
384  Temp32 = ((UINT32) Digit) & 0xF;
385 
386  /* Check the range of the digit */
387 
388  if (Temp32 > 9)
389  {
391  "BCD digit too large (not decimal): 0x%X",
392  Temp32));
393 
395  goto Cleanup;
396  }
397 
398  /* Sum the digit into the result with the current power of 10 */
399 
400  ReturnDesc->Integer.Value +=
401  (((UINT64) Temp32) * PowerOfTen);
402 
403  /* Shift to next BCD digit */
404 
405  Digit >>= 4;
406 
407  /* Next power of 10 */
408 
409  PowerOfTen *= 10;
410  }
411  break;
412 
413  case AML_LOAD_OP: /* Result1 = Load (Operand[0], Result1) */
414 
415  ReturnDesc->Integer.Value = 0;
416  Status = AcpiExLoadOp (Operand[0], ReturnDesc, WalkState);
417  if (ACPI_SUCCESS (Status))
418  {
419  /* Return -1 (non-zero) indicates success */
420 
421  ReturnDesc->Integer.Value = 0xFFFFFFFFFFFFFFFF;
422  }
423  break;
424 
425  case AML_TO_BCD_OP: /* ToBcd (Operand, Result) */
426 
427  ReturnDesc->Integer.Value = 0;
428  Digit = Operand[0]->Integer.Value;
429 
430  /* Each BCD digit is one nybble wide */
431 
432  for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
433  {
434  (void) AcpiUtShortDivide (Digit, 10, &Digit, &Temp32);
435 
436  /*
437  * Insert the BCD digit that resides in the
438  * remainder from above
439  */
440  ReturnDesc->Integer.Value |=
441  (((UINT64) Temp32) << ACPI_MUL_4 (i));
442  }
443 
444  /* Overflow if there is any data left in Digit */
445 
446  if (Digit > 0)
447  {
449  "Integer too large to convert to BCD: 0x%8.8X%8.8X",
450  ACPI_FORMAT_UINT64 (Operand[0]->Integer.Value)));
452  goto Cleanup;
453  }
454  break;
455 
456  case AML_CONDITIONAL_REF_OF_OP: /* CondRefOf (SourceObject, Result) */
457  /*
458  * This op is a little strange because the internal return value is
459  * different than the return value stored in the result descriptor
460  * (There are really two return values)
461  */
462  if ((ACPI_NAMESPACE_NODE *) Operand[0] == AcpiGbl_RootNode)
463  {
464  /*
465  * This means that the object does not exist in the namespace,
466  * return FALSE
467  */
468  ReturnDesc->Integer.Value = 0;
469  goto Cleanup;
470  }
471 
472  /* Get the object reference, store it, and remove our reference */
473 
474  Status = AcpiExGetObjectReference (Operand[0],
475  &ReturnDesc2, WalkState);
476  if (ACPI_FAILURE (Status))
477  {
478  goto Cleanup;
479  }
480 
481  Status = AcpiExStore (ReturnDesc2, Operand[1], WalkState);
482  AcpiUtRemoveReference (ReturnDesc2);
483 
484  /* The object exists in the namespace, return TRUE */
485 
486  ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
487  goto Cleanup;
488 
489 
490  default:
491 
492  /* No other opcodes get here */
493 
494  break;
495  }
496  break;
497 
498  case AML_STORE_OP: /* Store (Source, Target) */
499  /*
500  * A store operand is typically a number, string, buffer or lvalue
501  * Be careful about deleting the source object,
502  * since the object itself may have been stored.
503  */
504  Status = AcpiExStore (Operand[0], Operand[1], WalkState);
505  if (ACPI_FAILURE (Status))
506  {
508  }
509 
510  /* It is possible that the Store already produced a return object */
511 
512  if (!WalkState->ResultObj)
513  {
514  /*
515  * Normally, we would remove a reference on the Operand[0]
516  * parameter; But since it is being used as the internal return
517  * object (meaning we would normally increment it), the two
518  * cancel out, and we simply don't do anything.
519  */
520  WalkState->ResultObj = Operand[0];
521  WalkState->Operands[0] = NULL; /* Prevent deletion */
522  }
524 
525  /*
526  * ACPI 2.0 Opcodes
527  */
528  case AML_COPY_OBJECT_OP: /* CopyObject (Source, Target) */
529 
531  Operand[0], &ReturnDesc, WalkState);
532  break;
533 
534  case AML_TO_DECIMAL_STRING_OP: /* ToDecimalString (Data, Result) */
535 
537  Operand[0], &ReturnDesc, ACPI_EXPLICIT_CONVERT_DECIMAL);
538  if (ReturnDesc == Operand[0])
539  {
540  /* No conversion performed, add ref to handle return value */
541 
542  AcpiUtAddReference (ReturnDesc);
543  }
544  break;
545 
546  case AML_TO_HEX_STRING_OP: /* ToHexString (Data, Result) */
547 
549  Operand[0], &ReturnDesc, ACPI_EXPLICIT_CONVERT_HEX);
550  if (ReturnDesc == Operand[0])
551  {
552  /* No conversion performed, add ref to handle return value */
553 
554  AcpiUtAddReference (ReturnDesc);
555  }
556  break;
557 
558  case AML_TO_BUFFER_OP: /* ToBuffer (Data, Result) */
559 
560  Status = AcpiExConvertToBuffer (Operand[0], &ReturnDesc);
561  if (ReturnDesc == Operand[0])
562  {
563  /* No conversion performed, add ref to handle return value */
564 
565  AcpiUtAddReference (ReturnDesc);
566  }
567  break;
568 
569  case AML_TO_INTEGER_OP: /* ToInteger (Data, Result) */
570 
571  /* Perform "explicit" conversion */
572 
573  Status = AcpiExConvertToInteger (Operand[0], &ReturnDesc, 0);
574  if (ReturnDesc == Operand[0])
575  {
576  /* No conversion performed, add ref to handle return value */
577 
578  AcpiUtAddReference (ReturnDesc);
579  }
580  break;
581 
582  case AML_SHIFT_LEFT_BIT_OP: /* ShiftLeftBit (Source, BitNum) */
583  case AML_SHIFT_RIGHT_BIT_OP: /* ShiftRightBit (Source, BitNum) */
584 
585  /* These are two obsolete opcodes */
586 
588  "%s is obsolete and not implemented",
589  AcpiPsGetOpcodeName (WalkState->Opcode)));
590  Status = AE_SUPPORT;
591  goto Cleanup;
592 
593  default: /* Unknown opcode */
594 
595  ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
596  WalkState->Opcode));
598  goto Cleanup;
599  }
600 
601  if (ACPI_SUCCESS (Status))
602  {
603  /* Store the return value computed above into the target object */
604 
605  Status = AcpiExStore (ReturnDesc, Operand[1], WalkState);
606  }
607 
608 
609 Cleanup:
610 
611  /* Delete return object on error */
612 
613  if (ACPI_FAILURE (Status))
614  {
615  AcpiUtRemoveReference (ReturnDesc);
616  }
617 
618  /* Save return object on success */
619 
620  else if (!WalkState->ResultObj)
621  {
622  WalkState->ResultObj = ReturnDesc;
623  }
624 
626 }
627 
628 
629 /*******************************************************************************
630  *
631  * FUNCTION: AcpiExOpcode_1A_0T_1R
632  *
633  * PARAMETERS: WalkState - Current state (contains AML opcode)
634  *
635  * RETURN: Status
636  *
637  * DESCRIPTION: Execute opcode with one argument, no target, and a return value
638  *
639  ******************************************************************************/
640 
643  ACPI_WALK_STATE *WalkState)
644 {
645  ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
646  ACPI_OPERAND_OBJECT *TempDesc;
647  ACPI_OPERAND_OBJECT *ReturnDesc = NULL;
649  UINT32 Type;
650  UINT64 Value;
651 
652 
653  ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_1R,
654  AcpiPsGetOpcodeName (WalkState->Opcode));
655 
656 
657  /* Examine the AML opcode */
658 
659  switch (WalkState->Opcode)
660  {
661  case AML_LOGICAL_NOT_OP: /* LNot (Operand) */
662 
663  ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) 0);
664  if (!ReturnDesc)
665  {
667  goto Cleanup;
668  }
669 
670  /*
671  * Set result to ONES (TRUE) if Value == 0. Note:
672  * ReturnDesc->Integer.Value is initially == 0 (FALSE) from above.
673  */
674  if (!Operand[0]->Integer.Value)
675  {
676  ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
677  }
678  break;
679 
680  case AML_DECREMENT_OP: /* Decrement (Operand) */
681  case AML_INCREMENT_OP: /* Increment (Operand) */
682  /*
683  * Create a new integer. Can't just get the base integer and
684  * increment it because it may be an Arg or Field.
685  */
687  if (!ReturnDesc)
688  {
690  goto Cleanup;
691  }
692 
693  /*
694  * Since we are expecting a Reference operand, it can be either a
695  * NS Node or an internal object.
696  */
697  TempDesc = Operand[0];
699  {
700  /* Internal reference object - prevent deletion */
701 
702  AcpiUtAddReference (TempDesc);
703  }
704 
705  /*
706  * Convert the Reference operand to an Integer (This removes a
707  * reference on the Operand[0] object)
708  *
709  * NOTE: We use LNOT_OP here in order to force resolution of the
710  * reference operand to an actual integer.
711  */
713  &TempDesc, WalkState);
714  if (ACPI_FAILURE (Status))
715  {
717  "While resolving operands for [%s]",
718  AcpiPsGetOpcodeName (WalkState->Opcode)));
719 
720  goto Cleanup;
721  }
722 
723  /*
724  * TempDesc is now guaranteed to be an Integer object --
725  * Perform the actual increment or decrement
726  */
727  if (WalkState->Opcode == AML_INCREMENT_OP)
728  {
729  ReturnDesc->Integer.Value = TempDesc->Integer.Value + 1;
730  }
731  else
732  {
733  ReturnDesc->Integer.Value = TempDesc->Integer.Value - 1;
734  }
735 
736  /* Finished with this Integer object */
737 
738  AcpiUtRemoveReference (TempDesc);
739 
740  /*
741  * Store the result back (indirectly) through the original
742  * Reference object
743  */
744  Status = AcpiExStore (ReturnDesc, Operand[0], WalkState);
745  break;
746 
747  case AML_OBJECT_TYPE_OP: /* ObjectType (SourceObject) */
748  /*
749  * Note: The operand is not resolved at this point because we want to
750  * get the associated object, not its value. For example, we don't
751  * want to resolve a FieldUnit to its value, we want the actual
752  * FieldUnit object.
753  */
754 
755  /* Get the type of the base object */
756 
757  Status = AcpiExResolveMultiple (WalkState, Operand[0], &Type, NULL);
758  if (ACPI_FAILURE (Status))
759  {
760  goto Cleanup;
761  }
762 
763  /* Allocate a descriptor to hold the type. */
764 
765  ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) Type);
766  if (!ReturnDesc)
767  {
769  goto Cleanup;
770  }
771  break;
772 
773  case AML_SIZE_OF_OP: /* SizeOf (SourceObject) */
774  /*
775  * Note: The operand is not resolved at this point because we want to
776  * get the associated object, not its value.
777  */
778 
779  /* Get the base object */
780 
782  WalkState, Operand[0], &Type, &TempDesc);
783  if (ACPI_FAILURE (Status))
784  {
785  goto Cleanup;
786  }
787 
788  /*
789  * The type of the base object must be integer, buffer, string, or
790  * package. All others are not supported.
791  *
792  * NOTE: Integer is not specifically supported by the ACPI spec,
793  * but is supported implicitly via implicit operand conversion.
794  * rather than bother with conversion, we just use the byte width
795  * global (4 or 8 bytes).
796  */
797  switch (Type)
798  {
799  case ACPI_TYPE_INTEGER:
800 
801  Value = AcpiGbl_IntegerByteWidth;
802  break;
803 
804  case ACPI_TYPE_STRING:
805 
806  Value = TempDesc->String.Length;
807  break;
808 
809  case ACPI_TYPE_BUFFER:
810 
811  /* Buffer arguments may not be evaluated at this point */
812 
813  Status = AcpiDsGetBufferArguments (TempDesc);
814  Value = TempDesc->Buffer.Length;
815  break;
816 
817  case ACPI_TYPE_PACKAGE:
818 
819  /* Package arguments may not be evaluated at this point */
820 
821  Status = AcpiDsGetPackageArguments (TempDesc);
822  Value = TempDesc->Package.Count;
823  break;
824 
825  default:
826 
828  "Operand must be Buffer/Integer/String/Package"
829  " - found type %s",
831 
833  goto Cleanup;
834  }
835 
836  if (ACPI_FAILURE (Status))
837  {
838  goto Cleanup;
839  }
840 
841  /*
842  * Now that we have the size of the object, create a result
843  * object to hold the value
844  */
845  ReturnDesc = AcpiUtCreateIntegerObject (Value);
846  if (!ReturnDesc)
847  {
849  goto Cleanup;
850  }
851  break;
852 
853 
854  case AML_REF_OF_OP: /* RefOf (SourceObject) */
855 
857  Operand[0], &ReturnDesc, WalkState);
858  if (ACPI_FAILURE (Status))
859  {
860  goto Cleanup;
861  }
862  break;
863 
864 
865  case AML_DEREF_OF_OP: /* DerefOf (ObjReference | String) */
866 
867  /* Check for a method local or argument, or standalone String */
868 
870  {
871  TempDesc = AcpiNsGetAttachedObject (
872  (ACPI_NAMESPACE_NODE *) Operand[0]);
873  if (TempDesc &&
874  ((TempDesc->Common.Type == ACPI_TYPE_STRING) ||
875  (TempDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)))
876  {
877  Operand[0] = TempDesc;
878  AcpiUtAddReference (TempDesc);
879  }
880  else
881  {
883  goto Cleanup;
884  }
885  }
886  else
887  {
888  switch ((Operand[0])->Common.Type)
889  {
891  /*
892  * This is a DerefOf (LocalX | ArgX)
893  *
894  * Must resolve/dereference the local/arg reference first
895  */
896  switch (Operand[0]->Reference.Class)
897  {
898  case ACPI_REFCLASS_LOCAL:
899  case ACPI_REFCLASS_ARG:
900 
901  /* Set Operand[0] to the value of the local/arg */
902 
904  Operand[0]->Reference.Class,
905  Operand[0]->Reference.Value,
906  WalkState, &TempDesc);
907  if (ACPI_FAILURE (Status))
908  {
909  goto Cleanup;
910  }
911 
912  /*
913  * Delete our reference to the input object and
914  * point to the object just retrieved
915  */
916  AcpiUtRemoveReference (Operand[0]);
917  Operand[0] = TempDesc;
918  break;
919 
920  case ACPI_REFCLASS_REFOF:
921 
922  /* Get the object to which the reference refers */
923 
924  TempDesc = Operand[0]->Reference.Object;
925  AcpiUtRemoveReference (Operand[0]);
926  Operand[0] = TempDesc;
927  break;
928 
929  default:
930 
931  /* Must be an Index op - handled below */
932  break;
933  }
934  break;
935 
936  case ACPI_TYPE_STRING:
937 
938  break;
939 
940  default:
941 
943  goto Cleanup;
944  }
945  }
946 
948  {
949  if ((Operand[0])->Common.Type == ACPI_TYPE_STRING)
950  {
951  /*
952  * This is a DerefOf (String). The string is a reference
953  * to a named ACPI object.
954  *
955  * 1) Find the owning Node
956  * 2) Dereference the node to an actual object. Could be a
957  * Field, so we need to resolve the node to a value.
958  */
960  Operand[0]->String.Pointer,
963  ACPI_NAMESPACE_NODE, &ReturnDesc));
964  if (ACPI_FAILURE (Status))
965  {
966  goto Cleanup;
967  }
968 
971  ACPI_NAMESPACE_NODE, &ReturnDesc),
972  WalkState);
973  goto Cleanup;
974  }
975  }
976 
977  /* Operand[0] may have changed from the code above */
978 
980  {
981  /*
982  * This is a DerefOf (ObjectReference)
983  * Get the actual object from the Node (This is the dereference).
984  * This case may only happen when a LocalX or ArgX is
985  * dereferenced above, or for references to device and
986  * thermal objects.
987  */
988  switch (((ACPI_NAMESPACE_NODE *) Operand[0])->Type)
989  {
990  case ACPI_TYPE_DEVICE:
991  case ACPI_TYPE_THERMAL:
992 
993  /* These types have no node subobject, return the NS node */
994 
995  ReturnDesc = Operand[0];
996  break;
997 
998  default:
999  /* For most types, get the object attached to the node */
1000 
1001  ReturnDesc = AcpiNsGetAttachedObject (
1002  (ACPI_NAMESPACE_NODE *) Operand[0]);
1003  AcpiUtAddReference (ReturnDesc);
1004  break;
1005  }
1006  }
1007  else
1008  {
1009  /*
1010  * This must be a reference object produced by either the
1011  * Index() or RefOf() operator
1012  */
1013  switch (Operand[0]->Reference.Class)
1014  {
1015  case ACPI_REFCLASS_INDEX:
1016  /*
1017  * The target type for the Index operator must be
1018  * either a Buffer or a Package
1019  */
1020  switch (Operand[0]->Reference.TargetType)
1021  {
1023 
1024  TempDesc = Operand[0]->Reference.Object;
1025 
1026  /*
1027  * Create a new object that contains one element of the
1028  * buffer -- the element pointed to by the index.
1029  *
1030  * NOTE: index into a buffer is NOT a pointer to a
1031  * sub-buffer of the main buffer, it is only a pointer to a
1032  * single element (byte) of the buffer!
1033  *
1034  * Since we are returning the value of the buffer at the
1035  * indexed location, we don't need to add an additional
1036  * reference to the buffer itself.
1037  */
1038  ReturnDesc = AcpiUtCreateIntegerObject ((UINT64)
1039  TempDesc->Buffer.Pointer[Operand[0]->Reference.Value]);
1040  if (!ReturnDesc)
1041  {
1042  Status = AE_NO_MEMORY;
1043  goto Cleanup;
1044  }
1045  break;
1046 
1047  case ACPI_TYPE_PACKAGE:
1048  /*
1049  * Return the referenced element of the package. We must
1050  * add another reference to the referenced object, however.
1051  */
1052  ReturnDesc = *(Operand[0]->Reference.Where);
1053  if (!ReturnDesc)
1054  {
1055  /*
1056  * Element is NULL, do not allow the dereference.
1057  * This provides compatibility with other ACPI
1058  * implementations.
1059  */
1061  }
1062 
1063  AcpiUtAddReference (ReturnDesc);
1064  break;
1065 
1066  default:
1067 
1068  ACPI_ERROR ((AE_INFO,
1069  "Unknown Index TargetType 0x%X in reference object %p",
1070  Operand[0]->Reference.TargetType, Operand[0]));
1071 
1073  goto Cleanup;
1074  }
1075  break;
1076 
1077  case ACPI_REFCLASS_REFOF:
1078 
1079  ReturnDesc = Operand[0]->Reference.Object;
1080 
1081  if (ACPI_GET_DESCRIPTOR_TYPE (ReturnDesc) ==
1083  {
1084  ReturnDesc = AcpiNsGetAttachedObject (
1085  (ACPI_NAMESPACE_NODE *) ReturnDesc);
1086  if (!ReturnDesc)
1087  {
1088  break;
1089  }
1090 
1091  /*
1092  * June 2013:
1093  * BufferFields/FieldUnits require additional resolution
1094  */
1095  switch (ReturnDesc->Common.Type)
1096  {
1101 
1103  WalkState, ReturnDesc, &TempDesc);
1104  if (ACPI_FAILURE (Status))
1105  {
1107  }
1108 
1109  ReturnDesc = TempDesc;
1110  break;
1111 
1112  default:
1113 
1114  /* Add another reference to the object */
1115 
1116  AcpiUtAddReference (ReturnDesc);
1117  break;
1118  }
1119  }
1120  break;
1121 
1122  default:
1123 
1124  ACPI_ERROR ((AE_INFO,
1125  "Unknown class in reference(%p) - 0x%2.2X",
1126  Operand[0], Operand[0]->Reference.Class));
1127 
1128  Status = AE_TYPE;
1129  goto Cleanup;
1130  }
1131  }
1132  break;
1133 
1134  default:
1135 
1136  ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
1137  WalkState->Opcode));
1138 
1140  goto Cleanup;
1141  }
1142 
1143 
1144 Cleanup:
1145 
1146  /* Delete return object on error */
1147 
1148  if (ACPI_FAILURE (Status))
1149  {
1150  AcpiUtRemoveReference (ReturnDesc);
1151  }
1152 
1153  /* Save return object on success */
1154 
1155  else
1156  {
1157  WalkState->ResultObj = ReturnDesc;
1158  }
1159 
1161 }
#define ACPI_EXCEPTION(plist)
Definition: acoutput.h:239
#define AML_LOGICAL_NOT_OP
Definition: amlcode.h:122
#define ACPI_NS_SEARCH_PARENT
Definition: acnamesp.h:63
#define AML_STALL_OP
Definition: amlcode.h:166
#define AML_TO_BCD_OP
Definition: amlcode.h:174
#define AML_RESET_OP
Definition: amlcode.h:171
void AcpiUtAddReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:752
#define AML_SIZE_OF_OP
Definition: amlcode.h:111
const char * AcpiPsGetOpcodeName(UINT16 Opcode)
Definition: psopinfo.c:169
UINT64 AcpiOsGetTimer(void)
Definition: osl.c:884
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define ACPI_TYPE_THERMAL
Definition: actypes.h:700
ACPI_STATUS AcpiExStore(ACPI_OPERAND_OBJECT *SourceDesc, ACPI_OPERAND_OBJECT *DestDesc, ACPI_WALK_STATE *WalkState)
Definition: exstore.c:91
#define AE_NO_MEMORY
Definition: acexcep.h:112
ACPI_STATUS AcpiNsGetNodeUnlocked(ACPI_NAMESPACE_NODE *PrefixNode, const char *ExternalPathname, UINT32 Flags, ACPI_NAMESPACE_NODE **OutNode)
Definition: nsutils.c:777
ACPI_STATUS AcpiExSystemResetEvent(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: exsystem.c:332
ACPI_OBJECT_PACKAGE Package
Definition: acobject.h:523
#define AE_AML_NUMERIC_OVERFLOW
Definition: acexcep.h:187
#define ACPI_TYPE_BUFFER
Definition: actypes.h:690
#define ACPI_TYPE_INTEGER
Definition: actypes.h:688
ACPI_STATUS AcpiExResolveMultiple(ACPI_WALK_STATE *WalkState, ACPI_OPERAND_OBJECT *Operand, ACPI_OBJECT_TYPE *ReturnType, ACPI_OPERAND_OBJECT **ReturnDesc)
Definition: exresolv.c:350
ACPI_STATUS AcpiExOpcode_1A_0T_1R(ACPI_WALK_STATE *WalkState)
Definition: exoparg1.c:642
#define AML_SIGNAL_OP
Definition: amlcode.h:169
#define AML_SHIFT_LEFT_BIT_OP
Definition: amlcode.h:161
#define AML_TIMER_OP
Definition: amlcode.h:179
#define AML_TO_DECIMAL_STRING_OP
Definition: amlcode.h:127
#define AML_SLEEP_OP
Definition: amlcode.h:167
#define ACPI_TYPE_LOCAL_REFERENCE
Definition: actypes.h:719
#define ACPI_MUL_4(a)
Definition: acmacros.h:211
UINT32 ACPI_STATUS
Definition: actypes.h:460
ACPI_STATUS AcpiDsGetBufferArguments(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: dsargs.c:294
#define AE_AML_OPERAND_TYPE
Definition: acexcep.h:182
#define ACPI_TYPE_LOCAL_INDEX_FIELD
Definition: actypes.h:718
ACPI_STATUS AcpiExSystemDoSleep(UINT64 HowLongMs)
Definition: exsystem.c:223
#define AML_TO_INTEGER_OP
Definition: amlcode.h:129
#define ACPI_INTEGER_BIT_SIZE
Definition: actypes.h:490
#define ACPI_TYPE_PACKAGE
Definition: actypes.h:691
#define ACPI_EXPLICIT_CONVERT_HEX
Definition: acinterp.h:125
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
ACPI_STATUS AcpiExOpcode_1A_0T_0R(ACPI_WALK_STATE *WalkState)
Definition: exoparg1.c:161
#define AML_LOAD_OP
Definition: amlcode.h:165
#define AML_DEREF_OF_OP
Definition: amlcode.h:107
#define AML_TO_HEX_STRING_OP
Definition: amlcode.h:128
unsigned int UINT32
ACPI_STATUS AcpiExSystemSignalEvent(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: exsystem.c:265
ACPI_STATUS AcpiExResolveNodeToValue(ACPI_NAMESPACE_NODE **ObjectPtr, ACPI_WALK_STATE *WalkState)
Definition: exresnte.c:82
#define AML_TO_BUFFER_OP
Definition: amlcode.h:126
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
#define AML_FIND_SET_RIGHT_BIT_OP
Definition: amlcode.h:106
#define AML_SHIFT_RIGHT_BIT_OP
Definition: amlcode.h:160
#define AE_INFO
Definition: acoutput.h:230
#define AE_AML_BAD_OPCODE
Definition: acexcep.h:180
ACPI_STATUS AcpiExOpcode_0A_0T_1R(ACPI_WALK_STATE *WalkState)
Definition: exoparg1.c:92
ACPI_OBJECT_REFERENCE Reference
Definition: acobject.h:540
#define AML_STORE_OP
Definition: amlcode.h:88
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
Status
Definition: gdiplustypes.h:24
#define ACPI_DESC_TYPE_OPERAND
Definition: acobject.h:576
ACPI_STATUS AcpiUtShortDivide(UINT64 InDividend, UINT32 Divisor, UINT64 *OutQuotient, UINT32 *OutRemainder)
Definition: utmath.c:337
ACPI_OBJECT_BUFFER Buffer
Definition: acobject.h:522
#define AML_RELEASE_OP
Definition: amlcode.h:172
union acpi_operand_object * ResultObj
Definition: acstruct.h:121
#define AML_COPY_OBJECT_OP
Definition: amlcode.h:131
ACPI_OPERAND_OBJECT * AcpiUtCreateIntegerObject(UINT64 Value)
Definition: utobject.c:223
Type
Definition: Type.h:6
#define AE_SUPPORT
Definition: acexcep.h:123
ACPI_OPERAND_OBJECT * AcpiNsGetAttachedObject(ACPI_NAMESPACE_NODE *Node)
Definition: nsobject.c:308
ACPI_STATUS AcpiExConvertToString(ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ResultDesc, UINT32 Type)
Definition: exconvrt.c:440
#define ACPI_TYPE_LOCAL_REGION_FIELD
Definition: actypes.h:716
#define AML_OBJECT_TYPE_OP
Definition: amlcode.h:118
ACPI_GENERIC_STATE * ScopeInfo
Definition: acstruct.h:124
#define AML_FROM_BCD_OP
Definition: amlcode.h:173
ACPI_STATUS AcpiExConvertToInteger(ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ResultDesc, UINT32 ImplicitConversion)
Definition: exconvrt.c:79
ACPI_OBJECT_INTEGER Integer
Definition: acobject.h:520
#define AML_BIT_NOT_OP
Definition: amlcode.h:104
ACPI_STATUS AcpiExReleaseMutex(ACPI_OPERAND_OBJECT *ObjDesc, ACPI_WALK_STATE *WalkState)
Definition: exmutex.c:408
#define ACPI_TYPE_DEVICE
Definition: actypes.h:693
#define AML_CONDITIONAL_REF_OF_OP
Definition: amlcode.h:162
#define AE_TYPE
Definition: acexcep.h:116
static const WCHAR Cleanup[]
Definition: register.c:80
ACPI_OBJECT_STRING String
Definition: acobject.h:521
union acpi_operand_object * Operands[ACPI_OBJ_NUM_OPERANDS+1]
Definition: acstruct.h:105
#define ACPI_CAST_INDIRECT_PTR(t, p)
Definition: actypes.h:545
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
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FORMAT_UINT64(i)
Definition: acmacros.h:71
#define AML_FIND_SET_LEFT_BIT_OP
Definition: amlcode.h:105
ACPI_STATUS AcpiExUnloadTable(ACPI_OPERAND_OBJECT *DdbHandle)
Definition: exconfig.c:565
#define ACPI_TYPE_BUFFER_FIELD
Definition: actypes.h:701
ACPI_OBJECT_COMMON Common
Definition: acobject.h:519
#define ACPI_FUNCTION_TRACE_STR(a, b)
Definition: acoutput.h:483
ACPI_STATE_COMMON ACPI_NAMESPACE_NODE * Node
Definition: aclocal.h:740
void AcpiUtRemoveReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:790
const char * AcpiUtGetTypeName(ACPI_OBJECT_TYPE Type)
Definition: utdecode.c:250
#define NULL
Definition: types.h:112
ACPI_STATUS AcpiExSystemDoStall(UINT32 HowLongUs)
Definition: exsystem.c:174
ACPI_STATUS AcpiExOpcode_1A_1T_0R(ACPI_WALK_STATE *WalkState)
ACPI_STATUS AcpiDsGetPackageArguments(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: dsargs.c:344
#define AE_AML_UNINITIALIZED_ELEMENT
Definition: acexcep.h:186
#define AML_DECREMENT_OP
Definition: amlcode.h:94
#define AML_INCREMENT_OP
Definition: amlcode.h:93
ACPI_STATUS AcpiExConvertToBuffer(ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ResultDesc)
Definition: exconvrt.c:224
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
ACPI_STATUS AcpiExGetObjectReference(ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ReturnDesc, ACPI_WALK_STATE *WalkState)
Definition: exmisc.c:70
#define ACPI_TYPE_LOCAL_BANK_FIELD
Definition: actypes.h:717
ACPI_STATUS AcpiDsMethodDataGetValue(UINT8 Type, UINT32 Index, ACPI_WALK_STATE *WalkState, ACPI_OPERAND_OBJECT **DestDesc)
Definition: dsmthdat.c:406
#define ACPI_UINT64_MAX
Definition: actypes.h:67
#define AML_REF_OF_OP
Definition: amlcode.h:89
UINT16 Opcode
Definition: acstruct.h:78
ACPI_STATUS AcpiUtCopyIobjectToIobject(ACPI_OPERAND_OBJECT *SourceDesc, ACPI_OPERAND_OBJECT **DestDesc, ACPI_WALK_STATE *WalkState)
Definition: utcopy.c:1037
#define ACPI_TYPE_STRING
Definition: actypes.h:689
#define AML_UNLOAD_OP
Definition: amlcode.h:175
ACPI_STATUS AcpiExReadDataFromField(ACPI_WALK_STATE *WalkState, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **RetBufferDesc)
Definition: exfield.c:147
#define AcpiUtCreateInternalObject(t)
Definition: acutils.h:681
#define ACPI_DESC_TYPE_NAMED
Definition: acobject.h:577
unsigned long long UINT64
ACPI_STATUS AcpiExOpcode_1A_1T_1R(ACPI_WALK_STATE *WalkState)
Definition: exoparg1.c:286
ACPI_STATUS AcpiExResolveOperands(UINT16 Opcode, ACPI_OPERAND_OBJECT **StackPtr, ACPI_WALK_STATE *WalkState)
Definition: exresop.c:145
ACPI_STATUS AcpiExLoadOp(ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT *Target, ACPI_WALK_STATE *WalkState)
Definition: exconfig.c:343
#define ACPI_EXPLICIT_CONVERT_DECIMAL
Definition: acinterp.h:127
#define AE_OK
Definition: acexcep.h:97
ACPI_SCOPE_STATE Scope
Definition: aclocal.h:825
#define ACPI_GET_DESCRIPTOR_TYPE(d)
Definition: acmacros.h:414