128c506b8Sjruoho /******************************************************************************
228c506b8Sjruoho *
328c506b8Sjruoho * Module Name: exresolv - AML Interpreter object resolution
428c506b8Sjruoho *
528c506b8Sjruoho *****************************************************************************/
628c506b8Sjruoho
7124f4c82Sjruoho /*
8*046a2985Schristos * Copyright (C) 2000 - 2023, Intel Corp.
928c506b8Sjruoho * All rights reserved.
1028c506b8Sjruoho *
11124f4c82Sjruoho * Redistribution and use in source and binary forms, with or without
12124f4c82Sjruoho * modification, are permitted provided that the following conditions
13124f4c82Sjruoho * are met:
14124f4c82Sjruoho * 1. Redistributions of source code must retain the above copyright
15124f4c82Sjruoho * notice, this list of conditions, and the following disclaimer,
16124f4c82Sjruoho * without modification.
17124f4c82Sjruoho * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18124f4c82Sjruoho * substantially similar to the "NO WARRANTY" disclaimer below
19124f4c82Sjruoho * ("Disclaimer") and any redistribution must be conditioned upon
20124f4c82Sjruoho * including a substantially similar Disclaimer requirement for further
21124f4c82Sjruoho * binary redistribution.
22124f4c82Sjruoho * 3. Neither the names of the above-listed copyright holders nor the names
23124f4c82Sjruoho * of any contributors may be used to endorse or promote products derived
24124f4c82Sjruoho * from this software without specific prior written permission.
2528c506b8Sjruoho *
26124f4c82Sjruoho * Alternatively, this software may be distributed under the terms of the
27124f4c82Sjruoho * GNU General Public License ("GPL") version 2 as published by the Free
28124f4c82Sjruoho * Software Foundation.
2928c506b8Sjruoho *
30124f4c82Sjruoho * NO WARRANTY
31124f4c82Sjruoho * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32124f4c82Sjruoho * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3346a330b4Schristos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34124f4c82Sjruoho * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35124f4c82Sjruoho * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36124f4c82Sjruoho * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37124f4c82Sjruoho * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38124f4c82Sjruoho * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39124f4c82Sjruoho * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40124f4c82Sjruoho * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41124f4c82Sjruoho * POSSIBILITY OF SUCH DAMAGES.
42124f4c82Sjruoho */
4328c506b8Sjruoho
4428c506b8Sjruoho #include "acpi.h"
4528c506b8Sjruoho #include "accommon.h"
4628c506b8Sjruoho #include "amlcode.h"
4728c506b8Sjruoho #include "acdispat.h"
4828c506b8Sjruoho #include "acinterp.h"
4928c506b8Sjruoho #include "acnamesp.h"
5028c506b8Sjruoho
5128c506b8Sjruoho
5228c506b8Sjruoho #define _COMPONENT ACPI_EXECUTER
5328c506b8Sjruoho ACPI_MODULE_NAME ("exresolv")
5428c506b8Sjruoho
5528c506b8Sjruoho /* Local prototypes */
5628c506b8Sjruoho
5728c506b8Sjruoho static ACPI_STATUS
5828c506b8Sjruoho AcpiExResolveObjectToValue (
5928c506b8Sjruoho ACPI_OPERAND_OBJECT **StackPtr,
6028c506b8Sjruoho ACPI_WALK_STATE *WalkState);
6128c506b8Sjruoho
6228c506b8Sjruoho
6328c506b8Sjruoho /*******************************************************************************
6428c506b8Sjruoho *
6528c506b8Sjruoho * FUNCTION: AcpiExResolveToValue
6628c506b8Sjruoho *
6728c506b8Sjruoho * PARAMETERS: **StackPtr - Points to entry on ObjStack, which can
6828c506b8Sjruoho * be either an (ACPI_OPERAND_OBJECT *)
6928c506b8Sjruoho * or an ACPI_HANDLE.
7028c506b8Sjruoho * WalkState - Current method state
7128c506b8Sjruoho *
7228c506b8Sjruoho * RETURN: Status
7328c506b8Sjruoho *
7428c506b8Sjruoho * DESCRIPTION: Convert Reference objects to values
7528c506b8Sjruoho *
7628c506b8Sjruoho ******************************************************************************/
7728c506b8Sjruoho
7828c506b8Sjruoho ACPI_STATUS
AcpiExResolveToValue(ACPI_OPERAND_OBJECT ** StackPtr,ACPI_WALK_STATE * WalkState)7928c506b8Sjruoho AcpiExResolveToValue (
8028c506b8Sjruoho ACPI_OPERAND_OBJECT **StackPtr,
8128c506b8Sjruoho ACPI_WALK_STATE *WalkState)
8228c506b8Sjruoho {
8328c506b8Sjruoho ACPI_STATUS Status;
8428c506b8Sjruoho
8528c506b8Sjruoho
8628c506b8Sjruoho ACPI_FUNCTION_TRACE_PTR (ExResolveToValue, StackPtr);
8728c506b8Sjruoho
8828c506b8Sjruoho
8928c506b8Sjruoho if (!StackPtr || !*StackPtr)
9028c506b8Sjruoho {
9128c506b8Sjruoho ACPI_ERROR ((AE_INFO, "Internal - null pointer"));
9228c506b8Sjruoho return_ACPI_STATUS (AE_AML_NO_OPERAND);
9328c506b8Sjruoho }
9428c506b8Sjruoho
9528c506b8Sjruoho /*
9628c506b8Sjruoho * The entity pointed to by the StackPtr can be either
9728c506b8Sjruoho * 1) A valid ACPI_OPERAND_OBJECT, or
9828c506b8Sjruoho * 2) A ACPI_NAMESPACE_NODE (NamedObj)
9928c506b8Sjruoho */
10028c506b8Sjruoho if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr) == ACPI_DESC_TYPE_OPERAND)
10128c506b8Sjruoho {
10228c506b8Sjruoho Status = AcpiExResolveObjectToValue (StackPtr, WalkState);
10328c506b8Sjruoho if (ACPI_FAILURE (Status))
10428c506b8Sjruoho {
10528c506b8Sjruoho return_ACPI_STATUS (Status);
10628c506b8Sjruoho }
10728c506b8Sjruoho
10828c506b8Sjruoho if (!*StackPtr)
10928c506b8Sjruoho {
11028c506b8Sjruoho ACPI_ERROR ((AE_INFO, "Internal - null pointer"));
11128c506b8Sjruoho return_ACPI_STATUS (AE_AML_NO_OPERAND);
11228c506b8Sjruoho }
11328c506b8Sjruoho }
11428c506b8Sjruoho
11528c506b8Sjruoho /*
11628c506b8Sjruoho * Object on the stack may have changed if AcpiExResolveObjectToValue()
11728c506b8Sjruoho * was called (i.e., we can't use an _else_ here.)
11828c506b8Sjruoho */
11928c506b8Sjruoho if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr) == ACPI_DESC_TYPE_NAMED)
12028c506b8Sjruoho {
12128c506b8Sjruoho Status = AcpiExResolveNodeToValue (
12228c506b8Sjruoho ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, StackPtr),
12328c506b8Sjruoho WalkState);
12428c506b8Sjruoho if (ACPI_FAILURE (Status))
12528c506b8Sjruoho {
12628c506b8Sjruoho return_ACPI_STATUS (Status);
12728c506b8Sjruoho }
12828c506b8Sjruoho }
12928c506b8Sjruoho
13028c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Resolved object %p\n", *StackPtr));
13128c506b8Sjruoho return_ACPI_STATUS (AE_OK);
13228c506b8Sjruoho }
13328c506b8Sjruoho
13428c506b8Sjruoho
13528c506b8Sjruoho /*******************************************************************************
13628c506b8Sjruoho *
13728c506b8Sjruoho * FUNCTION: AcpiExResolveObjectToValue
13828c506b8Sjruoho *
13928c506b8Sjruoho * PARAMETERS: StackPtr - Pointer to an internal object
14028c506b8Sjruoho * WalkState - Current method state
14128c506b8Sjruoho *
14228c506b8Sjruoho * RETURN: Status
14328c506b8Sjruoho *
14428c506b8Sjruoho * DESCRIPTION: Retrieve the value from an internal object. The Reference type
14528c506b8Sjruoho * uses the associated AML opcode to determine the value.
14628c506b8Sjruoho *
14728c506b8Sjruoho ******************************************************************************/
14828c506b8Sjruoho
14928c506b8Sjruoho static ACPI_STATUS
AcpiExResolveObjectToValue(ACPI_OPERAND_OBJECT ** StackPtr,ACPI_WALK_STATE * WalkState)15028c506b8Sjruoho AcpiExResolveObjectToValue (
15128c506b8Sjruoho ACPI_OPERAND_OBJECT **StackPtr,
15228c506b8Sjruoho ACPI_WALK_STATE *WalkState)
15328c506b8Sjruoho {
15428c506b8Sjruoho ACPI_STATUS Status = AE_OK;
15528c506b8Sjruoho ACPI_OPERAND_OBJECT *StackDesc;
15628c506b8Sjruoho ACPI_OPERAND_OBJECT *ObjDesc = NULL;
15728c506b8Sjruoho UINT8 RefType;
15828c506b8Sjruoho
15928c506b8Sjruoho
16028c506b8Sjruoho ACPI_FUNCTION_TRACE (ExResolveObjectToValue);
16128c506b8Sjruoho
16228c506b8Sjruoho
16328c506b8Sjruoho StackDesc = *StackPtr;
16428c506b8Sjruoho
165ff4a156dSchristos /* This is an object of type ACPI_OPERAND_OBJECT */
16628c506b8Sjruoho
16728c506b8Sjruoho switch (StackDesc->Common.Type)
16828c506b8Sjruoho {
16928c506b8Sjruoho case ACPI_TYPE_LOCAL_REFERENCE:
17028c506b8Sjruoho
17128c506b8Sjruoho RefType = StackDesc->Reference.Class;
17228c506b8Sjruoho
17328c506b8Sjruoho switch (RefType)
17428c506b8Sjruoho {
17528c506b8Sjruoho case ACPI_REFCLASS_LOCAL:
17628c506b8Sjruoho case ACPI_REFCLASS_ARG:
17728c506b8Sjruoho /*
17828c506b8Sjruoho * Get the local from the method's state info
17928c506b8Sjruoho * Note: this increments the local's object reference count
18028c506b8Sjruoho */
18128c506b8Sjruoho Status = AcpiDsMethodDataGetValue (RefType,
18228c506b8Sjruoho StackDesc->Reference.Value, WalkState, &ObjDesc);
18328c506b8Sjruoho if (ACPI_FAILURE (Status))
18428c506b8Sjruoho {
18528c506b8Sjruoho return_ACPI_STATUS (Status);
18628c506b8Sjruoho }
18728c506b8Sjruoho
18828c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %X] ValueObj is %p\n",
18928c506b8Sjruoho StackDesc->Reference.Value, ObjDesc));
19028c506b8Sjruoho
19128c506b8Sjruoho /*
19228c506b8Sjruoho * Now we can delete the original Reference Object and
19328c506b8Sjruoho * replace it with the resolved value
19428c506b8Sjruoho */
19528c506b8Sjruoho AcpiUtRemoveReference (StackDesc);
19628c506b8Sjruoho *StackPtr = ObjDesc;
19728c506b8Sjruoho break;
19828c506b8Sjruoho
19928c506b8Sjruoho case ACPI_REFCLASS_INDEX:
20028c506b8Sjruoho
20128c506b8Sjruoho switch (StackDesc->Reference.TargetType)
20228c506b8Sjruoho {
20328c506b8Sjruoho case ACPI_TYPE_BUFFER_FIELD:
20428c506b8Sjruoho
20528c506b8Sjruoho /* Just return - do not dereference */
20628c506b8Sjruoho break;
20728c506b8Sjruoho
20828c506b8Sjruoho case ACPI_TYPE_PACKAGE:
20928c506b8Sjruoho
21028c506b8Sjruoho /* If method call or CopyObject - do not dereference */
21128c506b8Sjruoho
21228c506b8Sjruoho if ((WalkState->Opcode == AML_INT_METHODCALL_OP) ||
213835858a6Schristos (WalkState->Opcode == AML_COPY_OBJECT_OP))
21428c506b8Sjruoho {
21528c506b8Sjruoho break;
21628c506b8Sjruoho }
21728c506b8Sjruoho
21828c506b8Sjruoho /* Otherwise, dereference the PackageIndex to a package element */
21928c506b8Sjruoho
22028c506b8Sjruoho ObjDesc = *StackDesc->Reference.Where;
22128c506b8Sjruoho if (ObjDesc)
22228c506b8Sjruoho {
22328c506b8Sjruoho /*
22428c506b8Sjruoho * Valid object descriptor, copy pointer to return value
22528c506b8Sjruoho * (i.e., dereference the package index)
22628c506b8Sjruoho * Delete the ref object, increment the returned object
22728c506b8Sjruoho */
22828c506b8Sjruoho AcpiUtAddReference (ObjDesc);
22928c506b8Sjruoho *StackPtr = ObjDesc;
23028c506b8Sjruoho }
23128c506b8Sjruoho else
23228c506b8Sjruoho {
23328c506b8Sjruoho /*
23428c506b8Sjruoho * A NULL object descriptor means an uninitialized element of
23528c506b8Sjruoho * the package, can't dereference it
23628c506b8Sjruoho */
23728c506b8Sjruoho ACPI_ERROR ((AE_INFO,
23871e38f1dSchristos "Attempt to dereference an Index to "
23971e38f1dSchristos "NULL package element Idx=%p",
24028c506b8Sjruoho StackDesc));
24128c506b8Sjruoho Status = AE_AML_UNINITIALIZED_ELEMENT;
24228c506b8Sjruoho }
24328c506b8Sjruoho break;
24428c506b8Sjruoho
24528c506b8Sjruoho default:
24628c506b8Sjruoho
24728c506b8Sjruoho /* Invalid reference object */
24828c506b8Sjruoho
24928c506b8Sjruoho ACPI_ERROR ((AE_INFO,
25028c506b8Sjruoho "Unknown TargetType 0x%X in Index/Reference object %p",
25128c506b8Sjruoho StackDesc->Reference.TargetType, StackDesc));
25228c506b8Sjruoho Status = AE_AML_INTERNAL;
25328c506b8Sjruoho break;
25428c506b8Sjruoho }
25528c506b8Sjruoho break;
25628c506b8Sjruoho
25728c506b8Sjruoho case ACPI_REFCLASS_REFOF:
25828c506b8Sjruoho case ACPI_REFCLASS_DEBUG:
25928c506b8Sjruoho case ACPI_REFCLASS_TABLE:
26028c506b8Sjruoho
26128c506b8Sjruoho /* Just leave the object as-is, do not dereference */
26228c506b8Sjruoho
26328c506b8Sjruoho break;
26428c506b8Sjruoho
26528c506b8Sjruoho case ACPI_REFCLASS_NAME: /* Reference to a named object */
26628c506b8Sjruoho
26728c506b8Sjruoho /* Dereference the name */
26828c506b8Sjruoho
26928c506b8Sjruoho if ((StackDesc->Reference.Node->Type == ACPI_TYPE_DEVICE) ||
27028c506b8Sjruoho (StackDesc->Reference.Node->Type == ACPI_TYPE_THERMAL))
27128c506b8Sjruoho {
27228c506b8Sjruoho /* These node types do not have 'real' subobjects */
27328c506b8Sjruoho
27428c506b8Sjruoho *StackPtr = (void *) StackDesc->Reference.Node;
27528c506b8Sjruoho }
27628c506b8Sjruoho else
27728c506b8Sjruoho {
27828c506b8Sjruoho /* Get the object pointed to by the namespace node */
27928c506b8Sjruoho
28028c506b8Sjruoho *StackPtr = (StackDesc->Reference.Node)->Object;
28128c506b8Sjruoho AcpiUtAddReference (*StackPtr);
28228c506b8Sjruoho }
28328c506b8Sjruoho
28428c506b8Sjruoho AcpiUtRemoveReference (StackDesc);
28528c506b8Sjruoho break;
28628c506b8Sjruoho
28728c506b8Sjruoho default:
28828c506b8Sjruoho
28928c506b8Sjruoho ACPI_ERROR ((AE_INFO,
29071e38f1dSchristos "Unknown Reference type 0x%X in %p",
29171e38f1dSchristos RefType, StackDesc));
29228c506b8Sjruoho Status = AE_AML_INTERNAL;
29328c506b8Sjruoho break;
29428c506b8Sjruoho }
29528c506b8Sjruoho break;
29628c506b8Sjruoho
29728c506b8Sjruoho case ACPI_TYPE_BUFFER:
29828c506b8Sjruoho
29928c506b8Sjruoho Status = AcpiDsGetBufferArguments (StackDesc);
30028c506b8Sjruoho break;
30128c506b8Sjruoho
30228c506b8Sjruoho case ACPI_TYPE_PACKAGE:
30328c506b8Sjruoho
30428c506b8Sjruoho Status = AcpiDsGetPackageArguments (StackDesc);
30528c506b8Sjruoho break;
30628c506b8Sjruoho
30728c506b8Sjruoho case ACPI_TYPE_BUFFER_FIELD:
30828c506b8Sjruoho case ACPI_TYPE_LOCAL_REGION_FIELD:
30928c506b8Sjruoho case ACPI_TYPE_LOCAL_BANK_FIELD:
31028c506b8Sjruoho case ACPI_TYPE_LOCAL_INDEX_FIELD:
31128c506b8Sjruoho
31271e38f1dSchristos ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
31371e38f1dSchristos "FieldRead SourceDesc=%p Type=%X\n",
31428c506b8Sjruoho StackDesc, StackDesc->Common.Type));
31528c506b8Sjruoho
31628c506b8Sjruoho Status = AcpiExReadDataFromField (WalkState, StackDesc, &ObjDesc);
31728c506b8Sjruoho
31828c506b8Sjruoho /* Remove a reference to the original operand, then override */
31928c506b8Sjruoho
32028c506b8Sjruoho AcpiUtRemoveReference (*StackPtr);
32128c506b8Sjruoho *StackPtr = (void *) ObjDesc;
32228c506b8Sjruoho break;
32328c506b8Sjruoho
32428c506b8Sjruoho default:
325ff4a156dSchristos
32628c506b8Sjruoho break;
32728c506b8Sjruoho }
32828c506b8Sjruoho
32928c506b8Sjruoho return_ACPI_STATUS (Status);
33028c506b8Sjruoho }
33128c506b8Sjruoho
33228c506b8Sjruoho
33328c506b8Sjruoho /*******************************************************************************
33428c506b8Sjruoho *
33528c506b8Sjruoho * FUNCTION: AcpiExResolveMultiple
33628c506b8Sjruoho *
33728c506b8Sjruoho * PARAMETERS: WalkState - Current state (contains AML opcode)
33828c506b8Sjruoho * Operand - Starting point for resolution
33928c506b8Sjruoho * ReturnType - Where the object type is returned
34028c506b8Sjruoho * ReturnDesc - Where the resolved object is returned
34128c506b8Sjruoho *
34228c506b8Sjruoho * RETURN: Status
34328c506b8Sjruoho *
34428c506b8Sjruoho * DESCRIPTION: Return the base object and type. Traverse a reference list if
34528c506b8Sjruoho * necessary to get to the base object.
34628c506b8Sjruoho *
34728c506b8Sjruoho ******************************************************************************/
34828c506b8Sjruoho
34928c506b8Sjruoho ACPI_STATUS
AcpiExResolveMultiple(ACPI_WALK_STATE * WalkState,ACPI_OPERAND_OBJECT * Operand,ACPI_OBJECT_TYPE * ReturnType,ACPI_OPERAND_OBJECT ** ReturnDesc)35028c506b8Sjruoho AcpiExResolveMultiple (
35128c506b8Sjruoho ACPI_WALK_STATE *WalkState,
35228c506b8Sjruoho ACPI_OPERAND_OBJECT *Operand,
35328c506b8Sjruoho ACPI_OBJECT_TYPE *ReturnType,
35428c506b8Sjruoho ACPI_OPERAND_OBJECT **ReturnDesc)
35528c506b8Sjruoho {
35671e38f1dSchristos ACPI_OPERAND_OBJECT *ObjDesc = ACPI_CAST_PTR (void, Operand);
35771e38f1dSchristos ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Operand);
35828c506b8Sjruoho ACPI_OBJECT_TYPE Type;
35928c506b8Sjruoho ACPI_STATUS Status;
36028c506b8Sjruoho
36128c506b8Sjruoho
36228c506b8Sjruoho ACPI_FUNCTION_TRACE (AcpiExResolveMultiple);
36328c506b8Sjruoho
36428c506b8Sjruoho
36528c506b8Sjruoho /* Operand can be either a namespace node or an operand descriptor */
36628c506b8Sjruoho
36728c506b8Sjruoho switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
36828c506b8Sjruoho {
36928c506b8Sjruoho case ACPI_DESC_TYPE_OPERAND:
370ff4a156dSchristos
37128c506b8Sjruoho Type = ObjDesc->Common.Type;
37228c506b8Sjruoho break;
37328c506b8Sjruoho
37428c506b8Sjruoho case ACPI_DESC_TYPE_NAMED:
375ff4a156dSchristos
37628c506b8Sjruoho Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
37771e38f1dSchristos ObjDesc = AcpiNsGetAttachedObject (Node);
37828c506b8Sjruoho
37928c506b8Sjruoho /* If we had an Alias node, use the attached object for type info */
38028c506b8Sjruoho
38128c506b8Sjruoho if (Type == ACPI_TYPE_LOCAL_ALIAS)
38228c506b8Sjruoho {
38328c506b8Sjruoho Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
38471e38f1dSchristos ObjDesc = AcpiNsGetAttachedObject (
38571e38f1dSchristos (ACPI_NAMESPACE_NODE *) ObjDesc);
38671e38f1dSchristos }
38771e38f1dSchristos
38889b8eb6cSchristos switch (Type)
38989b8eb6cSchristos {
39089b8eb6cSchristos case ACPI_TYPE_DEVICE:
39189b8eb6cSchristos case ACPI_TYPE_THERMAL:
39289b8eb6cSchristos
39389b8eb6cSchristos /* These types have no attached subobject */
39489b8eb6cSchristos break;
39589b8eb6cSchristos
39689b8eb6cSchristos default:
39789b8eb6cSchristos
39889b8eb6cSchristos /* All other types require a subobject */
39989b8eb6cSchristos
40071e38f1dSchristos if (!ObjDesc)
40171e38f1dSchristos {
40271e38f1dSchristos ACPI_ERROR ((AE_INFO,
40371e38f1dSchristos "[%4.4s] Node is unresolved or uninitialized",
40471e38f1dSchristos AcpiUtGetNodeName (Node)));
40571e38f1dSchristos return_ACPI_STATUS (AE_AML_UNINITIALIZED_NODE);
40628c506b8Sjruoho }
40728c506b8Sjruoho break;
40889b8eb6cSchristos }
40989b8eb6cSchristos break;
41028c506b8Sjruoho
41128c506b8Sjruoho default:
41228c506b8Sjruoho return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
41328c506b8Sjruoho }
41428c506b8Sjruoho
41528c506b8Sjruoho /* If type is anything other than a reference, we are done */
41628c506b8Sjruoho
41728c506b8Sjruoho if (Type != ACPI_TYPE_LOCAL_REFERENCE)
41828c506b8Sjruoho {
41928c506b8Sjruoho goto Exit;
42028c506b8Sjruoho }
42128c506b8Sjruoho
42228c506b8Sjruoho /*
42328c506b8Sjruoho * For reference objects created via the RefOf, Index, or Load/LoadTable
42428c506b8Sjruoho * operators, we need to get to the base object (as per the ACPI
42528c506b8Sjruoho * specification of the ObjectType and SizeOf operators). This means
42628c506b8Sjruoho * traversing the list of possibly many nested references.
42728c506b8Sjruoho */
42828c506b8Sjruoho while (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
42928c506b8Sjruoho {
43028c506b8Sjruoho switch (ObjDesc->Reference.Class)
43128c506b8Sjruoho {
43228c506b8Sjruoho case ACPI_REFCLASS_REFOF:
43328c506b8Sjruoho case ACPI_REFCLASS_NAME:
43428c506b8Sjruoho
43528c506b8Sjruoho /* Dereference the reference pointer */
43628c506b8Sjruoho
43728c506b8Sjruoho if (ObjDesc->Reference.Class == ACPI_REFCLASS_REFOF)
43828c506b8Sjruoho {
43928c506b8Sjruoho Node = ObjDesc->Reference.Object;
44028c506b8Sjruoho }
44128c506b8Sjruoho else /* AML_INT_NAMEPATH_OP */
44228c506b8Sjruoho {
44328c506b8Sjruoho Node = ObjDesc->Reference.Node;
44428c506b8Sjruoho }
44528c506b8Sjruoho
44628c506b8Sjruoho /* All "References" point to a NS node */
44728c506b8Sjruoho
44828c506b8Sjruoho if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
44928c506b8Sjruoho {
45028c506b8Sjruoho ACPI_ERROR ((AE_INFO,
45128c506b8Sjruoho "Not a namespace node %p [%s]",
45228c506b8Sjruoho Node, AcpiUtGetDescriptorName (Node)));
45328c506b8Sjruoho return_ACPI_STATUS (AE_AML_INTERNAL);
45428c506b8Sjruoho }
45528c506b8Sjruoho
45628c506b8Sjruoho /* Get the attached object */
45728c506b8Sjruoho
45828c506b8Sjruoho ObjDesc = AcpiNsGetAttachedObject (Node);
45928c506b8Sjruoho if (!ObjDesc)
46028c506b8Sjruoho {
46128c506b8Sjruoho /* No object, use the NS node type */
46228c506b8Sjruoho
46328c506b8Sjruoho Type = AcpiNsGetType (Node);
46428c506b8Sjruoho goto Exit;
46528c506b8Sjruoho }
46628c506b8Sjruoho
46728c506b8Sjruoho /* Check for circular references */
46828c506b8Sjruoho
46928c506b8Sjruoho if (ObjDesc == Operand)
47028c506b8Sjruoho {
47128c506b8Sjruoho return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE);
47228c506b8Sjruoho }
47328c506b8Sjruoho break;
47428c506b8Sjruoho
47528c506b8Sjruoho case ACPI_REFCLASS_INDEX:
47628c506b8Sjruoho
47728c506b8Sjruoho /* Get the type of this reference (index into another object) */
47828c506b8Sjruoho
47928c506b8Sjruoho Type = ObjDesc->Reference.TargetType;
48028c506b8Sjruoho if (Type != ACPI_TYPE_PACKAGE)
48128c506b8Sjruoho {
48228c506b8Sjruoho goto Exit;
48328c506b8Sjruoho }
48428c506b8Sjruoho
48528c506b8Sjruoho /*
48628c506b8Sjruoho * The main object is a package, we want to get the type
48728c506b8Sjruoho * of the individual package element that is referenced by
48828c506b8Sjruoho * the index.
48928c506b8Sjruoho *
49028c506b8Sjruoho * This could of course in turn be another reference object.
49128c506b8Sjruoho */
49228c506b8Sjruoho ObjDesc = *(ObjDesc->Reference.Where);
49328c506b8Sjruoho if (!ObjDesc)
49428c506b8Sjruoho {
49528c506b8Sjruoho /* NULL package elements are allowed */
49628c506b8Sjruoho
49728c506b8Sjruoho Type = 0; /* Uninitialized */
49828c506b8Sjruoho goto Exit;
49928c506b8Sjruoho }
50028c506b8Sjruoho break;
50128c506b8Sjruoho
50228c506b8Sjruoho case ACPI_REFCLASS_TABLE:
50328c506b8Sjruoho
50428c506b8Sjruoho Type = ACPI_TYPE_DDB_HANDLE;
50528c506b8Sjruoho goto Exit;
50628c506b8Sjruoho
50728c506b8Sjruoho case ACPI_REFCLASS_LOCAL:
50828c506b8Sjruoho case ACPI_REFCLASS_ARG:
50928c506b8Sjruoho
51028c506b8Sjruoho if (ReturnDesc)
51128c506b8Sjruoho {
51228c506b8Sjruoho Status = AcpiDsMethodDataGetValue (ObjDesc->Reference.Class,
51328c506b8Sjruoho ObjDesc->Reference.Value, WalkState, &ObjDesc);
51428c506b8Sjruoho if (ACPI_FAILURE (Status))
51528c506b8Sjruoho {
51628c506b8Sjruoho return_ACPI_STATUS (Status);
51728c506b8Sjruoho }
51828c506b8Sjruoho AcpiUtRemoveReference (ObjDesc);
51928c506b8Sjruoho }
52028c506b8Sjruoho else
52128c506b8Sjruoho {
52228c506b8Sjruoho Status = AcpiDsMethodDataGetNode (ObjDesc->Reference.Class,
52328c506b8Sjruoho ObjDesc->Reference.Value, WalkState, &Node);
52428c506b8Sjruoho if (ACPI_FAILURE (Status))
52528c506b8Sjruoho {
52628c506b8Sjruoho return_ACPI_STATUS (Status);
52728c506b8Sjruoho }
52828c506b8Sjruoho
52928c506b8Sjruoho ObjDesc = AcpiNsGetAttachedObject (Node);
53028c506b8Sjruoho if (!ObjDesc)
53128c506b8Sjruoho {
53228c506b8Sjruoho Type = ACPI_TYPE_ANY;
53328c506b8Sjruoho goto Exit;
53428c506b8Sjruoho }
53528c506b8Sjruoho }
53628c506b8Sjruoho break;
53728c506b8Sjruoho
53828c506b8Sjruoho case ACPI_REFCLASS_DEBUG:
53928c506b8Sjruoho
54028c506b8Sjruoho /* The Debug Object is of type "DebugObject" */
54128c506b8Sjruoho
54228c506b8Sjruoho Type = ACPI_TYPE_DEBUG_OBJECT;
54328c506b8Sjruoho goto Exit;
54428c506b8Sjruoho
54528c506b8Sjruoho default:
54628c506b8Sjruoho
54728c506b8Sjruoho ACPI_ERROR ((AE_INFO,
54871e38f1dSchristos "Unknown Reference Class 0x%2.2X",
54971e38f1dSchristos ObjDesc->Reference.Class));
55028c506b8Sjruoho return_ACPI_STATUS (AE_AML_INTERNAL);
55128c506b8Sjruoho }
55228c506b8Sjruoho }
55328c506b8Sjruoho
55428c506b8Sjruoho /*
55528c506b8Sjruoho * Now we are guaranteed to have an object that has not been created
55628c506b8Sjruoho * via the RefOf or Index operators.
55728c506b8Sjruoho */
55828c506b8Sjruoho Type = ObjDesc->Common.Type;
55928c506b8Sjruoho
56028c506b8Sjruoho
56128c506b8Sjruoho Exit:
56228c506b8Sjruoho /* Convert internal types to external types */
56328c506b8Sjruoho
56428c506b8Sjruoho switch (Type)
56528c506b8Sjruoho {
56628c506b8Sjruoho case ACPI_TYPE_LOCAL_REGION_FIELD:
56728c506b8Sjruoho case ACPI_TYPE_LOCAL_BANK_FIELD:
56828c506b8Sjruoho case ACPI_TYPE_LOCAL_INDEX_FIELD:
56928c506b8Sjruoho
57028c506b8Sjruoho Type = ACPI_TYPE_FIELD_UNIT;
57128c506b8Sjruoho break;
57228c506b8Sjruoho
57328c506b8Sjruoho case ACPI_TYPE_LOCAL_SCOPE:
57428c506b8Sjruoho
57528c506b8Sjruoho /* Per ACPI Specification, Scope is untyped */
57628c506b8Sjruoho
57728c506b8Sjruoho Type = ACPI_TYPE_ANY;
57828c506b8Sjruoho break;
57928c506b8Sjruoho
58028c506b8Sjruoho default:
581ff4a156dSchristos
58228c506b8Sjruoho /* No change to Type required */
583ff4a156dSchristos
58428c506b8Sjruoho break;
58528c506b8Sjruoho }
58628c506b8Sjruoho
58728c506b8Sjruoho *ReturnType = Type;
58828c506b8Sjruoho if (ReturnDesc)
58928c506b8Sjruoho {
59028c506b8Sjruoho *ReturnDesc = ObjDesc;
59128c506b8Sjruoho }
59228c506b8Sjruoho return_ACPI_STATUS (AE_OK);
59328c506b8Sjruoho }
594