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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: exoparg1 - AML execution - opcodes with 1 argument
  4.  *              $Revision: 120 $
  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 "acparser.h"
  26. #include "acdispat.h"
  27. #include "acinterp.h"
  28. #include "amlcode.h"
  29. #include "acnamesp.h"
  30. #define _COMPONENT          ACPI_EXECUTER
  31.  MODULE_NAME         ("exoparg1")
  32. /*!
  33.  * Naming convention for AML interpreter execution routines.
  34.  *
  35.  * The routines that begin execution of AML opcodes are named with a common
  36.  * convention based upon the number of arguments, the number of target operands,
  37.  * and whether or not a value is returned:
  38.  *
  39.  *      AcpiExOpcode_xA_yT_zR
  40.  *
  41.  * Where:
  42.  *
  43.  * xA - ARGUMENTS:    The number of arguments (input operands) that are
  44.  *                    required for this opcode type (1 through 6 args).
  45.  * yT - TARGETS:      The number of targets (output operands) that are required
  46.  *                    for this opcode type (0, 1, or 2 targets).
  47.  * zR - RETURN VALUE: Indicates whether this opcode type returns a value
  48.  *                    as the function return (0 or 1).
  49.  *
  50.  * The AcpiExOpcode* functions are called via the Dispatcher component with
  51.  * fully resolved operands.
  52. !*/
  53. /*******************************************************************************
  54.  *
  55.  * FUNCTION:    Acpi_ex_opcode_1A_0T_0R
  56.  *
  57.  * PARAMETERS:  Walk_state          - Current state (contains AML opcode)
  58.  *
  59.  * RETURN:      Status
  60.  *
  61.  * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
  62.  *              object stack
  63.  *
  64.  ******************************************************************************/
  65. acpi_status
  66. acpi_ex_opcode_1A_0T_0R (
  67. acpi_walk_state         *walk_state)
  68. {
  69. acpi_operand_object     **operand = &walk_state->operands[0];
  70. acpi_status             status = AE_OK;
  71. FUNCTION_TRACE_STR ("Ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
  72. /* Examine the opcode */
  73. switch (walk_state->opcode) {
  74. case AML_RELEASE_OP:    /*  Release (Mutex_object) */
  75. status = acpi_ex_release_mutex (operand[0], walk_state);
  76. break;
  77. case AML_RESET_OP:      /*  Reset (Event_object) */
  78. status = acpi_ex_system_reset_event (operand[0]);
  79. break;
  80. case AML_SIGNAL_OP:     /*  Signal (Event_object) */
  81. status = acpi_ex_system_signal_event (operand[0]);
  82. break;
  83. case AML_SLEEP_OP:      /*  Sleep (Msec_time) */
  84. acpi_ex_system_do_suspend ((u32) operand[0]->integer.value);
  85. break;
  86. case AML_STALL_OP:      /*  Stall (Usec_time) */
  87. acpi_ex_system_do_stall ((u32) operand[0]->integer.value);
  88. break;
  89. case AML_UNLOAD_OP:     /*  Unload (Handle) */
  90. status = acpi_ex_unload_table (operand[0]);
  91. break;
  92. default:                /*  Unknown opcode  */
  93. REPORT_ERROR (("Acpi_ex_opcode_1A_0T_0R: Unknown opcode %Xn",
  94. walk_state->opcode));
  95. status = AE_AML_BAD_OPCODE;
  96. break;
  97. }
  98. return_ACPI_STATUS (status);
  99. }
  100. /*******************************************************************************
  101.  *
  102.  * FUNCTION:    Acpi_ex_opcode_1A_1T_0R
  103.  *
  104.  * PARAMETERS:  Walk_state          - Current state (contains AML opcode)
  105.  *
  106.  * RETURN:      Status
  107.  *
  108.  * DESCRIPTION: Execute opcode with one argument, one target, and no
  109.  *              return value.
  110.  *
  111.  ******************************************************************************/
  112. acpi_status
  113. acpi_ex_opcode_1A_1T_0R (
  114. acpi_walk_state         *walk_state)
  115. {
  116. acpi_status             status = AE_OK;
  117. acpi_operand_object     **operand = &walk_state->operands[0];
  118. FUNCTION_TRACE_STR ("Ex_opcode_1A_1T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
  119. switch (walk_state->opcode) {
  120. case AML_LOAD_OP:
  121. status = acpi_ex_load_op (operand[0], operand[1]);
  122. break;
  123. default:                        /* Unknown opcode */
  124. REPORT_ERROR (("Acpi_ex_opcode_1A_1T_0R: Unknown opcode %Xn",
  125. walk_state->opcode));
  126. status = AE_AML_BAD_OPCODE;
  127. goto cleanup;
  128. }
  129. cleanup:
  130. return_ACPI_STATUS (status);
  131. }
  132. /*******************************************************************************
  133.  *
  134.  * FUNCTION:    Acpi_ex_opcode_1A_1T_1R
  135.  *
  136.  * PARAMETERS:  Walk_state          - Current state (contains AML opcode)
  137.  *
  138.  * RETURN:      Status
  139.  *
  140.  * DESCRIPTION: Execute opcode with one argument, one target, and a
  141.  *              return value.
  142.  *
  143.  ******************************************************************************/
  144. acpi_status
  145. acpi_ex_opcode_1A_1T_1R (
  146. acpi_walk_state         *walk_state)
  147. {
  148. acpi_status             status = AE_OK;
  149. acpi_operand_object     **operand = &walk_state->operands[0];
  150. acpi_operand_object     *return_desc = NULL;
  151. acpi_operand_object     *return_desc2 = NULL;
  152. u32                     temp32;
  153. u32                     i;
  154. u32                     j;
  155. acpi_integer            digit;
  156. FUNCTION_TRACE_STR ("Ex_opcode_1A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
  157. /* Create a return object of type Integer for most opcodes */
  158. switch (walk_state->opcode) {
  159. case AML_BIT_NOT_OP:
  160. case AML_FIND_SET_LEFT_BIT_OP:
  161. case AML_FIND_SET_RIGHT_BIT_OP:
  162. case AML_FROM_BCD_OP:
  163. case AML_TO_BCD_OP:
  164. case AML_COND_REF_OF_OP:
  165. return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
  166. if (!return_desc) {
  167. status = AE_NO_MEMORY;
  168. goto cleanup;
  169. }
  170. break;
  171. }
  172. switch (walk_state->opcode) {
  173. case AML_BIT_NOT_OP:            /* Not (Operand, Result)  */
  174. return_desc->integer.value = ~operand[0]->integer.value;
  175. break;
  176. case AML_FIND_SET_LEFT_BIT_OP:  /* Find_set_left_bit (Operand, Result) */
  177. return_desc->integer.value = operand[0]->integer.value;
  178. /*
  179.  * Acpi specification describes Integer type as a little
  180.  * endian unsigned value, so this boundary condition is valid.
  181.  */
  182. for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
  183. return_desc->integer.value >>= 1;
  184. }
  185. return_desc->integer.value = temp32;
  186. break;
  187. case AML_FIND_SET_RIGHT_BIT_OP: /* Find_set_right_bit (Operand, Result) */
  188. return_desc->integer.value = operand[0]->integer.value;
  189. /*
  190.  * The Acpi specification describes Integer type as a little
  191.  * endian unsigned value, so this boundary condition is valid.
  192.  */
  193. for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
  194. return_desc->integer.value <<= 1;
  195. }
  196. /* Since the bit position is one-based, subtract from 33 (65) */
  197. return_desc->integer.value = temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - temp32;
  198. break;
  199. case AML_FROM_BCD_OP:           /* From_bcd (BCDValue, Result) */
  200. /*
  201.  * The 64-bit ACPI integer can hold 16 4-bit BCD integers
  202.  */
  203. return_desc->integer.value = 0;
  204. for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) {
  205. /* Get one BCD digit */
  206. digit = (acpi_integer) ((operand[0]->integer.value >> (i * 4)) & 0xF);
  207. /* Check the range of the digit */
  208. if (digit > 9) {
  209. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD digit too large: %dn",
  210. (u32) digit));
  211. status = AE_AML_NUMERIC_OVERFLOW;
  212. goto cleanup;
  213. }
  214. if (digit > 0) {
  215. /* Sum into the result with the appropriate power of 10 */
  216. for (j = 0; j < i; j++) {
  217. digit *= 10;
  218. }
  219. return_desc->integer.value += digit;
  220. }
  221. }
  222. break;
  223. case AML_TO_BCD_OP:             /* To_bcd (Operand, Result) */
  224. if (operand[0]->integer.value > ACPI_MAX_BCD_VALUE) {
  225. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD overflow: %8.8X%8.8Xn",
  226. HIDWORD(operand[0]->integer.value), LODWORD(operand[0]->integer.value)));
  227. status = AE_AML_NUMERIC_OVERFLOW;
  228. goto cleanup;
  229. }
  230. return_desc->integer.value = 0;
  231. for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) {
  232. /* Divide by nth factor of 10 */
  233. temp32 = 0;
  234. digit = operand[0]->integer.value;
  235. for (j = 0; j < i; j++) {
  236. acpi_ut_short_divide (&digit, 10, &digit, &temp32);
  237. }
  238. /* Create the BCD digit from the remainder above */
  239. if (digit > 0) {
  240. return_desc->integer.value += (temp32 << (i * 4));
  241. }
  242. }
  243. break;
  244. case AML_COND_REF_OF_OP:        /* Cond_ref_of (Source_object, Result) */
  245. /*
  246.  * This op is a little strange because the internal return value is
  247.  * different than the return value stored in the result descriptor
  248.  * (There are really two return values)
  249.  */
  250. if ((acpi_namespace_node *) operand[0] == acpi_gbl_root_node) {
  251. /*
  252.  * This means that the object does not exist in the namespace,
  253.  * return FALSE
  254.  */
  255. return_desc->integer.value = 0;
  256. /*
  257.  * Must delete the result descriptor since there is no reference
  258.  * being returned
  259.  */
  260. acpi_ut_remove_reference (operand[1]);
  261. goto cleanup;
  262. }
  263. /* Get the object reference and store it */
  264. status = acpi_ex_get_object_reference (operand[0], &return_desc2, walk_state);
  265. if (ACPI_FAILURE (status)) {
  266. goto cleanup;
  267. }
  268. status = acpi_ex_store (return_desc2, operand[1], walk_state);
  269. /* The object exists in the namespace, return TRUE */
  270. return_desc->integer.value = ACPI_INTEGER_MAX;
  271. goto cleanup;
  272. break;
  273. case AML_STORE_OP:              /* Store (Source, Target) */
  274. /*
  275.  * A store operand is typically a number, string, buffer or lvalue
  276.  * Be careful about deleting the source object,
  277.  * since the object itself may have been stored.
  278.  */
  279. status = acpi_ex_store (operand[0], operand[1], walk_state);
  280. if (ACPI_FAILURE (status)) {
  281. return_ACPI_STATUS (status);
  282. }
  283. /*
  284.  * Normally, we would remove a reference on the Operand[0] parameter;
  285.  * But since it is being used as the internal return object
  286.  * (meaning we would normally increment it), the two cancel out,
  287.  * and we simply don't do anything.
  288.  */
  289. walk_state->result_obj = operand[0];
  290. walk_state->operands[0] = NULL; /* Prevent deletion */
  291. return_ACPI_STATUS (status);
  292. break;
  293. /*
  294.  * ACPI 2.0 Opcodes
  295.  */
  296. case AML_COPY_OP:               /* Copy (Source, Target) */
  297. status = AE_NOT_IMPLEMENTED;
  298. goto cleanup;
  299. break;
  300. case AML_TO_DECSTRING_OP:       /* To_decimal_string (Data, Result) */
  301. status = acpi_ex_convert_to_string (operand[0], &return_desc, 10, ACPI_UINT32_MAX, walk_state);
  302. break;
  303. case AML_TO_HEXSTRING_OP:       /* To_hex_string (Data, Result) */
  304. status = acpi_ex_convert_to_string (operand[0], &return_desc, 16, ACPI_UINT32_MAX, walk_state);
  305. break;
  306. case AML_TO_BUFFER_OP:          /* To_buffer (Data, Result) */
  307. status = acpi_ex_convert_to_buffer (operand[0], &return_desc, walk_state);
  308. break;
  309. case AML_TO_INTEGER_OP:         /* To_integer (Data, Result) */
  310. status = acpi_ex_convert_to_integer (operand[0], &return_desc, walk_state);
  311. break;
  312. /*
  313.  * These are two obsolete opcodes
  314.  */
  315. case AML_SHIFT_LEFT_BIT_OP:     /*  Shift_left_bit (Source, Bit_num) */
  316. case AML_SHIFT_RIGHT_BIT_OP:    /*  Shift_right_bit (Source, Bit_num) */
  317. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s is obsolete and not implementedn",
  318.   acpi_ps_get_opcode_name (walk_state->opcode)));
  319. status = AE_SUPPORT;
  320. goto cleanup;
  321. break;
  322. default:                        /* Unknown opcode */
  323. REPORT_ERROR (("Acpi_ex_opcode_1A_1T_1R: Unknown opcode %Xn",
  324. walk_state->opcode));
  325. status = AE_AML_BAD_OPCODE;
  326. goto cleanup;
  327. }
  328. /*
  329.  * Store the return value computed above into the target object
  330.  */
  331. status = acpi_ex_store (return_desc, operand[1], walk_state);
  332. cleanup:
  333. walk_state->result_obj = return_desc;
  334. /* Delete return object on error */
  335. if (ACPI_FAILURE (status)) {
  336. acpi_ut_remove_reference (return_desc);
  337. }
  338. return_ACPI_STATUS (status);
  339. }
  340. /*******************************************************************************
  341.  *
  342.  * FUNCTION:    Acpi_ex_opcode_1A_0T_1R
  343.  *
  344.  * PARAMETERS:  Walk_state          - Current state (contains AML opcode)
  345.  *
  346.  * RETURN:      Status
  347.  *
  348.  * DESCRIPTION: Execute opcode with one argument, no target, and a return value
  349.  *
  350.  ******************************************************************************/
  351. acpi_status
  352. acpi_ex_opcode_1A_0T_1R (
  353. acpi_walk_state         *walk_state)
  354. {
  355. acpi_operand_object     **operand = &walk_state->operands[0];
  356. acpi_operand_object     *temp_desc;
  357. acpi_operand_object     *return_desc = NULL;
  358. acpi_status             status = AE_OK;
  359. u32                     type;
  360. acpi_integer            value;
  361. FUNCTION_TRACE_STR ("Ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
  362. /* Get the operand and decode the opcode */
  363. switch (walk_state->opcode) {
  364. case AML_LNOT_OP:               /* LNot (Operand) */
  365. return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
  366. if (!return_desc) {
  367. status = AE_NO_MEMORY;
  368. goto cleanup;
  369. }
  370. return_desc->integer.value = !operand[0]->integer.value;
  371. break;
  372. case AML_DECREMENT_OP:          /* Decrement (Operand)  */
  373. case AML_INCREMENT_OP:          /* Increment (Operand)  */
  374. /*
  375.  * Since we are expecting a Reference operand, it
  376.  * can be either a Node or an internal object.
  377.  */
  378. return_desc = operand[0];
  379. if (VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_INTERNAL)) {
  380. /* Internal reference object - prevent deletion */
  381. acpi_ut_add_reference (return_desc);
  382. }
  383. /*
  384.  * Convert the Return_desc Reference to a Number
  385.  * (This removes a reference on the Return_desc object)
  386.  */
  387. status = acpi_ex_resolve_operands (AML_LNOT_OP, &return_desc, walk_state);
  388. if (ACPI_FAILURE (status)) {
  389. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %sn",
  390. acpi_ps_get_opcode_name (walk_state->opcode), acpi_format_exception(status)));
  391. goto cleanup;
  392. }
  393. /*
  394.  * Return_desc is now guaranteed to be an Integer object
  395.  * Do the actual increment or decrement
  396.  */
  397. if (AML_INCREMENT_OP == walk_state->opcode) {
  398. return_desc->integer.value++;
  399. }
  400. else {
  401. return_desc->integer.value--;
  402. }
  403. /* Store the result back in the original descriptor */
  404. status = acpi_ex_store (return_desc, operand[0], walk_state);
  405. break;
  406. case AML_TYPE_OP:               /* Object_type (Source_object) */
  407. if (INTERNAL_TYPE_REFERENCE == operand[0]->common.type) {
  408. /*
  409.  * Not a Name -- an indirect name pointer would have
  410.  * been converted to a direct name pointer in Resolve_operands
  411.  */
  412. switch (operand[0]->reference.opcode) {
  413. case AML_ZERO_OP:
  414. case AML_ONE_OP:
  415. case AML_ONES_OP:
  416. case AML_REVISION_OP:
  417. /* Constants are of type Integer */
  418. type = ACPI_TYPE_INTEGER;
  419. break;
  420. case AML_DEBUG_OP:
  421. /* Per 1.0b spec, Debug object is of type "Debug_object" */
  422. type = ACPI_TYPE_DEBUG_OBJECT;
  423. break;
  424. case AML_INDEX_OP:
  425. /* Get the type of this reference (index into another object) */
  426. type = operand[0]->reference.target_type;
  427. if (type == ACPI_TYPE_PACKAGE) {
  428. /*
  429.  * The main object is a package, we want to get the type
  430.  * of the individual package element that is referenced by
  431.  * the index.
  432.  */
  433. type = (*(operand[0]->reference.where))->common.type;
  434. }
  435. break;
  436. case AML_LOCAL_OP:
  437. case AML_ARG_OP:
  438. type = acpi_ds_method_data_get_type (operand[0]->reference.opcode,
  439.   operand[0]->reference.offset, walk_state);
  440. break;
  441. default:
  442. REPORT_ERROR (("Acpi_ex_opcode_1A_0T_1R/Type_op: Internal error - Unknown Reference subtype %Xn",
  443. operand[0]->reference.opcode));
  444. status = AE_AML_INTERNAL;
  445. goto cleanup;
  446. }
  447. }
  448. else {
  449. /*
  450.  * It's not a Reference, so it must be a direct name pointer.
  451.  */
  452. type = acpi_ns_get_type ((acpi_namespace_node *) operand[0]);
  453. /* Convert internal types to external types */
  454. switch (type) {
  455. case INTERNAL_TYPE_REGION_FIELD:
  456. case INTERNAL_TYPE_BANK_FIELD:
  457. case INTERNAL_TYPE_INDEX_FIELD:
  458. type = ACPI_TYPE_FIELD_UNIT;
  459. }
  460. }
  461. /* Allocate a descriptor to hold the type. */
  462. return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
  463. if (!return_desc) {
  464. status = AE_NO_MEMORY;
  465. goto cleanup;
  466. }
  467. return_desc->integer.value = type;
  468. break;
  469. case AML_SIZE_OF_OP:            /* Size_of (Source_object) */
  470. temp_desc = operand[0];
  471. if (VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_NAMED)) {
  472. temp_desc = acpi_ns_get_attached_object ((acpi_namespace_node *) operand[0]);
  473. }
  474. if (!temp_desc) {
  475. value = 0;
  476. }
  477. else {
  478. switch (temp_desc->common.type) {
  479. case ACPI_TYPE_BUFFER:
  480. value = temp_desc->buffer.length;
  481. break;
  482. case ACPI_TYPE_STRING:
  483. value = temp_desc->string.length;
  484. break;
  485. case ACPI_TYPE_PACKAGE:
  486. value = temp_desc->package.count;
  487. break;
  488. case INTERNAL_TYPE_REFERENCE:
  489. /* TBD: this must be a reference to a buf/str/pkg?? */
  490. value = 4;
  491. break;
  492. default:
  493. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Not Buf/Str/Pkg - found type %Xn",
  494. temp_desc->common.type));
  495. status = AE_AML_OPERAND_TYPE;
  496. goto cleanup;
  497. }
  498. }
  499. /*
  500.  * Now that we have the size of the object, create a result
  501.  * object to hold the value
  502.  */
  503. return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
  504. if (!return_desc) {
  505. status = AE_NO_MEMORY;
  506. goto cleanup;
  507. }
  508. return_desc->integer.value = value;
  509. break;
  510. case AML_REF_OF_OP:             /* Ref_of (Source_object) */
  511. status = acpi_ex_get_object_reference (operand[0], &return_desc, walk_state);
  512. if (ACPI_FAILURE (status)) {
  513. goto cleanup;
  514. }
  515. break;
  516. case AML_DEREF_OF_OP:           /* Deref_of (Obj_reference) */
  517. /* Check for a method local or argument */
  518. if (!VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_NAMED)) {
  519. /*
  520.  * Must resolve/dereference the local/arg reference first
  521.  */
  522. switch (operand[0]->reference.opcode) {
  523. /* Set Operand[0] to the value of the local/arg */
  524. case AML_LOCAL_OP:
  525. case AML_ARG_OP:
  526. acpi_ds_method_data_get_value (operand[0]->reference.opcode,
  527. operand[0]->reference.offset, walk_state, &temp_desc);
  528. /*
  529.  * Delete our reference to the input object and
  530.  * point to the object just retrieved
  531.  */
  532. acpi_ut_remove_reference (operand[0]);
  533. operand[0] = temp_desc;
  534. break;
  535. default:
  536. /* Index op - handled below */
  537. break;
  538. }
  539. }
  540. /* Operand[0] may have changed from the code above */
  541. if (VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_NAMED)) {
  542. /* Get the actual object from the Node (This is the dereference) */
  543. return_desc = ((acpi_namespace_node *) operand[0])->object;
  544. /* Returning a pointer to the object, add another reference! */
  545. acpi_ut_add_reference (return_desc);
  546. }
  547. else {
  548. /*
  549.  * This must be a reference object produced by the Index
  550.  * ASL operation -- check internal opcode
  551.  */
  552. if ((operand[0]->reference.opcode != AML_INDEX_OP) &&
  553. (operand[0]->reference.opcode != AML_REF_OF_OP)) {
  554. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode in ref(%p) - %Xn",
  555. operand[0], operand[0]->reference.opcode));
  556. status = AE_TYPE;
  557. goto cleanup;
  558. }
  559. switch (operand[0]->reference.opcode) {
  560. case AML_INDEX_OP:
  561. /*
  562.  * Supported target types for the Index operator are
  563.  * 1) A Buffer
  564.  * 2) A Package
  565.  */
  566. if (operand[0]->reference.target_type == ACPI_TYPE_BUFFER_FIELD) {
  567. /*
  568.  * The target is a buffer, we must create a new object that
  569.  * contains one element of the buffer, the element pointed
  570.  * to by the index.
  571.  *
  572.  * NOTE: index into a buffer is NOT a pointer to a
  573.  * sub-buffer of the main buffer, it is only a pointer to a
  574.  * single element (byte) of the buffer!
  575.  */
  576. return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
  577. if (!return_desc) {
  578. status = AE_NO_MEMORY;
  579. goto cleanup;
  580. }
  581. temp_desc = operand[0]->reference.object;
  582. return_desc->integer.value =
  583. temp_desc->buffer.pointer[operand[0]->reference.offset];
  584. /* TBD: [Investigate] (see below) Don't add an additional
  585.  * ref!
  586.  */
  587. }
  588. else if (operand[0]->reference.target_type == ACPI_TYPE_PACKAGE) {
  589. /*
  590.  * The target is a package, we want to return the referenced
  591.  * element of the package.  We must add another reference to
  592.  * this object, however.
  593.  */
  594. return_desc = *(operand[0]->reference.where);
  595. if (!return_desc) {
  596. /*
  597.  * We can't return a NULL dereferenced value.  This is
  598.  * an uninitialized package element and is thus a
  599.  * severe error.
  600.  */
  601. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "NULL package element obj %pn",
  602. operand[0]));
  603. status = AE_AML_UNINITIALIZED_ELEMENT;
  604. goto cleanup;
  605. }
  606. acpi_ut_add_reference (return_desc);
  607. }
  608. else {
  609. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Target_type %X in obj %pn",
  610. operand[0]->reference.target_type, operand[0]));
  611. status = AE_AML_OPERAND_TYPE;
  612. goto cleanup;
  613. }
  614. break;
  615. case AML_REF_OF_OP:
  616. return_desc = operand[0]->reference.object;
  617. /* Add another reference to the object! */
  618. acpi_ut_add_reference (return_desc);
  619. break;
  620. }
  621. }
  622. break;
  623. default:
  624. REPORT_ERROR (("Acpi_ex_opcode_1A_0T_1R: Unknown opcode %Xn",
  625. walk_state->opcode));
  626. status = AE_AML_BAD_OPCODE;
  627. goto cleanup;
  628. }
  629. cleanup:
  630. /* Delete return object on error */
  631. if (ACPI_FAILURE (status)) {
  632. acpi_ut_remove_reference (return_desc);
  633. }
  634. walk_state->result_obj = return_desc;
  635. return_ACPI_STATUS (status);
  636. }