xref: /netbsd-src/sys/external/bsd/acpica/dist/executer/exresolv.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
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