2 /******************************************************************************
4 * Module Name: amresnte - AML Interpreter object resolution
7 *****************************************************************************/
10 * Copyright (C) 2000, 2001 R. Byron Moore
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #define _COMPONENT ACPI_EXECUTER
33 MODULE_NAME ("amresnte")
36 /*******************************************************************************
38 * FUNCTION: Acpi_aml_resolve_node_to_value
40 * PARAMETERS: Stack_ptr - Pointer to a location on a stack that contains
41 * a pointer to an Node
45 * DESCRIPTION: Resolve a ACPI_NAMESPACE_NODE (Node,
46 * A.K.A. a "direct name pointer")
48 * Note: for some of the data types, the pointer attached to the Node
49 * can be either a pointer to an actual internal object or a pointer into the
50 * AML stream itself. These types are currently:
58 ******************************************************************************/
61 acpi_aml_resolve_node_to_value (
62 ACPI_NAMESPACE_NODE
**stack_ptr
,
63 ACPI_WALK_STATE
*walk_state
)
66 ACPI_STATUS status
= AE_OK
;
67 ACPI_OPERAND_OBJECT
*val_desc
= NULL
;
68 ACPI_OPERAND_OBJECT
*obj_desc
= NULL
;
69 ACPI_NAMESPACE_NODE
*node
;
70 u8
*aml_pointer
= NULL
;
71 OBJECT_TYPE_INTERNAL entry_type
;
73 u8 attached_aml_pointer
= FALSE
;
75 ACPI_INTEGER temp_val
;
76 OBJECT_TYPE_INTERNAL object_type
;
83 * The stack pointer is a "Direct name ptr", and points to a
84 * a ACPI_NAMESPACE_NODE (Node). Get the pointer that is attached to
88 val_desc
= acpi_ns_get_attached_object ((ACPI_HANDLE
) node
);
89 entry_type
= acpi_ns_get_type ((ACPI_HANDLE
) node
);
92 * The Val_desc attached to the Node can be either:
93 * 1) An internal ACPI object
94 * 2) A pointer into the AML stream (into one of the ACPI system tables)
97 if (acpi_tb_system_table_pointer (val_desc
)) {
98 attached_aml_pointer
= TRUE
;
99 aml_opcode
= *((u8
*) val_desc
);
100 aml_pointer
= ((u8
*) val_desc
) + 1;
106 * Several Entry_types do not require further processing, so
107 * we will return immediately
109 /* Devices rarely have an attached object, return the Node
110 * and Method locals and arguments have a pseudo-Node
112 if (entry_type
== ACPI_TYPE_DEVICE
||
113 (node
->flags
& (ANOBJ_METHOD_ARG
| ANOBJ_METHOD_LOCAL
))) {
118 return (AE_AML_NO_OPERAND
);
122 * Action is based on the type of the Node, which indicates the type
123 * of the attached object or pointer
125 switch (entry_type
) {
127 case ACPI_TYPE_PACKAGE
:
129 if (attached_aml_pointer
) {
131 * This means that the package initialization is not parsed
132 * -- should not happen
134 return (AE_NOT_IMPLEMENTED
);
137 /* Val_desc is an internal object in all cases by the time we get here */
139 if (ACPI_TYPE_PACKAGE
!= val_desc
->common
.type
) {
140 return (AE_AML_OPERAND_TYPE
);
143 /* Return an additional reference to the object */
146 acpi_cm_add_reference (obj_desc
);
150 case ACPI_TYPE_BUFFER
:
152 if (attached_aml_pointer
) {
154 * This means that the buffer initialization is not parsed
155 * -- should not happen
157 return (AE_NOT_IMPLEMENTED
);
160 /* Val_desc is an internal object in all cases by the time we get here */
162 if (ACPI_TYPE_BUFFER
!= val_desc
->common
.type
) {
163 return (AE_AML_OPERAND_TYPE
);
166 /* Return an additional reference to the object */
169 acpi_cm_add_reference (obj_desc
);
173 case ACPI_TYPE_STRING
:
175 if (attached_aml_pointer
) {
176 /* Allocate a new string object */
178 obj_desc
= acpi_cm_create_internal_object (ACPI_TYPE_STRING
);
180 return (AE_NO_MEMORY
);
183 /* Init the internal object */
185 obj_desc
->string
.pointer
= (NATIVE_CHAR
*) aml_pointer
;
186 obj_desc
->string
.length
= STRLEN (obj_desc
->string
.pointer
);
190 if (ACPI_TYPE_STRING
!= val_desc
->common
.type
) {
191 return (AE_AML_OPERAND_TYPE
);
194 /* Return an additional reference to the object */
197 acpi_cm_add_reference (obj_desc
);
203 case ACPI_TYPE_INTEGER
:
206 * The Node has an attached internal object, make sure that it's a
210 if (ACPI_TYPE_INTEGER
!= val_desc
->common
.type
) {
211 return (AE_AML_OPERAND_TYPE
);
214 /* Return an additional reference to the object */
217 acpi_cm_add_reference (obj_desc
);
221 case INTERNAL_TYPE_DEF_FIELD
:
224 * TBD: [Investigate] Is this the correct solution?
226 * This section was extended to convert to generic buffer if
227 * the return length is greater than 32 bits, but still allows
228 * for returning a type Number for smaller values because the
229 * caller can then apply arithmetic operators on those fields.
231 * XXX - Implementation limitation: Fields are implemented as type
232 * XXX - Number, but they really are supposed to be type Buffer.
233 * XXX - The two are interchangeable only for lengths <= 32 bits.
235 if(val_desc
->field
.length
> 32) {
236 object_type
= ACPI_TYPE_BUFFER
;
239 object_type
= ACPI_TYPE_INTEGER
;
243 * Create the destination buffer object and the buffer space.
245 obj_desc
= acpi_cm_create_internal_object (object_type
);
247 return (AE_NO_MEMORY
);
251 * Fill in the object specific details
253 if (ACPI_TYPE_BUFFER
== object_type
) {
254 obj_desc
->buffer
.pointer
= acpi_cm_callocate (val_desc
->field
.length
);
255 if (!obj_desc
->buffer
.pointer
) {
256 acpi_cm_remove_reference(obj_desc
);
257 return (AE_NO_MEMORY
);
260 obj_desc
->buffer
.length
= val_desc
->field
.length
;
262 status
= acpi_aml_access_named_field (ACPI_READ
, (ACPI_HANDLE
) node
,
263 obj_desc
->buffer
.pointer
, obj_desc
->buffer
.length
);
265 if (ACPI_FAILURE (status
)) {
270 status
= acpi_aml_access_named_field (ACPI_READ
, (ACPI_HANDLE
) node
,
271 &temp_val
, sizeof (temp_val
));
273 if (ACPI_FAILURE (status
)) {
277 obj_desc
->integer
.value
= temp_val
;
284 case INTERNAL_TYPE_BANK_FIELD
:
286 if (attached_aml_pointer
) {
287 return (AE_AML_OPERAND_TYPE
);
290 if (INTERNAL_TYPE_BANK_FIELD
!= val_desc
->common
.type
) {
291 return (AE_AML_OPERAND_TYPE
);
295 /* Get the global lock if needed */
297 obj_desc
= (ACPI_OPERAND_OBJECT
*) *stack_ptr
;
298 locked
= acpi_aml_acquire_global_lock (obj_desc
->field_unit
.lock_rule
);
300 /* Set Index value to select proper Data register */
301 /* perform the update */
303 status
= acpi_aml_access_named_field (ACPI_WRITE
,
304 val_desc
->bank_field
.bank_select
, &val_desc
->bank_field
.value
,
305 sizeof (val_desc
->bank_field
.value
));
307 acpi_aml_release_global_lock (locked
);
310 if (ACPI_FAILURE (status
)) {
314 /* Read Data value */
316 status
= acpi_aml_access_named_field (ACPI_READ
,
317 (ACPI_HANDLE
) val_desc
->bank_field
.container
,
318 &temp_val
, sizeof (temp_val
));
319 if (ACPI_FAILURE (status
)) {
323 /* Create an object for the result */
325 obj_desc
= acpi_cm_create_internal_object (ACPI_TYPE_INTEGER
);
327 return (AE_NO_MEMORY
);
330 obj_desc
->integer
.value
= temp_val
;
334 case INTERNAL_TYPE_INDEX_FIELD
:
336 if (attached_aml_pointer
) {
337 return (AE_AML_OPERAND_TYPE
);
340 if (INTERNAL_TYPE_INDEX_FIELD
!= val_desc
->common
.type
) {
341 return (AE_AML_OPERAND_TYPE
);
345 /* Set Index value to select proper Data register */
346 /* Get the global lock if needed */
348 obj_desc
= (ACPI_OPERAND_OBJECT
*) *stack_ptr
;
349 locked
= acpi_aml_acquire_global_lock (obj_desc
->field_unit
.lock_rule
);
351 /* Perform the update */
353 status
= acpi_aml_access_named_field (ACPI_WRITE
,
354 val_desc
->index_field
.index
, &val_desc
->index_field
.value
,
355 sizeof (val_desc
->index_field
.value
));
357 acpi_aml_release_global_lock (locked
);
359 if (ACPI_FAILURE (status
)) {
363 /* Read Data value */
365 status
= acpi_aml_access_named_field (ACPI_READ
, val_desc
->index_field
.data
,
366 &temp_val
, sizeof (temp_val
));
367 if (ACPI_FAILURE (status
)) {
371 /* Create an object for the result */
373 obj_desc
= acpi_cm_create_internal_object (ACPI_TYPE_INTEGER
);
375 return (AE_NO_MEMORY
);
378 obj_desc
->integer
.value
= temp_val
;
382 case ACPI_TYPE_FIELD_UNIT
:
384 if (attached_aml_pointer
) {
385 return (AE_AML_OPERAND_TYPE
);
388 if (val_desc
->common
.type
!= (u8
) entry_type
) {
389 return (AE_AML_OPERAND_TYPE
);
393 /* Create object for result */
395 obj_desc
= acpi_cm_create_internal_object (ACPI_TYPE_ANY
);
397 return (AE_NO_MEMORY
);
400 status
= acpi_aml_get_field_unit_value (val_desc
, obj_desc
);
401 if (ACPI_FAILURE (status
)) {
402 acpi_cm_remove_reference (obj_desc
);
410 * For these objects, just return the object attached to the Node
413 case ACPI_TYPE_MUTEX
:
414 case ACPI_TYPE_METHOD
:
415 case ACPI_TYPE_POWER
:
416 case ACPI_TYPE_PROCESSOR
:
417 case ACPI_TYPE_THERMAL
:
418 case ACPI_TYPE_EVENT
:
419 case ACPI_TYPE_REGION
:
422 /* Return an additional reference to the object */
425 acpi_cm_add_reference (obj_desc
);
429 /* TYPE_Any is untyped, and thus there is no object associated with it */
433 return (AE_AML_OPERAND_TYPE
); /* Cannot be AE_TYPE */
438 * The only named references allowed are named constants
440 * e.g. Name (\OSFL, Ones)
442 case INTERNAL_TYPE_REFERENCE
:
444 switch (val_desc
->reference
.opcode
) {
460 temp_val
= ACPI_INTEGER_MAX
;
466 return (AE_AML_BAD_OPCODE
);
469 /* Create object for result */
471 obj_desc
= acpi_cm_create_internal_object (ACPI_TYPE_INTEGER
);
473 return (AE_NO_MEMORY
);
476 obj_desc
->integer
.value
= temp_val
;
478 /* Truncate value if we are executing from a 32-bit ACPI table */
480 acpi_aml_truncate_for32bit_table (obj_desc
, walk_state
);
484 /* Default case is for unknown types */
488 return (AE_AML_OPERAND_TYPE
);
490 } /* switch (Entry_type) */
493 /* Put the object descriptor on the stack */
495 *stack_ptr
= (void *) obj_desc
;