Subversion Repositories Kolibri OS

Rev

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

  1. /******************************************************************************
  2.  *
  3.  * Module Name: dsopcode - Dispatcher support for regions and fields
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /*
  8.  * Copyright (C) 2000 - 2015, Intel Corp.
  9.  * All rights reserved.
  10.  *
  11.  * Redistribution and use in source and binary forms, with or without
  12.  * modification, are permitted provided that the following conditions
  13.  * are met:
  14.  * 1. Redistributions of source code must retain the above copyright
  15.  *    notice, this list of conditions, and the following disclaimer,
  16.  *    without modification.
  17.  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18.  *    substantially similar to the "NO WARRANTY" disclaimer below
  19.  *    ("Disclaimer") and any redistribution must be conditioned upon
  20.  *    including a substantially similar Disclaimer requirement for further
  21.  *    binary redistribution.
  22.  * 3. Neither the names of the above-listed copyright holders nor the names
  23.  *    of any contributors may be used to endorse or promote products derived
  24.  *    from this software without specific prior written permission.
  25.  *
  26.  * Alternatively, this software may be distributed under the terms of the
  27.  * GNU General Public License ("GPL") version 2 as published by the Free
  28.  * Software Foundation.
  29.  *
  30.  * NO WARRANTY
  31.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35.  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40.  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41.  * POSSIBILITY OF SUCH DAMAGES.
  42.  */
  43.  
  44. #include <acpi/acpi.h>
  45. #include "accommon.h"
  46. #include "acparser.h"
  47. #include "amlcode.h"
  48. #include "acdispat.h"
  49. #include "acinterp.h"
  50. #include "acnamesp.h"
  51. #include "acevents.h"
  52. #include "actables.h"
  53.  
  54. #define _COMPONENT          ACPI_DISPATCHER
  55. ACPI_MODULE_NAME("dsopcode")
  56.  
  57. /* Local prototypes */
  58. static acpi_status
  59. acpi_ds_init_buffer_field(u16 aml_opcode,
  60.                           union acpi_operand_object *obj_desc,
  61.                           union acpi_operand_object *buffer_desc,
  62.                           union acpi_operand_object *offset_desc,
  63.                           union acpi_operand_object *length_desc,
  64.                           union acpi_operand_object *result_desc);
  65.  
  66. /*******************************************************************************
  67.  *
  68.  * FUNCTION:    acpi_ds_initialize_region
  69.  *
  70.  * PARAMETERS:  obj_handle      - Region namespace node
  71.  *
  72.  * RETURN:      Status
  73.  *
  74.  * DESCRIPTION: Front end to ev_initialize_region
  75.  *
  76.  ******************************************************************************/
  77.  
  78. acpi_status acpi_ds_initialize_region(acpi_handle obj_handle)
  79. {
  80.         union acpi_operand_object *obj_desc;
  81.         acpi_status status;
  82.  
  83.         obj_desc = acpi_ns_get_attached_object(obj_handle);
  84.  
  85.         /* Namespace is NOT locked */
  86.  
  87.         status = acpi_ev_initialize_region(obj_desc, FALSE);
  88.         return (status);
  89. }
  90.  
  91. /*******************************************************************************
  92.  *
  93.  * FUNCTION:    acpi_ds_init_buffer_field
  94.  *
  95.  * PARAMETERS:  aml_opcode      - create_xxx_field
  96.  *              obj_desc        - buffer_field object
  97.  *              buffer_desc     - Host Buffer
  98.  *              offset_desc     - Offset into buffer
  99.  *              length_desc     - Length of field (CREATE_FIELD_OP only)
  100.  *              result_desc     - Where to store the result
  101.  *
  102.  * RETURN:      Status
  103.  *
  104.  * DESCRIPTION: Perform actual initialization of a buffer field
  105.  *
  106.  ******************************************************************************/
  107.  
  108. static acpi_status
  109. acpi_ds_init_buffer_field(u16 aml_opcode,
  110.                           union acpi_operand_object *obj_desc,
  111.                           union acpi_operand_object *buffer_desc,
  112.                           union acpi_operand_object *offset_desc,
  113.                           union acpi_operand_object *length_desc,
  114.                           union acpi_operand_object *result_desc)
  115. {
  116.         u32 offset;
  117.         u32 bit_offset;
  118.         u32 bit_count;
  119.         u8 field_flags;
  120.         acpi_status status;
  121.  
  122.         ACPI_FUNCTION_TRACE_PTR(ds_init_buffer_field, obj_desc);
  123.  
  124.         /* Host object must be a Buffer */
  125.  
  126.         if (buffer_desc->common.type != ACPI_TYPE_BUFFER) {
  127.                 ACPI_ERROR((AE_INFO,
  128.                             "Target of Create Field is not a Buffer object - %s",
  129.                             acpi_ut_get_object_type_name(buffer_desc)));
  130.  
  131.                 status = AE_AML_OPERAND_TYPE;
  132.                 goto cleanup;
  133.         }
  134.  
  135.         /*
  136.          * The last parameter to all of these opcodes (result_desc) started
  137.          * out as a name_string, and should therefore now be a NS node
  138.          * after resolution in acpi_ex_resolve_operands().
  139.          */
  140.         if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) {
  141.                 ACPI_ERROR((AE_INFO,
  142.                             "(%s) destination not a NS Node [%s]",
  143.                             acpi_ps_get_opcode_name(aml_opcode),
  144.                             acpi_ut_get_descriptor_name(result_desc)));
  145.  
  146.                 status = AE_AML_OPERAND_TYPE;
  147.                 goto cleanup;
  148.         }
  149.  
  150.         offset = (u32) offset_desc->integer.value;
  151.  
  152.         /*
  153.          * Setup the Bit offsets and counts, according to the opcode
  154.          */
  155.         switch (aml_opcode) {
  156.         case AML_CREATE_FIELD_OP:
  157.  
  158.                 /* Offset is in bits, count is in bits */
  159.  
  160.                 field_flags = AML_FIELD_ACCESS_BYTE;
  161.                 bit_offset = offset;
  162.                 bit_count = (u32) length_desc->integer.value;
  163.  
  164.                 /* Must have a valid (>0) bit count */
  165.  
  166.                 if (bit_count == 0) {
  167.                         ACPI_ERROR((AE_INFO,
  168.                                     "Attempt to CreateField of length zero"));
  169.                         status = AE_AML_OPERAND_VALUE;
  170.                         goto cleanup;
  171.                 }
  172.                 break;
  173.  
  174.         case AML_CREATE_BIT_FIELD_OP:
  175.  
  176.                 /* Offset is in bits, Field is one bit */
  177.  
  178.                 bit_offset = offset;
  179.                 bit_count = 1;
  180.                 field_flags = AML_FIELD_ACCESS_BYTE;
  181.                 break;
  182.  
  183.         case AML_CREATE_BYTE_FIELD_OP:
  184.  
  185.                 /* Offset is in bytes, field is one byte */
  186.  
  187.                 bit_offset = 8 * offset;
  188.                 bit_count = 8;
  189.                 field_flags = AML_FIELD_ACCESS_BYTE;
  190.                 break;
  191.  
  192.         case AML_CREATE_WORD_FIELD_OP:
  193.  
  194.                 /* Offset is in bytes, field is one word */
  195.  
  196.                 bit_offset = 8 * offset;
  197.                 bit_count = 16;
  198.                 field_flags = AML_FIELD_ACCESS_WORD;
  199.                 break;
  200.  
  201.         case AML_CREATE_DWORD_FIELD_OP:
  202.  
  203.                 /* Offset is in bytes, field is one dword */
  204.  
  205.                 bit_offset = 8 * offset;
  206.                 bit_count = 32;
  207.                 field_flags = AML_FIELD_ACCESS_DWORD;
  208.                 break;
  209.  
  210.         case AML_CREATE_QWORD_FIELD_OP:
  211.  
  212.                 /* Offset is in bytes, field is one qword */
  213.  
  214.                 bit_offset = 8 * offset;
  215.                 bit_count = 64;
  216.                 field_flags = AML_FIELD_ACCESS_QWORD;
  217.                 break;
  218.  
  219.         default:
  220.  
  221.                 ACPI_ERROR((AE_INFO,
  222.                             "Unknown field creation opcode 0x%02X",
  223.                             aml_opcode));
  224.                 status = AE_AML_BAD_OPCODE;
  225.                 goto cleanup;
  226.         }
  227.  
  228.         /* Entire field must fit within the current length of the buffer */
  229.  
  230.         if ((bit_offset + bit_count) > (8 * (u32) buffer_desc->buffer.length)) {
  231.                 ACPI_ERROR((AE_INFO,
  232.                             "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
  233.                             acpi_ut_get_node_name(result_desc),
  234.                             bit_offset + bit_count,
  235.                             acpi_ut_get_node_name(buffer_desc->buffer.node),
  236.                             8 * (u32) buffer_desc->buffer.length));
  237.                 status = AE_AML_BUFFER_LIMIT;
  238.                 goto cleanup;
  239.         }
  240.  
  241.         /*
  242.          * Initialize areas of the field object that are common to all fields
  243.          * For field_flags, use LOCK_RULE = 0 (NO_LOCK),
  244.          * UPDATE_RULE = 0 (UPDATE_PRESERVE)
  245.          */
  246.         status = acpi_ex_prep_common_field_object(obj_desc, field_flags, 0,
  247.                                                   bit_offset, bit_count);
  248.         if (ACPI_FAILURE(status)) {
  249.                 goto cleanup;
  250.         }
  251.  
  252.         obj_desc->buffer_field.buffer_obj = buffer_desc;
  253.  
  254.         /* Reference count for buffer_desc inherits obj_desc count */
  255.  
  256.         buffer_desc->common.reference_count = (u16)
  257.             (buffer_desc->common.reference_count +
  258.              obj_desc->common.reference_count);
  259.  
  260. cleanup:
  261.  
  262.         /* Always delete the operands */
  263.  
  264.         acpi_ut_remove_reference(offset_desc);
  265.         acpi_ut_remove_reference(buffer_desc);
  266.  
  267.         if (aml_opcode == AML_CREATE_FIELD_OP) {
  268.                 acpi_ut_remove_reference(length_desc);
  269.         }
  270.  
  271.         /* On failure, delete the result descriptor */
  272.  
  273.         if (ACPI_FAILURE(status)) {
  274.                 acpi_ut_remove_reference(result_desc);  /* Result descriptor */
  275.         } else {
  276.                 /* Now the address and length are valid for this buffer_field */
  277.  
  278.                 obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID;
  279.         }
  280.  
  281.         return_ACPI_STATUS(status);
  282. }
  283.  
  284. /*******************************************************************************
  285.  *
  286.  * FUNCTION:    acpi_ds_eval_buffer_field_operands
  287.  *
  288.  * PARAMETERS:  walk_state      - Current walk
  289.  *              op              - A valid buffer_field Op object
  290.  *
  291.  * RETURN:      Status
  292.  *
  293.  * DESCRIPTION: Get buffer_field Buffer and Index
  294.  *              Called from acpi_ds_exec_end_op during buffer_field parse tree walk
  295.  *
  296.  ******************************************************************************/
  297.  
  298. acpi_status
  299. acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state,
  300.                                    union acpi_parse_object *op)
  301. {
  302.         acpi_status status;
  303.         union acpi_operand_object *obj_desc;
  304.         struct acpi_namespace_node *node;
  305.         union acpi_parse_object *next_op;
  306.  
  307.         ACPI_FUNCTION_TRACE_PTR(ds_eval_buffer_field_operands, op);
  308.  
  309.         /*
  310.          * This is where we evaluate the address and length fields of the
  311.          * create_xxx_field declaration
  312.          */
  313.         node = op->common.node;
  314.  
  315.         /* next_op points to the op that holds the Buffer */
  316.  
  317.         next_op = op->common.value.arg;
  318.  
  319.         /* Evaluate/create the address and length operands */
  320.  
  321.         status = acpi_ds_create_operands(walk_state, next_op);
  322.         if (ACPI_FAILURE(status)) {
  323.                 return_ACPI_STATUS(status);
  324.         }
  325.  
  326.         obj_desc = acpi_ns_get_attached_object(node);
  327.         if (!obj_desc) {
  328.                 return_ACPI_STATUS(AE_NOT_EXIST);
  329.         }
  330.  
  331.         /* Resolve the operands */
  332.  
  333.         status = acpi_ex_resolve_operands(op->common.aml_opcode,
  334.                                           ACPI_WALK_OPERANDS, walk_state);
  335.         if (ACPI_FAILURE(status)) {
  336.                 ACPI_ERROR((AE_INFO, "(%s) bad operand(s), status 0x%X",
  337.                             acpi_ps_get_opcode_name(op->common.aml_opcode),
  338.                             status));
  339.  
  340.                 return_ACPI_STATUS(status);
  341.         }
  342.  
  343.         /* Initialize the Buffer Field */
  344.  
  345.         if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
  346.  
  347.                 /* NOTE: Slightly different operands for this opcode */
  348.  
  349.                 status =
  350.                     acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc,
  351.                                               walk_state->operands[0],
  352.                                               walk_state->operands[1],
  353.                                               walk_state->operands[2],
  354.                                               walk_state->operands[3]);
  355.         } else {
  356.                 /* All other, create_xxx_field opcodes */
  357.  
  358.                 status =
  359.                     acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc,
  360.                                               walk_state->operands[0],
  361.                                               walk_state->operands[1], NULL,
  362.                                               walk_state->operands[2]);
  363.         }
  364.  
  365.         return_ACPI_STATUS(status);
  366. }
  367.  
  368. /*******************************************************************************
  369.  *
  370.  * FUNCTION:    acpi_ds_eval_region_operands
  371.  *
  372.  * PARAMETERS:  walk_state      - Current walk
  373.  *              op              - A valid region Op object
  374.  *
  375.  * RETURN:      Status
  376.  *
  377.  * DESCRIPTION: Get region address and length
  378.  *              Called from acpi_ds_exec_end_op during op_region parse tree walk
  379.  *
  380.  ******************************************************************************/
  381.  
  382. acpi_status
  383. acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
  384.                              union acpi_parse_object *op)
  385. {
  386.         acpi_status status;
  387.         union acpi_operand_object *obj_desc;
  388.         union acpi_operand_object *operand_desc;
  389.         struct acpi_namespace_node *node;
  390.         union acpi_parse_object *next_op;
  391.  
  392.         ACPI_FUNCTION_TRACE_PTR(ds_eval_region_operands, op);
  393.  
  394.         /*
  395.          * This is where we evaluate the address and length fields of the
  396.          * op_region declaration
  397.          */
  398.         node = op->common.node;
  399.  
  400.         /* next_op points to the op that holds the space_ID */
  401.  
  402.         next_op = op->common.value.arg;
  403.  
  404.         /* next_op points to address op */
  405.  
  406.         next_op = next_op->common.next;
  407.  
  408.         /* Evaluate/create the address and length operands */
  409.  
  410.         status = acpi_ds_create_operands(walk_state, next_op);
  411.         if (ACPI_FAILURE(status)) {
  412.                 return_ACPI_STATUS(status);
  413.         }
  414.  
  415.         /* Resolve the length and address operands to numbers */
  416.  
  417.         status = acpi_ex_resolve_operands(op->common.aml_opcode,
  418.                                           ACPI_WALK_OPERANDS, walk_state);
  419.         if (ACPI_FAILURE(status)) {
  420.                 return_ACPI_STATUS(status);
  421.         }
  422.  
  423.         obj_desc = acpi_ns_get_attached_object(node);
  424.         if (!obj_desc) {
  425.                 return_ACPI_STATUS(AE_NOT_EXIST);
  426.         }
  427.  
  428.         /*
  429.          * Get the length operand and save it
  430.          * (at Top of stack)
  431.          */
  432.         operand_desc = walk_state->operands[walk_state->num_operands - 1];
  433.  
  434.         obj_desc->region.length = (u32) operand_desc->integer.value;
  435.         acpi_ut_remove_reference(operand_desc);
  436.  
  437.         /*
  438.          * Get the address and save it
  439.          * (at top of stack - 1)
  440.          */
  441.         operand_desc = walk_state->operands[walk_state->num_operands - 2];
  442.  
  443.         obj_desc->region.address = (acpi_physical_address)
  444.             operand_desc->integer.value;
  445.         acpi_ut_remove_reference(operand_desc);
  446.  
  447.         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
  448.                           obj_desc,
  449.                           ACPI_FORMAT_UINT64(obj_desc->region.address),
  450.                           obj_desc->region.length));
  451.  
  452.         /* Now the address and length are valid for this opregion */
  453.  
  454.         obj_desc->region.flags |= AOPOBJ_DATA_VALID;
  455.  
  456.         return_ACPI_STATUS(status);
  457. }
  458.  
  459. /*******************************************************************************
  460.  *
  461.  * FUNCTION:    acpi_ds_eval_table_region_operands
  462.  *
  463.  * PARAMETERS:  walk_state      - Current walk
  464.  *              op              - A valid region Op object
  465.  *
  466.  * RETURN:      Status
  467.  *
  468.  * DESCRIPTION: Get region address and length.
  469.  *              Called from acpi_ds_exec_end_op during data_table_region parse
  470.  *              tree walk.
  471.  *
  472.  ******************************************************************************/
  473.  
  474. acpi_status
  475. acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
  476.                                    union acpi_parse_object *op)
  477. {
  478.         acpi_status status;
  479.         union acpi_operand_object *obj_desc;
  480.         union acpi_operand_object **operand;
  481.         struct acpi_namespace_node *node;
  482.         union acpi_parse_object *next_op;
  483.         struct acpi_table_header *table;
  484.         u32 table_index;
  485.  
  486.         ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op);
  487.  
  488.         /*
  489.          * This is where we evaluate the Signature string, oem_id string,
  490.          * and oem_table_id string of the Data Table Region declaration
  491.          */
  492.         node = op->common.node;
  493.  
  494.         /* next_op points to Signature string op */
  495.  
  496.         next_op = op->common.value.arg;
  497.  
  498.         /*
  499.          * Evaluate/create the Signature string, oem_id string,
  500.          * and oem_table_id string operands
  501.          */
  502.         status = acpi_ds_create_operands(walk_state, next_op);
  503.         if (ACPI_FAILURE(status)) {
  504.                 return_ACPI_STATUS(status);
  505.         }
  506.  
  507.         operand = &walk_state->operands[0];
  508.  
  509.         /*
  510.          * Resolve the Signature string, oem_id string,
  511.          * and oem_table_id string operands
  512.          */
  513.         status = acpi_ex_resolve_operands(op->common.aml_opcode,
  514.                                           ACPI_WALK_OPERANDS, walk_state);
  515.         if (ACPI_FAILURE(status)) {
  516.                 goto cleanup;
  517.         }
  518.  
  519.         /* Find the ACPI table */
  520.  
  521.         status = acpi_tb_find_table(operand[0]->string.pointer,
  522.                                     operand[1]->string.pointer,
  523.                                     operand[2]->string.pointer, &table_index);
  524.         if (ACPI_FAILURE(status)) {
  525.                 if (status == AE_NOT_FOUND) {
  526.                         ACPI_ERROR((AE_INFO,
  527.                                     "ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT",
  528.                                     operand[0]->string.pointer,
  529.                                     operand[1]->string.pointer,
  530.                                     operand[2]->string.pointer));
  531.                 }
  532.                 goto cleanup;
  533.         }
  534.  
  535.         status = acpi_get_table_by_index(table_index, &table);
  536.         if (ACPI_FAILURE(status)) {
  537.                 goto cleanup;
  538.         }
  539.  
  540.         obj_desc = acpi_ns_get_attached_object(node);
  541.         if (!obj_desc) {
  542.                 status = AE_NOT_EXIST;
  543.                 goto cleanup;
  544.         }
  545.  
  546.         obj_desc->region.address = ACPI_PTR_TO_PHYSADDR(table);
  547.         obj_desc->region.length = table->length;
  548.  
  549.         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
  550.                           obj_desc,
  551.                           ACPI_FORMAT_UINT64(obj_desc->region.address),
  552.                           obj_desc->region.length));
  553.  
  554.         /* Now the address and length are valid for this opregion */
  555.  
  556.         obj_desc->region.flags |= AOPOBJ_DATA_VALID;
  557.  
  558. cleanup:
  559.         acpi_ut_remove_reference(operand[0]);
  560.         acpi_ut_remove_reference(operand[1]);
  561.         acpi_ut_remove_reference(operand[2]);
  562.  
  563.         return_ACPI_STATUS(status);
  564. }
  565.  
  566. /*******************************************************************************
  567.  *
  568.  * FUNCTION:    acpi_ds_eval_data_object_operands
  569.  *
  570.  * PARAMETERS:  walk_state      - Current walk
  571.  *              op              - A valid data_object Op object
  572.  *              obj_desc        - data_object
  573.  *
  574.  * RETURN:      Status
  575.  *
  576.  * DESCRIPTION: Get the operands and complete the following data object types:
  577.  *              Buffer, Package.
  578.  *
  579.  ******************************************************************************/
  580.  
  581. acpi_status
  582. acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
  583.                                   union acpi_parse_object *op,
  584.                                   union acpi_operand_object *obj_desc)
  585. {
  586.         acpi_status status;
  587.         union acpi_operand_object *arg_desc;
  588.         u32 length;
  589.  
  590.         ACPI_FUNCTION_TRACE(ds_eval_data_object_operands);
  591.  
  592.         /* The first operand (for all of these data objects) is the length */
  593.  
  594.         /*
  595.          * Set proper index into operand stack for acpi_ds_obj_stack_push
  596.          * invoked inside acpi_ds_create_operand.
  597.          */
  598.         walk_state->operand_index = walk_state->num_operands;
  599.  
  600.         status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1);
  601.         if (ACPI_FAILURE(status)) {
  602.                 return_ACPI_STATUS(status);
  603.         }
  604.  
  605.         status = acpi_ex_resolve_operands(walk_state->opcode,
  606.                                           &(walk_state->
  607.                                             operands[walk_state->num_operands -
  608.                                                      1]), walk_state);
  609.         if (ACPI_FAILURE(status)) {
  610.                 return_ACPI_STATUS(status);
  611.         }
  612.  
  613.         /* Extract length operand */
  614.  
  615.         arg_desc = walk_state->operands[walk_state->num_operands - 1];
  616.         length = (u32) arg_desc->integer.value;
  617.  
  618.         /* Cleanup for length operand */
  619.  
  620.         status = acpi_ds_obj_stack_pop(1, walk_state);
  621.         if (ACPI_FAILURE(status)) {
  622.                 return_ACPI_STATUS(status);
  623.         }
  624.  
  625.         acpi_ut_remove_reference(arg_desc);
  626.  
  627.         /*
  628.          * Create the actual data object
  629.          */
  630.         switch (op->common.aml_opcode) {
  631.         case AML_BUFFER_OP:
  632.  
  633.                 status =
  634.                     acpi_ds_build_internal_buffer_obj(walk_state, op, length,
  635.                                                       &obj_desc);
  636.                 break;
  637.  
  638.         case AML_PACKAGE_OP:
  639.         case AML_VAR_PACKAGE_OP:
  640.  
  641.                 status =
  642.                     acpi_ds_build_internal_package_obj(walk_state, op, length,
  643.                                                        &obj_desc);
  644.                 break;
  645.  
  646.         default:
  647.  
  648.                 return_ACPI_STATUS(AE_AML_BAD_OPCODE);
  649.         }
  650.  
  651.         if (ACPI_SUCCESS(status)) {
  652.                 /*
  653.                  * Return the object in the walk_state, unless the parent is a package -
  654.                  * in this case, the return object will be stored in the parse tree
  655.                  * for the package.
  656.                  */
  657.                 if ((!op->common.parent) ||
  658.                     ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) &&
  659.                      (op->common.parent->common.aml_opcode !=
  660.                       AML_VAR_PACKAGE_OP)
  661.                      && (op->common.parent->common.aml_opcode !=
  662.                          AML_NAME_OP))) {
  663.                         walk_state->result_obj = obj_desc;
  664.                 }
  665.         }
  666.  
  667.         return_ACPI_STATUS(status);
  668. }
  669.  
  670. /*******************************************************************************
  671.  *
  672.  * FUNCTION:    acpi_ds_eval_bank_field_operands
  673.  *
  674.  * PARAMETERS:  walk_state      - Current walk
  675.  *              op              - A valid bank_field Op object
  676.  *
  677.  * RETURN:      Status
  678.  *
  679.  * DESCRIPTION: Get bank_field bank_value
  680.  *              Called from acpi_ds_exec_end_op during bank_field parse tree walk
  681.  *
  682.  ******************************************************************************/
  683.  
  684. acpi_status
  685. acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state,
  686.                                  union acpi_parse_object *op)
  687. {
  688.         acpi_status status;
  689.         union acpi_operand_object *obj_desc;
  690.         union acpi_operand_object *operand_desc;
  691.         struct acpi_namespace_node *node;
  692.         union acpi_parse_object *next_op;
  693.         union acpi_parse_object *arg;
  694.  
  695.         ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op);
  696.  
  697.         /*
  698.          * This is where we evaluate the bank_value field of the
  699.          * bank_field declaration
  700.          */
  701.  
  702.         /* next_op points to the op that holds the Region */
  703.  
  704.         next_op = op->common.value.arg;
  705.  
  706.         /* next_op points to the op that holds the Bank Register */
  707.  
  708.         next_op = next_op->common.next;
  709.  
  710.         /* next_op points to the op that holds the Bank Value */
  711.  
  712.         next_op = next_op->common.next;
  713.  
  714.         /*
  715.          * Set proper index into operand stack for acpi_ds_obj_stack_push
  716.          * invoked inside acpi_ds_create_operand.
  717.          *
  718.          * We use walk_state->Operands[0] to store the evaluated bank_value
  719.          */
  720.         walk_state->operand_index = 0;
  721.  
  722.         status = acpi_ds_create_operand(walk_state, next_op, 0);
  723.         if (ACPI_FAILURE(status)) {
  724.                 return_ACPI_STATUS(status);
  725.         }
  726.  
  727.         status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state);
  728.         if (ACPI_FAILURE(status)) {
  729.                 return_ACPI_STATUS(status);
  730.         }
  731.  
  732.         ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS,
  733.                            acpi_ps_get_opcode_name(op->common.aml_opcode), 1);
  734.         /*
  735.          * Get the bank_value operand and save it
  736.          * (at Top of stack)
  737.          */
  738.         operand_desc = walk_state->operands[0];
  739.  
  740.         /* Arg points to the start Bank Field */
  741.  
  742.         arg = acpi_ps_get_arg(op, 4);
  743.         while (arg) {
  744.  
  745.                 /* Ignore OFFSET and ACCESSAS terms here */
  746.  
  747.                 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
  748.                         node = arg->common.node;
  749.  
  750.                         obj_desc = acpi_ns_get_attached_object(node);
  751.                         if (!obj_desc) {
  752.                                 return_ACPI_STATUS(AE_NOT_EXIST);
  753.                         }
  754.  
  755.                         obj_desc->bank_field.value =
  756.                             (u32) operand_desc->integer.value;
  757.                 }
  758.  
  759.                 /* Move to next field in the list */
  760.  
  761.                 arg = arg->common.next;
  762.         }
  763.  
  764.         acpi_ut_remove_reference(operand_desc);
  765.         return_ACPI_STATUS(status);
  766. }
  767.