xref: /netbsd-src/sys/external/bsd/acpica/dist/dispatcher/dsobject.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
128c506b8Sjruoho /******************************************************************************
228c506b8Sjruoho  *
328c506b8Sjruoho  * Module Name: dsobject - Dispatcher object management routines
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 "acparser.h"
4728c506b8Sjruoho #include "amlcode.h"
4828c506b8Sjruoho #include "acdispat.h"
4928c506b8Sjruoho #include "acnamesp.h"
5028c506b8Sjruoho #include "acinterp.h"
5128c506b8Sjruoho 
5228c506b8Sjruoho #define _COMPONENT          ACPI_DISPATCHER
5328c506b8Sjruoho         ACPI_MODULE_NAME    ("dsobject")
5428c506b8Sjruoho 
5528c506b8Sjruoho 
5628c506b8Sjruoho /*******************************************************************************
5728c506b8Sjruoho  *
5828c506b8Sjruoho  * FUNCTION:    AcpiDsBuildInternalObject
5928c506b8Sjruoho  *
6028c506b8Sjruoho  * PARAMETERS:  WalkState       - Current walk state
6128c506b8Sjruoho  *              Op              - Parser object to be translated
6228c506b8Sjruoho  *              ObjDescPtr      - Where the ACPI internal object is returned
6328c506b8Sjruoho  *
6428c506b8Sjruoho  * RETURN:      Status
6528c506b8Sjruoho  *
6628c506b8Sjruoho  * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
6728c506b8Sjruoho  *              Simple objects are any objects other than a package object!
6828c506b8Sjruoho  *
6928c506b8Sjruoho  ******************************************************************************/
7028c506b8Sjruoho 
7189b8eb6cSchristos ACPI_STATUS
AcpiDsBuildInternalObject(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * Op,ACPI_OPERAND_OBJECT ** ObjDescPtr)7228c506b8Sjruoho AcpiDsBuildInternalObject (
7328c506b8Sjruoho     ACPI_WALK_STATE         *WalkState,
7428c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
7528c506b8Sjruoho     ACPI_OPERAND_OBJECT     **ObjDescPtr)
7628c506b8Sjruoho {
7728c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ObjDesc;
7828c506b8Sjruoho     ACPI_STATUS             Status;
7928c506b8Sjruoho 
8028c506b8Sjruoho 
8128c506b8Sjruoho     ACPI_FUNCTION_TRACE (DsBuildInternalObject);
8228c506b8Sjruoho 
8328c506b8Sjruoho 
8428c506b8Sjruoho     *ObjDescPtr = NULL;
8528c506b8Sjruoho     if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
8628c506b8Sjruoho     {
8728c506b8Sjruoho         /*
8828c506b8Sjruoho          * This is a named object reference. If this name was
8989b8eb6cSchristos          * previously looked up in the namespace, it was stored in
9089b8eb6cSchristos          * this op. Otherwise, go ahead and look it up now
9128c506b8Sjruoho          */
9228c506b8Sjruoho         if (!Op->Common.Node)
9328c506b8Sjruoho         {
9428c506b8Sjruoho             /* Check if we are resolving a named reference within a package */
9528c506b8Sjruoho 
9628c506b8Sjruoho             if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
97835858a6Schristos                 (Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP))
9828c506b8Sjruoho             {
9928c506b8Sjruoho                 /*
10089b8eb6cSchristos                  * We won't resolve package elements here, we will do this
10189b8eb6cSchristos                  * after all ACPI tables are loaded into the namespace. This
10289b8eb6cSchristos                  * behavior supports both forward references to named objects
10389b8eb6cSchristos                  * and external references to objects in other tables.
10428c506b8Sjruoho                  */
10589b8eb6cSchristos                 goto CreateNewObject;
10689b8eb6cSchristos             }
10789b8eb6cSchristos             else
10889b8eb6cSchristos             {
10989b8eb6cSchristos                 Status = AcpiNsLookup (WalkState->ScopeInfo,
11089b8eb6cSchristos                     Op->Common.Value.String,
11189b8eb6cSchristos                     ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
11289b8eb6cSchristos                     ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL,
11389b8eb6cSchristos                     ACPI_CAST_INDIRECT_PTR (
11489b8eb6cSchristos                         ACPI_NAMESPACE_NODE, &(Op->Common.Node)));
11528c506b8Sjruoho                 if (ACPI_FAILURE (Status))
11628c506b8Sjruoho                 {
117b406f703Schristos                     ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
118b406f703Schristos                         Op->Common.Value.String, Status);
11928c506b8Sjruoho                     return_ACPI_STATUS (Status);
12028c506b8Sjruoho                 }
12128c506b8Sjruoho             }
12228c506b8Sjruoho         }
12328c506b8Sjruoho     }
12428c506b8Sjruoho 
12589b8eb6cSchristos CreateNewObject:
12689b8eb6cSchristos 
12728c506b8Sjruoho     /* Create and init a new internal ACPI object */
12828c506b8Sjruoho 
12928c506b8Sjruoho     ObjDesc = AcpiUtCreateInternalObject (
13028c506b8Sjruoho         (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType);
13128c506b8Sjruoho     if (!ObjDesc)
13228c506b8Sjruoho     {
13328c506b8Sjruoho         return_ACPI_STATUS (AE_NO_MEMORY);
13428c506b8Sjruoho     }
13528c506b8Sjruoho 
13671e38f1dSchristos     Status = AcpiDsInitObjectFromOp (
13771e38f1dSchristos         WalkState, Op, Op->Common.AmlOpcode, &ObjDesc);
13828c506b8Sjruoho     if (ACPI_FAILURE (Status))
13928c506b8Sjruoho     {
14028c506b8Sjruoho         AcpiUtRemoveReference (ObjDesc);
14128c506b8Sjruoho         return_ACPI_STATUS (Status);
14228c506b8Sjruoho     }
14328c506b8Sjruoho 
14489b8eb6cSchristos     /*
14589b8eb6cSchristos      * Handling for unresolved package reference elements.
14689b8eb6cSchristos      * These are elements that are namepaths.
14789b8eb6cSchristos      */
14889b8eb6cSchristos     if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
14989b8eb6cSchristos         (Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP))
15089b8eb6cSchristos     {
15189b8eb6cSchristos         ObjDesc->Reference.Resolved = TRUE;
15289b8eb6cSchristos 
15389b8eb6cSchristos         if ((Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
15489b8eb6cSchristos             !ObjDesc->Reference.Node)
15589b8eb6cSchristos         {
15689b8eb6cSchristos             /*
15789b8eb6cSchristos              * Name was unresolved above.
15889b8eb6cSchristos              * Get the prefix node for later lookup
15989b8eb6cSchristos              */
16089b8eb6cSchristos             ObjDesc->Reference.Node = WalkState->ScopeInfo->Scope.Node;
16189b8eb6cSchristos             ObjDesc->Reference.Aml = Op->Common.Aml;
16289b8eb6cSchristos             ObjDesc->Reference.Resolved = FALSE;
16389b8eb6cSchristos         }
16489b8eb6cSchristos     }
16589b8eb6cSchristos 
16628c506b8Sjruoho     *ObjDescPtr = ObjDesc;
16728c506b8Sjruoho     return_ACPI_STATUS (Status);
16828c506b8Sjruoho }
16928c506b8Sjruoho 
17028c506b8Sjruoho 
17128c506b8Sjruoho /*******************************************************************************
17228c506b8Sjruoho  *
17328c506b8Sjruoho  * FUNCTION:    AcpiDsBuildInternalBufferObj
17428c506b8Sjruoho  *
17528c506b8Sjruoho  * PARAMETERS:  WalkState       - Current walk state
17628c506b8Sjruoho  *              Op              - Parser object to be translated
17728c506b8Sjruoho  *              BufferLength    - Length of the buffer
17828c506b8Sjruoho  *              ObjDescPtr      - Where the ACPI internal object is returned
17928c506b8Sjruoho  *
18028c506b8Sjruoho  * RETURN:      Status
18128c506b8Sjruoho  *
18228c506b8Sjruoho  * DESCRIPTION: Translate a parser Op package object to the equivalent
18328c506b8Sjruoho  *              namespace object
18428c506b8Sjruoho  *
18528c506b8Sjruoho  ******************************************************************************/
18628c506b8Sjruoho 
18728c506b8Sjruoho ACPI_STATUS
AcpiDsBuildInternalBufferObj(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * Op,UINT32 BufferLength,ACPI_OPERAND_OBJECT ** ObjDescPtr)18828c506b8Sjruoho AcpiDsBuildInternalBufferObj (
18928c506b8Sjruoho     ACPI_WALK_STATE         *WalkState,
19028c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
19128c506b8Sjruoho     UINT32                  BufferLength,
19228c506b8Sjruoho     ACPI_OPERAND_OBJECT     **ObjDescPtr)
19328c506b8Sjruoho {
19428c506b8Sjruoho     ACPI_PARSE_OBJECT       *Arg;
19528c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ObjDesc;
19628c506b8Sjruoho     ACPI_PARSE_OBJECT       *ByteList;
19728c506b8Sjruoho     UINT32                  ByteListLength = 0;
19828c506b8Sjruoho 
19928c506b8Sjruoho 
20028c506b8Sjruoho     ACPI_FUNCTION_TRACE (DsBuildInternalBufferObj);
20128c506b8Sjruoho 
20228c506b8Sjruoho 
20328c506b8Sjruoho     /*
20428c506b8Sjruoho      * If we are evaluating a Named buffer object "Name (xxxx, Buffer)".
20528c506b8Sjruoho      * The buffer object already exists (from the NS node), otherwise it must
20628c506b8Sjruoho      * be created.
20728c506b8Sjruoho      */
20828c506b8Sjruoho     ObjDesc = *ObjDescPtr;
20928c506b8Sjruoho     if (!ObjDesc)
21028c506b8Sjruoho     {
21128c506b8Sjruoho         /* Create a new buffer object */
21228c506b8Sjruoho 
21328c506b8Sjruoho         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
21428c506b8Sjruoho         *ObjDescPtr = ObjDesc;
21528c506b8Sjruoho         if (!ObjDesc)
21628c506b8Sjruoho         {
21728c506b8Sjruoho             return_ACPI_STATUS (AE_NO_MEMORY);
21828c506b8Sjruoho         }
21928c506b8Sjruoho     }
22028c506b8Sjruoho 
22128c506b8Sjruoho     /*
22228c506b8Sjruoho      * Second arg is the buffer data (optional) ByteList can be either
22328c506b8Sjruoho      * individual bytes or a string initializer. In either case, a
22428c506b8Sjruoho      * ByteList appears in the AML.
22528c506b8Sjruoho      */
22628c506b8Sjruoho     Arg = Op->Common.Value.Arg;         /* skip first arg */
22728c506b8Sjruoho 
22828c506b8Sjruoho     ByteList = Arg->Named.Next;
22928c506b8Sjruoho     if (ByteList)
23028c506b8Sjruoho     {
23128c506b8Sjruoho         if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP)
23228c506b8Sjruoho         {
23328c506b8Sjruoho             ACPI_ERROR ((AE_INFO,
23428c506b8Sjruoho                 "Expecting bytelist, found AML opcode 0x%X in op %p",
23528c506b8Sjruoho                 ByteList->Common.AmlOpcode, ByteList));
23628c506b8Sjruoho 
23728c506b8Sjruoho             AcpiUtRemoveReference (ObjDesc);
23828c506b8Sjruoho             return (AE_TYPE);
23928c506b8Sjruoho         }
24028c506b8Sjruoho 
24128c506b8Sjruoho         ByteListLength = (UINT32) ByteList->Common.Value.Integer;
24228c506b8Sjruoho     }
24328c506b8Sjruoho 
24428c506b8Sjruoho     /*
24528c506b8Sjruoho      * The buffer length (number of bytes) will be the larger of:
24628c506b8Sjruoho      * 1) The specified buffer length and
24728c506b8Sjruoho      * 2) The length of the initializer byte list
24828c506b8Sjruoho      */
24928c506b8Sjruoho     ObjDesc->Buffer.Length = BufferLength;
25028c506b8Sjruoho     if (ByteListLength > BufferLength)
25128c506b8Sjruoho     {
25228c506b8Sjruoho         ObjDesc->Buffer.Length = ByteListLength;
25328c506b8Sjruoho     }
25428c506b8Sjruoho 
25528c506b8Sjruoho     /* Allocate the buffer */
25628c506b8Sjruoho 
25728c506b8Sjruoho     if (ObjDesc->Buffer.Length == 0)
25828c506b8Sjruoho     {
25928c506b8Sjruoho         ObjDesc->Buffer.Pointer = NULL;
26028c506b8Sjruoho         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
26128c506b8Sjruoho             "Buffer defined with zero length in AML, creating\n"));
26228c506b8Sjruoho     }
26328c506b8Sjruoho     else
26428c506b8Sjruoho     {
26571e38f1dSchristos         ObjDesc->Buffer.Pointer =
26671e38f1dSchristos             ACPI_ALLOCATE_ZEROED (ObjDesc->Buffer.Length);
26728c506b8Sjruoho         if (!ObjDesc->Buffer.Pointer)
26828c506b8Sjruoho         {
26928c506b8Sjruoho             AcpiUtDeleteObjectDesc (ObjDesc);
27028c506b8Sjruoho             return_ACPI_STATUS (AE_NO_MEMORY);
27128c506b8Sjruoho         }
27228c506b8Sjruoho 
27328c506b8Sjruoho         /* Initialize buffer from the ByteList (if present) */
27428c506b8Sjruoho 
27528c506b8Sjruoho         if (ByteList)
27628c506b8Sjruoho         {
277c72da027Schristos             memcpy (ObjDesc->Buffer.Pointer, ByteList->Named.Data,
27828c506b8Sjruoho                 ByteListLength);
27928c506b8Sjruoho         }
28028c506b8Sjruoho     }
28128c506b8Sjruoho 
28228c506b8Sjruoho     ObjDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
28328c506b8Sjruoho     Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
28428c506b8Sjruoho     return_ACPI_STATUS (AE_OK);
28528c506b8Sjruoho }
28628c506b8Sjruoho 
28728c506b8Sjruoho /*******************************************************************************
28828c506b8Sjruoho  *
28928c506b8Sjruoho  * FUNCTION:    AcpiDsCreateNode
29028c506b8Sjruoho  *
29128c506b8Sjruoho  * PARAMETERS:  WalkState       - Current walk state
29228c506b8Sjruoho  *              Node            - NS Node to be initialized
29328c506b8Sjruoho  *              Op              - Parser object to be translated
29428c506b8Sjruoho  *
29528c506b8Sjruoho  * RETURN:      Status
29628c506b8Sjruoho  *
29728c506b8Sjruoho  * DESCRIPTION: Create the object to be associated with a namespace node
29828c506b8Sjruoho  *
29928c506b8Sjruoho  ******************************************************************************/
30028c506b8Sjruoho 
30128c506b8Sjruoho ACPI_STATUS
AcpiDsCreateNode(ACPI_WALK_STATE * WalkState,ACPI_NAMESPACE_NODE * Node,ACPI_PARSE_OBJECT * Op)30228c506b8Sjruoho AcpiDsCreateNode (
30328c506b8Sjruoho     ACPI_WALK_STATE         *WalkState,
30428c506b8Sjruoho     ACPI_NAMESPACE_NODE     *Node,
30528c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op)
30628c506b8Sjruoho {
30728c506b8Sjruoho     ACPI_STATUS             Status;
30828c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ObjDesc;
30928c506b8Sjruoho 
31028c506b8Sjruoho 
31128c506b8Sjruoho     ACPI_FUNCTION_TRACE_PTR (DsCreateNode, Op);
31228c506b8Sjruoho 
31328c506b8Sjruoho 
31428c506b8Sjruoho     /*
31528c506b8Sjruoho      * Because of the execution pass through the non-control-method
31628c506b8Sjruoho      * parts of the table, we can arrive here twice. Only init
31728c506b8Sjruoho      * the named object node the first time through
31828c506b8Sjruoho      */
31928c506b8Sjruoho     if (AcpiNsGetAttachedObject (Node))
32028c506b8Sjruoho     {
32128c506b8Sjruoho         return_ACPI_STATUS (AE_OK);
32228c506b8Sjruoho     }
32328c506b8Sjruoho 
32428c506b8Sjruoho     if (!Op->Common.Value.Arg)
32528c506b8Sjruoho     {
32628c506b8Sjruoho         /* No arguments, there is nothing to do */
32728c506b8Sjruoho 
32828c506b8Sjruoho         return_ACPI_STATUS (AE_OK);
32928c506b8Sjruoho     }
33028c506b8Sjruoho 
33128c506b8Sjruoho     /* Build an internal object for the argument(s) */
33228c506b8Sjruoho 
33371e38f1dSchristos     Status = AcpiDsBuildInternalObject (
33471e38f1dSchristos         WalkState, Op->Common.Value.Arg, &ObjDesc);
33528c506b8Sjruoho     if (ACPI_FAILURE (Status))
33628c506b8Sjruoho     {
33728c506b8Sjruoho         return_ACPI_STATUS (Status);
33828c506b8Sjruoho     }
33928c506b8Sjruoho 
34028c506b8Sjruoho     /* Re-type the object according to its argument */
34128c506b8Sjruoho 
34228c506b8Sjruoho     Node->Type = ObjDesc->Common.Type;
34328c506b8Sjruoho 
34428c506b8Sjruoho     /* Attach obj to node */
34528c506b8Sjruoho 
34628c506b8Sjruoho     Status = AcpiNsAttachObject (Node, ObjDesc, Node->Type);
34728c506b8Sjruoho 
34828c506b8Sjruoho     /* Remove local reference to the object */
34928c506b8Sjruoho 
35028c506b8Sjruoho     AcpiUtRemoveReference (ObjDesc);
35128c506b8Sjruoho     return_ACPI_STATUS (Status);
35228c506b8Sjruoho }
35328c506b8Sjruoho 
35428c506b8Sjruoho 
35528c506b8Sjruoho /*******************************************************************************
35628c506b8Sjruoho  *
35728c506b8Sjruoho  * FUNCTION:    AcpiDsInitObjectFromOp
35828c506b8Sjruoho  *
35928c506b8Sjruoho  * PARAMETERS:  WalkState       - Current walk state
36028c506b8Sjruoho  *              Op              - Parser op used to init the internal object
36128c506b8Sjruoho  *              Opcode          - AML opcode associated with the object
36228c506b8Sjruoho  *              RetObjDesc      - Namespace object to be initialized
36328c506b8Sjruoho  *
36428c506b8Sjruoho  * RETURN:      Status
36528c506b8Sjruoho  *
36628c506b8Sjruoho  * DESCRIPTION: Initialize a namespace object from a parser Op and its
36728c506b8Sjruoho  *              associated arguments. The namespace object is a more compact
36828c506b8Sjruoho  *              representation of the Op and its arguments.
36928c506b8Sjruoho  *
37028c506b8Sjruoho  ******************************************************************************/
37128c506b8Sjruoho 
37228c506b8Sjruoho ACPI_STATUS
AcpiDsInitObjectFromOp(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * Op,UINT16 Opcode,ACPI_OPERAND_OBJECT ** RetObjDesc)37328c506b8Sjruoho AcpiDsInitObjectFromOp (
37428c506b8Sjruoho     ACPI_WALK_STATE         *WalkState,
37528c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
37628c506b8Sjruoho     UINT16                  Opcode,
37728c506b8Sjruoho     ACPI_OPERAND_OBJECT     **RetObjDesc)
37828c506b8Sjruoho {
37928c506b8Sjruoho     const ACPI_OPCODE_INFO  *OpInfo;
38028c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ObjDesc;
38128c506b8Sjruoho     ACPI_STATUS             Status = AE_OK;
38228c506b8Sjruoho 
38328c506b8Sjruoho 
38428c506b8Sjruoho     ACPI_FUNCTION_TRACE (DsInitObjectFromOp);
38528c506b8Sjruoho 
38628c506b8Sjruoho 
38728c506b8Sjruoho     ObjDesc = *RetObjDesc;
38828c506b8Sjruoho     OpInfo = AcpiPsGetOpcodeInfo (Opcode);
38928c506b8Sjruoho     if (OpInfo->Class == AML_CLASS_UNKNOWN)
39028c506b8Sjruoho     {
39128c506b8Sjruoho         /* Unknown opcode */
39228c506b8Sjruoho 
39328c506b8Sjruoho         return_ACPI_STATUS (AE_TYPE);
39428c506b8Sjruoho     }
39528c506b8Sjruoho 
39628c506b8Sjruoho     /* Perform per-object initialization */
39728c506b8Sjruoho 
39828c506b8Sjruoho     switch (ObjDesc->Common.Type)
39928c506b8Sjruoho     {
40028c506b8Sjruoho     case ACPI_TYPE_BUFFER:
40128c506b8Sjruoho         /*
40228c506b8Sjruoho          * Defer evaluation of Buffer TermArg operand
40328c506b8Sjruoho          */
40471e38f1dSchristos         ObjDesc->Buffer.Node = ACPI_CAST_PTR (
40571e38f1dSchristos             ACPI_NAMESPACE_NODE, WalkState->Operands[0]);
40628c506b8Sjruoho         ObjDesc->Buffer.AmlStart = Op->Named.Data;
40728c506b8Sjruoho         ObjDesc->Buffer.AmlLength = Op->Named.Length;
40828c506b8Sjruoho         break;
40928c506b8Sjruoho 
41028c506b8Sjruoho     case ACPI_TYPE_PACKAGE:
41128c506b8Sjruoho         /*
41289b8eb6cSchristos          * Defer evaluation of Package TermArg operand and all
41389b8eb6cSchristos          * package elements. (01/2017): We defer the element
41489b8eb6cSchristos          * resolution to allow forward references from the package
41589b8eb6cSchristos          * in order to provide compatibility with other ACPI
41689b8eb6cSchristos          * implementations.
41728c506b8Sjruoho          */
41871e38f1dSchristos         ObjDesc->Package.Node = ACPI_CAST_PTR (
41971e38f1dSchristos             ACPI_NAMESPACE_NODE, WalkState->Operands[0]);
42089b8eb6cSchristos 
42189b8eb6cSchristos         if (!Op->Named.Data)
42289b8eb6cSchristos         {
42389b8eb6cSchristos             return_ACPI_STATUS (AE_OK);
42489b8eb6cSchristos         }
42589b8eb6cSchristos 
42628c506b8Sjruoho         ObjDesc->Package.AmlStart = Op->Named.Data;
42728c506b8Sjruoho         ObjDesc->Package.AmlLength = Op->Named.Length;
42828c506b8Sjruoho         break;
42928c506b8Sjruoho 
43028c506b8Sjruoho     case ACPI_TYPE_INTEGER:
43128c506b8Sjruoho 
43228c506b8Sjruoho         switch (OpInfo->Type)
43328c506b8Sjruoho         {
43428c506b8Sjruoho         case AML_TYPE_CONSTANT:
43528c506b8Sjruoho             /*
43628c506b8Sjruoho              * Resolve AML Constants here - AND ONLY HERE!
43728c506b8Sjruoho              * All constants are integers.
43828c506b8Sjruoho              * We mark the integer with a flag that indicates that it started
43928c506b8Sjruoho              * life as a constant -- so that stores to constants will perform
44028c506b8Sjruoho              * as expected (noop). ZeroOp is used as a placeholder for optional
44128c506b8Sjruoho              * target operands.
44228c506b8Sjruoho              */
44328c506b8Sjruoho             ObjDesc->Common.Flags = AOPOBJ_AML_CONSTANT;
44428c506b8Sjruoho 
44528c506b8Sjruoho             switch (Opcode)
44628c506b8Sjruoho             {
44728c506b8Sjruoho             case AML_ZERO_OP:
44828c506b8Sjruoho 
44928c506b8Sjruoho                 ObjDesc->Integer.Value = 0;
45028c506b8Sjruoho                 break;
45128c506b8Sjruoho 
45228c506b8Sjruoho             case AML_ONE_OP:
45328c506b8Sjruoho 
45428c506b8Sjruoho                 ObjDesc->Integer.Value = 1;
45528c506b8Sjruoho                 break;
45628c506b8Sjruoho 
45728c506b8Sjruoho             case AML_ONES_OP:
45828c506b8Sjruoho 
45928c506b8Sjruoho                 ObjDesc->Integer.Value = ACPI_UINT64_MAX;
46028c506b8Sjruoho 
46128c506b8Sjruoho                 /* Truncate value if we are executing from a 32-bit ACPI table */
46228c506b8Sjruoho 
463ff4a156dSchristos                 (void) AcpiExTruncateFor32bitTable (ObjDesc);
46428c506b8Sjruoho                 break;
46528c506b8Sjruoho 
46628c506b8Sjruoho             case AML_REVISION_OP:
46728c506b8Sjruoho 
46828c506b8Sjruoho                 ObjDesc->Integer.Value = ACPI_CA_VERSION;
46928c506b8Sjruoho                 break;
47028c506b8Sjruoho 
47128c506b8Sjruoho             default:
47228c506b8Sjruoho 
47328c506b8Sjruoho                 ACPI_ERROR ((AE_INFO,
47428c506b8Sjruoho                     "Unknown constant opcode 0x%X", Opcode));
47528c506b8Sjruoho                 Status = AE_AML_OPERAND_TYPE;
47628c506b8Sjruoho                 break;
47728c506b8Sjruoho             }
47828c506b8Sjruoho             break;
47928c506b8Sjruoho 
48028c506b8Sjruoho         case AML_TYPE_LITERAL:
48128c506b8Sjruoho 
48228c506b8Sjruoho             ObjDesc->Integer.Value = Op->Common.Value.Integer;
483ff4a156dSchristos 
484ff4a156dSchristos             if (AcpiExTruncateFor32bitTable (ObjDesc))
485ff4a156dSchristos             {
486ff4a156dSchristos                 /* Warn if we found a 64-bit constant in a 32-bit table */
487ff4a156dSchristos 
488ff4a156dSchristos                 ACPI_WARNING ((AE_INFO,
489ff4a156dSchristos                     "Truncated 64-bit constant found in 32-bit table: %8.8X%8.8X => %8.8X",
490ff4a156dSchristos                     ACPI_FORMAT_UINT64 (Op->Common.Value.Integer),
491ff4a156dSchristos                     (UINT32) ObjDesc->Integer.Value));
492ff4a156dSchristos             }
49328c506b8Sjruoho             break;
49428c506b8Sjruoho 
49528c506b8Sjruoho         default:
496ff4a156dSchristos 
49728c506b8Sjruoho             ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X",
49828c506b8Sjruoho                 OpInfo->Type));
49928c506b8Sjruoho             Status = AE_AML_OPERAND_TYPE;
50028c506b8Sjruoho             break;
50128c506b8Sjruoho         }
50228c506b8Sjruoho         break;
50328c506b8Sjruoho 
50428c506b8Sjruoho     case ACPI_TYPE_STRING:
50528c506b8Sjruoho 
50628c506b8Sjruoho         ObjDesc->String.Pointer = Op->Common.Value.String;
507c72da027Schristos         ObjDesc->String.Length = (UINT32) strlen (Op->Common.Value.String);
50828c506b8Sjruoho 
50928c506b8Sjruoho         /*
51028c506b8Sjruoho          * The string is contained in the ACPI table, don't ever try
51128c506b8Sjruoho          * to delete it
51228c506b8Sjruoho          */
51328c506b8Sjruoho         ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;
51428c506b8Sjruoho         break;
51528c506b8Sjruoho 
51628c506b8Sjruoho     case ACPI_TYPE_METHOD:
51728c506b8Sjruoho         break;
51828c506b8Sjruoho 
51928c506b8Sjruoho     case ACPI_TYPE_LOCAL_REFERENCE:
52028c506b8Sjruoho 
52128c506b8Sjruoho         switch (OpInfo->Type)
52228c506b8Sjruoho         {
52328c506b8Sjruoho         case AML_TYPE_LOCAL_VARIABLE:
52428c506b8Sjruoho 
525835858a6Schristos             /* Local ID (0-7) is (AML opcode - base AML_FIRST_LOCAL_OP) */
52628c506b8Sjruoho 
527835858a6Schristos             ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_FIRST_LOCAL_OP;
52828c506b8Sjruoho             ObjDesc->Reference.Class = ACPI_REFCLASS_LOCAL;
52928c506b8Sjruoho 
53028c506b8Sjruoho             Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_LOCAL,
53128c506b8Sjruoho                 ObjDesc->Reference.Value, WalkState,
53228c506b8Sjruoho                 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE,
53328c506b8Sjruoho                     &ObjDesc->Reference.Object));
53428c506b8Sjruoho             break;
53528c506b8Sjruoho 
53628c506b8Sjruoho         case AML_TYPE_METHOD_ARGUMENT:
53728c506b8Sjruoho 
538835858a6Schristos             /* Arg ID (0-6) is (AML opcode - base AML_FIRST_ARG_OP) */
53928c506b8Sjruoho 
540835858a6Schristos             ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_FIRST_ARG_OP;
54128c506b8Sjruoho             ObjDesc->Reference.Class = ACPI_REFCLASS_ARG;
54228c506b8Sjruoho 
54328c506b8Sjruoho             Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_ARG,
54428c506b8Sjruoho                 ObjDesc->Reference.Value, WalkState,
54528c506b8Sjruoho                 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE,
54628c506b8Sjruoho                     &ObjDesc->Reference.Object));
54728c506b8Sjruoho             break;
54828c506b8Sjruoho 
54928c506b8Sjruoho         default: /* Object name or Debug object */
55028c506b8Sjruoho 
55128c506b8Sjruoho             switch (Op->Common.AmlOpcode)
55228c506b8Sjruoho             {
55328c506b8Sjruoho             case AML_INT_NAMEPATH_OP:
55428c506b8Sjruoho 
55528c506b8Sjruoho                 /* Node was saved in Op */
55628c506b8Sjruoho 
55728c506b8Sjruoho                 ObjDesc->Reference.Node = Op->Common.Node;
55828c506b8Sjruoho                 ObjDesc->Reference.Class = ACPI_REFCLASS_NAME;
55989b8eb6cSchristos                 if (Op->Common.Node)
56089b8eb6cSchristos                 {
56189b8eb6cSchristos                     ObjDesc->Reference.Object = Op->Common.Node->Object;
56289b8eb6cSchristos                 }
56328c506b8Sjruoho                 break;
56428c506b8Sjruoho 
56528c506b8Sjruoho             case AML_DEBUG_OP:
56628c506b8Sjruoho 
56728c506b8Sjruoho                 ObjDesc->Reference.Class = ACPI_REFCLASS_DEBUG;
56828c506b8Sjruoho                 break;
56928c506b8Sjruoho 
57028c506b8Sjruoho             default:
57128c506b8Sjruoho 
57228c506b8Sjruoho                 ACPI_ERROR ((AE_INFO,
57328c506b8Sjruoho                     "Unimplemented reference type for AML opcode: 0x%4.4X", Opcode));
57428c506b8Sjruoho                 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
57528c506b8Sjruoho             }
57628c506b8Sjruoho             break;
57728c506b8Sjruoho         }
57828c506b8Sjruoho         break;
57928c506b8Sjruoho 
58028c506b8Sjruoho     default:
58128c506b8Sjruoho 
58228c506b8Sjruoho         ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X",
58328c506b8Sjruoho             ObjDesc->Common.Type));
58428c506b8Sjruoho 
58528c506b8Sjruoho         Status = AE_AML_OPERAND_TYPE;
58628c506b8Sjruoho         break;
58728c506b8Sjruoho     }
58828c506b8Sjruoho 
58928c506b8Sjruoho     return_ACPI_STATUS (Status);
59028c506b8Sjruoho }
591