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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: dsmthdat - control method arguments and local variables
  4.  *              $Revision: 49 $
  5.  *
  6.  ******************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 R. Byron Moore
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. #include "acpi.h"
  25. #include "acparser.h"
  26. #include "acdispat.h"
  27. #include "acinterp.h"
  28. #include "amlcode.h"
  29. #include "acnamesp.h"
  30. #define _COMPONENT          ACPI_DISPATCHER
  31.  MODULE_NAME         ("dsmthdat")
  32. /*******************************************************************************
  33.  *
  34.  * FUNCTION:    Acpi_ds_method_data_init
  35.  *
  36.  * PARAMETERS:  Walk_state          - Current walk state object
  37.  *
  38.  * RETURN:      Status
  39.  *
  40.  * DESCRIPTION: Initialize the data structures that hold the method's arguments
  41.  *              and locals.  The data struct is an array of NTEs for each.
  42.  *              This allows Ref_of and De_ref_of to work properly for these
  43.  *              special data types.
  44.  *
  45.  ******************************************************************************/
  46. acpi_status
  47. acpi_ds_method_data_init (
  48. acpi_walk_state         *walk_state)
  49. {
  50. u32                     i;
  51. FUNCTION_TRACE ("Ds_method_data_init");
  52. /*
  53.  * Walk_state fields are initialized to zero by the
  54.  * ACPI_MEM_CALLOCATE().
  55.  *
  56.  * An Node is assigned to each argument and local so
  57.  * that Ref_of() can return a pointer to the Node.
  58.  */
  59. /* Init the method arguments */
  60. for (i = 0; i < MTH_NUM_ARGS; i++) {
  61. MOVE_UNALIGNED32_TO_32 (&walk_state->arguments[i].name,
  62.  NAMEOF_ARG_NTE);
  63. walk_state->arguments[i].name      |= (i << 24);
  64. walk_state->arguments[i].data_type  = ACPI_DESC_TYPE_NAMED;
  65. walk_state->arguments[i].type       = ACPI_TYPE_ANY;
  66. walk_state->arguments[i].flags      = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG;
  67. }
  68. /* Init the method locals */
  69. for (i = 0; i < MTH_NUM_LOCALS; i++) {
  70. MOVE_UNALIGNED32_TO_32 (&walk_state->local_variables[i].name,
  71.  NAMEOF_LOCAL_NTE);
  72. walk_state->local_variables[i].name  |= (i << 24);
  73. walk_state->local_variables[i].data_type = ACPI_DESC_TYPE_NAMED;
  74. walk_state->local_variables[i].type   = ACPI_TYPE_ANY;
  75. walk_state->local_variables[i].flags  = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL;
  76. }
  77. return_ACPI_STATUS (AE_OK);
  78. }
  79. /*******************************************************************************
  80.  *
  81.  * FUNCTION:    Acpi_ds_method_data_delete_all
  82.  *
  83.  * PARAMETERS:  Walk_state          - Current walk state object
  84.  *
  85.  * RETURN:      Status
  86.  *
  87.  * DESCRIPTION: Delete method locals and arguments.  Arguments are only
  88.  *              deleted if this method was called from another method.
  89.  *
  90.  ******************************************************************************/
  91. acpi_status
  92. acpi_ds_method_data_delete_all (
  93. acpi_walk_state         *walk_state)
  94. {
  95. u32                     index;
  96. acpi_operand_object     *object;
  97. FUNCTION_TRACE ("Ds_method_data_delete_all");
  98. /* Delete the locals */
  99. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Deleting local variables in %pn", walk_state));
  100. for (index = 0; index < MTH_NUM_LOCALS; index++) {
  101. object = walk_state->local_variables[index].object;
  102. if (object) {
  103. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%pn", index, object));
  104. /* Remove first */
  105. walk_state->local_variables[index].object = NULL;
  106. /* Was given a ref when stored */
  107. acpi_ut_remove_reference (object);
  108.    }
  109. }
  110. /* Delete the arguments */
  111. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Deleting arguments in %pn", walk_state));
  112. for (index = 0; index < MTH_NUM_ARGS; index++) {
  113. object = walk_state->arguments[index].object;
  114. if (object) {
  115. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%pn", index, object));
  116. /* Remove first */
  117. walk_state->arguments[index].object = NULL;
  118.  /* Was given a ref when stored */
  119. acpi_ut_remove_reference (object);
  120. }
  121. }
  122. return_ACPI_STATUS (AE_OK);
  123. }
  124. /*******************************************************************************
  125.  *
  126.  * FUNCTION:    Acpi_ds_method_data_init_args
  127.  *
  128.  * PARAMETERS:  *Params         - Pointer to a parameter list for the method
  129.  *              Max_param_count - The arg count for this method
  130.  *              Walk_state      - Current walk state object
  131.  *
  132.  * RETURN:      Status
  133.  *
  134.  * DESCRIPTION: Initialize arguments for a method
  135.  *
  136.  ******************************************************************************/
  137. acpi_status
  138. acpi_ds_method_data_init_args (
  139. acpi_operand_object     **params,
  140. u32                     max_param_count,
  141. acpi_walk_state         *walk_state)
  142. {
  143. acpi_status             status;
  144. u32                     mindex;
  145. u32                     pindex;
  146. FUNCTION_TRACE_PTR ("Ds_method_data_init_args", params);
  147. if (!params) {
  148. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to methodn"));
  149. return_ACPI_STATUS (AE_OK);
  150. }
  151. /* Copy passed parameters into the new method stack frame  */
  152. for (pindex = mindex = 0;
  153. (mindex < MTH_NUM_ARGS) && (pindex < max_param_count);
  154. mindex++) {
  155. if (params[pindex]) {
  156. /*
  157.  * A valid parameter.
  158.  * Set the current method argument to the
  159.  * Params[Pindex++] argument object descriptor
  160.  */
  161. status = acpi_ds_store_object_to_local (AML_ARG_OP, mindex,
  162.   params[pindex], walk_state);
  163. if (ACPI_FAILURE (status)) {
  164. break;
  165. }
  166. pindex++;
  167. }
  168. else {
  169. break;
  170. }
  171. }
  172. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to methodn", pindex));
  173. return_ACPI_STATUS (AE_OK);
  174. }
  175. /*******************************************************************************
  176.  *
  177.  * FUNCTION:    Acpi_ds_method_data_get_entry
  178.  *
  179.  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
  180.  *              Index               - Which local_var or argument to get
  181.  *              Entry               - Pointer to where a pointer to the stack
  182.  *                                    entry is returned.
  183.  *              Walk_state          - Current walk state object
  184.  *
  185.  * RETURN:      Status
  186.  *
  187.  * DESCRIPTION: Get the address of the object entry given by Opcode:Index
  188.  *
  189.  ******************************************************************************/
  190. acpi_status
  191. acpi_ds_method_data_get_entry (
  192. u16                     opcode,
  193. u32                     index,
  194. acpi_walk_state         *walk_state,
  195. acpi_operand_object     ***entry)
  196. {
  197. FUNCTION_TRACE_U32 ("Ds_method_data_get_entry", index);
  198. /*
  199.  * Get the requested object.
  200.  * The stack "Opcode" is either a Local_variable or an Argument
  201.  */
  202. switch (opcode) {
  203. case AML_LOCAL_OP:
  204. if (index > MTH_MAX_LOCAL) {
  205. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Local_var index %d is invalid (max %d)n",
  206. index, MTH_MAX_LOCAL));
  207. return_ACPI_STATUS (AE_BAD_PARAMETER);
  208. }
  209. *entry = (acpi_operand_object  **)
  210.  &walk_state->local_variables[index].object;
  211. break;
  212. case AML_ARG_OP:
  213. if (index > MTH_MAX_ARG) {
  214. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Arg index %d is invalid (max %d)n",
  215. index, MTH_MAX_ARG));
  216. return_ACPI_STATUS (AE_BAD_PARAMETER);
  217. }
  218. *entry = (acpi_operand_object  **)
  219.  &walk_state->arguments[index].object;
  220. break;
  221. default:
  222. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Opcode %d is invalidn", opcode));
  223. return_ACPI_STATUS (AE_BAD_PARAMETER);
  224. }
  225. return_ACPI_STATUS (AE_OK);
  226. }
  227. /*******************************************************************************
  228.  *
  229.  * FUNCTION:    Acpi_ds_method_data_set_entry
  230.  *
  231.  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
  232.  *              Index               - Which local_var or argument to get
  233.  *              Object              - Object to be inserted into the stack entry
  234.  *              Walk_state          - Current walk state object
  235.  *
  236.  * RETURN:      Status
  237.  *
  238.  * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
  239.  *
  240.  ******************************************************************************/
  241. acpi_status
  242. acpi_ds_method_data_set_entry (
  243. u16                     opcode,
  244. u32                     index,
  245. acpi_operand_object     *object,
  246. acpi_walk_state         *walk_state)
  247. {
  248. acpi_status             status;
  249. acpi_operand_object     **entry;
  250. FUNCTION_TRACE ("Ds_method_data_set_entry");
  251. /* Get a pointer to the stack entry to set */
  252. status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
  253. if (ACPI_FAILURE (status)) {
  254. return_ACPI_STATUS (status);
  255. }
  256. /* Increment ref count so object can't be deleted while installed */
  257. acpi_ut_add_reference (object);
  258. /* Install the object into the stack entry */
  259. *entry = object;
  260. return_ACPI_STATUS (AE_OK);
  261. }
  262. /*******************************************************************************
  263.  *
  264.  * FUNCTION:    Acpi_ds_method_data_get_type
  265.  *
  266.  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
  267.  *              Index               - Which local_var or argument whose type
  268.  *                                      to get
  269.  *              Walk_state          - Current walk state object
  270.  *
  271.  * RETURN:      Data type of selected Arg or Local
  272.  *              Used only in Exec_monadic2()/Type_op.
  273.  *
  274.  ******************************************************************************/
  275. acpi_object_type8
  276. acpi_ds_method_data_get_type (
  277. u16                     opcode,
  278. u32                     index,
  279. acpi_walk_state         *walk_state)
  280. {
  281. acpi_status             status;
  282. acpi_operand_object     **entry;
  283. acpi_operand_object     *object;
  284. FUNCTION_TRACE ("Ds_method_data_get_type");
  285. /* Get a pointer to the requested stack entry */
  286. status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
  287. if (ACPI_FAILURE (status)) {
  288. return_VALUE ((ACPI_TYPE_NOT_FOUND));
  289. }
  290. /* Get the object from the method stack */
  291. object = *entry;
  292. /* Get the object type */
  293. if (!object) {
  294. /* Any == 0 => "uninitialized" -- see spec 15.2.3.5.2.28 */
  295. return_VALUE (ACPI_TYPE_ANY);
  296. }
  297. return_VALUE (object->common.type);
  298. }
  299. /*******************************************************************************
  300.  *
  301.  * FUNCTION:    Acpi_ds_method_data_get_node
  302.  *
  303.  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
  304.  *              Index               - Which local_var or argument whose type
  305.  *                                      to get
  306.  *              Walk_state          - Current walk state object
  307.  *
  308.  * RETURN:      Get the Node associated with a local or arg.
  309.  *
  310.  ******************************************************************************/
  311. acpi_namespace_node *
  312. acpi_ds_method_data_get_node (
  313. u16                     opcode,
  314. u32                     index,
  315. acpi_walk_state         *walk_state)
  316. {
  317. acpi_namespace_node     *node = NULL;
  318. FUNCTION_TRACE ("Ds_method_data_get_node");
  319. switch (opcode) {
  320. case AML_LOCAL_OP:
  321. if (index > MTH_MAX_LOCAL) {
  322. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Local index %d is invalid (max %d)n",
  323. index, MTH_MAX_LOCAL));
  324. return_PTR (node);
  325. }
  326. node =  &walk_state->local_variables[index];
  327. break;
  328. case AML_ARG_OP:
  329. if (index > MTH_MAX_ARG) {
  330. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Arg index %d is invalid (max %d)n",
  331. index, MTH_MAX_ARG));
  332. return_PTR (node);
  333. }
  334. node = &walk_state->arguments[index];
  335. break;
  336. default:
  337. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Opcode %d is invalidn", opcode));
  338. break;
  339. }
  340. return_PTR (node);
  341. }
  342. /*******************************************************************************
  343.  *
  344.  * FUNCTION:    Acpi_ds_method_data_get_value
  345.  *
  346.  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
  347.  *              Index               - Which local_var or argument to get
  348.  *              Walk_state          - Current walk state object
  349.  *              *Dest_desc          - Ptr to Descriptor into which selected Arg
  350.  *                                    or Local value should be copied
  351.  *
  352.  * RETURN:      Status
  353.  *
  354.  * DESCRIPTION: Retrieve value of selected Arg or Local from the method frame
  355.  *              at the current top of the method stack.
  356.  *              Used only in Acpi_ex_resolve_to_value().
  357.  *
  358.  ******************************************************************************/
  359. acpi_status
  360. acpi_ds_method_data_get_value (
  361. u16                     opcode,
  362. u32                     index,
  363. acpi_walk_state         *walk_state,
  364. acpi_operand_object     **dest_desc)
  365. {
  366. acpi_status             status;
  367. acpi_operand_object     **entry;
  368. acpi_operand_object     *object;
  369. FUNCTION_TRACE ("Ds_method_data_get_value");
  370. /* Validate the object descriptor */
  371. if (!dest_desc) {
  372. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null object descriptor pointern"));
  373. return_ACPI_STATUS (AE_BAD_PARAMETER);
  374. }
  375. /* Get a pointer to the requested method stack entry */
  376. status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
  377. if (ACPI_FAILURE (status)) {
  378. return_ACPI_STATUS (status);
  379. }
  380. /* Get the object from the method stack */
  381. object = *entry;
  382. /* Examine the returned object, it must be valid. */
  383. if (!object) {
  384. /*
  385.  * Index points to uninitialized object stack value.
  386.  * This means that either 1) The expected argument was
  387.  * not passed to the method, or 2) A local variable
  388.  * was referenced by the method (via the ASL)
  389.  * before it was initialized.  Either case is an error.
  390.  */
  391. switch (opcode) {
  392. case AML_ARG_OP:
  393. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Arg[%d] at entry %pn",
  394. index, entry));
  395. return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
  396. break;
  397. case AML_LOCAL_OP:
  398. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Local[%d] at entry %pn",
  399. index, entry));
  400. return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
  401. break;
  402. }
  403. }
  404. /*
  405.  * Index points to initialized and valid object stack value.
  406.  * Return an additional reference to the object
  407.  */
  408. *dest_desc = object;
  409. acpi_ut_add_reference (object);
  410. return_ACPI_STATUS (AE_OK);
  411. }
  412. /*******************************************************************************
  413.  *
  414.  * FUNCTION:    Acpi_ds_method_data_delete_value
  415.  *
  416.  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
  417.  *              Index               - Which local_var or argument to delete
  418.  *              Walk_state          - Current walk state object
  419.  *
  420.  * RETURN:      Status
  421.  *
  422.  * DESCRIPTION: Delete the entry at Opcode:Index on the method stack.  Inserts
  423.  *              a null into the stack slot after the object is deleted.
  424.  *
  425.  ******************************************************************************/
  426. acpi_status
  427. acpi_ds_method_data_delete_value (
  428. u16                     opcode,
  429. u32                     index,
  430. acpi_walk_state         *walk_state)
  431. {
  432. acpi_status             status;
  433. acpi_operand_object     **entry;
  434. acpi_operand_object     *object;
  435. FUNCTION_TRACE ("Ds_method_data_delete_value");
  436. /* Get a pointer to the requested entry */
  437. status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
  438. if (ACPI_FAILURE (status)) {
  439. return_ACPI_STATUS (status);
  440. }
  441. /* Get the current entry in this slot k */
  442. object = *entry;
  443. /*
  444.  * Undefine the Arg or Local by setting its descriptor
  445.  * pointer to NULL. Locals/Args can contain both
  446.  * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
  447.  */
  448. *entry = NULL;
  449. if ((object) &&
  450. (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_INTERNAL))) {
  451. /*
  452.  * There is a valid object in this slot
  453.  * Decrement the reference count by one to balance the
  454.  * increment when the object was stored in the slot.
  455.  */
  456. acpi_ut_remove_reference (object);
  457. }
  458. return_ACPI_STATUS (AE_OK);
  459. }
  460. /*******************************************************************************
  461.  *
  462.  * FUNCTION:    Acpi_ds_store_object_to_local
  463.  *
  464.  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
  465.  *              Index               - Which local_var or argument to set
  466.  *              Src_desc            - Value to be stored
  467.  *              Walk_state          - Current walk state
  468.  *
  469.  * RETURN:      Status
  470.  *
  471.  * DESCRIPTION: Store a value in an Arg or Local.  The Src_desc is installed
  472.  *              as the new value for the Arg or Local and the reference count
  473.  *              for Src_desc is incremented.
  474.  *
  475.  ******************************************************************************/
  476. acpi_status
  477. acpi_ds_store_object_to_local (
  478. u16                     opcode,
  479. u32                     index,
  480. acpi_operand_object     *src_desc,
  481. acpi_walk_state         *walk_state)
  482. {
  483. acpi_status             status;
  484. acpi_operand_object     **entry;
  485. FUNCTION_TRACE ("Ds_method_data_set_value");
  486. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%d Idx=%d Obj=%pn",
  487. opcode, index, src_desc));
  488. /* Parameter validation */
  489. if (!src_desc) {
  490. return_ACPI_STATUS (AE_BAD_PARAMETER);
  491. }
  492. /* Get a pointer to the requested method stack entry */
  493. status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
  494. if (ACPI_FAILURE (status)) {
  495. goto cleanup;
  496. }
  497. if (*entry == src_desc) {
  498. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!n", src_desc));
  499. goto cleanup;
  500. }
  501. /*
  502.  * If there is an object already in this slot, we either
  503.  * have to delete it, or if this is an argument and there
  504.  * is an object reference stored there, we have to do
  505.  * an indirect store!
  506.  */
  507. if (*entry) {
  508. /*
  509.  * Check for an indirect store if an argument
  510.  * contains an object reference (stored as an Node).
  511.  * We don't allow this automatic dereferencing for
  512.  * locals, since a store to a local should overwrite
  513.  * anything there, including an object reference.
  514.  *
  515.  * If both Arg0 and Local0 contain Ref_of (Local4):
  516.  *
  517.  * Store (1, Arg0)             - Causes indirect store to local4
  518.  * Store (1, Local0)           - Stores 1 in local0, overwriting
  519.  *                                  the reference to local4
  520.  * Store (1, De_refof (Local0)) - Causes indirect store to local4
  521.  *
  522.  * Weird, but true.
  523.  */
  524. if ((opcode == AML_ARG_OP) &&
  525. (VALID_DESCRIPTOR_TYPE (*entry, ACPI_DESC_TYPE_NAMED))) {
  526. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
  527. "Arg (%p) is an Obj_ref(Node), storing in %pn",
  528. src_desc, *entry));
  529. /* Detach an existing object from the Node */
  530. acpi_ns_detach_object ((acpi_namespace_node *) *entry);
  531. /*
  532.  * Store this object into the Node
  533.  * (do the indirect store)
  534.  */
  535. status = acpi_ns_attach_object ((acpi_namespace_node *) *entry, src_desc,
  536.    src_desc->common.type);
  537. return_ACPI_STATUS (status);
  538. }
  539. #ifdef ACPI_ENABLE_IMPLICIT_CONVERSION
  540. /*
  541.  * Perform "Implicit conversion" of the new object to the type of the
  542.  * existing object
  543.  */
  544. status = acpi_ex_convert_to_target_type ((*entry)->common.type, &src_desc, walk_state);
  545. if (ACPI_FAILURE (status)) {
  546. goto cleanup;
  547. }
  548. #endif
  549. /*
  550.  * Delete the existing object
  551.  * before storing the new one
  552.  */
  553. acpi_ds_method_data_delete_value (opcode, index, walk_state);
  554. }
  555. /*
  556.  * Install the Obj_stack descriptor (*Src_desc) into
  557.  * the descriptor for the Arg or Local.
  558.  * Install the new object in the stack entry
  559.  * (increments the object reference count by one)
  560.  */
  561. status = acpi_ds_method_data_set_entry (opcode, index, src_desc, walk_state);
  562. if (ACPI_FAILURE (status)) {
  563. goto cleanup;
  564. }
  565. /* Normal exit */
  566. return_ACPI_STATUS (AE_OK);
  567. /* Error exit */
  568. cleanup:
  569. return_ACPI_STATUS (status);
  570. }