exoparg1.c 27 KB

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