Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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/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. static acpi_status
  57. acpi_ds_execute_arguments(struct acpi_namespace_node *node,
  58.                           struct acpi_namespace_node *scope_node,
  59.                           u32 aml_length, u8 *aml_start);
  60.  
  61. /*******************************************************************************
  62.  *
  63.  * FUNCTION:    acpi_ds_execute_arguments
  64.  *
  65.  * PARAMETERS:  node                - Object NS node
  66.  *              scope_node          - Parent NS node
  67.  *              aml_length          - Length of executable AML
  68.  *              aml_start           - Pointer to the AML
  69.  *
  70.  * RETURN:      Status.
  71.  *
  72.  * DESCRIPTION: Late (deferred) execution of region or field arguments
  73.  *
  74.  ******************************************************************************/
  75.  
  76. static acpi_status
  77. acpi_ds_execute_arguments(struct acpi_namespace_node *node,
  78.                           struct acpi_namespace_node *scope_node,
  79.                           u32 aml_length, u8 *aml_start)
  80. {
  81.         acpi_status status;
  82.         union acpi_parse_object *op;
  83.         struct acpi_walk_state *walk_state;
  84.  
  85.         ACPI_FUNCTION_TRACE(ds_execute_arguments);
  86.  
  87.         /* Allocate a new parser op to be the root of the parsed tree */
  88.  
  89.         op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP, aml_start);
  90.         if (!op) {
  91.                 return_ACPI_STATUS(AE_NO_MEMORY);
  92.         }
  93.  
  94.         /* Save the Node for use in acpi_ps_parse_aml */
  95.  
  96.         op->common.node = scope_node;
  97.  
  98.         /* Create and initialize a new parser state */
  99.  
  100.         walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
  101.         if (!walk_state) {
  102.                 status = AE_NO_MEMORY;
  103.                 goto cleanup;
  104.         }
  105.  
  106.         status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
  107.                                        aml_length, NULL, ACPI_IMODE_LOAD_PASS1);
  108.         if (ACPI_FAILURE(status)) {
  109.                 acpi_ds_delete_walk_state(walk_state);
  110.                 goto cleanup;
  111.         }
  112.  
  113.         /* Mark this parse as a deferred opcode */
  114.  
  115.         walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;
  116.         walk_state->deferred_node = node;
  117.  
  118.         /* Pass1: Parse the entire declaration */
  119.  
  120.         status = acpi_ps_parse_aml(walk_state);
  121.         if (ACPI_FAILURE(status)) {
  122.                 goto cleanup;
  123.         }
  124.  
  125.         /* Get and init the Op created above */
  126.  
  127.         op->common.node = node;
  128.         acpi_ps_delete_parse_tree(op);
  129.  
  130.         /* Evaluate the deferred arguments */
  131.  
  132.         op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP, aml_start);
  133.         if (!op) {
  134.                 return_ACPI_STATUS(AE_NO_MEMORY);
  135.         }
  136.  
  137.         op->common.node = scope_node;
  138.  
  139.         /* Create and initialize a new parser state */
  140.  
  141.         walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
  142.         if (!walk_state) {
  143.                 status = AE_NO_MEMORY;
  144.                 goto cleanup;
  145.         }
  146.  
  147.         /* Execute the opcode and arguments */
  148.  
  149.         status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
  150.                                        aml_length, NULL, ACPI_IMODE_EXECUTE);
  151.         if (ACPI_FAILURE(status)) {
  152.                 acpi_ds_delete_walk_state(walk_state);
  153.                 goto cleanup;
  154.         }
  155.  
  156.         /* Mark this execution as a deferred opcode */
  157.  
  158.         walk_state->deferred_node = node;
  159.         status = acpi_ps_parse_aml(walk_state);
  160.  
  161. cleanup:
  162.         acpi_ps_delete_parse_tree(op);
  163.         return_ACPI_STATUS(status);
  164. }
  165.  
  166. /*******************************************************************************
  167.  *
  168.  * FUNCTION:    acpi_ds_get_buffer_field_arguments
  169.  *
  170.  * PARAMETERS:  obj_desc        - A valid buffer_field object
  171.  *
  172.  * RETURN:      Status.
  173.  *
  174.  * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
  175.  *              evaluation of these field attributes.
  176.  *
  177.  ******************************************************************************/
  178.  
  179. acpi_status
  180. acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
  181. {
  182.         union acpi_operand_object *extra_desc;
  183.         struct acpi_namespace_node *node;
  184.         acpi_status status;
  185.  
  186.         ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc);
  187.  
  188.         if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
  189.                 return_ACPI_STATUS(AE_OK);
  190.         }
  191.  
  192.         /* Get the AML pointer (method object) and buffer_field node */
  193.  
  194.         extra_desc = acpi_ns_get_secondary_object(obj_desc);
  195.         node = obj_desc->buffer_field.node;
  196.  
  197.         ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_BUFFER_FIELD,
  198.                                                       node, NULL));
  199.  
  200.         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
  201.                           acpi_ut_get_node_name(node)));
  202.  
  203.         /* Execute the AML code for the term_arg arguments */
  204.  
  205.         status = acpi_ds_execute_arguments(node, node->parent,
  206.                                            extra_desc->extra.aml_length,
  207.                                            extra_desc->extra.aml_start);
  208.         return_ACPI_STATUS(status);
  209. }
  210.  
  211. /*******************************************************************************
  212.  *
  213.  * FUNCTION:    acpi_ds_get_bank_field_arguments
  214.  *
  215.  * PARAMETERS:  obj_desc        - A valid bank_field object
  216.  *
  217.  * RETURN:      Status.
  218.  *
  219.  * DESCRIPTION: Get bank_field bank_value. This implements the late
  220.  *              evaluation of these field attributes.
  221.  *
  222.  ******************************************************************************/
  223.  
  224. acpi_status
  225. acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)
  226. {
  227.         union acpi_operand_object *extra_desc;
  228.         struct acpi_namespace_node *node;
  229.         acpi_status status;
  230.  
  231.         ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc);
  232.  
  233.         if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
  234.                 return_ACPI_STATUS(AE_OK);
  235.         }
  236.  
  237.         /* Get the AML pointer (method object) and bank_field node */
  238.  
  239.         extra_desc = acpi_ns_get_secondary_object(obj_desc);
  240.         node = obj_desc->bank_field.node;
  241.  
  242.         ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
  243.                         (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL));
  244.  
  245.         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
  246.                           acpi_ut_get_node_name(node)));
  247.  
  248.         /* Execute the AML code for the term_arg arguments */
  249.  
  250.         status = acpi_ds_execute_arguments(node, node->parent,
  251.                                            extra_desc->extra.aml_length,
  252.                                            extra_desc->extra.aml_start);
  253.         if (ACPI_FAILURE(status)) {
  254.                 return_ACPI_STATUS(status);
  255.         }
  256.  
  257.         status = acpi_ut_add_address_range(obj_desc->region.space_id,
  258.                                            obj_desc->region.address,
  259.                                            obj_desc->region.length, node);
  260.         return_ACPI_STATUS(status);
  261. }
  262.  
  263. /*******************************************************************************
  264.  *
  265.  * FUNCTION:    acpi_ds_get_buffer_arguments
  266.  *
  267.  * PARAMETERS:  obj_desc        - A valid Buffer object
  268.  *
  269.  * RETURN:      Status.
  270.  *
  271.  * DESCRIPTION: Get Buffer length and initializer byte list. This implements
  272.  *              the late evaluation of these attributes.
  273.  *
  274.  ******************************************************************************/
  275.  
  276. acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc)
  277. {
  278.         struct acpi_namespace_node *node;
  279.         acpi_status status;
  280.  
  281.         ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc);
  282.  
  283.         if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
  284.                 return_ACPI_STATUS(AE_OK);
  285.         }
  286.  
  287.         /* Get the Buffer node */
  288.  
  289.         node = obj_desc->buffer.node;
  290.         if (!node) {
  291.                 ACPI_ERROR((AE_INFO,
  292.                             "No pointer back to namespace node in buffer object %p",
  293.                             obj_desc));
  294.                 return_ACPI_STATUS(AE_AML_INTERNAL);
  295.         }
  296.  
  297.         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n"));
  298.  
  299.         /* Execute the AML code for the term_arg arguments */
  300.  
  301.         status = acpi_ds_execute_arguments(node, node,
  302.                                            obj_desc->buffer.aml_length,
  303.                                            obj_desc->buffer.aml_start);
  304.         return_ACPI_STATUS(status);
  305. }
  306.  
  307. /*******************************************************************************
  308.  *
  309.  * FUNCTION:    acpi_ds_get_package_arguments
  310.  *
  311.  * PARAMETERS:  obj_desc        - A valid Package object
  312.  *
  313.  * RETURN:      Status.
  314.  *
  315.  * DESCRIPTION: Get Package length and initializer byte list. This implements
  316.  *              the late evaluation of these attributes.
  317.  *
  318.  ******************************************************************************/
  319.  
  320. acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc)
  321. {
  322.         struct acpi_namespace_node *node;
  323.         acpi_status status;
  324.  
  325.         ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc);
  326.  
  327.         if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
  328.                 return_ACPI_STATUS(AE_OK);
  329.         }
  330.  
  331.         /* Get the Package node */
  332.  
  333.         node = obj_desc->package.node;
  334.         if (!node) {
  335.                 ACPI_ERROR((AE_INFO,
  336.                             "No pointer back to namespace node in package %p",
  337.                             obj_desc));
  338.                 return_ACPI_STATUS(AE_AML_INTERNAL);
  339.         }
  340.  
  341.         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Arg Init\n"));
  342.  
  343.         /* Execute the AML code for the term_arg arguments */
  344.  
  345.         status = acpi_ds_execute_arguments(node, node,
  346.                                            obj_desc->package.aml_length,
  347.                                            obj_desc->package.aml_start);
  348.         return_ACPI_STATUS(status);
  349. }
  350.  
  351. /*******************************************************************************
  352.  *
  353.  * FUNCTION:    acpi_ds_get_region_arguments
  354.  *
  355.  * PARAMETERS:  obj_desc        - A valid region object
  356.  *
  357.  * RETURN:      Status.
  358.  *
  359.  * DESCRIPTION: Get region address and length. This implements the late
  360.  *              evaluation of these region attributes.
  361.  *
  362.  ******************************************************************************/
  363.  
  364. acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
  365. {
  366.         struct acpi_namespace_node *node;
  367.         acpi_status status;
  368.         union acpi_operand_object *extra_desc;
  369.  
  370.         ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc);
  371.  
  372.         if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
  373.                 return_ACPI_STATUS(AE_OK);
  374.         }
  375.  
  376.         extra_desc = acpi_ns_get_secondary_object(obj_desc);
  377.         if (!extra_desc) {
  378.                 return_ACPI_STATUS(AE_NOT_EXIST);
  379.         }
  380.  
  381.         /* Get the Region node */
  382.  
  383.         node = obj_desc->region.node;
  384.  
  385.         ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
  386.                         (ACPI_TYPE_REGION, node, NULL));
  387.  
  388.         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
  389.                           acpi_ut_get_node_name(node),
  390.                           extra_desc->extra.aml_start));
  391.  
  392.         /* Execute the argument AML */
  393.  
  394.         status = acpi_ds_execute_arguments(node, extra_desc->extra.scope_node,
  395.                                            extra_desc->extra.aml_length,
  396.                                            extra_desc->extra.aml_start);
  397.         if (ACPI_FAILURE(status)) {
  398.                 return_ACPI_STATUS(status);
  399.         }
  400.  
  401.         status = acpi_ut_add_address_range(obj_desc->region.space_id,
  402.                                            obj_desc->region.address,
  403.                                            obj_desc->region.length, node);
  404.         return_ACPI_STATUS(status);
  405. }
  406.