Home | History | Annotate | Line # | Download | only in dispatcher
dsargs.c revision 1.1.1.9
      1 /******************************************************************************
      2  *
      3  * Module Name: dsargs - Support for execution of dynamic arguments for static
      4  *                       objects (regions, fields, buffer fields, etc.)
      5  *
      6  *****************************************************************************/
      7 
      8 /*
      9  * Copyright (C) 2000 - 2018, Intel Corp.
     10  * All rights reserved.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions, and the following disclaimer,
     17  *    without modification.
     18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     19  *    substantially similar to the "NO WARRANTY" disclaimer below
     20  *    ("Disclaimer") and any redistribution must be conditioned upon
     21  *    including a substantially similar Disclaimer requirement for further
     22  *    binary redistribution.
     23  * 3. Neither the names of the above-listed copyright holders nor the names
     24  *    of any contributors may be used to endorse or promote products derived
     25  *    from this software without specific prior written permission.
     26  *
     27  * Alternatively, this software may be distributed under the terms of the
     28  * GNU General Public License ("GPL") version 2 as published by the Free
     29  * Software Foundation.
     30  *
     31  * NO WARRANTY
     32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     42  * POSSIBILITY OF SUCH DAMAGES.
     43  */
     44 
     45 #include "acpi.h"
     46 #include "accommon.h"
     47 #include "acparser.h"
     48 #include "amlcode.h"
     49 #include "acdispat.h"
     50 #include "acnamesp.h"
     51 
     52 #define _COMPONENT          ACPI_DISPATCHER
     53         ACPI_MODULE_NAME    ("dsargs")
     54 
     55 /* Local prototypes */
     56 
     57 static ACPI_STATUS
     58 AcpiDsExecuteArguments (
     59     ACPI_NAMESPACE_NODE     *Node,
     60     ACPI_NAMESPACE_NODE     *ScopeNode,
     61     UINT32                  AmlLength,
     62     UINT8                   *AmlStart);
     63 
     64 
     65 /*******************************************************************************
     66  *
     67  * FUNCTION:    AcpiDsExecuteArguments
     68  *
     69  * PARAMETERS:  Node                - Object NS node
     70  *              ScopeNode           - Parent NS node
     71  *              AmlLength           - Length of executable AML
     72  *              AmlStart            - Pointer to the AML
     73  *
     74  * RETURN:      Status.
     75  *
     76  * DESCRIPTION: Late (deferred) execution of region or field arguments
     77  *
     78  ******************************************************************************/
     79 
     80 static ACPI_STATUS
     81 AcpiDsExecuteArguments (
     82     ACPI_NAMESPACE_NODE     *Node,
     83     ACPI_NAMESPACE_NODE     *ScopeNode,
     84     UINT32                  AmlLength,
     85     UINT8                   *AmlStart)
     86 {
     87     ACPI_STATUS             Status;
     88     ACPI_PARSE_OBJECT       *Op;
     89     ACPI_WALK_STATE         *WalkState;
     90 
     91 
     92     ACPI_FUNCTION_TRACE_PTR (DsExecuteArguments, AmlStart);
     93 
     94 
     95     /* Allocate a new parser op to be the root of the parsed tree */
     96 
     97     Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP, AmlStart);
     98     if (!Op)
     99     {
    100         return_ACPI_STATUS (AE_NO_MEMORY);
    101     }
    102 
    103     /* Save the Node for use in AcpiPsParseAml */
    104 
    105     Op->Common.Node = ScopeNode;
    106 
    107     /* Create and initialize a new parser state */
    108 
    109     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
    110     if (!WalkState)
    111     {
    112         Status = AE_NO_MEMORY;
    113         goto Cleanup;
    114     }
    115 
    116     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
    117         AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
    118     if (ACPI_FAILURE (Status))
    119     {
    120         AcpiDsDeleteWalkState (WalkState);
    121         goto Cleanup;
    122     }
    123 
    124     /* Mark this parse as a deferred opcode */
    125 
    126     WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP;
    127     WalkState->DeferredNode = Node;
    128 
    129     /* Pass1: Parse the entire declaration */
    130 
    131     Status = AcpiPsParseAml (WalkState);
    132     if (ACPI_FAILURE (Status))
    133     {
    134         goto Cleanup;
    135     }
    136 
    137     /* Get and init the Op created above */
    138 
    139     Op->Common.Node = Node;
    140     AcpiPsDeleteParseTree (Op);
    141 
    142     /* Evaluate the deferred arguments */
    143 
    144     Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP, AmlStart);
    145     if (!Op)
    146     {
    147         return_ACPI_STATUS (AE_NO_MEMORY);
    148     }
    149 
    150     Op->Common.Node = ScopeNode;
    151 
    152     /* Create and initialize a new parser state */
    153 
    154     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
    155     if (!WalkState)
    156     {
    157         Status = AE_NO_MEMORY;
    158         goto Cleanup;
    159     }
    160 
    161     /* Execute the opcode and arguments */
    162 
    163     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
    164         AmlLength, NULL, ACPI_IMODE_EXECUTE);
    165     if (ACPI_FAILURE (Status))
    166     {
    167         AcpiDsDeleteWalkState (WalkState);
    168         goto Cleanup;
    169     }
    170 
    171     /* Mark this execution as a deferred opcode */
    172 
    173     WalkState->DeferredNode = Node;
    174     Status = AcpiPsParseAml (WalkState);
    175 
    176 Cleanup:
    177     AcpiPsDeleteParseTree (Op);
    178     return_ACPI_STATUS (Status);
    179 }
    180 
    181 
    182 /*******************************************************************************
    183  *
    184  * FUNCTION:    AcpiDsGetBufferFieldArguments
    185  *
    186  * PARAMETERS:  ObjDesc         - A valid BufferField object
    187  *
    188  * RETURN:      Status.
    189  *
    190  * DESCRIPTION: Get BufferField Buffer and Index. This implements the late
    191  *              evaluation of these field attributes.
    192  *
    193  ******************************************************************************/
    194 
    195 ACPI_STATUS
    196 AcpiDsGetBufferFieldArguments (
    197     ACPI_OPERAND_OBJECT     *ObjDesc)
    198 {
    199     ACPI_OPERAND_OBJECT     *ExtraDesc;
    200     ACPI_NAMESPACE_NODE     *Node;
    201     ACPI_STATUS             Status;
    202 
    203 
    204     ACPI_FUNCTION_TRACE_PTR (DsGetBufferFieldArguments, ObjDesc);
    205 
    206 
    207     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
    208     {
    209         return_ACPI_STATUS (AE_OK);
    210     }
    211 
    212     /* Get the AML pointer (method object) and BufferField node */
    213 
    214     ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
    215     Node = ObjDesc->BufferField.Node;
    216 
    217     ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
    218         ACPI_TYPE_BUFFER_FIELD, Node, NULL));
    219 
    220     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
    221         AcpiUtGetNodeName (Node)));
    222 
    223     /* Execute the AML code for the TermArg arguments */
    224 
    225     Status = AcpiDsExecuteArguments (Node, Node->Parent,
    226         ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
    227     return_ACPI_STATUS (Status);
    228 }
    229 
    230 
    231 /*******************************************************************************
    232  *
    233  * FUNCTION:    AcpiDsGetBankFieldArguments
    234  *
    235  * PARAMETERS:  ObjDesc         - A valid BankField object
    236  *
    237  * RETURN:      Status.
    238  *
    239  * DESCRIPTION: Get BankField BankValue. This implements the late
    240  *              evaluation of these field attributes.
    241  *
    242  ******************************************************************************/
    243 
    244 ACPI_STATUS
    245 AcpiDsGetBankFieldArguments (
    246     ACPI_OPERAND_OBJECT     *ObjDesc)
    247 {
    248     ACPI_OPERAND_OBJECT     *ExtraDesc;
    249     ACPI_NAMESPACE_NODE     *Node;
    250     ACPI_STATUS             Status;
    251 
    252 
    253     ACPI_FUNCTION_TRACE_PTR (DsGetBankFieldArguments, ObjDesc);
    254 
    255 
    256     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
    257     {
    258         return_ACPI_STATUS (AE_OK);
    259     }
    260 
    261     /* Get the AML pointer (method object) and BankField node */
    262 
    263     ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
    264     Node = ObjDesc->BankField.Node;
    265 
    266     ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
    267         ACPI_TYPE_LOCAL_BANK_FIELD, Node, NULL));
    268 
    269     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
    270         AcpiUtGetNodeName (Node)));
    271 
    272     /* Execute the AML code for the TermArg arguments */
    273 
    274     Status = AcpiDsExecuteArguments (Node, Node->Parent,
    275         ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
    276     return_ACPI_STATUS (Status);
    277 }
    278 
    279 
    280 /*******************************************************************************
    281  *
    282  * FUNCTION:    AcpiDsGetBufferArguments
    283  *
    284  * PARAMETERS:  ObjDesc         - A valid Buffer object
    285  *
    286  * RETURN:      Status.
    287  *
    288  * DESCRIPTION: Get Buffer length and initializer byte list. This implements
    289  *              the late evaluation of these attributes.
    290  *
    291  ******************************************************************************/
    292 
    293 ACPI_STATUS
    294 AcpiDsGetBufferArguments (
    295     ACPI_OPERAND_OBJECT     *ObjDesc)
    296 {
    297     ACPI_NAMESPACE_NODE     *Node;
    298     ACPI_STATUS             Status;
    299 
    300 
    301     ACPI_FUNCTION_TRACE_PTR (DsGetBufferArguments, ObjDesc);
    302 
    303 
    304     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
    305     {
    306         return_ACPI_STATUS (AE_OK);
    307     }
    308 
    309     /* Get the Buffer node */
    310 
    311     Node = ObjDesc->Buffer.Node;
    312     if (!Node)
    313     {
    314         ACPI_ERROR ((AE_INFO,
    315             "No pointer back to namespace node in buffer object %p",
    316             ObjDesc));
    317         return_ACPI_STATUS (AE_AML_INTERNAL);
    318     }
    319 
    320     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
    321 
    322     /* Execute the AML code for the TermArg arguments */
    323 
    324     Status = AcpiDsExecuteArguments (Node, Node,
    325         ObjDesc->Buffer.AmlLength, ObjDesc->Buffer.AmlStart);
    326     return_ACPI_STATUS (Status);
    327 }
    328 
    329 
    330 /*******************************************************************************
    331  *
    332  * FUNCTION:    AcpiDsGetPackageArguments
    333  *
    334  * PARAMETERS:  ObjDesc         - A valid Package object
    335  *
    336  * RETURN:      Status.
    337  *
    338  * DESCRIPTION: Get Package length and initializer byte list. This implements
    339  *              the late evaluation of these attributes.
    340  *
    341  ******************************************************************************/
    342 
    343 ACPI_STATUS
    344 AcpiDsGetPackageArguments (
    345     ACPI_OPERAND_OBJECT     *ObjDesc)
    346 {
    347     ACPI_NAMESPACE_NODE     *Node;
    348     ACPI_STATUS             Status;
    349 
    350 
    351     ACPI_FUNCTION_TRACE_PTR (DsGetPackageArguments, ObjDesc);
    352 
    353 
    354     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
    355     {
    356         return_ACPI_STATUS (AE_OK);
    357     }
    358 
    359     /* Get the Package node */
    360 
    361     Node = ObjDesc->Package.Node;
    362     if (!Node)
    363     {
    364         ACPI_ERROR ((AE_INFO,
    365             "No pointer back to namespace node in package %p", ObjDesc));
    366         return_ACPI_STATUS (AE_AML_INTERNAL);
    367     }
    368 
    369     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Argument Init, AML Ptr: %p\n",
    370         ObjDesc->Package.AmlStart));
    371 
    372     /* Execute the AML code for the TermArg arguments */
    373 
    374     Status = AcpiDsExecuteArguments (Node, Node,
    375         ObjDesc->Package.AmlLength, ObjDesc->Package.AmlStart);
    376 
    377     return_ACPI_STATUS (Status);
    378 }
    379 
    380 
    381 /*******************************************************************************
    382  *
    383  * FUNCTION:    AcpiDsGetRegionArguments
    384  *
    385  * PARAMETERS:  ObjDesc         - A valid region object
    386  *
    387  * RETURN:      Status.
    388  *
    389  * DESCRIPTION: Get region address and length. This implements the late
    390  *              evaluation of these region attributes.
    391  *
    392  ******************************************************************************/
    393 
    394 ACPI_STATUS
    395 AcpiDsGetRegionArguments (
    396     ACPI_OPERAND_OBJECT     *ObjDesc)
    397 {
    398     ACPI_NAMESPACE_NODE     *Node;
    399     ACPI_STATUS             Status;
    400     ACPI_OPERAND_OBJECT     *ExtraDesc;
    401 
    402 
    403     ACPI_FUNCTION_TRACE_PTR (DsGetRegionArguments, ObjDesc);
    404 
    405 
    406     if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
    407     {
    408         return_ACPI_STATUS (AE_OK);
    409     }
    410 
    411     ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
    412     if (!ExtraDesc)
    413     {
    414         return_ACPI_STATUS (AE_NOT_EXIST);
    415     }
    416 
    417     /* Get the Region node */
    418 
    419     Node = ObjDesc->Region.Node;
    420 
    421     ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
    422         ACPI_TYPE_REGION, Node, NULL));
    423 
    424     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    425         "[%4.4s] OpRegion Arg Init at AML %p\n",
    426         AcpiUtGetNodeName (Node), ExtraDesc->Extra.AmlStart));
    427 
    428     /* Execute the argument AML */
    429 
    430     Status = AcpiDsExecuteArguments (Node, ExtraDesc->Extra.ScopeNode,
    431         ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
    432     if (ACPI_FAILURE (Status))
    433     {
    434         return_ACPI_STATUS (Status);
    435     }
    436 
    437     Status = AcpiUtAddAddressRange (ObjDesc->Region.SpaceId,
    438         ObjDesc->Region.Address, ObjDesc->Region.Length, Node);
    439     return_ACPI_STATUS (Status);
    440 }
    441