exresolv.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:11k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: exresolv - AML Interpreter object resolution
  4.  *              $Revision: 101 $
  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 "amlcode.h"
  26. #include "acparser.h"
  27. #include "acdispat.h"
  28. #include "acinterp.h"
  29. #include "acnamesp.h"
  30. #include "actables.h"
  31. #include "acevents.h"
  32. #define _COMPONENT          ACPI_EXECUTER
  33.  MODULE_NAME         ("exresolv")
  34. /*******************************************************************************
  35.  *
  36.  * FUNCTION:    Acpi_ex_get_buffer_field_value
  37.  *
  38.  * PARAMETERS:  *Obj_desc           - Pointer to a Buffer_field
  39.  *              *Result_desc        - Pointer to an empty descriptor which will
  40.  *                                    become an Integer with the field's value
  41.  *
  42.  * RETURN:      Status
  43.  *
  44.  * DESCRIPTION: Retrieve the value from a Buffer_field
  45.  *
  46.  ******************************************************************************/
  47. acpi_status
  48. acpi_ex_get_buffer_field_value (
  49. acpi_operand_object     *obj_desc,
  50. acpi_operand_object     *result_desc)
  51. {
  52. acpi_status             status;
  53. u32                     mask;
  54. u8                      *location;
  55. FUNCTION_TRACE ("Ex_get_buffer_field_value");
  56. /*
  57.  * Parameter validation
  58.  */
  59. if (!obj_desc) {
  60. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null field pointern"));
  61. return_ACPI_STATUS (AE_AML_NO_OPERAND);
  62. }
  63. if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
  64. status = acpi_ds_get_buffer_field_arguments (obj_desc);
  65. if (ACPI_FAILURE (status)) {
  66. return_ACPI_STATUS (status);
  67. }
  68. }
  69. if (!obj_desc->buffer_field.buffer_obj) {
  70. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null container pointern"));
  71. return_ACPI_STATUS (AE_AML_INTERNAL);
  72. }
  73. if (ACPI_TYPE_BUFFER != obj_desc->buffer_field.buffer_obj->common.type) {
  74. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - container is not a Buffern"));
  75. return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  76. }
  77. if (!result_desc) {
  78. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null result pointern"));
  79. return_ACPI_STATUS (AE_AML_INTERNAL);
  80. }
  81. /* Field location is (base of buffer) + (byte offset) */
  82. location = obj_desc->buffer_field.buffer_obj->buffer.pointer
  83.  + obj_desc->buffer_field.base_byte_offset;
  84. /*
  85.  * Construct Mask with as many 1 bits as the field width
  86.  *
  87.  * NOTE: Only the bottom 5 bits are valid for a shift operation, so
  88.  *  special care must be taken for any shift greater than 31 bits.
  89.  *
  90.  * TBD: [Unhandled] Fields greater than 32 bits will not work.
  91.  */
  92. if (obj_desc->buffer_field.bit_length < 32) {
  93. mask = ((u32) 1 << obj_desc->buffer_field.bit_length) - (u32) 1;
  94. }
  95. else {
  96. mask = ACPI_UINT32_MAX;
  97. }
  98. result_desc->integer.type = (u8) ACPI_TYPE_INTEGER;
  99. /* Get the 32 bit value at the location */
  100. MOVE_UNALIGNED32_TO_32 (&result_desc->integer.value, location);
  101. /*
  102.  * Shift the 32-bit word containing the field, and mask off the
  103.  * resulting value
  104.  */
  105. result_desc->integer.value =
  106. (result_desc->integer.value >> obj_desc->buffer_field.start_field_bit_offset) & mask;
  107. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  108. "** Read from buffer %p byte %d bit %d width %d addr %p mask %08X val %8.8X%8.8Xn",
  109. obj_desc->buffer_field.buffer_obj->buffer.pointer,
  110. obj_desc->buffer_field.base_byte_offset,
  111. obj_desc->buffer_field.start_field_bit_offset,
  112. obj_desc->buffer_field.bit_length,
  113. location, mask,
  114. HIDWORD(result_desc->integer.value),
  115. LODWORD(result_desc->integer.value)));
  116. return_ACPI_STATUS (AE_OK);
  117. }
  118. /*******************************************************************************
  119.  *
  120.  * FUNCTION:    Acpi_ex_resolve_to_value
  121.  *
  122.  * PARAMETERS:  **Stack_ptr         - Points to entry on Obj_stack, which can
  123.  *                                    be either an (acpi_operand_object *)
  124.  *                                    or an acpi_handle.
  125.  *              Walk_state          - Current method state
  126.  *
  127.  * RETURN:      Status
  128.  *
  129.  * DESCRIPTION: Convert Reference objects to values
  130.  *
  131.  ******************************************************************************/
  132. acpi_status
  133. acpi_ex_resolve_to_value (
  134. acpi_operand_object     **stack_ptr,
  135. acpi_walk_state         *walk_state)
  136. {
  137. acpi_status             status;
  138. FUNCTION_TRACE_PTR ("Ex_resolve_to_value", stack_ptr);
  139. if (!stack_ptr || !*stack_ptr) {
  140. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null pointern"));
  141. return_ACPI_STATUS (AE_AML_NO_OPERAND);
  142. }
  143. /*
  144.  * The entity pointed to by the Stack_ptr can be either
  145.  * 1) A valid acpi_operand_object, or
  146.  * 2) A acpi_namespace_node (Named_obj)
  147.  */
  148. if (VALID_DESCRIPTOR_TYPE (*stack_ptr, ACPI_DESC_TYPE_INTERNAL)) {
  149. status = acpi_ex_resolve_object_to_value (stack_ptr, walk_state);
  150. if (ACPI_FAILURE (status)) {
  151. return_ACPI_STATUS (status);
  152. }
  153. }
  154. /*
  155.  * Object on the stack may have changed if Acpi_ex_resolve_object_to_value()
  156.  * was called (i.e., we can't use an _else_ here.)
  157.  */
  158. if (VALID_DESCRIPTOR_TYPE (*stack_ptr, ACPI_DESC_TYPE_NAMED)) {
  159. status = acpi_ex_resolve_node_to_value ((acpi_namespace_node **) stack_ptr,
  160.   walk_state);
  161. if (ACPI_FAILURE (status)) {
  162. return_ACPI_STATUS (status);
  163. }
  164. }
  165. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Resolved object %pn", *stack_ptr));
  166. return_ACPI_STATUS (AE_OK);
  167. }
  168. /*******************************************************************************
  169.  *
  170.  * FUNCTION:    Acpi_ex_resolve_object_to_value
  171.  *
  172.  * PARAMETERS:  Stack_ptr       - Pointer to a stack location that contains a
  173.  *                                ptr to an internal object.
  174.  *              Walk_state      - Current method state
  175.  *
  176.  * RETURN:      Status
  177.  *
  178.  * DESCRIPTION: Retrieve the value from an internal object.  The Reference type
  179.  *              uses the associated AML opcode to determine the value.
  180.  *
  181.  ******************************************************************************/
  182. acpi_status
  183. acpi_ex_resolve_object_to_value (
  184. acpi_operand_object     **stack_ptr,
  185. acpi_walk_state         *walk_state)
  186. {
  187. acpi_status             status = AE_OK;
  188. acpi_operand_object     *stack_desc;
  189. void                    *temp_node;
  190. acpi_operand_object     *obj_desc;
  191. u16                     opcode;
  192. FUNCTION_TRACE ("Ex_resolve_object_to_value");
  193. stack_desc = *stack_ptr;
  194. /* This is an acpi_operand_object  */
  195. switch (stack_desc->common.type) {
  196. case INTERNAL_TYPE_REFERENCE:
  197. opcode = stack_desc->reference.opcode;
  198. switch (opcode) {
  199. case AML_NAME_OP:
  200. /*
  201.  * Convert indirect name ptr to a direct name ptr.
  202.  * Then, Acpi_ex_resolve_node_to_value can be used to get the value
  203.  */
  204. temp_node = stack_desc->reference.object;
  205. /* Delete the Reference Object */
  206. acpi_ut_remove_reference (stack_desc);
  207. /* Put direct name pointer onto stack and exit */
  208. (*stack_ptr) = temp_node;
  209. break;
  210. case AML_LOCAL_OP:
  211. case AML_ARG_OP:
  212. /*
  213.  * Get the local from the method's state info
  214.  * Note: this increments the local's object reference count
  215.  */
  216. status = acpi_ds_method_data_get_value (opcode,
  217.   stack_desc->reference.offset, walk_state, &obj_desc);
  218. if (ACPI_FAILURE (status)) {
  219. return_ACPI_STATUS (status);
  220. }
  221. /*
  222.  * Now we can delete the original Reference Object and
  223.  * replace it with the resolve value
  224.  */
  225. acpi_ut_remove_reference (stack_desc);
  226. *stack_ptr = obj_desc;
  227. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "[Arg/Local %d] Value_obj is %pn",
  228. stack_desc->reference.offset, obj_desc));
  229. break;
  230. /*
  231.  * For constants, we must change the reference/constant object
  232.  * to a real integer object
  233.  */
  234. case AML_ZERO_OP:
  235. case AML_ONE_OP:
  236. case AML_ONES_OP:
  237. case AML_REVISION_OP:
  238. /* Create a new integer object */
  239. obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
  240. if (!obj_desc) {
  241. return_ACPI_STATUS (AE_NO_MEMORY);
  242. }
  243. switch (opcode) {
  244. case AML_ZERO_OP:
  245. obj_desc->integer.value = 0;
  246. break;
  247. case AML_ONE_OP:
  248. obj_desc->integer.value = 1;
  249. break;
  250. case AML_ONES_OP:
  251. obj_desc->integer.value = ACPI_INTEGER_MAX;
  252. /* Truncate value if we are executing from a 32-bit ACPI table */
  253. acpi_ex_truncate_for32bit_table (obj_desc, walk_state);
  254. break;
  255. case AML_REVISION_OP:
  256. obj_desc->integer.value = ACPI_CA_SUPPORT_LEVEL;
  257. break;
  258. }
  259. /*
  260.  * Remove a reference from the original reference object
  261.  * and put the new object in its place
  262.  */
  263. acpi_ut_remove_reference (stack_desc);
  264. *stack_ptr = obj_desc;
  265. break;
  266. case AML_INDEX_OP:
  267. switch (stack_desc->reference.target_type) {
  268. case ACPI_TYPE_BUFFER_FIELD:
  269. /* Just return - leave the Reference on the stack */
  270. break;
  271. case ACPI_TYPE_PACKAGE:
  272. obj_desc = *stack_desc->reference.where;
  273. if (obj_desc) {
  274. /*
  275.  * Valid obj descriptor, copy pointer to return value
  276.  * (i.e., dereference the package index)
  277.  * Delete the ref object, increment the returned object
  278.  */
  279. acpi_ut_remove_reference (stack_desc);
  280. acpi_ut_add_reference (obj_desc);
  281. *stack_ptr = obj_desc;
  282. }
  283. else {
  284. /*
  285.  * A NULL object descriptor means an unitialized element of
  286.  * the package, can't dereference it
  287.  */
  288. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  289. "Attempt to deref an Index to NULL pkg element Idx=%pn",
  290. stack_desc));
  291. status = AE_AML_UNINITIALIZED_ELEMENT;
  292. }
  293. break;
  294. default:
  295. /* Invalid reference object */
  296. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  297. "Unknown Target_type %X in Index/Reference obj %pn",
  298. stack_desc->reference.target_type, stack_desc));
  299. status = AE_AML_INTERNAL;
  300. break;
  301. }
  302. break;
  303. case AML_DEBUG_OP:
  304. /* Just leave the object as-is */
  305. break;
  306. default:
  307. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference object subtype %02X in %pn",
  308. opcode, stack_desc));
  309. status = AE_AML_INTERNAL;
  310. break;
  311. }   /* switch (Opcode) */
  312. break; /* case INTERNAL_TYPE_REFERENCE */
  313. case ACPI_TYPE_BUFFER_FIELD:
  314. obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_ANY);
  315. if (!obj_desc) {
  316. return_ACPI_STATUS (AE_NO_MEMORY);
  317. }
  318. status = acpi_ex_get_buffer_field_value (stack_desc, obj_desc);
  319. if (ACPI_FAILURE (status)) {
  320. acpi_ut_remove_reference (obj_desc);
  321. obj_desc = NULL;
  322. }
  323. *stack_ptr = (void *) obj_desc;
  324. break;
  325. case INTERNAL_TYPE_BANK_FIELD:
  326. obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_ANY);
  327. if (!obj_desc) {
  328. return_ACPI_STATUS (AE_NO_MEMORY);
  329. }
  330. /* TBD: WRONG! */
  331. status = acpi_ex_get_buffer_field_value (stack_desc, obj_desc);
  332. if (ACPI_FAILURE (status)) {
  333. acpi_ut_remove_reference (obj_desc);
  334. obj_desc = NULL;
  335. }
  336. *stack_ptr = (void *) obj_desc;
  337. break;
  338. /* TBD: [Future] - may need to handle Index_field, and Def_field someday */
  339. default:
  340. break;
  341. }   /* switch (Stack_desc->Common.Type) */
  342. return_ACPI_STATUS (status);
  343. }