Subversion Repositories Kolibri OS

Rev

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

  1. /******************************************************************************
  2.  *
  3.  * Module Name: exoparg1 - AML execution - opcodes with 1 argument
  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 "acdispat.h"
  48. #include "acinterp.h"
  49. #include "amlcode.h"
  50. #include "acnamesp.h"
  51.  
  52. #define _COMPONENT          ACPI_EXECUTER
  53. ACPI_MODULE_NAME("exoparg1")
  54.  
  55. /*!
  56.  * Naming convention for AML interpreter execution routines.
  57.  *
  58.  * The routines that begin execution of AML opcodes are named with a common
  59.  * convention based upon the number of arguments, the number of target operands,
  60.  * and whether or not a value is returned:
  61.  *
  62.  *      AcpiExOpcode_xA_yT_zR
  63.  *
  64.  * Where:
  65.  *
  66.  * xA - ARGUMENTS:    The number of arguments (input operands) that are
  67.  *                    required for this opcode type (0 through 6 args).
  68.  * yT - TARGETS:      The number of targets (output operands) that are required
  69.  *                    for this opcode type (0, 1, or 2 targets).
  70.  * zR - RETURN VALUE: Indicates whether this opcode type returns a value
  71.  *                    as the function return (0 or 1).
  72.  *
  73.  * The AcpiExOpcode* functions are called via the Dispatcher component with
  74.  * fully resolved operands.
  75. !*/
  76. /*******************************************************************************
  77.  *
  78.  * FUNCTION:    acpi_ex_opcode_0A_0T_1R
  79.  *
  80.  * PARAMETERS:  walk_state          - Current state (contains AML opcode)
  81.  *
  82.  * RETURN:      Status
  83.  *
  84.  * DESCRIPTION: Execute operator with no operands, one return value
  85.  *
  86.  ******************************************************************************/
  87. acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state)
  88. {
  89.         acpi_status status = AE_OK;
  90.         union acpi_operand_object *return_desc = NULL;
  91.  
  92.         ACPI_FUNCTION_TRACE_STR(ex_opcode_0A_0T_1R,
  93.                                 acpi_ps_get_opcode_name(walk_state->opcode));
  94.  
  95.         /* Examine the AML opcode */
  96.  
  97.         switch (walk_state->opcode) {
  98.         case AML_TIMER_OP:      /*  Timer () */
  99.  
  100.                 /* Create a return object of type Integer */
  101.  
  102.                 return_desc =
  103.                     acpi_ut_create_integer_object(acpi_os_get_timer());
  104.                 if (!return_desc) {
  105.                         status = AE_NO_MEMORY;
  106.                         goto cleanup;
  107.                 }
  108.                 break;
  109.  
  110.         default:                /*  Unknown opcode  */
  111.  
  112.                 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
  113.                             walk_state->opcode));
  114.                 status = AE_AML_BAD_OPCODE;
  115.                 break;
  116.         }
  117.  
  118. cleanup:
  119.  
  120.         /* Delete return object on error */
  121.  
  122.         if ((ACPI_FAILURE(status)) || walk_state->result_obj) {
  123.                 acpi_ut_remove_reference(return_desc);
  124.                 walk_state->result_obj = NULL;
  125.         } else {
  126.                 /* Save the return value */
  127.  
  128.                 walk_state->result_obj = return_desc;
  129.         }
  130.  
  131.         return_ACPI_STATUS(status);
  132. }
  133.  
  134. /*******************************************************************************
  135.  *
  136.  * FUNCTION:    acpi_ex_opcode_1A_0T_0R
  137.  *
  138.  * PARAMETERS:  walk_state          - Current state (contains AML opcode)
  139.  *
  140.  * RETURN:      Status
  141.  *
  142.  * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
  143.  *              object stack
  144.  *
  145.  ******************************************************************************/
  146.  
  147. acpi_status acpi_ex_opcode_1A_0T_0R(struct acpi_walk_state *walk_state)
  148. {
  149.         union acpi_operand_object **operand = &walk_state->operands[0];
  150.         acpi_status status = AE_OK;
  151.  
  152.         ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_0T_0R,
  153.                                 acpi_ps_get_opcode_name(walk_state->opcode));
  154.  
  155.         /* Examine the AML opcode */
  156.  
  157.         switch (walk_state->opcode) {
  158.         case AML_RELEASE_OP:    /*  Release (mutex_object) */
  159.  
  160.                 status = acpi_ex_release_mutex(operand[0], walk_state);
  161.                 break;
  162.  
  163.         case AML_RESET_OP:      /*  Reset (event_object) */
  164.  
  165.                 status = acpi_ex_system_reset_event(operand[0]);
  166.                 break;
  167.  
  168.         case AML_SIGNAL_OP:     /*  Signal (event_object) */
  169.  
  170.                 status = acpi_ex_system_signal_event(operand[0]);
  171.                 break;
  172.  
  173.         case AML_SLEEP_OP:      /*  Sleep (msec_time) */
  174.  
  175.                 status = acpi_ex_system_do_sleep(operand[0]->integer.value);
  176.                 break;
  177.  
  178.         case AML_STALL_OP:      /*  Stall (usec_time) */
  179.  
  180.                 status =
  181.                     acpi_ex_system_do_stall((u32) operand[0]->integer.value);
  182.                 break;
  183.  
  184.         case AML_UNLOAD_OP:     /*  Unload (Handle) */
  185.  
  186.                 status = acpi_ex_unload_table(operand[0]);
  187.                 break;
  188.  
  189.         default:                /*  Unknown opcode  */
  190.  
  191.                 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
  192.                             walk_state->opcode));
  193.                 status = AE_AML_BAD_OPCODE;
  194.                 break;
  195.         }
  196.  
  197.         return_ACPI_STATUS(status);
  198. }
  199.  
  200. /*******************************************************************************
  201.  *
  202.  * FUNCTION:    acpi_ex_opcode_1A_1T_0R
  203.  *
  204.  * PARAMETERS:  walk_state          - Current state (contains AML opcode)
  205.  *
  206.  * RETURN:      Status
  207.  *
  208.  * DESCRIPTION: Execute opcode with one argument, one target, and no
  209.  *              return value.
  210.  *
  211.  ******************************************************************************/
  212.  
  213. acpi_status acpi_ex_opcode_1A_1T_0R(struct acpi_walk_state *walk_state)
  214. {
  215.         acpi_status status = AE_OK;
  216.         union acpi_operand_object **operand = &walk_state->operands[0];
  217.  
  218.         ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_1T_0R,
  219.                                 acpi_ps_get_opcode_name(walk_state->opcode));
  220.  
  221.         /* Examine the AML opcode */
  222.  
  223.         switch (walk_state->opcode) {
  224.         case AML_LOAD_OP:
  225.  
  226.                 status = acpi_ex_load_op(operand[0], operand[1], walk_state);
  227.                 break;
  228.  
  229.         default:                /* Unknown opcode */
  230.  
  231.                 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
  232.                             walk_state->opcode));
  233.                 status = AE_AML_BAD_OPCODE;
  234.                 goto cleanup;
  235.         }
  236.  
  237. cleanup:
  238.  
  239.         return_ACPI_STATUS(status);
  240. }
  241.  
  242. /*******************************************************************************
  243.  *
  244.  * FUNCTION:    acpi_ex_opcode_1A_1T_1R
  245.  *
  246.  * PARAMETERS:  walk_state          - Current state (contains AML opcode)
  247.  *
  248.  * RETURN:      Status
  249.  *
  250.  * DESCRIPTION: Execute opcode with one argument, one target, and a
  251.  *              return value.
  252.  *
  253.  ******************************************************************************/
  254.  
  255. acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state)
  256. {
  257.         acpi_status status = AE_OK;
  258.         union acpi_operand_object **operand = &walk_state->operands[0];
  259.         union acpi_operand_object *return_desc = NULL;
  260.         union acpi_operand_object *return_desc2 = NULL;
  261.         u32 temp32;
  262.         u32 i;
  263.         u64 power_of_ten;
  264.         u64 digit;
  265.  
  266.         ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_1T_1R,
  267.                                 acpi_ps_get_opcode_name(walk_state->opcode));
  268.  
  269.         /* Examine the AML opcode */
  270.  
  271.         switch (walk_state->opcode) {
  272.         case AML_BIT_NOT_OP:
  273.         case AML_FIND_SET_LEFT_BIT_OP:
  274.         case AML_FIND_SET_RIGHT_BIT_OP:
  275.         case AML_FROM_BCD_OP:
  276.         case AML_TO_BCD_OP:
  277.         case AML_COND_REF_OF_OP:
  278.  
  279.                 /* Create a return object of type Integer for these opcodes */
  280.  
  281.                 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
  282.                 if (!return_desc) {
  283.                         status = AE_NO_MEMORY;
  284.                         goto cleanup;
  285.                 }
  286.  
  287.                 switch (walk_state->opcode) {
  288.                 case AML_BIT_NOT_OP:    /* Not (Operand, Result)  */
  289.  
  290.                         return_desc->integer.value = ~operand[0]->integer.value;
  291.                         break;
  292.  
  293.                 case AML_FIND_SET_LEFT_BIT_OP:  /* find_set_left_bit (Operand, Result) */
  294.  
  295.                         return_desc->integer.value = operand[0]->integer.value;
  296.  
  297.                         /*
  298.                          * Acpi specification describes Integer type as a little
  299.                          * endian unsigned value, so this boundary condition is valid.
  300.                          */
  301.                         for (temp32 = 0; return_desc->integer.value &&
  302.                              temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
  303.                                 return_desc->integer.value >>= 1;
  304.                         }
  305.  
  306.                         return_desc->integer.value = temp32;
  307.                         break;
  308.  
  309.                 case AML_FIND_SET_RIGHT_BIT_OP: /* find_set_right_bit (Operand, Result) */
  310.  
  311.                         return_desc->integer.value = operand[0]->integer.value;
  312.  
  313.                         /*
  314.                          * The Acpi specification describes Integer type as a little
  315.                          * endian unsigned value, so this boundary condition is valid.
  316.                          */
  317.                         for (temp32 = 0; return_desc->integer.value &&
  318.                              temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
  319.                                 return_desc->integer.value <<= 1;
  320.                         }
  321.  
  322.                         /* Since the bit position is one-based, subtract from 33 (65) */
  323.  
  324.                         return_desc->integer.value =
  325.                             temp32 ==
  326.                             0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - temp32;
  327.                         break;
  328.  
  329.                 case AML_FROM_BCD_OP:   /* from_bcd (BCDValue, Result) */
  330.                         /*
  331.                          * The 64-bit ACPI integer can hold 16 4-bit BCD characters
  332.                          * (if table is 32-bit, integer can hold 8 BCD characters)
  333.                          * Convert each 4-bit BCD value
  334.                          */
  335.                         power_of_ten = 1;
  336.                         return_desc->integer.value = 0;
  337.                         digit = operand[0]->integer.value;
  338.  
  339.                         /* Convert each BCD digit (each is one nybble wide) */
  340.  
  341.                         for (i = 0;
  342.                              (i < acpi_gbl_integer_nybble_width) && (digit > 0);
  343.                              i++) {
  344.  
  345.                                 /* Get the least significant 4-bit BCD digit */
  346.  
  347.                                 temp32 = ((u32) digit) & 0xF;
  348.  
  349.                                 /* Check the range of the digit */
  350.  
  351.                                 if (temp32 > 9) {
  352.                                         ACPI_ERROR((AE_INFO,
  353.                                                     "BCD digit too large (not decimal): 0x%X",
  354.                                                     temp32));
  355.  
  356.                                         status = AE_AML_NUMERIC_OVERFLOW;
  357.                                         goto cleanup;
  358.                                 }
  359.  
  360.                                 /* Sum the digit into the result with the current power of 10 */
  361.  
  362.                                 return_desc->integer.value +=
  363.                                     (((u64) temp32) * power_of_ten);
  364.  
  365.                                 /* Shift to next BCD digit */
  366.  
  367.                                 digit >>= 4;
  368.  
  369.                                 /* Next power of 10 */
  370.  
  371.                                 power_of_ten *= 10;
  372.                         }
  373.                         break;
  374.  
  375.                 case AML_TO_BCD_OP:     /* to_bcd (Operand, Result) */
  376.  
  377.                         return_desc->integer.value = 0;
  378.                         digit = operand[0]->integer.value;
  379.  
  380.                         /* Each BCD digit is one nybble wide */
  381.  
  382.                         for (i = 0;
  383.                              (i < acpi_gbl_integer_nybble_width) && (digit > 0);
  384.                              i++) {
  385.                                 (void)acpi_ut_short_divide(digit, 10, &digit,
  386.                                                            &temp32);
  387.  
  388.                                 /*
  389.                                  * Insert the BCD digit that resides in the
  390.                                  * remainder from above
  391.                                  */
  392.                                 return_desc->integer.value |=
  393.                                     (((u64) temp32) << ACPI_MUL_4(i));
  394.                         }
  395.  
  396.                         /* Overflow if there is any data left in Digit */
  397.  
  398.                         if (digit > 0) {
  399.                                 ACPI_ERROR((AE_INFO,
  400.                                             "Integer too large to convert to BCD: 0x%8.8X%8.8X",
  401.                                             ACPI_FORMAT_UINT64(operand[0]->
  402.                                                                integer.value)));
  403.                                 status = AE_AML_NUMERIC_OVERFLOW;
  404.                                 goto cleanup;
  405.                         }
  406.                         break;
  407.  
  408.                 case AML_COND_REF_OF_OP:        /* cond_ref_of (source_object, Result) */
  409.                         /*
  410.                          * This op is a little strange because the internal return value is
  411.                          * different than the return value stored in the result descriptor
  412.                          * (There are really two return values)
  413.                          */
  414.                         if ((struct acpi_namespace_node *)operand[0] ==
  415.                             acpi_gbl_root_node) {
  416.                                 /*
  417.                                  * This means that the object does not exist in the namespace,
  418.                                  * return FALSE
  419.                                  */
  420.                                 return_desc->integer.value = 0;
  421.                                 goto cleanup;
  422.                         }
  423.  
  424.                         /* Get the object reference, store it, and remove our reference */
  425.  
  426.                         status = acpi_ex_get_object_reference(operand[0],
  427.                                                               &return_desc2,
  428.                                                               walk_state);
  429.                         if (ACPI_FAILURE(status)) {
  430.                                 goto cleanup;
  431.                         }
  432.  
  433.                         status =
  434.                             acpi_ex_store(return_desc2, operand[1], walk_state);
  435.                         acpi_ut_remove_reference(return_desc2);
  436.  
  437.                         /* The object exists in the namespace, return TRUE */
  438.  
  439.                         return_desc->integer.value = ACPI_UINT64_MAX;
  440.                         goto cleanup;
  441.  
  442.                 default:
  443.  
  444.                         /* No other opcodes get here */
  445.  
  446.                         break;
  447.                 }
  448.                 break;
  449.  
  450.         case AML_STORE_OP:      /* Store (Source, Target) */
  451.                 /*
  452.                  * A store operand is typically a number, string, buffer or lvalue
  453.                  * Be careful about deleting the source object,
  454.                  * since the object itself may have been stored.
  455.                  */
  456.                 status = acpi_ex_store(operand[0], operand[1], walk_state);
  457.                 if (ACPI_FAILURE(status)) {
  458.                         return_ACPI_STATUS(status);
  459.                 }
  460.  
  461.                 /* It is possible that the Store already produced a return object */
  462.  
  463.                 if (!walk_state->result_obj) {
  464.                         /*
  465.                          * Normally, we would remove a reference on the Operand[0]
  466.                          * parameter; But since it is being used as the internal return
  467.                          * object (meaning we would normally increment it), the two
  468.                          * cancel out, and we simply don't do anything.
  469.                          */
  470.                         walk_state->result_obj = operand[0];
  471.                         walk_state->operands[0] = NULL; /* Prevent deletion */
  472.                 }
  473.                 return_ACPI_STATUS(status);
  474.  
  475.                 /*
  476.                  * ACPI 2.0 Opcodes
  477.                  */
  478.         case AML_COPY_OP:       /* Copy (Source, Target) */
  479.  
  480.                 status =
  481.                     acpi_ut_copy_iobject_to_iobject(operand[0], &return_desc,
  482.                                                     walk_state);
  483.                 break;
  484.  
  485.         case AML_TO_DECSTRING_OP:       /* to_decimal_string (Data, Result) */
  486.  
  487.                 status = acpi_ex_convert_to_string(operand[0], &return_desc,
  488.                                                    ACPI_EXPLICIT_CONVERT_DECIMAL);
  489.                 if (return_desc == operand[0]) {
  490.  
  491.                         /* No conversion performed, add ref to handle return value */
  492.                         acpi_ut_add_reference(return_desc);
  493.                 }
  494.                 break;
  495.  
  496.         case AML_TO_HEXSTRING_OP:       /* to_hex_string (Data, Result) */
  497.  
  498.                 status = acpi_ex_convert_to_string(operand[0], &return_desc,
  499.                                                    ACPI_EXPLICIT_CONVERT_HEX);
  500.                 if (return_desc == operand[0]) {
  501.  
  502.                         /* No conversion performed, add ref to handle return value */
  503.                         acpi_ut_add_reference(return_desc);
  504.                 }
  505.                 break;
  506.  
  507.         case AML_TO_BUFFER_OP:  /* to_buffer (Data, Result) */
  508.  
  509.                 status = acpi_ex_convert_to_buffer(operand[0], &return_desc);
  510.                 if (return_desc == operand[0]) {
  511.  
  512.                         /* No conversion performed, add ref to handle return value */
  513.                         acpi_ut_add_reference(return_desc);
  514.                 }
  515.                 break;
  516.  
  517.         case AML_TO_INTEGER_OP: /* to_integer (Data, Result) */
  518.  
  519.                 status = acpi_ex_convert_to_integer(operand[0], &return_desc,
  520.                                                     ACPI_ANY_BASE);
  521.                 if (return_desc == operand[0]) {
  522.  
  523.                         /* No conversion performed, add ref to handle return value */
  524.                         acpi_ut_add_reference(return_desc);
  525.                 }
  526.                 break;
  527.  
  528.         case AML_SHIFT_LEFT_BIT_OP:     /* shift_left_bit (Source, bit_num) */
  529.         case AML_SHIFT_RIGHT_BIT_OP:    /* shift_right_bit (Source, bit_num) */
  530.  
  531.                 /* These are two obsolete opcodes */
  532.  
  533.                 ACPI_ERROR((AE_INFO,
  534.                             "%s is obsolete and not implemented",
  535.                             acpi_ps_get_opcode_name(walk_state->opcode)));
  536.                 status = AE_SUPPORT;
  537.                 goto cleanup;
  538.  
  539.         default:                /* Unknown opcode */
  540.  
  541.                 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
  542.                             walk_state->opcode));
  543.                 status = AE_AML_BAD_OPCODE;
  544.                 goto cleanup;
  545.         }
  546.  
  547.         if (ACPI_SUCCESS(status)) {
  548.  
  549.                 /* Store the return value computed above into the target object */
  550.  
  551.                 status = acpi_ex_store(return_desc, operand[1], walk_state);
  552.         }
  553.  
  554. cleanup:
  555.  
  556.         /* Delete return object on error */
  557.  
  558.         if (ACPI_FAILURE(status)) {
  559.                 acpi_ut_remove_reference(return_desc);
  560.         }
  561.  
  562.         /* Save return object on success */
  563.  
  564.         else if (!walk_state->result_obj) {
  565.                 walk_state->result_obj = return_desc;
  566.         }
  567.  
  568.         return_ACPI_STATUS(status);
  569. }
  570.  
  571. /*******************************************************************************
  572.  *
  573.  * FUNCTION:    acpi_ex_opcode_1A_0T_1R
  574.  *
  575.  * PARAMETERS:  walk_state          - Current state (contains AML opcode)
  576.  *
  577.  * RETURN:      Status
  578.  *
  579.  * DESCRIPTION: Execute opcode with one argument, no target, and a return value
  580.  *
  581.  ******************************************************************************/
  582.  
  583. acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
  584. {
  585.         union acpi_operand_object **operand = &walk_state->operands[0];
  586.         union acpi_operand_object *temp_desc;
  587.         union acpi_operand_object *return_desc = NULL;
  588.         acpi_status status = AE_OK;
  589.         u32 type;
  590.         u64 value;
  591.  
  592.         ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_0T_1R,
  593.                                 acpi_ps_get_opcode_name(walk_state->opcode));
  594.  
  595.         /* Examine the AML opcode */
  596.  
  597.         switch (walk_state->opcode) {
  598.         case AML_LNOT_OP:       /* LNot (Operand) */
  599.  
  600.                 return_desc = acpi_ut_create_integer_object((u64) 0);
  601.                 if (!return_desc) {
  602.                         status = AE_NO_MEMORY;
  603.                         goto cleanup;
  604.                 }
  605.  
  606.                 /*
  607.                  * Set result to ONES (TRUE) if Value == 0. Note:
  608.                  * return_desc->Integer.Value is initially == 0 (FALSE) from above.
  609.                  */
  610.                 if (!operand[0]->integer.value) {
  611.                         return_desc->integer.value = ACPI_UINT64_MAX;
  612.                 }
  613.                 break;
  614.  
  615.         case AML_DECREMENT_OP:  /* Decrement (Operand)  */
  616.         case AML_INCREMENT_OP:  /* Increment (Operand)  */
  617.                 /*
  618.                  * Create a new integer. Can't just get the base integer and
  619.                  * increment it because it may be an Arg or Field.
  620.                  */
  621.                 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
  622.                 if (!return_desc) {
  623.                         status = AE_NO_MEMORY;
  624.                         goto cleanup;
  625.                 }
  626.  
  627.                 /*
  628.                  * Since we are expecting a Reference operand, it can be either a
  629.                  * NS Node or an internal object.
  630.                  */
  631.                 temp_desc = operand[0];
  632.                 if (ACPI_GET_DESCRIPTOR_TYPE(temp_desc) ==
  633.                     ACPI_DESC_TYPE_OPERAND) {
  634.  
  635.                         /* Internal reference object - prevent deletion */
  636.  
  637.                         acpi_ut_add_reference(temp_desc);
  638.                 }
  639.  
  640.                 /*
  641.                  * Convert the Reference operand to an Integer (This removes a
  642.                  * reference on the Operand[0] object)
  643.                  *
  644.                  * NOTE:  We use LNOT_OP here in order to force resolution of the
  645.                  * reference operand to an actual integer.
  646.                  */
  647.                 status =
  648.                     acpi_ex_resolve_operands(AML_LNOT_OP, &temp_desc,
  649.                                              walk_state);
  650.                 if (ACPI_FAILURE(status)) {
  651.                         ACPI_EXCEPTION((AE_INFO, status,
  652.                                         "While resolving operands for [%s]",
  653.                                         acpi_ps_get_opcode_name(walk_state->
  654.                                                                 opcode)));
  655.  
  656.                         goto cleanup;
  657.                 }
  658.  
  659.                 /*
  660.                  * temp_desc is now guaranteed to be an Integer object --
  661.                  * Perform the actual increment or decrement
  662.                  */
  663.                 if (walk_state->opcode == AML_INCREMENT_OP) {
  664.                         return_desc->integer.value =
  665.                             temp_desc->integer.value + 1;
  666.                 } else {
  667.                         return_desc->integer.value =
  668.                             temp_desc->integer.value - 1;
  669.                 }
  670.  
  671.                 /* Finished with this Integer object */
  672.  
  673.                 acpi_ut_remove_reference(temp_desc);
  674.  
  675.                 /*
  676.                  * Store the result back (indirectly) through the original
  677.                  * Reference object
  678.                  */
  679.                 status = acpi_ex_store(return_desc, operand[0], walk_state);
  680.                 break;
  681.  
  682.         case AML_TYPE_OP:       /* object_type (source_object) */
  683.                 /*
  684.                  * Note: The operand is not resolved at this point because we want to
  685.                  * get the associated object, not its value. For example, we don't
  686.                  * want to resolve a field_unit to its value, we want the actual
  687.                  * field_unit object.
  688.                  */
  689.  
  690.                 /* Get the type of the base object */
  691.  
  692.                 status =
  693.                     acpi_ex_resolve_multiple(walk_state, operand[0], &type,
  694.                                              NULL);
  695.                 if (ACPI_FAILURE(status)) {
  696.                         goto cleanup;
  697.                 }
  698.  
  699.                 /* Allocate a descriptor to hold the type. */
  700.  
  701.                 return_desc = acpi_ut_create_integer_object((u64) type);
  702.                 if (!return_desc) {
  703.                         status = AE_NO_MEMORY;
  704.                         goto cleanup;
  705.                 }
  706.                 break;
  707.  
  708.         case AML_SIZE_OF_OP:    /* size_of (source_object) */
  709.                 /*
  710.                  * Note: The operand is not resolved at this point because we want to
  711.                  * get the associated object, not its value.
  712.                  */
  713.  
  714.                 /* Get the base object */
  715.  
  716.                 status = acpi_ex_resolve_multiple(walk_state,
  717.                                                   operand[0], &type,
  718.                                                   &temp_desc);
  719.                 if (ACPI_FAILURE(status)) {
  720.                         goto cleanup;
  721.                 }
  722.  
  723.                 /*
  724.                  * The type of the base object must be integer, buffer, string, or
  725.                  * package. All others are not supported.
  726.                  *
  727.                  * NOTE: Integer is not specifically supported by the ACPI spec,
  728.                  * but is supported implicitly via implicit operand conversion.
  729.                  * rather than bother with conversion, we just use the byte width
  730.                  * global (4 or 8 bytes).
  731.                  */
  732.                 switch (type) {
  733.                 case ACPI_TYPE_INTEGER:
  734.  
  735.                         value = acpi_gbl_integer_byte_width;
  736.                         break;
  737.  
  738.                 case ACPI_TYPE_STRING:
  739.  
  740.                         value = temp_desc->string.length;
  741.                         break;
  742.  
  743.                 case ACPI_TYPE_BUFFER:
  744.  
  745.                         /* Buffer arguments may not be evaluated at this point */
  746.  
  747.                         status = acpi_ds_get_buffer_arguments(temp_desc);
  748.                         value = temp_desc->buffer.length;
  749.                         break;
  750.  
  751.                 case ACPI_TYPE_PACKAGE:
  752.  
  753.                         /* Package arguments may not be evaluated at this point */
  754.  
  755.                         status = acpi_ds_get_package_arguments(temp_desc);
  756.                         value = temp_desc->package.count;
  757.                         break;
  758.  
  759.                 default:
  760.  
  761.                         ACPI_ERROR((AE_INFO,
  762.                                     "Operand must be Buffer/Integer/String/Package - found type %s",
  763.                                     acpi_ut_get_type_name(type)));
  764.                         status = AE_AML_OPERAND_TYPE;
  765.                         goto cleanup;
  766.                 }
  767.  
  768.                 if (ACPI_FAILURE(status)) {
  769.                         goto cleanup;
  770.                 }
  771.  
  772.                 /*
  773.                  * Now that we have the size of the object, create a result
  774.                  * object to hold the value
  775.                  */
  776.                 return_desc = acpi_ut_create_integer_object(value);
  777.                 if (!return_desc) {
  778.                         status = AE_NO_MEMORY;
  779.                         goto cleanup;
  780.                 }
  781.                 break;
  782.  
  783.         case AML_REF_OF_OP:     /* ref_of (source_object) */
  784.  
  785.                 status =
  786.                     acpi_ex_get_object_reference(operand[0], &return_desc,
  787.                                                  walk_state);
  788.                 if (ACPI_FAILURE(status)) {
  789.                         goto cleanup;
  790.                 }
  791.                 break;
  792.  
  793.         case AML_DEREF_OF_OP:   /* deref_of (obj_reference | String) */
  794.  
  795.                 /* Check for a method local or argument, or standalone String */
  796.  
  797.                 if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) ==
  798.                     ACPI_DESC_TYPE_NAMED) {
  799.                         temp_desc =
  800.                             acpi_ns_get_attached_object((struct
  801.                                                          acpi_namespace_node *)
  802.                                                         operand[0]);
  803.                         if (temp_desc
  804.                             && ((temp_desc->common.type == ACPI_TYPE_STRING)
  805.                                 || (temp_desc->common.type ==
  806.                                     ACPI_TYPE_LOCAL_REFERENCE))) {
  807.                                 operand[0] = temp_desc;
  808.                                 acpi_ut_add_reference(temp_desc);
  809.                         } else {
  810.                                 status = AE_AML_OPERAND_TYPE;
  811.                                 goto cleanup;
  812.                         }
  813.                 } else {
  814.                         switch ((operand[0])->common.type) {
  815.                         case ACPI_TYPE_LOCAL_REFERENCE:
  816.                                 /*
  817.                                  * This is a deref_of (local_x | arg_x)
  818.                                  *
  819.                                  * Must resolve/dereference the local/arg reference first
  820.                                  */
  821.                                 switch (operand[0]->reference.class) {
  822.                                 case ACPI_REFCLASS_LOCAL:
  823.                                 case ACPI_REFCLASS_ARG:
  824.  
  825.                                         /* Set Operand[0] to the value of the local/arg */
  826.  
  827.                                         status =
  828.                                             acpi_ds_method_data_get_value
  829.                                             (operand[0]->reference.class,
  830.                                              operand[0]->reference.value,
  831.                                              walk_state, &temp_desc);
  832.                                         if (ACPI_FAILURE(status)) {
  833.                                                 goto cleanup;
  834.                                         }
  835.  
  836.                                         /*
  837.                                          * Delete our reference to the input object and
  838.                                          * point to the object just retrieved
  839.                                          */
  840.                                         acpi_ut_remove_reference(operand[0]);
  841.                                         operand[0] = temp_desc;
  842.                                         break;
  843.  
  844.                                 case ACPI_REFCLASS_REFOF:
  845.  
  846.                                         /* Get the object to which the reference refers */
  847.  
  848.                                         temp_desc =
  849.                                             operand[0]->reference.object;
  850.                                         acpi_ut_remove_reference(operand[0]);
  851.                                         operand[0] = temp_desc;
  852.                                         break;
  853.  
  854.                                 default:
  855.  
  856.                                         /* Must be an Index op - handled below */
  857.                                         break;
  858.                                 }
  859.                                 break;
  860.  
  861.                         case ACPI_TYPE_STRING:
  862.  
  863.                                 break;
  864.  
  865.                         default:
  866.  
  867.                                 status = AE_AML_OPERAND_TYPE;
  868.                                 goto cleanup;
  869.                         }
  870.                 }
  871.  
  872.                 if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) !=
  873.                     ACPI_DESC_TYPE_NAMED) {
  874.                         if ((operand[0])->common.type == ACPI_TYPE_STRING) {
  875.                                 /*
  876.                                  * This is a deref_of (String). The string is a reference
  877.                                  * to a named ACPI object.
  878.                                  *
  879.                                  * 1) Find the owning Node
  880.                                  * 2) Dereference the node to an actual object. Could be a
  881.                                  *    Field, so we need to resolve the node to a value.
  882.                                  */
  883.                                 status =
  884.                                     acpi_ns_get_node(walk_state->scope_info->
  885.                                                      scope.node,
  886.                                                      operand[0]->string.pointer,
  887.                                                      ACPI_NS_SEARCH_PARENT,
  888.                                                      ACPI_CAST_INDIRECT_PTR
  889.                                                      (struct
  890.                                                       acpi_namespace_node,
  891.                                                       &return_desc));
  892.                                 if (ACPI_FAILURE(status)) {
  893.                                         goto cleanup;
  894.                                 }
  895.  
  896.                                 status =
  897.                                     acpi_ex_resolve_node_to_value
  898.                                     (ACPI_CAST_INDIRECT_PTR
  899.                                      (struct acpi_namespace_node, &return_desc),
  900.                                      walk_state);
  901.                                 goto cleanup;
  902.                         }
  903.                 }
  904.  
  905.                 /* Operand[0] may have changed from the code above */
  906.  
  907.                 if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) ==
  908.                     ACPI_DESC_TYPE_NAMED) {
  909.                         /*
  910.                          * This is a deref_of (object_reference)
  911.                          * Get the actual object from the Node (This is the dereference).
  912.                          * This case may only happen when a local_x or arg_x is
  913.                          * dereferenced above.
  914.                          */
  915.                         return_desc = acpi_ns_get_attached_object((struct
  916.                                                                    acpi_namespace_node
  917.                                                                    *)
  918.                                                                   operand[0]);
  919.                         acpi_ut_add_reference(return_desc);
  920.                 } else {
  921.                         /*
  922.                          * This must be a reference object produced by either the
  923.                          * Index() or ref_of() operator
  924.                          */
  925.                         switch (operand[0]->reference.class) {
  926.                         case ACPI_REFCLASS_INDEX:
  927.                                 /*
  928.                                  * The target type for the Index operator must be
  929.                                  * either a Buffer or a Package
  930.                                  */
  931.                                 switch (operand[0]->reference.target_type) {
  932.                                 case ACPI_TYPE_BUFFER_FIELD:
  933.  
  934.                                         temp_desc =
  935.                                             operand[0]->reference.object;
  936.  
  937.                                         /*
  938.                                          * Create a new object that contains one element of the
  939.                                          * buffer -- the element pointed to by the index.
  940.                                          *
  941.                                          * NOTE: index into a buffer is NOT a pointer to a
  942.                                          * sub-buffer of the main buffer, it is only a pointer to a
  943.                                          * single element (byte) of the buffer!
  944.                                          *
  945.                                          * Since we are returning the value of the buffer at the
  946.                                          * indexed location, we don't need to add an additional
  947.                                          * reference to the buffer itself.
  948.                                          */
  949.                                         return_desc =
  950.                                             acpi_ut_create_integer_object((u64)
  951.                                                                           temp_desc->buffer.pointer[operand[0]->reference.value]);
  952.                                         if (!return_desc) {
  953.                                                 status = AE_NO_MEMORY;
  954.                                                 goto cleanup;
  955.                                         }
  956.                                         break;
  957.  
  958.                                 case ACPI_TYPE_PACKAGE:
  959.                                         /*
  960.                                          * Return the referenced element of the package. We must
  961.                                          * add another reference to the referenced object, however.
  962.                                          */
  963.                                         return_desc =
  964.                                             *(operand[0]->reference.where);
  965.                                         if (!return_desc) {
  966.                                                 /*
  967.                                                  * Element is NULL, do not allow the dereference.
  968.                                                  * This provides compatibility with other ACPI
  969.                                                  * implementations.
  970.                                                  */
  971.                                                 return_ACPI_STATUS
  972.                                                     (AE_AML_UNINITIALIZED_ELEMENT);
  973.                                         }
  974.  
  975.                                         acpi_ut_add_reference(return_desc);
  976.                                         break;
  977.  
  978.                                 default:
  979.  
  980.                                         ACPI_ERROR((AE_INFO,
  981.                                                     "Unknown Index TargetType 0x%X in reference object %p",
  982.                                                     operand[0]->reference.
  983.                                                     target_type, operand[0]));
  984.                                         status = AE_AML_OPERAND_TYPE;
  985.                                         goto cleanup;
  986.                                 }
  987.                                 break;
  988.  
  989.                         case ACPI_REFCLASS_REFOF:
  990.  
  991.                                 return_desc = operand[0]->reference.object;
  992.  
  993.                                 if (ACPI_GET_DESCRIPTOR_TYPE(return_desc) ==
  994.                                     ACPI_DESC_TYPE_NAMED) {
  995.                                         return_desc =
  996.                                             acpi_ns_get_attached_object((struct
  997.                                                                          acpi_namespace_node
  998.                                                                          *)
  999.                                                                         return_desc);
  1000.                                         if (!return_desc) {
  1001.                                                 break;
  1002.                                         }
  1003.  
  1004.                                         /*
  1005.                                          * June 2013:
  1006.                                          * buffer_fields/field_units require additional resolution
  1007.                                          */
  1008.                                         switch (return_desc->common.type) {
  1009.                                         case ACPI_TYPE_BUFFER_FIELD:
  1010.                                         case ACPI_TYPE_LOCAL_REGION_FIELD:
  1011.                                         case ACPI_TYPE_LOCAL_BANK_FIELD:
  1012.                                         case ACPI_TYPE_LOCAL_INDEX_FIELD:
  1013.  
  1014.                                                 status =
  1015.                                                     acpi_ex_read_data_from_field
  1016.                                                     (walk_state, return_desc,
  1017.                                                      &temp_desc);
  1018.                                                 if (ACPI_FAILURE(status)) {
  1019.                                                         goto cleanup;
  1020.                                                 }
  1021.  
  1022.                                                 return_desc = temp_desc;
  1023.                                                 break;
  1024.  
  1025.                                         default:
  1026.  
  1027.                                                 /* Add another reference to the object */
  1028.  
  1029.                                                 acpi_ut_add_reference
  1030.                                                     (return_desc);
  1031.                                                 break;
  1032.                                         }
  1033.                                 }
  1034.                                 break;
  1035.  
  1036.                         default:
  1037.  
  1038.                                 ACPI_ERROR((AE_INFO,
  1039.                                             "Unknown class in reference(%p) - 0x%2.2X",
  1040.                                             operand[0],
  1041.                                             operand[0]->reference.class));
  1042.  
  1043.                                 status = AE_TYPE;
  1044.                                 goto cleanup;
  1045.                         }
  1046.                 }
  1047.                 break;
  1048.  
  1049.         default:
  1050.  
  1051.                 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
  1052.                             walk_state->opcode));
  1053.                 status = AE_AML_BAD_OPCODE;
  1054.                 goto cleanup;
  1055.         }
  1056.  
  1057. cleanup:
  1058.  
  1059.         /* Delete return object on error */
  1060.  
  1061.         if (ACPI_FAILURE(status)) {
  1062.                 acpi_ut_remove_reference(return_desc);
  1063.         }
  1064.  
  1065.         /* Save return object on success */
  1066.  
  1067.         else {
  1068.                 walk_state->result_obj = return_desc;
  1069.         }
  1070.  
  1071.         return_ACPI_STATUS(status);
  1072. }
  1073.