blob: e3ca7f6539c1318a4a5012ba28481ed6508e58e6 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/******************************************************************************
2 *
3 * Module Name: dswload - Dispatcher namespace load callbacks
4 *
5 *****************************************************************************/
6
7/*
Bob Moore4a90c7e2006-01-13 16:22:00 -05008 * Copyright (C) 2000 - 2006, R. Byron Moore
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <acpi/acpi.h>
45#include <acpi/acparser.h>
46#include <acpi/amlcode.h>
47#include <acpi/acdispat.h>
48#include <acpi/acinterp.h>
49#include <acpi/acnamesp.h>
50#include <acpi/acevents.h>
51
Robert Moore73459f72005-06-24 00:00:00 -040052#ifdef ACPI_ASL_COMPILER
Linus Torvalds1da177e2005-04-16 15:20:36 -070053#include <acpi/acdisasm.h>
54#endif
55
56#define _COMPONENT ACPI_DISPATCHER
Len Brown4be44fc2005-08-05 00:44:28 -040057ACPI_MODULE_NAME("dswload")
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
59/*******************************************************************************
60 *
61 * FUNCTION: acpi_ds_init_callbacks
62 *
63 * PARAMETERS: walk_state - Current state of the parse tree walk
64 * pass_number - 1, 2, or 3
65 *
66 * RETURN: Status
67 *
68 * DESCRIPTION: Init walk state callbacks
69 *
70 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -070071acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -040072acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
Linus Torvalds1da177e2005-04-16 15:20:36 -070073{
74
75 switch (pass_number) {
76 case 1:
Len Brown4be44fc2005-08-05 00:44:28 -040077 walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
78 ACPI_PARSE_DELETE_TREE;
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 walk_state->descending_callback = acpi_ds_load1_begin_op;
80 walk_state->ascending_callback = acpi_ds_load1_end_op;
81 break;
82
83 case 2:
Len Brown4be44fc2005-08-05 00:44:28 -040084 walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
85 ACPI_PARSE_DELETE_TREE;
Linus Torvalds1da177e2005-04-16 15:20:36 -070086 walk_state->descending_callback = acpi_ds_load2_begin_op;
87 walk_state->ascending_callback = acpi_ds_load2_end_op;
88 break;
89
90 case 3:
91#ifndef ACPI_NO_METHOD_EXECUTION
Len Brown4be44fc2005-08-05 00:44:28 -040092 walk_state->parse_flags |= ACPI_PARSE_EXECUTE |
93 ACPI_PARSE_DELETE_TREE;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094 walk_state->descending_callback = acpi_ds_exec_begin_op;
95 walk_state->ascending_callback = acpi_ds_exec_end_op;
96#endif
97 break;
98
99 default:
100 return (AE_BAD_PARAMETER);
101 }
102
103 return (AE_OK);
104}
105
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106/*******************************************************************************
107 *
108 * FUNCTION: acpi_ds_load1_begin_op
109 *
110 * PARAMETERS: walk_state - Current state of the parse tree walk
Robert Moore44f6c012005-04-18 22:49:35 -0400111 * out_op - Where to return op if a new one is created
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 *
113 * RETURN: Status
114 *
115 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
116 *
117 ******************************************************************************/
118
119acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400120acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
121 union acpi_parse_object ** out_op)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122{
Len Brown4be44fc2005-08-05 00:44:28 -0400123 union acpi_parse_object *op;
124 struct acpi_namespace_node *node;
125 acpi_status status;
126 acpi_object_type object_type;
127 char *path;
128 u32 flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129
Bob Mooreb229cf92006-04-21 17:15:00 -0400130 ACPI_FUNCTION_TRACE(ds_load1_begin_op);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
132 op = walk_state->op;
Len Brown4be44fc2005-08-05 00:44:28 -0400133 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
134 walk_state));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
136 /* We are only interested in opcodes that have an associated name */
137
138 if (op) {
139 if (!(walk_state->op_info->flags & AML_NAMED)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 *out_op = op;
Bob Moore28f55eb2005-12-02 18:27:00 -0500141 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142 }
143
144 /* Check if this object has already been installed in the namespace */
145
146 if (op->common.node) {
147 *out_op = op;
Bob Moore28f55eb2005-12-02 18:27:00 -0500148 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 }
150 }
151
Len Brown4be44fc2005-08-05 00:44:28 -0400152 path = acpi_ps_get_next_namestring(&walk_state->parser_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153
154 /* Map the raw opcode into an internal object type */
155
156 object_type = walk_state->op_info->object_type;
157
Len Brown4be44fc2005-08-05 00:44:28 -0400158 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
159 "State=%p Op=%p [%s]\n", walk_state, op,
160 acpi_ut_get_type_name(object_type)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161
162 switch (walk_state->opcode) {
163 case AML_SCOPE_OP:
164
165 /*
166 * The target name of the Scope() operator must exist at this point so
167 * that we can actually open the scope to enter new names underneath it.
168 * Allow search-to-root for single namesegs.
169 */
Len Brown4be44fc2005-08-05 00:44:28 -0400170 status =
171 acpi_ns_lookup(walk_state->scope_info, path, object_type,
172 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
173 walk_state, &(node));
Robert Moore73459f72005-06-24 00:00:00 -0400174#ifdef ACPI_ASL_COMPILER
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175 if (status == AE_NOT_FOUND) {
176 /*
177 * Table disassembly:
Bob Moore967440e2006-06-23 17:04:00 -0400178 * Target of Scope() not found. Generate an External for it, and
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 * insert the name into the namespace.
180 */
Bob Moore958dd242006-05-12 17:12:00 -0400181 acpi_dm_add_to_external_list(path, ACPI_TYPE_DEVICE, 0);
Len Brown4be44fc2005-08-05 00:44:28 -0400182 status =
183 acpi_ns_lookup(walk_state->scope_info, path,
184 object_type, ACPI_IMODE_LOAD_PASS1,
185 ACPI_NS_SEARCH_PARENT, walk_state,
Bob Moore958dd242006-05-12 17:12:00 -0400186 &node);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 }
188#endif
Len Brown4be44fc2005-08-05 00:44:28 -0400189 if (ACPI_FAILURE(status)) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500190 ACPI_ERROR_NAMESPACE(path, status);
Bob Moore28f55eb2005-12-02 18:27:00 -0500191 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192 }
193
194 /*
195 * Check to make sure that the target is
196 * one of the opcodes that actually opens a scope
197 */
198 switch (node->type) {
Len Brown4be44fc2005-08-05 00:44:28 -0400199 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200 case ACPI_TYPE_DEVICE:
201 case ACPI_TYPE_POWER:
202 case ACPI_TYPE_PROCESSOR:
203 case ACPI_TYPE_THERMAL:
204
205 /* These are acceptable types */
206 break;
207
208 case ACPI_TYPE_INTEGER:
209 case ACPI_TYPE_STRING:
210 case ACPI_TYPE_BUFFER:
211
212 /*
Bob Moore967440e2006-06-23 17:04:00 -0400213 * These types we will allow, but we will change the type. This
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 * enables some existing code of the form:
215 *
216 * Name (DEB, 0)
217 * Scope (DEB) { ... }
218 *
Bob Moore967440e2006-06-23 17:04:00 -0400219 * Note: silently change the type here. On the second pass, we will report
Robert Moore44f6c012005-04-18 22:49:35 -0400220 * a warning
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 */
Len Brown4be44fc2005-08-05 00:44:28 -0400222 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
223 "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
224 path,
225 acpi_ut_get_type_name(node->type)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226
227 node->type = ACPI_TYPE_ANY;
228 walk_state->scope_info->common.value = ACPI_TYPE_ANY;
229 break;
230
231 default:
232
233 /* All other types are an error */
234
Bob Mooreb8e4d892006-01-27 16:43:00 -0500235 ACPI_ERROR((AE_INFO,
236 "Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)",
237 acpi_ut_get_type_name(node->type), path));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238
Bob Moore28f55eb2005-12-02 18:27:00 -0500239 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 }
241 break;
242
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244 /*
Robert Moore44f6c012005-04-18 22:49:35 -0400245 * For all other named opcodes, we will enter the name into
246 * the namespace.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 *
248 * Setup the search flags.
249 * Since we are entering a name into the namespace, we do not want to
250 * enable the search-to-root upsearch.
251 *
252 * There are only two conditions where it is acceptable that the name
253 * already exists:
254 * 1) the Scope() operator can reopen a scoping object that was
255 * previously defined (Scope, Method, Device, etc.)
256 * 2) Whenever we are parsing a deferred opcode (op_region, Buffer,
257 * buffer_field, or Package), the name of the object is already
258 * in the namespace.
259 */
260 if (walk_state->deferred_node) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400261
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 /* This name is already in the namespace, get the node */
263
264 node = walk_state->deferred_node;
265 status = AE_OK;
266 break;
267 }
268
Bob Moore28f55eb2005-12-02 18:27:00 -0500269 /*
270 * If we are executing a method, do not create any namespace objects
271 * during the load phase, only during execution.
272 */
273 if (walk_state->method_node) {
274 node = NULL;
275 status = AE_OK;
276 break;
277 }
278
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 flags = ACPI_NS_NO_UPSEARCH;
280 if ((walk_state->opcode != AML_SCOPE_OP) &&
Len Brown4be44fc2005-08-05 00:44:28 -0400281 (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 flags |= ACPI_NS_ERROR_IF_FOUND;
Len Brown4be44fc2005-08-05 00:44:28 -0400283 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
284 "[%s] Cannot already exist\n",
285 acpi_ut_get_type_name(object_type)));
286 } else {
287 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
288 "[%s] Both Find or Create allowed\n",
289 acpi_ut_get_type_name(object_type)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 }
291
292 /*
Bob Moore967440e2006-06-23 17:04:00 -0400293 * Enter the named type into the internal namespace. We enter the name
294 * as we go downward in the parse tree. Any necessary subobjects that
Robert Moore44f6c012005-04-18 22:49:35 -0400295 * involve arguments to the opcode must be created as we go back up the
296 * parse tree later.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297 */
Len Brown4be44fc2005-08-05 00:44:28 -0400298 status =
299 acpi_ns_lookup(walk_state->scope_info, path, object_type,
300 ACPI_IMODE_LOAD_PASS1, flags, walk_state,
Bob Moore958dd242006-05-12 17:12:00 -0400301 &node);
Len Brown4be44fc2005-08-05 00:44:28 -0400302 if (ACPI_FAILURE(status)) {
Bob Moore958dd242006-05-12 17:12:00 -0400303 if (status == AE_ALREADY_EXISTS) {
304
305 /* The name already exists in this scope */
306
307 if (node->flags & ANOBJ_IS_EXTERNAL) {
308 /*
309 * Allow one create on an object or segment that was
310 * previously declared External
311 */
312 node->flags &= ~ANOBJ_IS_EXTERNAL;
313 node->type = (u8) object_type;
314
315 /* Just retyped a node, probably will need to open a scope */
316
317 if (acpi_ns_opens_scope(object_type)) {
318 status =
319 acpi_ds_scope_stack_push
320 (node, object_type,
321 walk_state);
322 if (ACPI_FAILURE(status)) {
323 return_ACPI_STATUS
324 (status);
325 }
326 }
Bob Moore967440e2006-06-23 17:04:00 -0400327
Bob Moore958dd242006-05-12 17:12:00 -0400328 status = AE_OK;
329 }
330 }
331
332 if (ACPI_FAILURE(status)) {
Bob Moore958dd242006-05-12 17:12:00 -0400333 ACPI_ERROR_NAMESPACE(path, status);
334 return_ACPI_STATUS(status);
335 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 }
337 break;
338 }
339
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340 /* Common exit */
341
342 if (!op) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400343
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 /* Create a new op */
345
Len Brown4be44fc2005-08-05 00:44:28 -0400346 op = acpi_ps_alloc_op(walk_state->opcode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347 if (!op) {
Bob Moore28f55eb2005-12-02 18:27:00 -0500348 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 }
350 }
351
Bob Moore28f55eb2005-12-02 18:27:00 -0500352 /* Initialize the op */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353
354#if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY))
Bob Moorec51a4de2005-11-17 13:07:00 -0500355 op->named.path = ACPI_CAST_PTR(u8, path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356#endif
357
Bob Moore28f55eb2005-12-02 18:27:00 -0500358 if (node) {
359 /*
360 * Put the Node in the "op" object that the parser uses, so we
361 * can get it again quickly when this scope is closed
362 */
363 op->common.node = node;
364 op->named.name = node->name.integer;
365 }
366
Len Brown4be44fc2005-08-05 00:44:28 -0400367 acpi_ps_append_arg(acpi_ps_get_parent_scope(&walk_state->parser_state),
368 op);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 *out_op = op;
Bob Moore28f55eb2005-12-02 18:27:00 -0500370 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371}
372
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373/*******************************************************************************
374 *
375 * FUNCTION: acpi_ds_load1_end_op
376 *
377 * PARAMETERS: walk_state - Current state of the parse tree walk
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 *
379 * RETURN: Status
380 *
381 * DESCRIPTION: Ascending callback used during the loading of the namespace,
382 * both control methods and everything else.
383 *
384 ******************************************************************************/
385
Bob Moore28f55eb2005-12-02 18:27:00 -0500386acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387{
Len Brown4be44fc2005-08-05 00:44:28 -0400388 union acpi_parse_object *op;
389 acpi_object_type object_type;
390 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391
Bob Mooreb229cf92006-04-21 17:15:00 -0400392 ACPI_FUNCTION_TRACE(ds_load1_end_op);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393
394 op = walk_state->op;
Len Brown4be44fc2005-08-05 00:44:28 -0400395 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
396 walk_state));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397
398 /* We are only interested in opcodes that have an associated name */
399
400 if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) {
Bob Moore28f55eb2005-12-02 18:27:00 -0500401 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 }
403
404 /* Get the object type to determine if we should pop the scope */
405
406 object_type = walk_state->op_info->object_type;
407
408#ifndef ACPI_NO_METHOD_EXECUTION
409 if (walk_state->op_info->flags & AML_FIELD) {
Bob Moore28f55eb2005-12-02 18:27:00 -0500410 /*
411 * If we are executing a method, do not create any namespace objects
412 * during the load phase, only during execution.
413 */
414 if (!walk_state->method_node) {
415 if (walk_state->opcode == AML_FIELD_OP ||
416 walk_state->opcode == AML_BANK_FIELD_OP ||
417 walk_state->opcode == AML_INDEX_FIELD_OP) {
418 status =
419 acpi_ds_init_field_objects(op, walk_state);
420 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 }
Bob Moore28f55eb2005-12-02 18:27:00 -0500422 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 }
424
Bob Moore28f55eb2005-12-02 18:27:00 -0500425 /*
426 * If we are executing a method, do not create any namespace objects
427 * during the load phase, only during execution.
428 */
429 if (!walk_state->method_node) {
430 if (op->common.aml_opcode == AML_REGION_OP) {
431 status =
432 acpi_ex_create_region(op->named.data,
433 op->named.length,
Bob Moore967440e2006-06-23 17:04:00 -0400434 (acpi_adr_space_type) ((op->
435 common.
436 value.
437 arg)->
438 common.
439 value.
440 integer),
Bob Moore28f55eb2005-12-02 18:27:00 -0500441 walk_state);
442 if (ACPI_FAILURE(status)) {
443 return_ACPI_STATUS(status);
444 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 }
446 }
447#endif
448
449 if (op->common.aml_opcode == AML_NAME_OP) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400450
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 /* For Name opcode, get the object type from the argument */
452
453 if (op->common.value.arg) {
Len Brown4be44fc2005-08-05 00:44:28 -0400454 object_type = (acpi_ps_get_opcode_info((op->common.
455 value.arg)->
456 common.
457 aml_opcode))->
458 object_type;
Bob Moore28f55eb2005-12-02 18:27:00 -0500459
460 /* Set node type if we have a namespace node */
461
462 if (op->common.node) {
463 op->common.node->type = (u8) object_type;
464 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 }
466 }
467
Bob Mooredefba1d2005-12-16 17:05:00 -0500468 /*
469 * If we are executing a method, do not create any namespace objects
470 * during the load phase, only during execution.
471 */
472 if (!walk_state->method_node) {
473 if (op->common.aml_opcode == AML_METHOD_OP) {
474 /*
475 * method_op pkg_length name_string method_flags term_list
476 *
477 * Note: We must create the method node/object pair as soon as we
Bob Moore967440e2006-06-23 17:04:00 -0400478 * see the method declaration. This allows later pass1 parsing
Bob Mooredefba1d2005-12-16 17:05:00 -0500479 * of invocations of the method (need to know the number of
480 * arguments.)
481 */
482 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
Bob Mooreb229cf92006-04-21 17:15:00 -0400483 "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
Bob Mooredefba1d2005-12-16 17:05:00 -0500484 walk_state, op, op->named.node));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485
Bob Mooredefba1d2005-12-16 17:05:00 -0500486 if (!acpi_ns_get_attached_object(op->named.node)) {
487 walk_state->operands[0] =
488 ACPI_CAST_PTR(void, op->named.node);
489 walk_state->num_operands = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490
Bob Mooredefba1d2005-12-16 17:05:00 -0500491 status =
492 acpi_ds_create_operands(walk_state,
493 op->common.value.
494 arg);
495 if (ACPI_SUCCESS(status)) {
496 status =
497 acpi_ex_create_method(op->named.
498 data,
499 op->named.
500 length,
501 walk_state);
502 }
Bob Moore967440e2006-06-23 17:04:00 -0400503
Bob Mooredefba1d2005-12-16 17:05:00 -0500504 walk_state->operands[0] = NULL;
505 walk_state->num_operands = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506
Bob Mooredefba1d2005-12-16 17:05:00 -0500507 if (ACPI_FAILURE(status)) {
508 return_ACPI_STATUS(status);
509 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 }
511 }
512 }
513
Bob Mooredefba1d2005-12-16 17:05:00 -0500514 /* Pop the scope stack (only if loading a table) */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515
Bob Mooredefba1d2005-12-16 17:05:00 -0500516 if (!walk_state->method_node && acpi_ns_opens_scope(object_type)) {
Len Brown4be44fc2005-08-05 00:44:28 -0400517 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
518 "(%s): Popping scope for Op %p\n",
519 acpi_ut_get_type_name(object_type), op));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520
Len Brown4be44fc2005-08-05 00:44:28 -0400521 status = acpi_ds_scope_stack_pop(walk_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 }
523
Bob Moore28f55eb2005-12-02 18:27:00 -0500524 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525}
526
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527/*******************************************************************************
528 *
529 * FUNCTION: acpi_ds_load2_begin_op
530 *
531 * PARAMETERS: walk_state - Current state of the parse tree walk
Robert Moore44f6c012005-04-18 22:49:35 -0400532 * out_op - Wher to return op if a new one is created
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 *
534 * RETURN: Status
535 *
536 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
537 *
538 ******************************************************************************/
539
540acpi_status
Bob Moore28f55eb2005-12-02 18:27:00 -0500541acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
542 union acpi_parse_object **out_op)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543{
Len Brown4be44fc2005-08-05 00:44:28 -0400544 union acpi_parse_object *op;
545 struct acpi_namespace_node *node;
546 acpi_status status;
547 acpi_object_type object_type;
548 char *buffer_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
Bob Mooreb229cf92006-04-21 17:15:00 -0400550 ACPI_FUNCTION_TRACE(ds_load2_begin_op);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551
552 op = walk_state->op;
Len Brown4be44fc2005-08-05 00:44:28 -0400553 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
554 walk_state));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555
556 if (op) {
Robert Moore88ac00f2005-05-26 00:00:00 -0400557 if ((walk_state->control_state) &&
Len Brown4be44fc2005-08-05 00:44:28 -0400558 (walk_state->control_state->common.state ==
559 ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400560
Robert Moore88ac00f2005-05-26 00:00:00 -0400561 /* We are executing a while loop outside of a method */
562
Len Brown4be44fc2005-08-05 00:44:28 -0400563 status = acpi_ds_exec_begin_op(walk_state, out_op);
564 return_ACPI_STATUS(status);
Robert Moore88ac00f2005-05-26 00:00:00 -0400565 }
566
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 /* We only care about Namespace opcodes here */
568
Robert Moore44f6c012005-04-18 22:49:35 -0400569 if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&
Len Brown4be44fc2005-08-05 00:44:28 -0400570 (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
571 (!(walk_state->op_info->flags & AML_NAMED))) {
Robert Mooreaff8c272005-09-02 17:24:17 -0400572#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
Robert Moore44f6c012005-04-18 22:49:35 -0400573 if ((walk_state->op_info->class == AML_CLASS_EXECUTE) ||
Len Brown4be44fc2005-08-05 00:44:28 -0400574 (walk_state->op_info->class == AML_CLASS_CONTROL)) {
575 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
576 "Begin/EXEC: %s (fl %8.8X)\n",
577 walk_state->op_info->name,
578 walk_state->op_info->flags));
Robert Moore88ac00f2005-05-26 00:00:00 -0400579
580 /* Executing a type1 or type2 opcode outside of a method */
581
Len Brown4be44fc2005-08-05 00:44:28 -0400582 status =
583 acpi_ds_exec_begin_op(walk_state, out_op);
584 return_ACPI_STATUS(status);
Robert Moore44f6c012005-04-18 22:49:35 -0400585 }
Robert Mooreaff8c272005-09-02 17:24:17 -0400586#endif
Len Brown4be44fc2005-08-05 00:44:28 -0400587 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 }
589
Robert Moore44f6c012005-04-18 22:49:35 -0400590 /* Get the name we are going to enter or lookup in the namespace */
591
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592 if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400593
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 /* For Namepath op, get the path string */
595
596 buffer_ptr = op->common.value.string;
597 if (!buffer_ptr) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400598
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 /* No name, just exit */
600
Len Brown4be44fc2005-08-05 00:44:28 -0400601 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 }
Len Brown4be44fc2005-08-05 00:44:28 -0400603 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 /* Get name from the op */
605
Bob Moore967440e2006-06-23 17:04:00 -0400606 buffer_ptr = ACPI_CAST_PTR(char, &op->named.name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 }
Len Brown4be44fc2005-08-05 00:44:28 -0400608 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 /* Get the namestring from the raw AML */
610
Len Brown4be44fc2005-08-05 00:44:28 -0400611 buffer_ptr =
612 acpi_ps_get_next_namestring(&walk_state->parser_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 }
614
615 /* Map the opcode into an internal object type */
616
617 object_type = walk_state->op_info->object_type;
618
Len Brown4be44fc2005-08-05 00:44:28 -0400619 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
620 "State=%p Op=%p Type=%X\n", walk_state, op,
621 object_type));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622
623 switch (walk_state->opcode) {
624 case AML_FIELD_OP:
625 case AML_BANK_FIELD_OP:
626 case AML_INDEX_FIELD_OP:
627
628 node = NULL;
629 status = AE_OK;
630 break;
631
632 case AML_INT_NAMEPATH_OP:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 /*
Robert Moore44f6c012005-04-18 22:49:35 -0400634 * The name_path is an object reference to an existing object.
635 * Don't enter the name into the namespace, but look it up
636 * for use later.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 */
Len Brown4be44fc2005-08-05 00:44:28 -0400638 status =
639 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
640 object_type, ACPI_IMODE_EXECUTE,
641 ACPI_NS_SEARCH_PARENT, walk_state, &(node));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 break;
643
644 case AML_SCOPE_OP:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 /*
Robert Moore44f6c012005-04-18 22:49:35 -0400646 * The Path is an object reference to an existing object.
647 * Don't enter the name into the namespace, but look it up
648 * for use later.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649 */
Len Brown4be44fc2005-08-05 00:44:28 -0400650 status =
651 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
652 object_type, ACPI_IMODE_EXECUTE,
653 ACPI_NS_SEARCH_PARENT, walk_state, &(node));
654 if (ACPI_FAILURE(status)) {
Robert Moore73459f72005-06-24 00:00:00 -0400655#ifdef ACPI_ASL_COMPILER
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 if (status == AE_NOT_FOUND) {
657 status = AE_OK;
Len Brown4be44fc2005-08-05 00:44:28 -0400658 } else {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500659 ACPI_ERROR_NAMESPACE(buffer_ptr, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 }
661#else
Bob Mooreb8e4d892006-01-27 16:43:00 -0500662 ACPI_ERROR_NAMESPACE(buffer_ptr, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663#endif
Len Brown4be44fc2005-08-05 00:44:28 -0400664 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 }
Bob Moore967440e2006-06-23 17:04:00 -0400666
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 /*
668 * We must check to make sure that the target is
669 * one of the opcodes that actually opens a scope
670 */
671 switch (node->type) {
Len Brown4be44fc2005-08-05 00:44:28 -0400672 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 case ACPI_TYPE_DEVICE:
674 case ACPI_TYPE_POWER:
675 case ACPI_TYPE_PROCESSOR:
676 case ACPI_TYPE_THERMAL:
677
678 /* These are acceptable types */
679 break;
680
681 case ACPI_TYPE_INTEGER:
682 case ACPI_TYPE_STRING:
683 case ACPI_TYPE_BUFFER:
684
685 /*
Bob Moore967440e2006-06-23 17:04:00 -0400686 * These types we will allow, but we will change the type. This
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 * enables some existing code of the form:
688 *
689 * Name (DEB, 0)
690 * Scope (DEB) { ... }
691 */
Bob Mooreb8e4d892006-01-27 16:43:00 -0500692 ACPI_WARNING((AE_INFO,
693 "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)",
694 buffer_ptr,
695 acpi_ut_get_type_name(node->type)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696
697 node->type = ACPI_TYPE_ANY;
698 walk_state->scope_info->common.value = ACPI_TYPE_ANY;
699 break;
700
701 default:
702
703 /* All other types are an error */
704
Bob Mooreb8e4d892006-01-27 16:43:00 -0500705 ACPI_ERROR((AE_INFO,
706 "Invalid type (%s) for target of Scope operator [%4.4s]",
707 acpi_ut_get_type_name(node->type),
708 buffer_ptr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709
710 return (AE_AML_OPERAND_TYPE);
711 }
712 break;
713
714 default:
715
716 /* All other opcodes */
717
718 if (op && op->common.node) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400719
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 /* This op/node was previously entered into the namespace */
721
722 node = op->common.node;
723
Len Brown4be44fc2005-08-05 00:44:28 -0400724 if (acpi_ns_opens_scope(object_type)) {
725 status =
726 acpi_ds_scope_stack_push(node, object_type,
727 walk_state);
728 if (ACPI_FAILURE(status)) {
729 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 }
Bob Moore967440e2006-06-23 17:04:00 -0400732
Len Brown4be44fc2005-08-05 00:44:28 -0400733 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734 }
735
736 /*
Bob Moore967440e2006-06-23 17:04:00 -0400737 * Enter the named type into the internal namespace. We enter the name
738 * as we go downward in the parse tree. Any necessary subobjects that
Robert Moore44f6c012005-04-18 22:49:35 -0400739 * involve arguments to the opcode must be created as we go back up the
740 * parse tree later.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741 *
742 * Note: Name may already exist if we are executing a deferred opcode.
743 */
744 if (walk_state->deferred_node) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400745
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 /* This name is already in the namespace, get the node */
747
748 node = walk_state->deferred_node;
749 status = AE_OK;
750 break;
751 }
752
Robert Moore88ac00f2005-05-26 00:00:00 -0400753 /* Add new entry into namespace */
754
Len Brown4be44fc2005-08-05 00:44:28 -0400755 status =
756 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
757 object_type, ACPI_IMODE_LOAD_PASS2,
758 ACPI_NS_NO_UPSEARCH, walk_state, &(node));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 break;
760 }
761
Len Brown4be44fc2005-08-05 00:44:28 -0400762 if (ACPI_FAILURE(status)) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500763 ACPI_ERROR_NAMESPACE(buffer_ptr, status);
Len Brown4be44fc2005-08-05 00:44:28 -0400764 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 }
766
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 if (!op) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400768
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 /* Create a new op */
770
Len Brown4be44fc2005-08-05 00:44:28 -0400771 op = acpi_ps_alloc_op(walk_state->opcode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 if (!op) {
Len Brown4be44fc2005-08-05 00:44:28 -0400773 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 }
775
776 /* Initialize the new op */
777
778 if (node) {
779 op->named.name = node->name.integer;
780 }
Robert Moore88ac00f2005-05-26 00:00:00 -0400781 *out_op = op;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 }
783
784 /*
785 * Put the Node in the "op" object that the parser uses, so we
786 * can get it again quickly when this scope is closed
787 */
788 op->common.node = node;
Len Brown4be44fc2005-08-05 00:44:28 -0400789 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790}
791
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792/*******************************************************************************
793 *
794 * FUNCTION: acpi_ds_load2_end_op
795 *
796 * PARAMETERS: walk_state - Current state of the parse tree walk
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797 *
798 * RETURN: Status
799 *
800 * DESCRIPTION: Ascending callback used during the loading of the namespace,
801 * both control methods and everything else.
802 *
803 ******************************************************************************/
804
Len Brown4be44fc2005-08-05 00:44:28 -0400805acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806{
Len Brown4be44fc2005-08-05 00:44:28 -0400807 union acpi_parse_object *op;
808 acpi_status status = AE_OK;
809 acpi_object_type object_type;
810 struct acpi_namespace_node *node;
811 union acpi_parse_object *arg;
812 struct acpi_namespace_node *new_node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813#ifndef ACPI_NO_METHOD_EXECUTION
Len Brown4be44fc2005-08-05 00:44:28 -0400814 u32 i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815#endif
816
Bob Mooreb229cf92006-04-21 17:15:00 -0400817 ACPI_FUNCTION_TRACE(ds_load2_end_op);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818
819 op = walk_state->op;
Len Brown4be44fc2005-08-05 00:44:28 -0400820 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
821 walk_state->op_info->name, op, walk_state));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822
Robert Moore88ac00f2005-05-26 00:00:00 -0400823 /* Check if opcode had an associated namespace object */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824
825 if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
Robert Moore88ac00f2005-05-26 00:00:00 -0400826#ifndef ACPI_NO_METHOD_EXECUTION
Robert Mooreaff8c272005-09-02 17:24:17 -0400827#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
Robert Moore88ac00f2005-05-26 00:00:00 -0400828 /* No namespace object. Executable opcode? */
829
830 if ((walk_state->op_info->class == AML_CLASS_EXECUTE) ||
Len Brown4be44fc2005-08-05 00:44:28 -0400831 (walk_state->op_info->class == AML_CLASS_CONTROL)) {
832 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
833 "End/EXEC: %s (fl %8.8X)\n",
834 walk_state->op_info->name,
835 walk_state->op_info->flags));
Robert Moore88ac00f2005-05-26 00:00:00 -0400836
837 /* Executing a type1 or type2 opcode outside of a method */
838
Len Brown4be44fc2005-08-05 00:44:28 -0400839 status = acpi_ds_exec_end_op(walk_state);
840 return_ACPI_STATUS(status);
Robert Moore88ac00f2005-05-26 00:00:00 -0400841 }
842#endif
Robert Mooreaff8c272005-09-02 17:24:17 -0400843#endif
Len Brown4be44fc2005-08-05 00:44:28 -0400844 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 }
846
847 if (op->common.aml_opcode == AML_SCOPE_OP) {
Len Brown4be44fc2005-08-05 00:44:28 -0400848 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
849 "Ending scope Op=%p State=%p\n", op,
850 walk_state));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 }
852
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853 object_type = walk_state->op_info->object_type;
854
855 /*
856 * Get the Node/name from the earlier lookup
857 * (It was saved in the *op structure)
858 */
859 node = op->common.node;
860
861 /*
862 * Put the Node on the object stack (Contains the ACPI Name of
863 * this object)
864 */
Len Brown4be44fc2005-08-05 00:44:28 -0400865 walk_state->operands[0] = (void *)node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 walk_state->num_operands = 1;
867
868 /* Pop the scope stack */
869
Len Brown4be44fc2005-08-05 00:44:28 -0400870 if (acpi_ns_opens_scope(object_type) &&
871 (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
872 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
873 "(%s) Popping scope for Op %p\n",
874 acpi_ut_get_type_name(object_type), op));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875
Len Brown4be44fc2005-08-05 00:44:28 -0400876 status = acpi_ds_scope_stack_pop(walk_state);
877 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878 goto cleanup;
879 }
880 }
881
882 /*
883 * Named operations are as follows:
884 *
885 * AML_ALIAS
886 * AML_BANKFIELD
887 * AML_CREATEBITFIELD
888 * AML_CREATEBYTEFIELD
889 * AML_CREATEDWORDFIELD
890 * AML_CREATEFIELD
891 * AML_CREATEQWORDFIELD
892 * AML_CREATEWORDFIELD
893 * AML_DATA_REGION
894 * AML_DEVICE
895 * AML_EVENT
896 * AML_FIELD
897 * AML_INDEXFIELD
898 * AML_METHOD
899 * AML_METHODCALL
900 * AML_MUTEX
901 * AML_NAME
902 * AML_NAMEDFIELD
903 * AML_OPREGION
904 * AML_POWERRES
905 * AML_PROCESSOR
906 * AML_SCOPE
907 * AML_THERMALZONE
908 */
909
Len Brown4be44fc2005-08-05 00:44:28 -0400910 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
Bob Mooreb229cf92006-04-21 17:15:00 -0400911 "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
Len Brown4be44fc2005-08-05 00:44:28 -0400912 acpi_ps_get_opcode_name(op->common.aml_opcode),
913 walk_state, op, node));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914
915 /* Decode the opcode */
916
917 arg = op->common.value.arg;
918
919 switch (walk_state->op_info->type) {
920#ifndef ACPI_NO_METHOD_EXECUTION
921
922 case AML_TYPE_CREATE_FIELD:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923 /*
924 * Create the field object, but the field buffer and index must
925 * be evaluated later during the execution phase
926 */
Len Brown4be44fc2005-08-05 00:44:28 -0400927 status = acpi_ds_create_buffer_field(op, walk_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 break;
929
Len Brown4be44fc2005-08-05 00:44:28 -0400930 case AML_TYPE_NAMED_FIELD:
Bob Moore28f55eb2005-12-02 18:27:00 -0500931 /*
932 * If we are executing a method, initialize the field
933 */
934 if (walk_state->method_node) {
935 status = acpi_ds_init_field_objects(op, walk_state);
936 }
937
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 switch (op->common.aml_opcode) {
939 case AML_INDEX_FIELD_OP:
940
Len Brown4be44fc2005-08-05 00:44:28 -0400941 status =
942 acpi_ds_create_index_field(op,
943 (acpi_handle) arg->
944 common.node, walk_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 break;
946
947 case AML_BANK_FIELD_OP:
948
Len Brown4be44fc2005-08-05 00:44:28 -0400949 status =
950 acpi_ds_create_bank_field(op, arg->common.node,
951 walk_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952 break;
953
954 case AML_FIELD_OP:
955
Len Brown4be44fc2005-08-05 00:44:28 -0400956 status =
957 acpi_ds_create_field(op, arg->common.node,
958 walk_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959 break;
960
961 default:
962 /* All NAMED_FIELD opcodes must be handled above */
963 break;
964 }
965 break;
966
Len Brown4be44fc2005-08-05 00:44:28 -0400967 case AML_TYPE_NAMED_SIMPLE:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968
Len Brown4be44fc2005-08-05 00:44:28 -0400969 status = acpi_ds_create_operands(walk_state, arg);
970 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971 goto cleanup;
972 }
973
974 switch (op->common.aml_opcode) {
975 case AML_PROCESSOR_OP:
976
Len Brown4be44fc2005-08-05 00:44:28 -0400977 status = acpi_ex_create_processor(walk_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978 break;
979
980 case AML_POWER_RES_OP:
981
Len Brown4be44fc2005-08-05 00:44:28 -0400982 status = acpi_ex_create_power_resource(walk_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983 break;
984
985 case AML_MUTEX_OP:
986
Len Brown4be44fc2005-08-05 00:44:28 -0400987 status = acpi_ex_create_mutex(walk_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 break;
989
990 case AML_EVENT_OP:
991
Len Brown4be44fc2005-08-05 00:44:28 -0400992 status = acpi_ex_create_event(walk_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 break;
994
995 case AML_DATA_REGION_OP:
996
Len Brown4be44fc2005-08-05 00:44:28 -0400997 status = acpi_ex_create_table_region(walk_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 break;
999
1000 case AML_ALIAS_OP:
1001
Len Brown4be44fc2005-08-05 00:44:28 -04001002 status = acpi_ex_create_alias(walk_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 break;
1004
1005 default:
1006 /* Unknown opcode */
1007
1008 status = AE_OK;
1009 goto cleanup;
1010 }
1011
1012 /* Delete operands */
1013
1014 for (i = 1; i < walk_state->num_operands; i++) {
Len Brown4be44fc2005-08-05 00:44:28 -04001015 acpi_ut_remove_reference(walk_state->operands[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 walk_state->operands[i] = NULL;
1017 }
1018
1019 break;
Len Brown4be44fc2005-08-05 00:44:28 -04001020#endif /* ACPI_NO_METHOD_EXECUTION */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021
1022 case AML_TYPE_NAMED_COMPLEX:
1023
1024 switch (op->common.aml_opcode) {
1025#ifndef ACPI_NO_METHOD_EXECUTION
1026 case AML_REGION_OP:
Bob Moore28f55eb2005-12-02 18:27:00 -05001027
1028 /*
1029 * If we are executing a method, initialize the region
1030 */
1031 if (walk_state->method_node) {
1032 status =
1033 acpi_ex_create_region(op->named.data,
1034 op->named.length,
1035 (acpi_adr_space_type)
1036 ((op->common.value.
1037 arg)->common.value.
1038 integer),
1039 walk_state);
1040 if (ACPI_FAILURE(status)) {
1041 return (status);
1042 }
1043 }
1044
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 /*
Robert Moore44f6c012005-04-18 22:49:35 -04001046 * The op_region is not fully parsed at this time. Only valid
1047 * argument is the space_id. (We must save the address of the
1048 * AML of the address and length operands)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 */
Bob Moore967440e2006-06-23 17:04:00 -04001050
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 /*
1052 * If we have a valid region, initialize it
1053 * Namespace is NOT locked at this point.
1054 */
Len Brown4be44fc2005-08-05 00:44:28 -04001055 status =
1056 acpi_ev_initialize_region
1057 (acpi_ns_get_attached_object(node), FALSE);
1058 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 /*
1060 * If AE_NOT_EXIST is returned, it is not fatal
1061 * because many regions get created before a handler
1062 * is installed for said region.
1063 */
1064 if (AE_NOT_EXIST == status) {
1065 status = AE_OK;
1066 }
1067 }
1068 break;
1069
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 case AML_NAME_OP:
1071
Len Brown4be44fc2005-08-05 00:44:28 -04001072 status = acpi_ds_create_node(walk_state, node, op);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 break;
Bob Mooredefba1d2005-12-16 17:05:00 -05001074
1075 case AML_METHOD_OP:
1076 /*
1077 * method_op pkg_length name_string method_flags term_list
1078 *
1079 * Note: We must create the method node/object pair as soon as we
Bob Moore967440e2006-06-23 17:04:00 -04001080 * see the method declaration. This allows later pass1 parsing
Bob Mooredefba1d2005-12-16 17:05:00 -05001081 * of invocations of the method (need to know the number of
1082 * arguments.)
1083 */
1084 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
Bob Mooreb229cf92006-04-21 17:15:00 -04001085 "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
Bob Mooredefba1d2005-12-16 17:05:00 -05001086 walk_state, op, op->named.node));
1087
1088 if (!acpi_ns_get_attached_object(op->named.node)) {
1089 walk_state->operands[0] =
1090 ACPI_CAST_PTR(void, op->named.node);
1091 walk_state->num_operands = 1;
1092
1093 status =
1094 acpi_ds_create_operands(walk_state,
1095 op->common.value.
1096 arg);
1097 if (ACPI_SUCCESS(status)) {
1098 status =
1099 acpi_ex_create_method(op->named.
1100 data,
1101 op->named.
1102 length,
1103 walk_state);
1104 }
1105 walk_state->operands[0] = NULL;
1106 walk_state->num_operands = 0;
1107
1108 if (ACPI_FAILURE(status)) {
1109 return_ACPI_STATUS(status);
1110 }
1111 }
1112 break;
1113
Len Brown4be44fc2005-08-05 00:44:28 -04001114#endif /* ACPI_NO_METHOD_EXECUTION */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115
1116 default:
1117 /* All NAMED_COMPLEX opcodes must be handled above */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 break;
1119 }
1120 break;
1121
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 case AML_CLASS_INTERNAL:
1123
1124 /* case AML_INT_NAMEPATH_OP: */
1125 break;
1126
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 case AML_CLASS_METHOD_CALL:
1128
Len Brown4be44fc2005-08-05 00:44:28 -04001129 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
Bob Mooreb229cf92006-04-21 17:15:00 -04001130 "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
Len Brown4be44fc2005-08-05 00:44:28 -04001131 walk_state, op, node));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132
1133 /*
1134 * Lookup the method name and save the Node
1135 */
Len Brown4be44fc2005-08-05 00:44:28 -04001136 status =
1137 acpi_ns_lookup(walk_state->scope_info,
1138 arg->common.value.string, ACPI_TYPE_ANY,
1139 ACPI_IMODE_LOAD_PASS2,
1140 ACPI_NS_SEARCH_PARENT |
1141 ACPI_NS_DONT_OPEN_SCOPE, walk_state,
1142 &(new_node));
1143 if (ACPI_SUCCESS(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 /*
1145 * Make sure that what we found is indeed a method
Robert Moore44f6c012005-04-18 22:49:35 -04001146 * We didn't search for a method on purpose, to see if the name
1147 * would resolve
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 */
1149 if (new_node->type != ACPI_TYPE_METHOD) {
1150 status = AE_AML_OPERAND_TYPE;
1151 }
1152
Robert Moore44f6c012005-04-18 22:49:35 -04001153 /* We could put the returned object (Node) on the object stack for
1154 * later, but for now, we will put it in the "op" object that the
1155 * parser uses, so we can get it again at the end of this scope
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156 */
1157 op->common.node = new_node;
Len Brown4be44fc2005-08-05 00:44:28 -04001158 } else {
Bob Mooreb8e4d892006-01-27 16:43:00 -05001159 ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 }
1161 break;
1162
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163 default:
1164 break;
1165 }
1166
Len Brown4be44fc2005-08-05 00:44:28 -04001167 cleanup:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168
1169 /* Remove the Node pushed at the very beginning */
1170
1171 walk_state->operands[0] = NULL;
1172 walk_state->num_operands = 0;
Len Brown4be44fc2005-08-05 00:44:28 -04001173 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174}