1 /*******************************************************************************
3 * Module Name: dsmthdat - control method arguments and local variables
6 ******************************************************************************/
9 * Copyright (C) 2000 R. Byron Moore
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 #define _COMPONENT DISPATCHER
36 MODULE_NAME ("dsmthdat")
39 /*******************************************************************************
41 * FUNCTION: Acpi_ds_method_data_init
43 * PARAMETERS: *Obj_desc
47 * DESCRIPTION: Initialize the data structures that hold the method's arguments
48 * and locals. The data struct is an array of NTEs for each.
49 * This allows Ref_of and De_ref_of to work properly for these
52 ******************************************************************************/
55 acpi_ds_method_data_init (
56 ACPI_WALK_STATE
*walk_state
)
62 * Walk_state fields are initialized to zero by the
63 * Acpi_cm_callocate().
65 * An Node is assigned to each argument and local so
66 * that Ref_of() can return a pointer to the Node.
69 /* Init the method arguments */
71 for (i
= 0; i
< MTH_NUM_ARGS
; i
++) {
72 MOVE_UNALIGNED32_TO_32 (&walk_state
->arguments
[i
].name
,
74 walk_state
->arguments
[i
].name
|= (i
<< 24);
75 walk_state
->arguments
[i
].data_type
= ACPI_DESC_TYPE_NAMED
;
76 walk_state
->arguments
[i
].type
= ACPI_TYPE_ANY
;
77 walk_state
->arguments
[i
].flags
= ANOBJ_END_OF_PEER_LIST
| ANOBJ_METHOD_ARG
;
80 /* Init the method locals */
82 for (i
= 0; i
< MTH_NUM_LOCALS
; i
++) {
83 MOVE_UNALIGNED32_TO_32 (&walk_state
->local_variables
[i
].name
,
86 walk_state
->local_variables
[i
].name
|= (i
<< 24);
87 walk_state
->local_variables
[i
].data_type
= ACPI_DESC_TYPE_NAMED
;
88 walk_state
->local_variables
[i
].type
= ACPI_TYPE_ANY
;
89 walk_state
->local_variables
[i
].flags
= ANOBJ_END_OF_PEER_LIST
| ANOBJ_METHOD_LOCAL
;
96 /*******************************************************************************
98 * FUNCTION: Acpi_ds_method_data_delete_all
104 * DESCRIPTION: Delete method locals and arguments. Arguments are only
105 * deleted if this method was called from another method.
107 ******************************************************************************/
110 acpi_ds_method_data_delete_all (
111 ACPI_WALK_STATE
*walk_state
)
114 ACPI_OPERAND_OBJECT
*object
;
117 /* Delete the locals */
119 for (index
= 0; index
< MTH_NUM_LOCALS
; index
++) {
120 object
= walk_state
->local_variables
[index
].object
;
124 walk_state
->local_variables
[index
].object
= NULL
;
126 /* Was given a ref when stored */
128 acpi_cm_remove_reference (object
);
133 /* Delete the arguments */
135 for (index
= 0; index
< MTH_NUM_ARGS
; index
++) {
136 object
= walk_state
->arguments
[index
].object
;
140 walk_state
->arguments
[index
].object
= NULL
;
142 /* Was given a ref when stored */
144 acpi_cm_remove_reference (object
);
152 /*******************************************************************************
154 * FUNCTION: Acpi_ds_method_data_init_args
160 * DESCRIPTION: Initialize arguments for a method
162 ******************************************************************************/
165 acpi_ds_method_data_init_args (
166 ACPI_OPERAND_OBJECT
**params
,
168 ACPI_WALK_STATE
*walk_state
)
179 /* Copy passed parameters into the new method stack frame */
181 for (pindex
= mindex
= 0;
182 (mindex
< MTH_NUM_ARGS
) && (pindex
< max_param_count
);
185 if (params
[pindex
]) {
188 * Set the current method argument to the
189 * Params[Pindex++] argument object descriptor
191 status
= acpi_ds_method_data_set_value (MTH_TYPE_ARG
, mindex
,
192 params
[pindex
], walk_state
);
193 if (ACPI_FAILURE (status
)) {
209 /*******************************************************************************
211 * FUNCTION: Acpi_ds_method_data_get_entry
213 * PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
214 * Index - Which local_var or argument to get
215 * Entry - Pointer to where a pointer to the stack
220 * DESCRIPTION: Get the address of the stack entry given by Type:Index
222 ******************************************************************************/
225 acpi_ds_method_data_get_entry (
228 ACPI_WALK_STATE
*walk_state
,
229 ACPI_OPERAND_OBJECT
***entry
)
234 * Get the requested object.
235 * The stack "Type" is either a Local_variable or an Argument
243 if (index
> MTH_MAX_LOCAL
) {
244 return (AE_BAD_PARAMETER
);
248 (ACPI_OPERAND_OBJECT
**) &walk_state
->local_variables
[index
].object
;
254 if (index
> MTH_MAX_ARG
) {
255 return (AE_BAD_PARAMETER
);
259 (ACPI_OPERAND_OBJECT
**) &walk_state
->arguments
[index
].object
;
264 return (AE_BAD_PARAMETER
);
272 /*******************************************************************************
274 * FUNCTION: Acpi_ds_method_data_set_entry
276 * PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
277 * Index - Which local_var or argument to get
278 * Object - Object to be inserted into the stack entry
282 * DESCRIPTION: Insert an object onto the method stack at entry Type:Index.
284 ******************************************************************************/
287 acpi_ds_method_data_set_entry (
290 ACPI_OPERAND_OBJECT
*object
,
291 ACPI_WALK_STATE
*walk_state
)
294 ACPI_OPERAND_OBJECT
**entry
;
297 /* Get a pointer to the stack entry to set */
299 status
= acpi_ds_method_data_get_entry (type
, index
, walk_state
, &entry
);
300 if (ACPI_FAILURE (status
)) {
304 /* Increment ref count so object can't be deleted while installed */
306 acpi_cm_add_reference (object
);
308 /* Install the object into the stack entry */
316 /*******************************************************************************
318 * FUNCTION: Acpi_ds_method_data_get_type
320 * PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
321 * Index - Which local_var or argument whose type
324 * RETURN: Data type of selected Arg or Local
325 * Used only in Exec_monadic2()/Type_op.
327 ******************************************************************************/
330 acpi_ds_method_data_get_type (
333 ACPI_WALK_STATE
*walk_state
)
336 ACPI_OPERAND_OBJECT
**entry
;
337 ACPI_OPERAND_OBJECT
*object
;
340 /* Get a pointer to the requested stack entry */
342 status
= acpi_ds_method_data_get_entry (type
, index
, walk_state
, &entry
);
343 if (ACPI_FAILURE (status
)) {
344 return ((ACPI_TYPE_NOT_FOUND
));
347 /* Get the object from the method stack */
351 /* Get the object type */
354 /* Any == 0 => "uninitialized" -- see spec 15.2.3.5.2.28 */
355 return (ACPI_TYPE_ANY
);
358 return (object
->common
.type
);
362 /*******************************************************************************
364 * FUNCTION: Acpi_ds_method_data_get_nte
366 * PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
367 * Index - Which local_var or argument whose type
370 * RETURN: Get the Node associated with a local or arg.
372 ******************************************************************************/
374 ACPI_NAMESPACE_NODE
*
375 acpi_ds_method_data_get_nte (
378 ACPI_WALK_STATE
*walk_state
)
380 ACPI_NAMESPACE_NODE
*node
= NULL
;
388 if (index
> MTH_MAX_LOCAL
) {
392 node
= &walk_state
->local_variables
[index
];
398 if (index
> MTH_MAX_ARG
) {
402 node
= &walk_state
->arguments
[index
];
415 /*******************************************************************************
417 * FUNCTION: Acpi_ds_method_data_get_value
419 * PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
420 * Index - Which local_var or argument to get
421 * *Dest_desc - Descriptor into which selected Arg
422 * or Local value should be copied
426 * DESCRIPTION: Retrieve value of selected Arg or Local from the method frame
427 * at the current top of the method stack.
428 * Used only in Acpi_aml_resolve_to_value().
430 ******************************************************************************/
433 acpi_ds_method_data_get_value (
436 ACPI_WALK_STATE
*walk_state
,
437 ACPI_OPERAND_OBJECT
**dest_desc
)
440 ACPI_OPERAND_OBJECT
**entry
;
441 ACPI_OPERAND_OBJECT
*object
;
444 /* Validate the object descriptor */
447 return (AE_BAD_PARAMETER
);
451 /* Get a pointer to the requested method stack entry */
453 status
= acpi_ds_method_data_get_entry (type
, index
, walk_state
, &entry
);
454 if (ACPI_FAILURE (status
)) {
458 /* Get the object from the method stack */
463 /* Examine the returned object, it must be valid. */
467 * Index points to uninitialized object stack value.
468 * This means that either 1) The expected argument was
469 * not passed to the method, or 2) A local variable
470 * was referenced by the method (via the ASL)
471 * before it was initialized. Either case is an error.
477 return (AE_AML_UNINITIALIZED_ARG
);
481 return (AE_AML_UNINITIALIZED_LOCAL
);
488 * Index points to initialized and valid object stack value.
489 * Return an additional reference to the object
493 acpi_cm_add_reference (object
);
499 /*******************************************************************************
501 * FUNCTION: Acpi_ds_method_data_delete_value
503 * PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
504 * Index - Which local_var or argument to delete
508 * DESCRIPTION: Delete the entry at Type:Index on the method stack. Inserts
509 * a null into the stack slot after the object is deleted.
511 ******************************************************************************/
514 acpi_ds_method_data_delete_value (
517 ACPI_WALK_STATE
*walk_state
)
520 ACPI_OPERAND_OBJECT
**entry
;
521 ACPI_OPERAND_OBJECT
*object
;
524 /* Get a pointer to the requested entry */
526 status
= acpi_ds_method_data_get_entry (type
, index
, walk_state
, &entry
);
527 if (ACPI_FAILURE (status
)) {
531 /* Get the current entry in this slot k */
536 * Undefine the Arg or Local by setting its descriptor
537 * pointer to NULL. Locals/Args can contain both
538 * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
544 (VALID_DESCRIPTOR_TYPE (object
, ACPI_DESC_TYPE_INTERNAL
)))
547 * There is a valid object in this slot
548 * Decrement the reference count by one to balance the
549 * increment when the object was stored in the slot.
552 acpi_cm_remove_reference (object
);
560 /*******************************************************************************
562 * FUNCTION: Acpi_ds_method_data_set_value
564 * PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
565 * Index - Which local_var or argument to set
566 * *Src_desc - Value to be stored
567 * *Dest_desc - Descriptor into which *Src_desc
568 * can be copied, or NULL if one must
569 * be allocated for the purpose. If
570 * provided, this descriptor will be
571 * used for the new value.
575 * DESCRIPTION: Store a value in an Arg or Local. The Src_desc is installed
576 * as the new value for the Arg or Local and the reference count
579 ******************************************************************************/
582 acpi_ds_method_data_set_value (
585 ACPI_OPERAND_OBJECT
*src_desc
,
586 ACPI_WALK_STATE
*walk_state
)
589 ACPI_OPERAND_OBJECT
**entry
;
592 /* Parameter validation */
595 return (AE_BAD_PARAMETER
);
599 /* Get a pointer to the requested method stack entry */
601 status
= acpi_ds_method_data_get_entry (type
, index
, walk_state
, &entry
);
602 if (ACPI_FAILURE (status
)) {
606 if (*entry
== src_desc
) {
612 * If there is an object already in this slot, we either
613 * have to delete it, or if this is an argument and there
614 * is an object reference stored there, we have to do
620 * Check for an indirect store if an argument
621 * contains an object reference (stored as an Node).
622 * We don't allow this automatic dereferencing for
623 * locals, since a store to a local should overwrite
624 * anything there, including an object reference.
626 * If both Arg0 and Local0 contain Ref_of (Local4):
628 * Store (1, Arg0) - Causes indirect store to local4
629 * Store (1, Local0) - Stores 1 in local0, overwriting
630 * the reference to local4
631 * Store (1, De_refof (Local0)) - Causes indirect store to local4
636 if ((type
== MTH_TYPE_ARG
) &&
637 (VALID_DESCRIPTOR_TYPE (*entry
, ACPI_DESC_TYPE_NAMED
)))
639 /* Detach an existing object from the Node */
641 acpi_ns_detach_object ((ACPI_NAMESPACE_NODE
*) *entry
);
644 * Store this object into the Node
645 * (do the indirect store)
648 status
= acpi_ns_attach_object ((ACPI_NAMESPACE_NODE
*) *entry
, src_desc
,
649 src_desc
->common
.type
);
655 * Otherwise, just delete the existing object
656 * before storing the new one
659 acpi_ds_method_data_delete_value (type
, index
, walk_state
);
664 * Install the Obj_stack descriptor (*Src_desc) into
665 * the descriptor for the Arg or Local.
666 * Install the new object in the stack entry
667 * (increments the object reference count by one)
670 status
= acpi_ds_method_data_set_entry (type
, index
, src_desc
, walk_state
);
671 if (ACPI_FAILURE (status
)) {