ReactOS  0.4.14-dev-1112-g2b067d6
exresolv.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Module Name: exresolv - AML Interpreter object resolution
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2020, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  * notice, this list of conditions, and the following disclaimer,
16  * without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  * substantially similar to the "NO WARRANTY" disclaimer below
19  * ("Disclaimer") and any redistribution must be conditioned upon
20  * including a substantially similar Disclaimer requirement for further
21  * binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  * of any contributors may be used to endorse or promote products derived
24  * from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include "acpi.h"
45 #include "accommon.h"
46 #include "amlcode.h"
47 #include "acdispat.h"
48 #include "acinterp.h"
49 #include "acnamesp.h"
50 
51 
52 #define _COMPONENT ACPI_EXECUTER
53  ACPI_MODULE_NAME ("exresolv")
54 
55 /* Local prototypes */
56 
57 static ACPI_STATUS
59  ACPI_OPERAND_OBJECT **StackPtr,
60  ACPI_WALK_STATE *WalkState);
61 
62 
63 /*******************************************************************************
64  *
65  * FUNCTION: AcpiExResolveToValue
66  *
67  * PARAMETERS: **StackPtr - Points to entry on ObjStack, which can
68  * be either an (ACPI_OPERAND_OBJECT *)
69  * or an ACPI_HANDLE.
70  * WalkState - Current method state
71  *
72  * RETURN: Status
73  *
74  * DESCRIPTION: Convert Reference objects to values
75  *
76  ******************************************************************************/
77 
80  ACPI_OPERAND_OBJECT **StackPtr,
81  ACPI_WALK_STATE *WalkState)
82 {
84 
85 
86  ACPI_FUNCTION_TRACE_PTR (ExResolveToValue, StackPtr);
87 
88 
89  if (!StackPtr || !*StackPtr)
90  {
91  ACPI_ERROR ((AE_INFO, "Internal - null pointer"));
93  }
94 
95  /*
96  * The entity pointed to by the StackPtr can be either
97  * 1) A valid ACPI_OPERAND_OBJECT, or
98  * 2) A ACPI_NAMESPACE_NODE (NamedObj)
99  */
101  {
102  Status = AcpiExResolveObjectToValue (StackPtr, WalkState);
103  if (ACPI_FAILURE (Status))
104  {
106  }
107 
108  if (!*StackPtr)
109  {
110  ACPI_ERROR ((AE_INFO, "Internal - null pointer"));
112  }
113  }
114 
115  /*
116  * Object on the stack may have changed if AcpiExResolveObjectToValue()
117  * was called (i.e., we can't use an _else_ here.)
118  */
120  {
123  WalkState);
124  if (ACPI_FAILURE (Status))
125  {
127  }
128  }
129 
130  ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Resolved object %p\n", *StackPtr));
132 }
133 
134 
135 /*******************************************************************************
136  *
137  * FUNCTION: AcpiExResolveObjectToValue
138  *
139  * PARAMETERS: StackPtr - Pointer to an internal object
140  * WalkState - Current method state
141  *
142  * RETURN: Status
143  *
144  * DESCRIPTION: Retrieve the value from an internal object. The Reference type
145  * uses the associated AML opcode to determine the value.
146  *
147  ******************************************************************************/
148 
149 static ACPI_STATUS
151  ACPI_OPERAND_OBJECT **StackPtr,
152  ACPI_WALK_STATE *WalkState)
153 {
155  ACPI_OPERAND_OBJECT *StackDesc;
156  ACPI_OPERAND_OBJECT *ObjDesc = NULL;
157  UINT8 RefType;
158 
159 
160  ACPI_FUNCTION_TRACE (ExResolveObjectToValue);
161 
162 
163  StackDesc = *StackPtr;
164 
165  /* This is an object of type ACPI_OPERAND_OBJECT */
166 
167  switch (StackDesc->Common.Type)
168  {
170 
171  RefType = StackDesc->Reference.Class;
172 
173  switch (RefType)
174  {
175  case ACPI_REFCLASS_LOCAL:
176  case ACPI_REFCLASS_ARG:
177  /*
178  * Get the local from the method's state info
179  * Note: this increments the local's object reference count
180  */
181  Status = AcpiDsMethodDataGetValue (RefType,
182  StackDesc->Reference.Value, WalkState, &ObjDesc);
183  if (ACPI_FAILURE (Status))
184  {
186  }
187 
188  ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %X] ValueObj is %p\n",
189  StackDesc->Reference.Value, ObjDesc));
190 
191  /*
192  * Now we can delete the original Reference Object and
193  * replace it with the resolved value
194  */
195  AcpiUtRemoveReference (StackDesc);
196  *StackPtr = ObjDesc;
197  break;
198 
199  case ACPI_REFCLASS_INDEX:
200 
201  switch (StackDesc->Reference.TargetType)
202  {
204 
205  /* Just return - do not dereference */
206  break;
207 
208  case ACPI_TYPE_PACKAGE:
209 
210  /* If method call or CopyObject - do not dereference */
211 
212  if ((WalkState->Opcode == AML_INT_METHODCALL_OP) ||
213  (WalkState->Opcode == AML_COPY_OBJECT_OP))
214  {
215  break;
216  }
217 
218  /* Otherwise, dereference the PackageIndex to a package element */
219 
220  ObjDesc = *StackDesc->Reference.Where;
221  if (ObjDesc)
222  {
223  /*
224  * Valid object descriptor, copy pointer to return value
225  * (i.e., dereference the package index)
226  * Delete the ref object, increment the returned object
227  */
228  AcpiUtAddReference (ObjDesc);
229  *StackPtr = ObjDesc;
230  }
231  else
232  {
233  /*
234  * A NULL object descriptor means an uninitialized element of
235  * the package, can't dereference it
236  */
238  "Attempt to dereference an Index to "
239  "NULL package element Idx=%p",
240  StackDesc));
242  }
243  break;
244 
245  default:
246 
247  /* Invalid reference object */
248 
250  "Unknown TargetType 0x%X in Index/Reference object %p",
251  StackDesc->Reference.TargetType, StackDesc));
253  break;
254  }
255  break;
256 
257  case ACPI_REFCLASS_REFOF:
258  case ACPI_REFCLASS_DEBUG:
259  case ACPI_REFCLASS_TABLE:
260 
261  /* Just leave the object as-is, do not dereference */
262 
263  break;
264 
265  case ACPI_REFCLASS_NAME: /* Reference to a named object */
266 
267  /* Dereference the name */
268 
269  if ((StackDesc->Reference.Node->Type == ACPI_TYPE_DEVICE) ||
270  (StackDesc->Reference.Node->Type == ACPI_TYPE_THERMAL))
271  {
272  /* These node types do not have 'real' subobjects */
273 
274  *StackPtr = (void *) StackDesc->Reference.Node;
275  }
276  else
277  {
278  /* Get the object pointed to by the namespace node */
279 
280  *StackPtr = (StackDesc->Reference.Node)->Object;
281  AcpiUtAddReference (*StackPtr);
282  }
283 
284  AcpiUtRemoveReference (StackDesc);
285  break;
286 
287  default:
288 
290  "Unknown Reference type 0x%X in %p",
291  RefType, StackDesc));
293  break;
294  }
295  break;
296 
297  case ACPI_TYPE_BUFFER:
298 
299  Status = AcpiDsGetBufferArguments (StackDesc);
300  break;
301 
302  case ACPI_TYPE_PACKAGE:
303 
304  Status = AcpiDsGetPackageArguments (StackDesc);
305  break;
306 
311 
313  "FieldRead SourceDesc=%p Type=%X\n",
314  StackDesc, StackDesc->Common.Type));
315 
316  Status = AcpiExReadDataFromField (WalkState, StackDesc, &ObjDesc);
317 
318  /* Remove a reference to the original operand, then override */
319 
320  AcpiUtRemoveReference (*StackPtr);
321  *StackPtr = (void *) ObjDesc;
322  break;
323 
324  default:
325 
326  break;
327  }
328 
330 }
331 
332 
333 /*******************************************************************************
334  *
335  * FUNCTION: AcpiExResolveMultiple
336  *
337  * PARAMETERS: WalkState - Current state (contains AML opcode)
338  * Operand - Starting point for resolution
339  * ReturnType - Where the object type is returned
340  * ReturnDesc - Where the resolved object is returned
341  *
342  * RETURN: Status
343  *
344  * DESCRIPTION: Return the base object and type. Traverse a reference list if
345  * necessary to get to the base object.
346  *
347  ******************************************************************************/
348 
351  ACPI_WALK_STATE *WalkState,
352  ACPI_OPERAND_OBJECT *Operand,
353  ACPI_OBJECT_TYPE *ReturnType,
354  ACPI_OPERAND_OBJECT **ReturnDesc)
355 {
356  ACPI_OPERAND_OBJECT *ObjDesc = ACPI_CAST_PTR (void, Operand);
360 
361 
363 
364 
365  /* Operand can be either a namespace node or an operand descriptor */
366 
367  switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
368  {
370 
371  Type = ObjDesc->Common.Type;
372  break;
373 
375 
376  Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
377  ObjDesc = AcpiNsGetAttachedObject (Node);
378 
379  /* If we had an Alias node, use the attached object for type info */
380 
382  {
383  Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
384  ObjDesc = AcpiNsGetAttachedObject (
385  (ACPI_NAMESPACE_NODE *) ObjDesc);
386  }
387 
388  switch (Type)
389  {
390  case ACPI_TYPE_DEVICE:
391  case ACPI_TYPE_THERMAL:
392 
393  /* These types have no attached subobject */
394  break;
395 
396  default:
397 
398  /* All other types require a subobject */
399 
400  if (!ObjDesc)
401  {
403  "[%4.4s] Node is unresolved or uninitialized",
406  }
407  break;
408  }
409  break;
410 
411  default:
413  }
414 
415  /* If type is anything other than a reference, we are done */
416 
418  {
419  goto Exit;
420  }
421 
422  /*
423  * For reference objects created via the RefOf, Index, or Load/LoadTable
424  * operators, we need to get to the base object (as per the ACPI
425  * specification of the ObjectType and SizeOf operators). This means
426  * traversing the list of possibly many nested references.
427  */
428  while (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
429  {
430  switch (ObjDesc->Reference.Class)
431  {
432  case ACPI_REFCLASS_REFOF:
433  case ACPI_REFCLASS_NAME:
434 
435  /* Dereference the reference pointer */
436 
437  if (ObjDesc->Reference.Class == ACPI_REFCLASS_REFOF)
438  {
439  Node = ObjDesc->Reference.Object;
440  }
441  else /* AML_INT_NAMEPATH_OP */
442  {
443  Node = ObjDesc->Reference.Node;
444  }
445 
446  /* All "References" point to a NS node */
447 
449  {
451  "Not a namespace node %p [%s]",
454  }
455 
456  /* Get the attached object */
457 
458  ObjDesc = AcpiNsGetAttachedObject (Node);
459  if (!ObjDesc)
460  {
461  /* No object, use the NS node type */
462 
463  Type = AcpiNsGetType (Node);
464  goto Exit;
465  }
466 
467  /* Check for circular references */
468 
469  if (ObjDesc == Operand)
470  {
472  }
473  break;
474 
475  case ACPI_REFCLASS_INDEX:
476 
477  /* Get the type of this reference (index into another object) */
478 
479  Type = ObjDesc->Reference.TargetType;
480  if (Type != ACPI_TYPE_PACKAGE)
481  {
482  goto Exit;
483  }
484 
485  /*
486  * The main object is a package, we want to get the type
487  * of the individual package element that is referenced by
488  * the index.
489  *
490  * This could of course in turn be another reference object.
491  */
492  ObjDesc = *(ObjDesc->Reference.Where);
493  if (!ObjDesc)
494  {
495  /* NULL package elements are allowed */
496 
497  Type = 0; /* Uninitialized */
498  goto Exit;
499  }
500  break;
501 
502  case ACPI_REFCLASS_TABLE:
503 
505  goto Exit;
506 
507  case ACPI_REFCLASS_LOCAL:
508  case ACPI_REFCLASS_ARG:
509 
510  if (ReturnDesc)
511  {
513  ObjDesc->Reference.Value, WalkState, &ObjDesc);
514  if (ACPI_FAILURE (Status))
515  {
517  }
518  AcpiUtRemoveReference (ObjDesc);
519  }
520  else
521  {
523  ObjDesc->Reference.Value, WalkState, &Node);
524  if (ACPI_FAILURE (Status))
525  {
527  }
528 
529  ObjDesc = AcpiNsGetAttachedObject (Node);
530  if (!ObjDesc)
531  {
533  goto Exit;
534  }
535  }
536  break;
537 
538  case ACPI_REFCLASS_DEBUG:
539 
540  /* The Debug Object is of type "DebugObject" */
541 
543  goto Exit;
544 
545  default:
546 
548  "Unknown Reference Class 0x%2.2X",
549  ObjDesc->Reference.Class));
551  }
552  }
553 
554  /*
555  * Now we are guaranteed to have an object that has not been created
556  * via the RefOf or Index operators.
557  */
558  Type = ObjDesc->Common.Type;
559 
560 
561 Exit:
562  /* Convert internal types to external types */
563 
564  switch (Type)
565  {
569 
571  break;
572 
574 
575  /* Per ACPI Specification, Scope is untyped */
576 
578  break;
579 
580  default:
581 
582  /* No change to Type required */
583 
584  break;
585  }
586 
587  *ReturnType = Type;
588  if (ReturnDesc)
589  {
590  *ReturnDesc = ObjDesc;
591  }
593 }
#define ACPI_TYPE_DEBUG_OBJECT
Definition: actypes.h:695
ACPI_STATUS AcpiDsMethodDataGetNode(UINT8 Type, UINT32 Index, ACPI_WALK_STATE *WalkState, ACPI_NAMESPACE_NODE **Node)
Definition: dsmthdat.c:275
const char * AcpiUtGetDescriptorName(void *Object)
Definition: utdecode.c:381
void AcpiUtAddReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:746
#define ACPI_TYPE_LOCAL_ALIAS
Definition: actypes.h:712
static ACPI_STATUS AcpiExResolveObjectToValue(ACPI_OPERAND_OBJECT **StackPtr, ACPI_WALK_STATE *WalkState)
Definition: exresolv.c:150
#define ACPI_TYPE_THERMAL
Definition: actypes.h:692
Type
Definition: Type.h:6
#define ACPI_TYPE_BUFFER
Definition: actypes.h:682
ACPI_STATUS AcpiExResolveMultiple(ACPI_WALK_STATE *WalkState, ACPI_OPERAND_OBJECT *Operand, ACPI_OBJECT_TYPE *ReturnType, ACPI_OPERAND_OBJECT **ReturnDesc)
Definition: exresolv.c:350
#define AE_AML_INTERNAL
Definition: acexcep.h:194
#define AML_INT_METHODCALL_OP
Definition: amlcode.h:210
#define AE_AML_NO_OPERAND
Definition: acexcep.h:181
#define ACPI_TYPE_LOCAL_REFERENCE
Definition: actypes.h:711
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:710
ACPI_OBJECT_TYPE AcpiNsGetType(ACPI_NAMESPACE_NODE *Node)
Definition: nsutils.c:120
#define ACPI_TYPE_PACKAGE
Definition: actypes.h:683
#define ACPI_TYPE_FIELD_UNIT
Definition: actypes.h:684
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
ACPI_OBJECT_COMMON_HEADER UINT8 Class
Definition: acobject.h:441
ACPI_STATUS AcpiExResolveNodeToValue(ACPI_NAMESPACE_NODE **ObjectPtr, ACPI_WALK_STATE *WalkState)
Definition: exresnte.c:82
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
smooth NULL
Definition: ftsmooth.c:416
#define AE_INFO
Definition: acoutput.h:230
UINT32 ACPI_OBJECT_TYPE
Definition: actypes.h:677
ACPI_OBJECT_REFERENCE Reference
Definition: acobject.h:538
#define ACPI_FUNCTION_TRACE_PTR(a, b)
Definition: acoutput.h:481
#define ACPI_DESC_TYPE_OPERAND
Definition: acobject.h:574
static void Exit(void)
Definition: sock.c:1331
#define AML_COPY_OBJECT_OP
Definition: amlcode.h:131
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
#define ACPI_TYPE_DDB_HANDLE
Definition: actypes.h:694
ACPI_OPERAND_OBJECT * AcpiNsGetAttachedObject(ACPI_NAMESPACE_NODE *Node)
Definition: nsobject.c:308
static IUnknown Object
Definition: main.c:512
#define ACPI_TYPE_LOCAL_REGION_FIELD
Definition: actypes.h:708
#define ACPI_TYPE_ANY
Definition: actypes.h:679
#define AE_AML_UNINITIALIZED_NODE
Definition: acexcep.h:213
ACPI_STATUS AcpiExResolveToValue(ACPI_OPERAND_OBJECT **StackPtr, ACPI_WALK_STATE *WalkState)
Definition: exresolv.c:79
#define ACPI_TYPE_DEVICE
Definition: actypes.h:685
Status
Definition: gdiplustypes.h:24
#define AE_AML_CIRCULAR_REFERENCE
Definition: acexcep.h:209
#define ACPI_DB_EXEC
Definition: acoutput.h:165
#define ACPI_CAST_INDIRECT_PTR(t, p)
Definition: actypes.h:545
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_TYPE_BUFFER_FIELD
Definition: actypes.h:693
ACPI_OBJECT_COMMON Common
Definition: acobject.h:517
ACPI_NAMESPACE_NODE * Node
Definition: acobject.h:445
void AcpiUtRemoveReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:784
ACPI_STATUS AcpiDsGetPackageArguments(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: dsargs.c:344
#define AE_AML_UNINITIALIZED_ELEMENT
Definition: acexcep.h:186
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
const char * AcpiUtGetNodeName(void *Object)
Definition: utdecode.c:305
#define ACPI_TYPE_LOCAL_SCOPE
Definition: actypes.h:718
#define ACPI_TYPE_LOCAL_BANK_FIELD
Definition: actypes.h:709
ACPI_STATUS AcpiDsMethodDataGetValue(UINT8 Type, UINT32 Index, ACPI_WALK_STATE *WalkState, ACPI_OPERAND_OBJECT **DestDesc)
Definition: dsmthdat.c:406
UINT16 Opcode
Definition: acstruct.h:78
union acpi_operand_object ** Where
Definition: acobject.h:446
ACPI_STATUS AcpiExReadDataFromField(ACPI_WALK_STATE *WalkState, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **RetBufferDesc)
Definition: exfield.c:147
#define ACPI_DESC_TYPE_NAMED
Definition: acobject.h:575
#define ACPI_CAST_PTR(t, p)
Definition: actypes.h:544
unsigned char UINT8
#define AE_OK
Definition: acexcep.h:97
Definition: dlist.c:348
#define ACPI_GET_DESCRIPTOR_TYPE(d)
Definition: acmacros.h:414