Merge trunk HEAD (r46369)
[reactos.git] / reactos / drivers / bus / acpi / executer / amresnte.c
1
2 /******************************************************************************
3 *
4 * Module Name: amresnte - AML Interpreter object resolution
5 * $Revision: 1.1 $
6 *
7 *****************************************************************************/
8
9 /*
10 * Copyright (C) 2000, 2001 R. Byron Moore
11 *
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.
16 *
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.
21 *
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
25 */
26
27
28 #include <acpi.h>
29
30
31
32 #define _COMPONENT ACPI_EXECUTER
33 MODULE_NAME ("amresnte")
34
35
36 /*******************************************************************************
37 *
38 * FUNCTION: Acpi_aml_resolve_node_to_value
39 *
40 * PARAMETERS: Stack_ptr - Pointer to a location on a stack that contains
41 * a pointer to an Node
42 *
43 * RETURN: Status
44 *
45 * DESCRIPTION: Resolve a ACPI_NAMESPACE_NODE (Node,
46 * A.K.A. a "direct name pointer")
47 *
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:
51 *
52 * ACPI_TYPE_INTEGER
53 * ACPI_TYPE_STRING
54 * ACPI_TYPE_BUFFER
55 * ACPI_TYPE_MUTEX
56 * ACPI_TYPE_PACKAGE
57 *
58 ******************************************************************************/
59
60 ACPI_STATUS
61 acpi_aml_resolve_node_to_value (
62 ACPI_NAMESPACE_NODE **stack_ptr,
63 ACPI_WALK_STATE *walk_state)
64
65 {
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;
72 u8 locked;
73 u8 attached_aml_pointer = FALSE;
74 u8 aml_opcode = 0;
75 ACPI_INTEGER temp_val;
76 OBJECT_TYPE_INTERNAL object_type;
77
78
79 node = *stack_ptr;
80
81
82 /*
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
85 * the Node.
86 */
87
88 val_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) node);
89 entry_type = acpi_ns_get_type ((ACPI_HANDLE) node);
90
91 /*
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)
95 */
96
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;
101
102 }
103
104
105 /*
106 * Several Entry_types do not require further processing, so
107 * we will return immediately
108 */
109 /* Devices rarely have an attached object, return the Node
110 * and Method locals and arguments have a pseudo-Node
111 */
112 if (entry_type == ACPI_TYPE_DEVICE ||
113 (node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) {
114 return (AE_OK);
115 }
116
117 if (!val_desc) {
118 return (AE_AML_NO_OPERAND);
119 }
120
121 /*
122 * Action is based on the type of the Node, which indicates the type
123 * of the attached object or pointer
124 */
125 switch (entry_type) {
126
127 case ACPI_TYPE_PACKAGE:
128
129 if (attached_aml_pointer) {
130 /*
131 * This means that the package initialization is not parsed
132 * -- should not happen
133 */
134 return (AE_NOT_IMPLEMENTED);
135 }
136
137 /* Val_desc is an internal object in all cases by the time we get here */
138
139 if (ACPI_TYPE_PACKAGE != val_desc->common.type) {
140 return (AE_AML_OPERAND_TYPE);
141 }
142
143 /* Return an additional reference to the object */
144
145 obj_desc = val_desc;
146 acpi_cm_add_reference (obj_desc);
147 break;
148
149
150 case ACPI_TYPE_BUFFER:
151
152 if (attached_aml_pointer) {
153 /*
154 * This means that the buffer initialization is not parsed
155 * -- should not happen
156 */
157 return (AE_NOT_IMPLEMENTED);
158 }
159
160 /* Val_desc is an internal object in all cases by the time we get here */
161
162 if (ACPI_TYPE_BUFFER != val_desc->common.type) {
163 return (AE_AML_OPERAND_TYPE);
164 }
165
166 /* Return an additional reference to the object */
167
168 obj_desc = val_desc;
169 acpi_cm_add_reference (obj_desc);
170 break;
171
172
173 case ACPI_TYPE_STRING:
174
175 if (attached_aml_pointer) {
176 /* Allocate a new string object */
177
178 obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_STRING);
179 if (!obj_desc) {
180 return (AE_NO_MEMORY);
181 }
182
183 /* Init the internal object */
184
185 obj_desc->string.pointer = (NATIVE_CHAR *) aml_pointer;
186 obj_desc->string.length = STRLEN (obj_desc->string.pointer);
187 }
188
189 else {
190 if (ACPI_TYPE_STRING != val_desc->common.type) {
191 return (AE_AML_OPERAND_TYPE);
192 }
193
194 /* Return an additional reference to the object */
195
196 obj_desc = val_desc;
197 acpi_cm_add_reference (obj_desc);
198 }
199
200 break;
201
202
203 case ACPI_TYPE_INTEGER:
204
205 /*
206 * The Node has an attached internal object, make sure that it's a
207 * number
208 */
209
210 if (ACPI_TYPE_INTEGER != val_desc->common.type) {
211 return (AE_AML_OPERAND_TYPE);
212 }
213
214 /* Return an additional reference to the object */
215
216 obj_desc = val_desc;
217 acpi_cm_add_reference (obj_desc);
218 break;
219
220
221 case INTERNAL_TYPE_DEF_FIELD:
222
223 /*
224 * TBD: [Investigate] Is this the correct solution?
225 *
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.
230 *
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.
234 */
235 if(val_desc->field.length > 32) {
236 object_type = ACPI_TYPE_BUFFER;
237 }
238 else {
239 object_type = ACPI_TYPE_INTEGER;
240 }
241
242 /*
243 * Create the destination buffer object and the buffer space.
244 */
245 obj_desc = acpi_cm_create_internal_object (object_type);
246 if (!obj_desc) {
247 return (AE_NO_MEMORY);
248 }
249
250 /*
251 * Fill in the object specific details
252 */
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);
258 }
259
260 obj_desc->buffer.length = val_desc->field.length;
261
262 status = acpi_aml_access_named_field (ACPI_READ, (ACPI_HANDLE) node,
263 obj_desc->buffer.pointer, obj_desc->buffer.length);
264
265 if (ACPI_FAILURE (status)) {
266 return (status);
267 }
268 }
269 else {
270 status = acpi_aml_access_named_field (ACPI_READ, (ACPI_HANDLE) node,
271 &temp_val, sizeof (temp_val));
272
273 if (ACPI_FAILURE (status)) {
274 return (status);
275 }
276
277 obj_desc->integer.value = temp_val;
278 }
279
280
281 break;
282
283
284 case INTERNAL_TYPE_BANK_FIELD:
285
286 if (attached_aml_pointer) {
287 return (AE_AML_OPERAND_TYPE);
288 }
289
290 if (INTERNAL_TYPE_BANK_FIELD != val_desc->common.type) {
291 return (AE_AML_OPERAND_TYPE);
292 }
293
294
295 /* Get the global lock if needed */
296
297 obj_desc = (ACPI_OPERAND_OBJECT *) *stack_ptr;
298 locked = acpi_aml_acquire_global_lock (obj_desc->field_unit.lock_rule);
299
300 /* Set Index value to select proper Data register */
301 /* perform the update */
302
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));
306
307 acpi_aml_release_global_lock (locked);
308
309
310 if (ACPI_FAILURE (status)) {
311 return (status);
312 }
313
314 /* Read Data value */
315
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)) {
320 return (status);
321 }
322
323 /* Create an object for the result */
324
325 obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
326 if (!obj_desc) {
327 return (AE_NO_MEMORY);
328 }
329
330 obj_desc->integer.value = temp_val;
331 break;
332
333
334 case INTERNAL_TYPE_INDEX_FIELD:
335
336 if (attached_aml_pointer) {
337 return (AE_AML_OPERAND_TYPE);
338 }
339
340 if (INTERNAL_TYPE_INDEX_FIELD != val_desc->common.type) {
341 return (AE_AML_OPERAND_TYPE);
342 }
343
344
345 /* Set Index value to select proper Data register */
346 /* Get the global lock if needed */
347
348 obj_desc = (ACPI_OPERAND_OBJECT *) *stack_ptr;
349 locked = acpi_aml_acquire_global_lock (obj_desc->field_unit.lock_rule);
350
351 /* Perform the update */
352
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));
356
357 acpi_aml_release_global_lock (locked);
358
359 if (ACPI_FAILURE (status)) {
360 return (status);
361 }
362
363 /* Read Data value */
364
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)) {
368 return (status);
369 }
370
371 /* Create an object for the result */
372
373 obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
374 if (!obj_desc) {
375 return (AE_NO_MEMORY);
376 }
377
378 obj_desc->integer.value = temp_val;
379 break;
380
381
382 case ACPI_TYPE_FIELD_UNIT:
383
384 if (attached_aml_pointer) {
385 return (AE_AML_OPERAND_TYPE);
386 }
387
388 if (val_desc->common.type != (u8) entry_type) {
389 return (AE_AML_OPERAND_TYPE);
390 break;
391 }
392
393 /* Create object for result */
394
395 obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_ANY);
396 if (!obj_desc) {
397 return (AE_NO_MEMORY);
398 }
399
400 status = acpi_aml_get_field_unit_value (val_desc, obj_desc);
401 if (ACPI_FAILURE (status)) {
402 acpi_cm_remove_reference (obj_desc);
403 return (status);
404 }
405
406 break;
407
408
409 /*
410 * For these objects, just return the object attached to the Node
411 */
412
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:
420
421
422 /* Return an additional reference to the object */
423
424 obj_desc = val_desc;
425 acpi_cm_add_reference (obj_desc);
426 break;
427
428
429 /* TYPE_Any is untyped, and thus there is no object associated with it */
430
431 case ACPI_TYPE_ANY:
432
433 return (AE_AML_OPERAND_TYPE); /* Cannot be AE_TYPE */
434 break;
435
436
437 /*
438 * The only named references allowed are named constants
439 *
440 * e.g. Name (\OSFL, Ones)
441 */
442 case INTERNAL_TYPE_REFERENCE:
443
444 switch (val_desc->reference.opcode) {
445
446 case AML_ZERO_OP:
447
448 temp_val = 0;
449 break;
450
451
452 case AML_ONE_OP:
453
454 temp_val = 1;
455 break;
456
457
458 case AML_ONES_OP:
459
460 temp_val = ACPI_INTEGER_MAX;
461 break;
462
463
464 default:
465
466 return (AE_AML_BAD_OPCODE);
467 }
468
469 /* Create object for result */
470
471 obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
472 if (!obj_desc) {
473 return (AE_NO_MEMORY);
474 }
475
476 obj_desc->integer.value = temp_val;
477
478 /* Truncate value if we are executing from a 32-bit ACPI table */
479
480 acpi_aml_truncate_for32bit_table (obj_desc, walk_state);
481 break;
482
483
484 /* Default case is for unknown types */
485
486 default:
487
488 return (AE_AML_OPERAND_TYPE);
489
490 } /* switch (Entry_type) */
491
492
493 /* Put the object descriptor on the stack */
494
495 *stack_ptr = (void *) obj_desc;
496
497 return (status);
498 }
499
500