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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: exstore - AML Interpreter object store support
  4.  *              $Revision: 150 $
  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. #include "actables.h"
  31. #define _COMPONENT          ACPI_EXECUTER
  32.  MODULE_NAME         ("exstore")
  33. /*******************************************************************************
  34.  *
  35.  * FUNCTION:    Acpi_ex_store
  36.  *
  37.  * PARAMETERS:  *Source_desc        - Value to be stored
  38.  *              *Dest_desc          - Where to store it.  Must be an NS node
  39.  *                                    or an acpi_operand_object of type
  40.  *                                    Reference;
  41.  *
  42.  * RETURN:      Status
  43.  *
  44.  * DESCRIPTION: Store the value described by Source_desc into the location
  45.  *              described by Dest_desc. Called by various interpreter
  46.  *              functions to store the result of an operation into
  47.  *              the destination operand.
  48.  *
  49.  ******************************************************************************/
  50. acpi_status
  51. acpi_ex_store (
  52. acpi_operand_object     *source_desc,
  53. acpi_operand_object     *dest_desc,
  54. acpi_walk_state         *walk_state)
  55. {
  56. acpi_status             status = AE_OK;
  57. acpi_operand_object     *ref_desc = dest_desc;
  58. FUNCTION_TRACE_PTR ("Ex_store", dest_desc);
  59. /* Validate parameters */
  60. if (!source_desc || !dest_desc) {
  61. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null pointern"));
  62. return_ACPI_STATUS (AE_AML_NO_OPERAND);
  63. }
  64. /* Dest_desc can be either a namespace node or an ACPI object */
  65. if (VALID_DESCRIPTOR_TYPE (dest_desc, ACPI_DESC_TYPE_NAMED)) {
  66. /*
  67.  * Dest is a namespace node,
  68.  * Storing an object into a Name "container"
  69.  */
  70. status = acpi_ex_store_object_to_node (source_desc,
  71.  (acpi_namespace_node *) dest_desc, walk_state);
  72. /* All done, that's it */
  73. return_ACPI_STATUS (status);
  74. }
  75. /* Destination object must be an object of type Reference */
  76. if (dest_desc->common.type != INTERNAL_TYPE_REFERENCE) {
  77. /* Destination is not an Reference */
  78. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  79. "Destination is not a Reference_obj [%p]n", dest_desc));
  80. DUMP_STACK_ENTRY (source_desc);
  81. DUMP_STACK_ENTRY (dest_desc);
  82. DUMP_OPERANDS (&dest_desc, IMODE_EXECUTE, "Ex_store",
  83.   2, "Target is not a Reference_obj");
  84. return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  85. }
  86. /*
  87.  * Examine the Reference opcode.  These cases are handled:
  88.  *
  89.  * 1) Store to Name (Change the object associated with a name)
  90.  * 2) Store to an indexed area of a Buffer or Package
  91.  * 3) Store to a Method Local or Arg
  92.  * 4) Store to the debug object
  93.  * 5) Store to a constant -- a noop
  94.  */
  95. switch (ref_desc->reference.opcode) {
  96. case AML_NAME_OP:
  97. /* Storing an object into a Name "container" */
  98. status = acpi_ex_store_object_to_node (source_desc, ref_desc->reference.object,
  99.   walk_state);
  100. break;
  101. case AML_INDEX_OP:
  102. /* Storing to an Index (pointer into a packager or buffer) */
  103. status = acpi_ex_store_object_to_index (source_desc, ref_desc, walk_state);
  104. break;
  105. case AML_LOCAL_OP:
  106. case AML_ARG_OP:
  107. /* Store to a method local/arg  */
  108. status = acpi_ds_store_object_to_local (ref_desc->reference.opcode,
  109.   ref_desc->reference.offset, source_desc, walk_state);
  110. break;
  111. case AML_DEBUG_OP:
  112. /*
  113.  * Storing to the Debug object causes the value stored to be
  114.  * displayed and otherwise has no effect -- see ACPI Specification
  115.  */
  116. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Write to Debug Object: ****:nn"));
  117. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %s: ",
  118.   acpi_ut_get_type_name (source_desc->common.type)));
  119. switch (source_desc->common.type) {
  120. case ACPI_TYPE_INTEGER:
  121. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%X (%d)n",
  122. (u32) source_desc->integer.value, (u32) source_desc->integer.value));
  123. break;
  124. case ACPI_TYPE_BUFFER:
  125. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Length 0x%Xn",
  126. (u32) source_desc->buffer.length));
  127. break;
  128. case ACPI_TYPE_STRING:
  129. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%sn", source_desc->string.pointer));
  130. break;
  131. case ACPI_TYPE_PACKAGE:
  132. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Elements - %pn",
  133. source_desc->package.elements));
  134. break;
  135. default:
  136. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "@0x%pn", source_desc));
  137. break;
  138. }
  139. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "n"));
  140. break;
  141. case AML_ZERO_OP:
  142. case AML_ONE_OP:
  143. case AML_ONES_OP:
  144. case AML_REVISION_OP:
  145. /*
  146.  * Storing to a constant is a no-op -- see ACPI Specification
  147.  * Delete the reference descriptor, however
  148.  */
  149. break;
  150. default:
  151. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - Unknown Reference subtype %02xn",
  152. ref_desc->reference.opcode));
  153. /* TBD: [Restructure] use object dump routine !! */
  154. DUMP_BUFFER (ref_desc, sizeof (acpi_operand_object));
  155. status = AE_AML_INTERNAL;
  156. break;
  157. }   /* switch (Ref_desc->Reference.Opcode) */
  158. return_ACPI_STATUS (status);
  159. }
  160. /*******************************************************************************
  161.  *
  162.  * FUNCTION:    Acpi_ex_store_object_to_index
  163.  *
  164.  * PARAMETERS:  *Source_desc          - Value to be stored
  165.  *              *Node               - Named object to receive the value
  166.  *
  167.  * RETURN:      Status
  168.  *
  169.  * DESCRIPTION: Store the object to the named object.
  170.  *
  171.  ******************************************************************************/
  172. acpi_status
  173. acpi_ex_store_object_to_index (
  174. acpi_operand_object     *source_desc,
  175. acpi_operand_object     *dest_desc,
  176. acpi_walk_state         *walk_state)
  177. {
  178. acpi_status             status = AE_OK;
  179. acpi_operand_object     *obj_desc;
  180. u32                     length;
  181. u32                     i;
  182. u8                      value = 0;
  183. FUNCTION_TRACE ("Ex_store_object_to_index");
  184. /*
  185.  * Destination must be a reference pointer, and
  186.  * must point to either a buffer or a package
  187.  */
  188. switch (dest_desc->reference.target_type) {
  189. case ACPI_TYPE_PACKAGE:
  190. /*
  191.  * Storing to a package element is not simple.  The source must be
  192.  * evaluated and converted to the type of the destination and then the
  193.  * source is copied into the destination - we can't just point to the
  194.  * source object.
  195.  */
  196. if (dest_desc->reference.target_type == ACPI_TYPE_PACKAGE) {
  197. /*
  198.  * The object at *(Dest_desc->Reference.Where) is the
  199.  * element within the package that is to be modified.
  200.  */
  201. obj_desc = *(dest_desc->reference.where);
  202. if (obj_desc) {
  203. /*
  204.  * If the Destination element is a package, we will delete
  205.  *  that object and construct a new one.
  206.  *
  207.  * TBD: [Investigate] Should both the src and dest be required
  208.  *      to be packages?
  209.  *       && (Source_desc->Common.Type == ACPI_TYPE_PACKAGE)
  210.  */
  211. if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
  212. /* Take away the reference for being part of a package */
  213. acpi_ut_remove_reference (obj_desc);
  214. obj_desc = NULL;
  215. }
  216. }
  217. if (!obj_desc) {
  218. /*
  219.  * If the Obj_desc is NULL, it means that an uninitialized package
  220.  * element has been used as a destination (this is OK), therefore,
  221.  * we must create the destination element to match the type of the
  222.  * source element NOTE: Source_desccan be of any type.
  223.  */
  224. obj_desc = acpi_ut_create_internal_object (source_desc->common.type);
  225. if (!obj_desc) {
  226. return_ACPI_STATUS (AE_NO_MEMORY);
  227. }
  228. /*
  229.  * If the source is a package, copy the source to the new dest
  230.  */
  231. if (ACPI_TYPE_PACKAGE == obj_desc->common.type) {
  232. status = acpi_ut_copy_ipackage_to_ipackage (source_desc, obj_desc, walk_state);
  233. if (ACPI_FAILURE (status)) {
  234. acpi_ut_remove_reference (obj_desc);
  235. return_ACPI_STATUS (status);
  236. }
  237. }
  238. /* Install the new descriptor into the package */
  239. *(dest_desc->reference.where) = obj_desc;
  240. }
  241. if (ACPI_TYPE_PACKAGE != obj_desc->common.type) {
  242. /*
  243.  * The destination element is not a package, so we need to
  244.  * convert the contents of the source (Source_desc) and copy into
  245.  * the destination (Obj_desc)
  246.  */
  247. status = acpi_ex_store_object_to_object (source_desc, obj_desc,
  248.   walk_state);
  249. if (ACPI_FAILURE (status)) {
  250. /*
  251.  * An error occurrered when copying the internal object
  252.  * so delete the reference.
  253.  */
  254. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  255. "Unable to copy the internal objectn"));
  256. return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  257. }
  258. }
  259. }
  260. break;
  261. case ACPI_TYPE_BUFFER_FIELD:
  262. /* TBD: can probably call the generic Buffer/Field routines */
  263. /*
  264.  * Storing into a buffer at a location defined by an Index.
  265.  *
  266.  * Each 8-bit element of the source object is written to the
  267.  * 8-bit Buffer Field of the Index destination object.
  268.  */
  269. /*
  270.  * Set the Obj_desc to the destination object and type check.
  271.  */
  272. obj_desc = dest_desc->reference.object;
  273. if (obj_desc->common.type != ACPI_TYPE_BUFFER) {
  274. return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  275. }
  276. /*
  277.  * The assignment of the individual elements will be slightly
  278.  * different for each source type.
  279.  */
  280. switch (source_desc->common.type) {
  281. case ACPI_TYPE_INTEGER:
  282. /*
  283.  * Type is Integer, assign bytewise
  284.  * This loop to assign each of the elements is somewhat
  285.  * backward because of the Big Endian-ness of IA-64
  286.  */
  287. length = sizeof (acpi_integer);
  288. for (i = length; i != 0; i--) {
  289. value = (u8)(source_desc->integer.value >> (MUL_8 (i - 1)));
  290. obj_desc->buffer.pointer[dest_desc->reference.offset] = value;
  291. }
  292. break;
  293. case ACPI_TYPE_BUFFER:
  294. /*
  295.  * Type is Buffer, the Length is in the structure.
  296.  * Just loop through the elements and assign each one in turn.
  297.  */
  298. length = source_desc->buffer.length;
  299. for (i = 0; i < length; i++) {
  300. value = source_desc->buffer.pointer[i];
  301. obj_desc->buffer.pointer[dest_desc->reference.offset] = value;
  302. }
  303. break;
  304. case ACPI_TYPE_STRING:
  305. /*
  306.  * Type is String, the Length is in the structure.
  307.  * Just loop through the elements and assign each one in turn.
  308.  */
  309. length = source_desc->string.length;
  310. for (i = 0; i < length; i++) {
  311. value = source_desc->string.pointer[i];
  312. obj_desc->buffer.pointer[dest_desc->reference.offset] = value;
  313. }
  314. break;
  315. default:
  316. /* Other types are invalid */
  317. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  318. "Source must be Number/Buffer/String type, not %Xn",
  319. source_desc->common.type));
  320. status = AE_AML_OPERAND_TYPE;
  321. break;
  322. }
  323. break;
  324. default:
  325. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Target is not a Package or Buffer_fieldn"));
  326. status = AE_AML_OPERAND_TYPE;
  327. break;
  328. }
  329. return_ACPI_STATUS (status);
  330. }
  331. /*******************************************************************************
  332.  *
  333.  * FUNCTION:    Acpi_ex_store_object_to_node
  334.  *
  335.  * PARAMETERS:  *Source_desc           - Value to be stored
  336.  *              *Node                  - Named object to receive the value
  337.  *
  338.  * RETURN:      Status
  339.  *
  340.  * DESCRIPTION: Store the object to the named object.
  341.  *
  342.  *              The Assignment of an object to a named object is handled here
  343.  *              The val passed in will replace the current value (if any)
  344.  *              with the input value.
  345.  *
  346.  *              When storing into an object the data is converted to the
  347.  *              target object type then stored in the object.  This means
  348.  *              that the target object type (for an initialized target) will
  349.  *              not be changed by a store operation.
  350.  *
  351.  *              NOTE: the global lock is acquired early.  This will result
  352.  *              in the global lock being held a bit longer.  Also, if the
  353.  *              function fails during set up we may get the lock when we
  354.  *              don't really need it.  I don't think we care.
  355.  *
  356.  ******************************************************************************/
  357. acpi_status
  358. acpi_ex_store_object_to_node (
  359. acpi_operand_object     *source_desc,
  360. acpi_namespace_node     *node,
  361. acpi_walk_state         *walk_state)
  362. {
  363. acpi_status             status = AE_OK;
  364. acpi_operand_object     *target_desc;
  365. acpi_object_type8       target_type = ACPI_TYPE_ANY;
  366. FUNCTION_TRACE ("Ex_store_object_to_node");
  367. /*
  368.  * Assuming the parameters were already validated
  369.  */
  370. /*
  371.  * Get current type of the node, and object attached to Node
  372.  */
  373. target_type = acpi_ns_get_type (node);
  374. target_desc = acpi_ns_get_attached_object (node);
  375. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Storing %p(%s) into node %p(%s)n",
  376. node, acpi_ut_get_type_name (source_desc->common.type),
  377. source_desc, acpi_ut_get_type_name (target_type)));
  378. /*
  379.  * Resolve the source object to an actual value
  380.  * (If it is a reference object)
  381.  */
  382. status = acpi_ex_resolve_object (&source_desc, target_type, walk_state);
  383. if (ACPI_FAILURE (status)) {
  384. return_ACPI_STATUS (status);
  385. }
  386. /*
  387.  * Do the actual store operation
  388.  */
  389. switch (target_type) {
  390. case ACPI_TYPE_BUFFER_FIELD:
  391. case INTERNAL_TYPE_REGION_FIELD:
  392. case INTERNAL_TYPE_BANK_FIELD:
  393. case INTERNAL_TYPE_INDEX_FIELD:
  394. /*
  395.  * For fields, copy the source data to the target field.
  396.  */
  397. status = acpi_ex_write_data_to_field (source_desc, target_desc);
  398. break;
  399. case ACPI_TYPE_INTEGER:
  400. case ACPI_TYPE_STRING:
  401. case ACPI_TYPE_BUFFER:
  402. /*
  403.  * These target types are all of type Integer/String/Buffer, and
  404.  * therefore support implicit conversion before the store.
  405.  *
  406.  * Copy and/or convert the source object to a new target object
  407.  */
  408. status = acpi_ex_store_object (source_desc, target_type, &target_desc, walk_state);
  409. if (ACPI_FAILURE (status)) {
  410. return_ACPI_STATUS (status);
  411. }
  412. /*
  413.  * Store the new Target_desc as the new value of the Name, and set
  414.  * the Name's type to that of the value being stored in it.
  415.  * Source_desc reference count is incremented by Attach_object.
  416.  */
  417. status = acpi_ns_attach_object (node, target_desc, target_type);
  418. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  419. "Store %s into %s via Convert/Attachn",
  420. acpi_ut_get_type_name (target_desc->common.type),
  421. acpi_ut_get_type_name (target_type)));
  422. break;
  423. default:
  424. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  425. "Storing %s (%p) directly into node (%p), no implicit conversionn",
  426. acpi_ut_get_type_name (source_desc->common.type), source_desc, node));
  427. /* No conversions for all other types.  Just attach the source object */
  428. status = acpi_ns_attach_object (node, source_desc, source_desc->common.type);
  429. break;
  430. }
  431. return_ACPI_STATUS (status);
  432. }
  433. /*******************************************************************************
  434.  *
  435.  * FUNCTION:    Acpi_ex_store_object_to_object
  436.  *
  437.  * PARAMETERS:  *Source_desc           - Value to be stored
  438.  *              *Dest_desc          - Object to receive the value
  439.  *
  440.  * RETURN:      Status
  441.  *
  442.  * DESCRIPTION: Store an object to another object.
  443.  *
  444.  *              The Assignment of an object to another (not named) object
  445.  *              is handled here.
  446.  *              The val passed in will replace the current value (if any)
  447.  *              with the input value.
  448.  *
  449.  *              When storing into an object the data is converted to the
  450.  *              target object type then stored in the object.  This means
  451.  *              that the target object type (for an initialized target) will
  452.  *              not be changed by a store operation.
  453.  *
  454.  *              This module allows destination types of Number, String,
  455.  *              and Buffer.
  456.  *
  457.  ******************************************************************************/
  458. acpi_status
  459. acpi_ex_store_object_to_object (
  460. acpi_operand_object     *source_desc,
  461. acpi_operand_object     *dest_desc,
  462. acpi_walk_state         *walk_state)
  463. {
  464. acpi_status             status = AE_OK;
  465. acpi_object_type8       destination_type = dest_desc->common.type;
  466. FUNCTION_TRACE ("Ex_store_object_to_object");
  467. /*
  468.  *  Assuming the parameters are valid!
  469.  */
  470. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Storing %p(%s) to %p(%s)n",
  471.   source_desc, acpi_ut_get_type_name (source_desc->common.type),
  472.   dest_desc, acpi_ut_get_type_name (dest_desc->common.type)));
  473. /*
  474.  * From this interface, we only support Integers/Strings/Buffers
  475.  */
  476. switch (destination_type) {
  477. case ACPI_TYPE_INTEGER:
  478. case ACPI_TYPE_STRING:
  479. case ACPI_TYPE_BUFFER:
  480. break;
  481. default:
  482. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Store into %s not implementedn",
  483. acpi_ut_get_type_name (dest_desc->common.type)));
  484. return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
  485. }
  486. /*
  487.  * Resolve the source object to an actual value
  488.  * (If it is a reference object)
  489.  */
  490. status = acpi_ex_resolve_object (&source_desc, destination_type, walk_state);
  491. if (ACPI_FAILURE (status)) {
  492. return_ACPI_STATUS (status);
  493. }
  494. /*
  495.  * Copy and/or convert the source object to the destination object
  496.  */
  497. status = acpi_ex_store_object (source_desc, destination_type, &dest_desc, walk_state);
  498. return_ACPI_STATUS (status);
  499. }