exoparg3.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: exoparg3 - AML execution - opcodes with 3 arguments
  4.  *              $Revision: 3 $
  5.  *
  6.  *****************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 R. Byron Moore
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. #include "acpi.h"
  25. #include "acinterp.h"
  26. #include "acparser.h"
  27. #include "amlcode.h"
  28. #define _COMPONENT          ACPI_EXECUTER
  29.  MODULE_NAME         ("exoparg3")
  30. /*!
  31.  * Naming convention for AML interpreter execution routines.
  32.  *
  33.  * The routines that begin execution of AML opcodes are named with a common
  34.  * convention based upon the number of arguments, the number of target operands,
  35.  * and whether or not a value is returned:
  36.  *
  37.  *      AcpiExOpcode_xA_yT_zR
  38.  *
  39.  * Where:
  40.  *
  41.  * xA - ARGUMENTS:    The number of arguments (input operands) that are
  42.  *                    required for this opcode type (1 through 6 args).
  43.  * yT - TARGETS:      The number of targets (output operands) that are required
  44.  *                    for this opcode type (0, 1, or 2 targets).
  45.  * zR - RETURN VALUE: Indicates whether this opcode type returns a value
  46.  *                    as the function return (0 or 1).
  47.  *
  48.  * The AcpiExOpcode* functions are called via the Dispatcher component with
  49.  * fully resolved operands.
  50. !*/
  51. /*******************************************************************************
  52.  *
  53.  * FUNCTION:    Acpi_ex_opcode_3A_0T_0R
  54.  *
  55.  * PARAMETERS:  Walk_state          - Current walk state
  56.  *
  57.  * RETURN:      Status
  58.  *
  59.  * DESCRIPTION: Execute Triadic operator (3 operands)
  60.  *
  61.  ******************************************************************************/
  62. acpi_status
  63. acpi_ex_opcode_3A_0T_0R (
  64. acpi_walk_state         *walk_state)
  65. {
  66. acpi_operand_object     **operand = &walk_state->operands[0];
  67. ACPI_SIGNAL_FATAL_INFO  *fatal;
  68. acpi_status             status = AE_OK;
  69. FUNCTION_TRACE_STR ("Ex_opcode_3A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
  70. switch (walk_state->opcode) {
  71. case AML_FATAL_OP:          /* Fatal (Fatal_type Fatal_code Fatal_arg)   */
  72. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  73. "Fatal_op: Type %x Code %x Arg %x <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<n",
  74. (u32) operand[0]->integer.value, (u32) operand[1]->integer.value,
  75. (u32) operand[2]->integer.value));
  76. fatal = ACPI_MEM_ALLOCATE (sizeof (ACPI_SIGNAL_FATAL_INFO));
  77. if (fatal) {
  78. fatal->type     = (u32) operand[0]->integer.value;
  79. fatal->code     = (u32) operand[1]->integer.value;
  80. fatal->argument = (u32) operand[2]->integer.value;
  81. }
  82. /*
  83.  * Always signal the OS!
  84.  */
  85. acpi_os_signal (ACPI_SIGNAL_FATAL, fatal);
  86. /* Might return while OS is shutting down, just continue */
  87. ACPI_MEM_FREE (fatal);
  88. break;
  89. default:
  90. REPORT_ERROR (("Acpi_ex_opcode_3A_0T_0R: Unknown opcode %Xn",
  91. walk_state->opcode));
  92. status = AE_AML_BAD_OPCODE;
  93. goto cleanup;
  94. break;
  95. }
  96. cleanup:
  97. return_ACPI_STATUS (status);
  98. }
  99. /*******************************************************************************
  100.  *
  101.  * FUNCTION:    Acpi_ex_opcode_3A_1T_1R
  102.  *
  103.  * PARAMETERS:  Walk_state          - Current walk state
  104.  *
  105.  * RETURN:      Status
  106.  *
  107.  * DESCRIPTION: Execute Triadic operator (3 operands)
  108.  *
  109.  ******************************************************************************/
  110. acpi_status
  111. acpi_ex_opcode_3A_1T_1R (
  112. acpi_walk_state         *walk_state)
  113. {
  114. acpi_operand_object     **operand = &walk_state->operands[0];
  115. acpi_operand_object     *return_desc = NULL;
  116. char                    *buffer;
  117. acpi_status             status = AE_OK;
  118. u32                     index;
  119. u32                     length;
  120. FUNCTION_TRACE_STR ("Ex_opcode_3A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
  121. switch (walk_state->opcode) {
  122. case AML_MID_OP:        /* Mid  (Source[0], Index[1], Length[2], Result[3]) */
  123. /*
  124.  * Create the return object.  The Source operand is guaranteed to be
  125.  * either a String or a Buffer, so just use its type.
  126.  */
  127. return_desc = acpi_ut_create_internal_object (operand[0]->common.type);
  128. if (!return_desc) {
  129. status = AE_NO_MEMORY;
  130. goto cleanup;
  131. }
  132. /* Get the Integer values from the objects */
  133. index = (u32) operand[1]->integer.value;
  134. length = (u32) operand[2]->integer.value;
  135. /*
  136.  * If the index is beyond the length of the String/Buffer, or if the
  137.  * requested length is zero, return a zero-length String/Buffer
  138.  */
  139. if ((index < operand[0]->string.length) &&
  140. (length > 0)) {
  141. /* Truncate request if larger than the actual String/Buffer */
  142. if ((index + length) >
  143. operand[0]->string.length) {
  144. length = operand[0]->string.length - index;
  145. }
  146. /* Allocate a new buffer for the String/Buffer */
  147. buffer = ACPI_MEM_CALLOCATE (length + 1);
  148. if (!buffer) {
  149. return (AE_NO_MEMORY);
  150. }
  151. /* Copy the portion requested */
  152. MEMCPY (buffer, operand[0]->string.pointer + index,
  153. length);
  154. /* Set the length of the new String/Buffer */
  155. return_desc->string.pointer = buffer;
  156. return_desc->string.length = length;
  157. }
  158. break;
  159. default:
  160. REPORT_ERROR (("Acpi_ex_opcode_3A_0T_0R: Unknown opcode %Xn",
  161. walk_state->opcode));
  162. status = AE_AML_BAD_OPCODE;
  163. goto cleanup;
  164. break;
  165. }
  166. /* Store the result in the target */
  167. status = acpi_ex_store (return_desc, operand[3], walk_state);
  168. cleanup:
  169. /* Delete return object on error */
  170. if (ACPI_FAILURE (status)) {
  171. acpi_ut_remove_reference (return_desc);
  172. }
  173. /* Set the return object and exit */
  174. walk_state->result_obj = return_desc;
  175. return_ACPI_STATUS (status);
  176. }