/drivers/acpi/acpica/exoparg1.c

http://github.com/mirrors/linux · C · 1064 lines · 561 code · 221 blank · 282 comment · 77 complexity · 17946d3c201593d9966b3dd3a7edcfe1 MD5 · raw file

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