Home | History | Annotate | Line # | Download | only in dispatcher
dsargs.c revision 1.1.1.5
      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 - 2015, 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 (DsExecuteArguments);
     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 (ACPI_TYPE_BUFFER_FIELD,
    218         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 (ACPI_TYPE_LOCAL_BANK_FIELD,
    267         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", ObjDesc));
    316         return_ACPI_STATUS (AE_AML_INTERNAL);
    317     }
    318 
    319     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
    320 
    321     /* Execute the AML code for the TermArg arguments */
    322 
    323     Status = AcpiDsExecuteArguments (Node, Node,
    324                 ObjDesc->Buffer.AmlLength, ObjDesc->Buffer.AmlStart);
    325     return_ACPI_STATUS (Status);
    326 }
    327 
    328 
    329 /*******************************************************************************
    330  *
    331  * FUNCTION:    AcpiDsGetPackageArguments
    332  *
    333  * PARAMETERS:  ObjDesc         - A valid Package object
    334  *
    335  * RETURN:      Status.
    336  *
    337  * DESCRIPTION: Get Package length and initializer byte list. This implements
    338  *              the late evaluation of these attributes.
    339  *
    340  ******************************************************************************/
    341 
    342 ACPI_STATUS
    343 AcpiDsGetPackageArguments (
    344     ACPI_OPERAND_OBJECT     *ObjDesc)
    345 {
    346     ACPI_NAMESPACE_NODE     *Node;
    347     ACPI_STATUS             Status;
    348 
    349 
    350     ACPI_FUNCTION_TRACE_PTR (DsGetPackageArguments, ObjDesc);
    351 
    352 
    353     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
    354     {
    355         return_ACPI_STATUS (AE_OK);
    356     }
    357 
    358     /* Get the Package node */
    359 
    360     Node = ObjDesc->Package.Node;
    361     if (!Node)
    362     {
    363         ACPI_ERROR ((AE_INFO,
    364             "No pointer back to namespace node in package %p", ObjDesc));
    365         return_ACPI_STATUS (AE_AML_INTERNAL);
    366     }
    367 
    368     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n"));
    369 
    370     /* Execute the AML code for the TermArg arguments */
    371 
    372     Status = AcpiDsExecuteArguments (Node, Node,
    373                 ObjDesc->Package.AmlLength, ObjDesc->Package.AmlStart);
    374     return_ACPI_STATUS (Status);
    375 }
    376 
    377 
    378 /*******************************************************************************
    379  *
    380  * FUNCTION:    AcpiDsGetRegionArguments
    381  *
    382  * PARAMETERS:  ObjDesc         - A valid region object
    383  *
    384  * RETURN:      Status.
    385  *
    386  * DESCRIPTION: Get region address and length. This implements the late
    387  *              evaluation of these region attributes.
    388  *
    389  ******************************************************************************/
    390 
    391 ACPI_STATUS
    392 AcpiDsGetRegionArguments (
    393     ACPI_OPERAND_OBJECT     *ObjDesc)
    394 {
    395     ACPI_NAMESPACE_NODE     *Node;
    396     ACPI_STATUS             Status;
    397     ACPI_OPERAND_OBJECT     *ExtraDesc;
    398 
    399 
    400     ACPI_FUNCTION_TRACE_PTR (DsGetRegionArguments, ObjDesc);
    401 
    402 
    403     if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
    404     {
    405         return_ACPI_STATUS (AE_OK);
    406     }
    407 
    408     ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
    409     if (!ExtraDesc)
    410     {
    411         return_ACPI_STATUS (AE_NOT_EXIST);
    412     }
    413 
    414     /* Get the Region node */
    415 
    416     Node = ObjDesc->Region.Node;
    417 
    418     ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_REGION, Node, NULL));
    419 
    420     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
    421         AcpiUtGetNodeName (Node), ExtraDesc->Extra.AmlStart));
    422 
    423     /* Execute the argument AML */
    424 
    425     Status = AcpiDsExecuteArguments (Node, ExtraDesc->Extra.ScopeNode,
    426                 ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
    427     if (ACPI_FAILURE (Status))
    428     {
    429         return_ACPI_STATUS (Status);
    430     }
    431 
    432     Status = AcpiUtAddAddressRange (ObjDesc->Region.SpaceId,
    433                  ObjDesc->Region.Address, ObjDesc->Region.Length,
    434                  Node);
    435     return_ACPI_STATUS (Status);
    436 }
    437