aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorMikhail Kouzmich <mikhail.v.kouzmich@intel.com>2007-02-02 11:48:21 -0500
committerLen Brown <len.brown@intel.com>2007-02-02 21:14:27 -0500
commit4d0b4af958453afe871022e44abd57fac09baf67 (patch)
tree696731c43ce935f318c7d873ccb12e008b2efa9e /drivers/acpi
parent2b705a8abbce1753c1e5af5ae2ed97e374277654 (diff)
ACPICA: Restructured module into multiple functions.
Restructured the AML ParseLoop function, breaking it into several subfunctions in order to reduce CPU stack use and improve maintainability Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/parser/psloop.c1406
1 files changed, 783 insertions, 623 deletions
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c
index e1541db3753a..a83be5201856 100644
--- a/drivers/acpi/parser/psloop.c
+++ b/drivers/acpi/parser/psloop.c
@@ -42,12 +42,11 @@
42 */ 42 */
43 43
44/* 44/*
45 * Parse the AML and build an operation tree as most interpreters, 45 * Parse the AML and build an operation tree as most interpreters, (such as
46 * like Perl, do. Parsing is done by hand rather than with a YACC 46 * Perl) do. Parsing is done by hand rather than with a YACC generated parser
47 * generated parser to tightly constrain stack and dynamic memory 47 * to tightly constrain stack and dynamic memory usage. Parsing is kept
48 * usage. At the same time, parsing is kept flexible and the code 48 * flexible and the code fairly compact by parsing based on a list of AML
49 * fairly compact by parsing based on a list of AML opcode 49 * opcode templates in aml_op_info[].
50 * templates in aml_op_info[]
51 */ 50 */
52 51
53#include <acpi/acpi.h> 52#include <acpi/acpi.h>
@@ -60,766 +59,679 @@ ACPI_MODULE_NAME("psloop")
60 59
61static u32 acpi_gbl_depth = 0; 60static u32 acpi_gbl_depth = 0;
62 61
62/* Local prototypes */
63
64static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
65
66static acpi_status
67acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
68 u8 * aml_op_start,
69 union acpi_parse_object *unnamed_op,
70 union acpi_parse_object **op);
71
72static acpi_status
73acpi_ps_create_op(struct acpi_walk_state *walk_state,
74 u8 * aml_op_start, union acpi_parse_object **new_op);
75
76static acpi_status
77acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
78 u8 * aml_op_start, union acpi_parse_object *op);
79
80static acpi_status
81acpi_ps_complete_op(struct acpi_walk_state *walk_state,
82 union acpi_parse_object **op, acpi_status status);
83
84static acpi_status
85acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
86 union acpi_parse_object *op, acpi_status status);
87
63/******************************************************************************* 88/*******************************************************************************
64 * 89 *
65 * FUNCTION: acpi_ps_parse_loop 90 * FUNCTION: acpi_ps_get_aml_opcode
66 * 91 *
67 * PARAMETERS: walk_state - Current state 92 * PARAMETERS: walk_state - Current state
68 * 93 *
69 * RETURN: Status 94 * RETURN: Status
70 * 95 *
71 * DESCRIPTION: Parse AML (pointed to by the current parser state) and return 96 * DESCRIPTION: Extract the next AML opcode from the input stream.
72 * a tree of ops.
73 * 97 *
74 ******************************************************************************/ 98 ******************************************************************************/
75 99
76acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) 100static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
77{ 101{
78 acpi_status status = AE_OK;
79 acpi_status status2;
80 union acpi_parse_object *op = NULL; /* current op */
81 union acpi_parse_object *arg = NULL;
82 union acpi_parse_object *pre_op = NULL;
83 struct acpi_parse_state *parser_state;
84 u8 *aml_op_start = NULL;
85 102
86 ACPI_FUNCTION_TRACE_PTR(ps_parse_loop, walk_state); 103 ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
87 104
88 if (walk_state->descending_callback == NULL) { 105 walk_state->aml_offset =
89 return_ACPI_STATUS(AE_BAD_PARAMETER); 106 (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml,
90 } 107 walk_state->parser_state.aml_start);
108 walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
91 109
92 parser_state = &walk_state->parser_state; 110 /*
93 walk_state->arg_types = 0; 111 * First cut to determine what we have found:
112 * 1) A valid AML opcode
113 * 2) A name string
114 * 3) An unknown/invalid opcode
115 */
116 walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
94 117
95#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) 118 switch (walk_state->op_info->class) {
119 case AML_CLASS_ASCII:
120 case AML_CLASS_PREFIX:
121 /*
122 * Starts with a valid prefix or ASCII char, this is a name
123 * string. Convert the bare name string to a namepath.
124 */
125 walk_state->opcode = AML_INT_NAMEPATH_OP;
126 walk_state->arg_types = ARGP_NAMESTRING;
127 break;
96 128
97 if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) { 129 case AML_CLASS_UNKNOWN:
98 130
99 /* We are restarting a preempted control method */ 131 /* The opcode is unrecognized. Just skip unknown opcodes */
100 132
101 if (acpi_ps_has_completed_scope(parser_state)) { 133 ACPI_ERROR((AE_INFO,
102 /* 134 "Found unknown opcode %X at AML address %p offset %X, ignoring",
103 * We must check if a predicate to an IF or WHILE statement 135 walk_state->opcode, walk_state->parser_state.aml,
104 * was just completed 136 walk_state->aml_offset));
105 */
106 if ((parser_state->scope->parse_scope.op) &&
107 ((parser_state->scope->parse_scope.op->common.
108 aml_opcode == AML_IF_OP)
109 || (parser_state->scope->parse_scope.op->common.
110 aml_opcode == AML_WHILE_OP))
111 && (walk_state->control_state)
112 && (walk_state->control_state->common.state ==
113 ACPI_CONTROL_PREDICATE_EXECUTING)) {
114 /*
115 * A predicate was just completed, get the value of the
116 * predicate and branch based on that value
117 */
118 walk_state->op = NULL;
119 status =
120 acpi_ds_get_predicate_value(walk_state,
121 ACPI_TO_POINTER
122 (TRUE));
123 if (ACPI_FAILURE(status)
124 && ((status & AE_CODE_MASK) !=
125 AE_CODE_CONTROL)) {
126 if (status == AE_AML_NO_RETURN_VALUE) {
127 ACPI_EXCEPTION((AE_INFO, status,
128 "Invoked method did not return a value"));
129 137
130 } 138 ACPI_DUMP_BUFFER(walk_state->parser_state.aml, 128);
131 ACPI_EXCEPTION((AE_INFO, status,
132 "GetPredicate Failed"));
133 return_ACPI_STATUS(status);
134 }
135 139
136 status = 140 /* Assume one-byte bad opcode */
137 acpi_ps_next_parse_state(walk_state, op,
138 status);
139 }
140 141
141 acpi_ps_pop_scope(parser_state, &op, 142 walk_state->parser_state.aml++;
142 &walk_state->arg_types, 143 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
143 &walk_state->arg_count);
144 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
145 "Popped scope, Op=%p\n", op));
146 } else if (walk_state->prev_op) {
147 144
148 /* We were in the middle of an op */ 145 default:
149 146
150 op = walk_state->prev_op; 147 /* Found opcode info, this is a normal opcode */
151 walk_state->arg_types = walk_state->prev_arg_types; 148
152 } 149 walk_state->parser_state.aml +=
150 acpi_ps_get_opcode_size(walk_state->opcode);
151 walk_state->arg_types = walk_state->op_info->parse_args;
152 break;
153 } 153 }
154#endif
155 154
156 /* Iterative parsing loop, while there is more AML to process: */ 155 return_ACPI_STATUS(AE_OK);
156}
157 157
158 while ((parser_state->aml < parser_state->aml_end) || (op)) { 158/*******************************************************************************
159 aml_op_start = parser_state->aml; 159 *
160 if (!op) { 160 * FUNCTION: acpi_ps_build_named_op
161 *
162 * PARAMETERS: walk_state - Current state
163 * aml_op_start - Begin of named Op in AML
164 * unnamed_op - Early Op (not a named Op)
165 * Op - Returned Op
166 *
167 * RETURN: Status
168 *
169 * DESCRIPTION: Parse a named Op
170 *
171 ******************************************************************************/
161 172
162 /* Get the next opcode from the AML stream */ 173static acpi_status
174acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
175 u8 * aml_op_start,
176 union acpi_parse_object *unnamed_op,
177 union acpi_parse_object **op)
178{
179 acpi_status status = AE_OK;
180 union acpi_parse_object *arg = NULL;
163 181
164 walk_state->aml_offset = 182 ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
165 (u32) ACPI_PTR_DIFF(parser_state->aml,
166 parser_state->aml_start);
167 walk_state->opcode = acpi_ps_peek_opcode(parser_state);
168 183
169 /* 184 unnamed_op->common.value.arg = NULL;
170 * First cut to determine what we have found: 185 unnamed_op->common.aml_opcode = walk_state->opcode;
171 * 1) A valid AML opcode
172 * 2) A name string
173 * 3) An unknown/invalid opcode
174 */
175 walk_state->op_info =
176 acpi_ps_get_opcode_info(walk_state->opcode);
177 switch (walk_state->op_info->class) {
178 case AML_CLASS_ASCII:
179 case AML_CLASS_PREFIX:
180 /*
181 * Starts with a valid prefix or ASCII char, this is a name
182 * string. Convert the bare name string to a namepath.
183 */
184 walk_state->opcode = AML_INT_NAMEPATH_OP;
185 walk_state->arg_types = ARGP_NAMESTRING;
186 break;
187 186
188 case AML_CLASS_UNKNOWN: 187 /*
188 * Get and append arguments until we find the node that contains
189 * the name (the type ARGP_NAME).
190 */
191 while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
192 (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) {
193 status =
194 acpi_ps_get_next_arg(walk_state,
195 &(walk_state->parser_state),
196 GET_CURRENT_ARG_TYPE(walk_state->
197 arg_types), &arg);
198 if (ACPI_FAILURE(status)) {
199 return_ACPI_STATUS(status);
200 }
189 201
190 /* The opcode is unrecognized. Just skip unknown opcodes */ 202 acpi_ps_append_arg(unnamed_op, arg);
203 INCREMENT_ARG_LIST(walk_state->arg_types);
204 }
191 205
192 ACPI_ERROR((AE_INFO, 206 /*
193 "Found unknown opcode %X at AML address %p offset %X, ignoring", 207 * Make sure that we found a NAME and didn't run out of arguments
194 walk_state->opcode, 208 */
195 parser_state->aml, 209 if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
196 walk_state->aml_offset)); 210 return_ACPI_STATUS(AE_AML_NO_OPERAND);
211 }
197 212
198 ACPI_DUMP_BUFFER(parser_state->aml, 128); 213 /* We know that this arg is a name, move to next arg */
199 214
200 /* Assume one-byte bad opcode */ 215 INCREMENT_ARG_LIST(walk_state->arg_types);
201 216
202 parser_state->aml++; 217 /*
203 continue; 218 * Find the object. This will either insert the object into
219 * the namespace or simply look it up
220 */
221 walk_state->op = NULL;
204 222
205 default: 223 status = walk_state->descending_callback(walk_state, op);
224 if (ACPI_FAILURE(status)) {
225 ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog"));
226 return_ACPI_STATUS(status);
227 }
206 228
207 /* Found opcode info, this is a normal opcode */ 229 if (!op) {
230 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
231 }
208 232
209 parser_state->aml += 233 status = acpi_ps_next_parse_state(walk_state, *op, status);
210 acpi_ps_get_opcode_size(walk_state->opcode); 234 if (ACPI_FAILURE(status)) {
211 walk_state->arg_types = 235 if (status == AE_CTRL_PENDING) {
212 walk_state->op_info->parse_args; 236 return_ACPI_STATUS(AE_CTRL_PARSE_PENDING);
213 break; 237 }
214 } 238 return_ACPI_STATUS(status);
239 }
215 240
216 /* Create Op structure and append to parent's argument list */ 241 acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
242 acpi_gbl_depth++;
217 243
218 if (walk_state->op_info->flags & AML_NAMED) { 244 if ((*op)->common.aml_opcode == AML_REGION_OP) {
245 /*
246 * Defer final parsing of an operation_region body, because we don't
247 * have enough info in the first pass to parse it correctly (i.e.,
248 * there may be method calls within the term_arg elements of the body.)
249 *
250 * However, we must continue parsing because the opregion is not a
251 * standalone package -- we don't know where the end is at this point.
252 *
253 * (Length is unknown until parse of the body complete)
254 */
255 (*op)->named.data = aml_op_start;
256 (*op)->named.length = 0;
257 }
219 258
220 /* Allocate a new pre_op if necessary */ 259 return_ACPI_STATUS(AE_OK);
260}
221 261
222 if (!pre_op) { 262/*******************************************************************************
223 pre_op = 263 *
224 acpi_ps_alloc_op(walk_state-> 264 * FUNCTION: acpi_ps_create_op
225 opcode); 265 *
226 if (!pre_op) { 266 * PARAMETERS: walk_state - Current state
227 status = AE_NO_MEMORY; 267 * aml_op_start - Op start in AML
228 goto close_this_op; 268 * new_op - Returned Op
229 } 269 *
230 } 270 * RETURN: Status
271 *
272 * DESCRIPTION: Get Op from AML
273 *
274 ******************************************************************************/
231 275
232 pre_op->common.value.arg = NULL; 276static acpi_status
233 pre_op->common.aml_opcode = walk_state->opcode; 277acpi_ps_create_op(struct acpi_walk_state *walk_state,
278 u8 * aml_op_start, union acpi_parse_object **new_op)
279{
280 acpi_status status = AE_OK;
281 union acpi_parse_object *op;
282 union acpi_parse_object *named_op = NULL;
234 283
235 /* 284 ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
236 * Get and append arguments until we find the node that contains
237 * the name (the type ARGP_NAME).
238 */
239 while (GET_CURRENT_ARG_TYPE
240 (walk_state->arg_types)
241 &&
242 (GET_CURRENT_ARG_TYPE
243 (walk_state->arg_types) != ARGP_NAME)) {
244 status =
245 acpi_ps_get_next_arg(walk_state,
246 parser_state,
247 GET_CURRENT_ARG_TYPE
248 (walk_state->
249 arg_types),
250 &arg);
251 if (ACPI_FAILURE(status)) {
252 goto close_this_op;
253 }
254 285
255 acpi_ps_append_arg(pre_op, arg); 286 status = acpi_ps_get_aml_opcode(walk_state);
256 INCREMENT_ARG_LIST(walk_state-> 287 if (status == AE_CTRL_PARSE_CONTINUE) {
257 arg_types); 288 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
258 } 289 }
259 290
260 /* 291 /* Create Op structure and append to parent's argument list */
261 * Make sure that we found a NAME and didn't run out of
262 * arguments
263 */
264 if (!GET_CURRENT_ARG_TYPE
265 (walk_state->arg_types)) {
266 status = AE_AML_NO_OPERAND;
267 goto close_this_op;
268 }
269 292
270 /* We know that this arg is a name, move to next arg */ 293 walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
294 op = acpi_ps_alloc_op(walk_state->opcode);
295 if (!op) {
296 return_ACPI_STATUS(AE_NO_MEMORY);
297 }
271 298
272 INCREMENT_ARG_LIST(walk_state->arg_types); 299 if (walk_state->op_info->flags & AML_NAMED) {
300 status =
301 acpi_ps_build_named_op(walk_state, aml_op_start, op,
302 &named_op);
303 acpi_ps_free_op(op);
304 if (ACPI_FAILURE(status)) {
305 return_ACPI_STATUS(status);
306 }
273 307
274 /* 308 *new_op = named_op;
275 * Find the object. This will either insert the object into 309 return_ACPI_STATUS(AE_OK);
276 * the namespace or simply look it up 310 }
277 */
278 walk_state->op = NULL;
279 311
280 status = 312 /* Not a named opcode, just allocate Op and append to parent */
281 walk_state->descending_callback(walk_state,
282 &op);
283 if (ACPI_FAILURE(status)) {
284 ACPI_EXCEPTION((AE_INFO, status,
285 "During name lookup/catalog"));
286 goto close_this_op;
287 }
288 313
289 if (!op) { 314 if (walk_state->op_info->flags & AML_CREATE) {
290 continue; 315 /*
291 } 316 * Backup to beginning of create_xXXfield declaration
317 * body_length is unknown until we parse the body
318 */
319 op->named.data = aml_op_start;
320 op->named.length = 0;
321 }
292 322
293 status = 323 acpi_ps_append_arg(acpi_ps_get_parent_scope
294 acpi_ps_next_parse_state(walk_state, op, 324 (&(walk_state->parser_state)), op);
295 status);
296 if (status == AE_CTRL_PENDING) {
297 status = AE_OK;
298 goto close_this_op;
299 }
300 325
301 if (ACPI_FAILURE(status)) { 326 if (walk_state->descending_callback != NULL) {
302 goto close_this_op; 327 /*
303 } 328 * Find the object. This will either insert the object into
329 * the namespace or simply look it up
330 */
331 walk_state->op = *new_op = op;
304 332
305 acpi_ps_append_arg(op, 333 status = walk_state->descending_callback(walk_state, &op);
306 pre_op->common.value.arg); 334 status = acpi_ps_next_parse_state(walk_state, op, status);
307 acpi_gbl_depth++; 335 if (status == AE_CTRL_PENDING) {
308 336 status = AE_CTRL_PARSE_PENDING;
309 if (op->common.aml_opcode == AML_REGION_OP) { 337 }
310 /* 338 }
311 * Defer final parsing of an operation_region body,
312 * because we don't have enough info in the first pass
313 * to parse it correctly (i.e., there may be method
314 * calls within the term_arg elements of the body.)
315 *
316 * However, we must continue parsing because
317 * the opregion is not a standalone package --
318 * we don't know where the end is at this point.
319 *
320 * (Length is unknown until parse of the body complete)
321 */
322 op->named.data = aml_op_start;
323 op->named.length = 0;
324 }
325 } else {
326 /* Not a named opcode, just allocate Op and append to parent */
327 339
328 walk_state->op_info = 340 return_ACPI_STATUS(status);
329 acpi_ps_get_opcode_info(walk_state->opcode); 341}
330 op = acpi_ps_alloc_op(walk_state->opcode);
331 if (!op) {
332 status = AE_NO_MEMORY;
333 goto close_this_op;
334 }
335 342
336 if (walk_state->op_info->flags & AML_CREATE) { 343/*******************************************************************************
337 /* 344 *
338 * Backup to beginning of create_xXXfield declaration 345 * FUNCTION: acpi_ps_get_arguments
339 * body_length is unknown until we parse the body 346 *
340 */ 347 * PARAMETERS: walk_state - Current state
341 op->named.data = aml_op_start; 348 * aml_op_start - Op start in AML
342 op->named.length = 0; 349 * Op - Current Op
343 } 350 *
351 * RETURN: Status
352 *
353 * DESCRIPTION: Get arguments for passed Op.
354 *
355 ******************************************************************************/
344 356
345 acpi_ps_append_arg(acpi_ps_get_parent_scope 357static acpi_status
346 (parser_state), op); 358acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
359 u8 * aml_op_start, union acpi_parse_object *op)
360{
361 acpi_status status = AE_OK;
362 union acpi_parse_object *arg = NULL;
347 363
348 if ((walk_state->descending_callback != NULL)) { 364 ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state);
349 /*
350 * Find the object. This will either insert the object into
351 * the namespace or simply look it up
352 */
353 walk_state->op = op;
354 365
355 status = 366 switch (op->common.aml_opcode) {
356 walk_state-> 367 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
357 descending_callback(walk_state, 368 case AML_WORD_OP: /* AML_WORDDATA_ARG */
358 &op); 369 case AML_DWORD_OP: /* AML_DWORDATA_ARG */
359 status = 370 case AML_QWORD_OP: /* AML_QWORDATA_ARG */
360 acpi_ps_next_parse_state(walk_state, 371 case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */
361 op,
362 status);
363 if (status == AE_CTRL_PENDING) {
364 status = AE_OK;
365 goto close_this_op;
366 }
367 372
368 if (ACPI_FAILURE(status)) { 373 /* Fill in constant or string argument directly */
369 goto close_this_op;
370 }
371 }
372 }
373 374
374 op->common.aml_offset = walk_state->aml_offset; 375 acpi_ps_get_next_simple_arg(&(walk_state->parser_state),
376 GET_CURRENT_ARG_TYPE(walk_state->
377 arg_types),
378 op);
379 break;
375 380
376 if (walk_state->op_info) { 381 case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
377 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 382
378 "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n", 383 status =
379 (u32) op->common.aml_opcode, 384 acpi_ps_get_next_namepath(walk_state,
380 walk_state->op_info->name, op, 385 &(walk_state->parser_state), op,
381 parser_state->aml, 386 1);
382 op->common.aml_offset)); 387 if (ACPI_FAILURE(status)) {
383 } 388 return_ACPI_STATUS(status);
384 } 389 }
385 390
391 walk_state->arg_types = 0;
392 break;
393
394 default:
386 /* 395 /*
387 * Start arg_count at zero because we don't know if there are 396 * Op is not a constant or string, append each argument to the Op
388 * any args yet
389 */ 397 */
390 walk_state->arg_count = 0; 398 while (GET_CURRENT_ARG_TYPE(walk_state->arg_types)
391 399 && !walk_state->arg_count) {
392 /* Are there any arguments that must be processed? */ 400 walk_state->aml_offset =
393 401 (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml,
394 if (walk_state->arg_types) { 402 walk_state->parser_state.
395 403 aml_start);
396 /* Get arguments */
397
398 switch (op->common.aml_opcode) {
399 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
400 case AML_WORD_OP: /* AML_WORDDATA_ARG */
401 case AML_DWORD_OP: /* AML_DWORDATA_ARG */
402 case AML_QWORD_OP: /* AML_QWORDATA_ARG */
403 case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */
404
405 /* Fill in constant or string argument directly */
406
407 acpi_ps_get_next_simple_arg(parser_state,
408 GET_CURRENT_ARG_TYPE
409 (walk_state->
410 arg_types), op);
411 break;
412
413 case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
414
415 status =
416 acpi_ps_get_next_namepath(walk_state,
417 parser_state, op,
418 1);
419 if (ACPI_FAILURE(status)) {
420 goto close_this_op;
421 }
422
423 walk_state->arg_types = 0;
424 break;
425 404
426 default: 405 status =
427 /* 406 acpi_ps_get_next_arg(walk_state,
428 * Op is not a constant or string, append each argument 407 &(walk_state->parser_state),
429 * to the Op 408 GET_CURRENT_ARG_TYPE
430 */ 409 (walk_state->arg_types), &arg);
431 while (GET_CURRENT_ARG_TYPE 410 if (ACPI_FAILURE(status)) {
432 (walk_state->arg_types) 411 return_ACPI_STATUS(status);
433 && !walk_state->arg_count) { 412 }
434 walk_state->aml_offset = (u32)
435 ACPI_PTR_DIFF(parser_state->aml,
436 parser_state->
437 aml_start);
438 413
439 status = 414 if (arg) {
440 acpi_ps_get_next_arg(walk_state, 415 arg->common.aml_offset = walk_state->aml_offset;
441 parser_state, 416 acpi_ps_append_arg(op, arg);
442 GET_CURRENT_ARG_TYPE 417 }
443 (walk_state->
444 arg_types),
445 &arg);
446 if (ACPI_FAILURE(status)) {
447 goto close_this_op;
448 }
449 418
450 if (arg) { 419 INCREMENT_ARG_LIST(walk_state->arg_types);
451 arg->common.aml_offset = 420 }
452 walk_state->aml_offset;
453 acpi_ps_append_arg(op, arg);
454 }
455 INCREMENT_ARG_LIST(walk_state->
456 arg_types);
457 }
458 421
459 /* Special processing for certain opcodes */ 422 /* Special processing for certain opcodes */
460 423
461 /* TBD (remove): Temporary mechanism to disable this code if needed */ 424 /* TBD (remove): Temporary mechanism to disable this code if needed */
462 425
463#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE 426#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
464 427
465 if ((walk_state->pass_number <= 428 if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) &&
466 ACPI_IMODE_LOAD_PASS1) 429 ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) {
467 && 430 /*
468 ((walk_state-> 431 * We want to skip If/Else/While constructs during Pass1 because we
469 parse_flags & ACPI_PARSE_DISASSEMBLE) == 432 * want to actually conditionally execute the code during Pass2.
470 0)) { 433 *
471 /* 434 * Except for disassembly, where we always want to walk the
472 * We want to skip If/Else/While constructs during Pass1 435 * If/Else/While packages
473 * because we want to actually conditionally execute the 436 */
474 * code during Pass2. 437 switch (op->common.aml_opcode) {
475 * 438 case AML_IF_OP:
476 * Except for disassembly, where we always want to 439 case AML_ELSE_OP:
477 * walk the If/Else/While packages 440 case AML_WHILE_OP:
478 */
479 switch (op->common.aml_opcode) {
480 case AML_IF_OP:
481 case AML_ELSE_OP:
482 case AML_WHILE_OP:
483
484 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
485 "Pass1: Skipping an If/Else/While body\n"));
486
487 /* Skip body of if/else/while in pass 1 */
488
489 parser_state->aml =
490 parser_state->pkg_end;
491 walk_state->arg_count = 0;
492 break;
493
494 default:
495 break;
496 }
497 }
498#endif
499 switch (op->common.aml_opcode) {
500 case AML_METHOD_OP:
501
502 /*
503 * Skip parsing of control method
504 * because we don't have enough info in the first pass
505 * to parse it correctly.
506 *
507 * Save the length and address of the body
508 */
509 op->named.data = parser_state->aml;
510 op->named.length =
511 (u32) (parser_state->pkg_end -
512 parser_state->aml);
513
514 /* Skip body of method */
515
516 parser_state->aml =
517 parser_state->pkg_end;
518 walk_state->arg_count = 0;
519 break;
520
521 case AML_BUFFER_OP:
522 case AML_PACKAGE_OP:
523 case AML_VAR_PACKAGE_OP:
524
525 if ((op->common.parent) &&
526 (op->common.parent->common.
527 aml_opcode == AML_NAME_OP)
528 && (walk_state->pass_number <=
529 ACPI_IMODE_LOAD_PASS2)) {
530 /*
531 * Skip parsing of Buffers and Packages
532 * because we don't have enough info in the first pass
533 * to parse them correctly.
534 */
535 op->named.data = aml_op_start;
536 op->named.length =
537 (u32) (parser_state->
538 pkg_end -
539 aml_op_start);
540
541 /* Skip body */
542
543 parser_state->aml =
544 parser_state->pkg_end;
545 walk_state->arg_count = 0;
546 }
547 break;
548 441
549 case AML_WHILE_OP: 442 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
443 "Pass1: Skipping an If/Else/While body\n"));
550 444
551 if (walk_state->control_state) { 445 /* Skip body of if/else/while in pass 1 */
552 walk_state->control_state->
553 control.package_end =
554 parser_state->pkg_end;
555 }
556 break;
557 446
558 default: 447 walk_state->parser_state.aml =
448 walk_state->parser_state.pkg_end;
449 walk_state->arg_count = 0;
450 break;
559 451
560 /* No action for all other opcodes */ 452 default:
561 break;
562 }
563 break; 453 break;
564 } 454 }
565 } 455 }
456#endif
566 457
567 /* Check for arguments that need to be processed */ 458 switch (op->common.aml_opcode) {
568 459 case AML_METHOD_OP:
569 if (walk_state->arg_count) {
570 /* 460 /*
571 * There are arguments (complex ones), push Op and 461 * Skip parsing of control method because we don't have enough
572 * prepare for argument 462 * info in the first pass to parse it correctly.
463 *
464 * Save the length and address of the body
573 */ 465 */
574 status = acpi_ps_push_scope(parser_state, op, 466 op->named.data = walk_state->parser_state.aml;
575 walk_state->arg_types, 467 op->named.length = (u32)
576 walk_state->arg_count); 468 (walk_state->parser_state.pkg_end -
577 if (ACPI_FAILURE(status)) { 469 walk_state->parser_state.aml);
578 goto close_this_op;
579 }
580 op = NULL;
581 continue;
582 }
583 470
584 /* 471 /* Skip body of method */
585 * All arguments have been processed -- Op is complete,
586 * prepare for next
587 */
588 walk_state->op_info =
589 acpi_ps_get_opcode_info(op->common.aml_opcode);
590 if (walk_state->op_info->flags & AML_NAMED) {
591 if (acpi_gbl_depth) {
592 acpi_gbl_depth--;
593 }
594 472
595 if (op->common.aml_opcode == AML_REGION_OP) { 473 walk_state->parser_state.aml =
474 walk_state->parser_state.pkg_end;
475 walk_state->arg_count = 0;
476 break;
477
478 case AML_BUFFER_OP:
479 case AML_PACKAGE_OP:
480 case AML_VAR_PACKAGE_OP:
481
482 if ((op->common.parent) &&
483 (op->common.parent->common.aml_opcode ==
484 AML_NAME_OP)
485 && (walk_state->pass_number <=
486 ACPI_IMODE_LOAD_PASS2)) {
596 /* 487 /*
597 * Skip parsing of control method or opregion body, 488 * Skip parsing of Buffers and Packages because we don't have
598 * because we don't have enough info in the first pass 489 * enough info in the first pass to parse them correctly.
599 * to parse them correctly.
600 *
601 * Completed parsing an op_region declaration, we now
602 * know the length.
603 */ 490 */
604 op->named.length = 491 op->named.data = aml_op_start;
605 (u32) (parser_state->aml - op->named.data); 492 op->named.length = (u32)
606 } 493 (walk_state->parser_state.pkg_end -
607 } 494 aml_op_start);
608 495
609 if (walk_state->op_info->flags & AML_CREATE) { 496 /* Skip body */
610 /*
611 * Backup to beginning of create_xXXfield declaration (1 for
612 * Opcode)
613 *
614 * body_length is unknown until we parse the body
615 */
616 op->named.length =
617 (u32) (parser_state->aml - op->named.data);
618 }
619 497
620 /* This op complete, notify the dispatcher */ 498 walk_state->parser_state.aml =
499 walk_state->parser_state.pkg_end;
500 walk_state->arg_count = 0;
501 }
502 break;
621 503
622 if (walk_state->ascending_callback != NULL) { 504 case AML_WHILE_OP:
623 walk_state->op = op;
624 walk_state->opcode = op->common.aml_opcode;
625 505
626 status = walk_state->ascending_callback(walk_state); 506 if (walk_state->control_state) {
627 status = 507 walk_state->control_state->control.package_end =
628 acpi_ps_next_parse_state(walk_state, op, status); 508 walk_state->parser_state.pkg_end;
629 if (status == AE_CTRL_PENDING) {
630 status = AE_OK;
631 goto close_this_op;
632 } 509 }
633 } 510 break;
634
635 close_this_op:
636 /*
637 * Finished one argument of the containing scope
638 */
639 parser_state->scope->parse_scope.arg_count--;
640 511
641 /* Finished with pre_op */ 512 default:
642 513
643 if (pre_op) { 514 /* No action for all other opcodes */
644 acpi_ps_free_op(pre_op); 515 break;
645 pre_op = NULL;
646 } 516 }
647 517
648 /* Close this Op (will result in parse subtree deletion) */ 518 break;
519 }
649 520
650 status2 = acpi_ps_complete_this_op(walk_state, op); 521 return_ACPI_STATUS(AE_OK);
651 if (ACPI_FAILURE(status2)) { 522}
652 return_ACPI_STATUS(status2);
653 }
654 op = NULL;
655 523
656 switch (status) { 524/*******************************************************************************
657 case AE_OK: 525 *
658 break; 526 * FUNCTION: acpi_ps_complete_op
527 *
528 * PARAMETERS: walk_state - Current state
529 * Op - Returned Op
530 * Status - Parse status before complete Op
531 *
532 * RETURN: Status
533 *
534 * DESCRIPTION: Complete Op
535 *
536 ******************************************************************************/
659 537
660 case AE_CTRL_TRANSFER: 538static acpi_status
539acpi_ps_complete_op(struct acpi_walk_state *walk_state,
540 union acpi_parse_object **op, acpi_status status)
541{
542 acpi_status status2;
661 543
662 /* We are about to transfer to a called method. */ 544 ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
663 545
664 walk_state->prev_op = op; 546 /*
665 walk_state->prev_arg_types = walk_state->arg_types; 547 * Finished one argument of the containing scope
666 return_ACPI_STATUS(status); 548 */
549 walk_state->parser_state.scope->parse_scope.arg_count--;
667 550
668 case AE_CTRL_END: 551 /* Close this Op (will result in parse subtree deletion) */
669 552
670 acpi_ps_pop_scope(parser_state, &op, 553 status2 = acpi_ps_complete_this_op(walk_state, *op);
671 &walk_state->arg_types, 554 if (ACPI_FAILURE(status2)) {
672 &walk_state->arg_count); 555 return_ACPI_STATUS(status2);
556 }
673 557
674 if (op) { 558 *op = NULL;
675 walk_state->op = op;
676 walk_state->op_info =
677 acpi_ps_get_opcode_info(op->common.
678 aml_opcode);
679 walk_state->opcode = op->common.aml_opcode;
680 559
681 status = 560 switch (status) {
682 walk_state->ascending_callback(walk_state); 561 case AE_OK:
683 status = 562 break;
684 acpi_ps_next_parse_state(walk_state, op,
685 status);
686 563
687 status2 = 564 case AE_CTRL_TRANSFER:
688 acpi_ps_complete_this_op(walk_state, op);
689 if (ACPI_FAILURE(status2)) {
690 return_ACPI_STATUS(status2);
691 }
692 op = NULL;
693 }
694 status = AE_OK;
695 break;
696 565
697 case AE_CTRL_BREAK: 566 /* We are about to transfer to a called method */
698 case AE_CTRL_CONTINUE:
699 567
700 /* Pop off scopes until we find the While */ 568 walk_state->prev_op = NULL;
569 walk_state->prev_arg_types = walk_state->arg_types;
570 return_ACPI_STATUS(status);
701 571
702 while (!op || (op->common.aml_opcode != AML_WHILE_OP)) { 572 case AE_CTRL_END:
703 acpi_ps_pop_scope(parser_state, &op,
704 &walk_state->arg_types,
705 &walk_state->arg_count);
706 573
707 if (op->common.aml_opcode != AML_WHILE_OP) { 574 acpi_ps_pop_scope(&(walk_state->parser_state), op,
708 status2 = 575 &walk_state->arg_types,
709 acpi_ds_result_stack_pop 576 &walk_state->arg_count);
710 (walk_state);
711 if (ACPI_FAILURE(status2)) {
712 return_ACPI_STATUS(status2);
713 }
714 }
715 }
716
717 /* Close this iteration of the While loop */
718 577
719 walk_state->op = op; 578 if (*op) {
579 walk_state->op = *op;
720 walk_state->op_info = 580 walk_state->op_info =
721 acpi_ps_get_opcode_info(op->common.aml_opcode); 581 acpi_ps_get_opcode_info((*op)->common.aml_opcode);
722 walk_state->opcode = op->common.aml_opcode; 582 walk_state->opcode = (*op)->common.aml_opcode;
723 583
724 status = walk_state->ascending_callback(walk_state); 584 status = walk_state->ascending_callback(walk_state);
725 status = 585 status =
726 acpi_ps_next_parse_state(walk_state, op, status); 586 acpi_ps_next_parse_state(walk_state, *op, status);
727 587
728 status2 = acpi_ps_complete_this_op(walk_state, op); 588 status2 = acpi_ps_complete_this_op(walk_state, *op);
729 if (ACPI_FAILURE(status2)) { 589 if (ACPI_FAILURE(status2)) {
730 return_ACPI_STATUS(status2); 590 return_ACPI_STATUS(status2);
731 } 591 }
732 op = NULL; 592 }
733
734 status = AE_OK;
735 break;
736 593
737 case AE_CTRL_TERMINATE: 594 status = AE_OK;
595 break;
738 596
739 status = AE_OK; 597 case AE_CTRL_BREAK:
598 case AE_CTRL_CONTINUE:
740 599
741 /* Clean up */ 600 /* Pop off scopes until we find the While */
742 do {
743 if (op) {
744 status2 =
745 acpi_ps_complete_this_op(walk_state,
746 op);
747 if (ACPI_FAILURE(status2)) {
748 return_ACPI_STATUS(status2);
749 }
750 601
751 status2 = 602 while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
752 acpi_ds_result_stack_pop 603 acpi_ps_pop_scope(&(walk_state->parser_state), op,
753 (walk_state); 604 &walk_state->arg_types,
754 if (ACPI_FAILURE(status2)) { 605 &walk_state->arg_count);
755 return_ACPI_STATUS(status2);
756 }
757 606
758 acpi_ut_delete_generic_state 607 if ((*op)->common.aml_opcode != AML_WHILE_OP) {
759 (acpi_ut_pop_generic_state 608 status2 = acpi_ds_result_stack_pop(walk_state);
760 (&walk_state->control_state)); 609 if (ACPI_FAILURE(status2)) {
610 return_ACPI_STATUS(status2);
761 } 611 }
612 }
613 }
762 614
763 acpi_ps_pop_scope(parser_state, &op, 615 /* Close this iteration of the While loop */
764 &walk_state->arg_types,
765 &walk_state->arg_count);
766 616
767 } while (op); 617 walk_state->op = *op;
618 walk_state->op_info =
619 acpi_ps_get_opcode_info((*op)->common.aml_opcode);
620 walk_state->opcode = (*op)->common.aml_opcode;
768 621
769 return_ACPI_STATUS(status); 622 status = walk_state->ascending_callback(walk_state);
623 status = acpi_ps_next_parse_state(walk_state, *op, status);
770 624
771 default: /* All other non-AE_OK status */ 625 status2 = acpi_ps_complete_this_op(walk_state, *op);
626 if (ACPI_FAILURE(status2)) {
627 return_ACPI_STATUS(status2);
628 }
772 629
773 do { 630 status = AE_OK;
774 if (op) { 631 break;
775 status2 = 632
776 acpi_ps_complete_this_op(walk_state, 633 case AE_CTRL_TERMINATE:
777 op); 634
778 if (ACPI_FAILURE(status2)) { 635 /* Clean up */
779 return_ACPI_STATUS(status2); 636 do {
780 } 637 if (*op) {
638 status2 =
639 acpi_ps_complete_this_op(walk_state, *op);
640 if (ACPI_FAILURE(status2)) {
641 return_ACPI_STATUS(status2);
642 }
643 status2 = acpi_ds_result_stack_pop(walk_state);
644 if (ACPI_FAILURE(status2)) {
645 return_ACPI_STATUS(status2);
781 } 646 }
782 647
783 acpi_ps_pop_scope(parser_state, &op, 648 acpi_ut_delete_generic_state
784 &walk_state->arg_types, 649 (acpi_ut_pop_generic_state
785 &walk_state->arg_count); 650 (&walk_state->control_state));
651 }
786 652
787 } while (op); 653 acpi_ps_pop_scope(&(walk_state->parser_state), op,
654 &walk_state->arg_types,
655 &walk_state->arg_count);
788 656
789 /* 657 } while (*op);
790 * TBD: Cleanup parse ops on error 658
791 */ 659 return_ACPI_STATUS(AE_OK);
792#if 0 660
793 if (op == NULL) { 661 default: /* All other non-AE_OK status */
794 acpi_ps_pop_scope(parser_state, &op, 662
795 &walk_state->arg_types, 663 do {
796 &walk_state->arg_count); 664 if (*op) {
665 status2 =
666 acpi_ps_complete_this_op(walk_state, *op);
667 if (ACPI_FAILURE(status2)) {
668 return_ACPI_STATUS(status2);
669 }
797 } 670 }
798#endif
799 walk_state->prev_op = op;
800 walk_state->prev_arg_types = walk_state->arg_types;
801 return_ACPI_STATUS(status);
802 }
803 671
804 /* This scope complete? */ 672 acpi_ps_pop_scope(&(walk_state->parser_state), op,
673 &walk_state->arg_types,
674 &walk_state->arg_count);
805 675
806 if (acpi_ps_has_completed_scope(parser_state)) { 676 } while (*op);
807 acpi_ps_pop_scope(parser_state, &op, 677
678#if 0
679 /*
680 * TBD: Cleanup parse ops on error
681 */
682 if (*op == NULL) {
683 acpi_ps_pop_scope(parser_state, op,
808 &walk_state->arg_types, 684 &walk_state->arg_types,
809 &walk_state->arg_count); 685 &walk_state->arg_count);
810 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
811 "Popped scope, Op=%p\n", op));
812 } else {
813 op = NULL;
814 } 686 }
687#endif
688 walk_state->prev_op = NULL;
689 walk_state->prev_arg_types = walk_state->arg_types;
690 return_ACPI_STATUS(status);
691 }
815 692
816 } /* while parser_state->Aml */ 693 /* This scope complete? */
694
695 if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
696 acpi_ps_pop_scope(&(walk_state->parser_state), op,
697 &walk_state->arg_types,
698 &walk_state->arg_count);
699 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
700 } else {
701 *op = NULL;
702 }
703
704 return_ACPI_STATUS(AE_OK);
705}
706
707/*******************************************************************************
708 *
709 * FUNCTION: acpi_ps_complete_final_op
710 *
711 * PARAMETERS: walk_state - Current state
712 * Op - Current Op
713 * Status - Current parse status before complete last
714 * Op
715 *
716 * RETURN: Status
717 *
718 * DESCRIPTION: Complete last Op.
719 *
720 ******************************************************************************/
721
722static acpi_status
723acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
724 union acpi_parse_object *op, acpi_status status)
725{
726 acpi_status status2;
727
728 ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
817 729
818 /* 730 /*
819 * Complete the last Op (if not completed), and clear the scope stack. 731 * Complete the last Op (if not completed), and clear the scope stack.
820 * It is easily possible to end an AML "package" with an unbounded number 732 * It is easily possible to end an AML "package" with an unbounded number
821 * of open scopes (such as when several ASL blocks are closed with 733 * of open scopes (such as when several ASL blocks are closed with
822 * sequential closing braces). We want to terminate each one cleanly. 734 * sequential closing braces). We want to terminate each one cleanly.
823 */ 735 */
824 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n", 736 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
825 op)); 737 op));
@@ -838,8 +750,12 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
838 acpi_ps_next_parse_state(walk_state, op, 750 acpi_ps_next_parse_state(walk_state, op,
839 status); 751 status);
840 if (status == AE_CTRL_PENDING) { 752 if (status == AE_CTRL_PENDING) {
841 status = AE_OK; 753 status =
842 goto close_this_op; 754 acpi_ps_complete_op(walk_state, &op,
755 AE_OK);
756 if (ACPI_FAILURE(status)) {
757 return_ACPI_STATUS(status);
758 }
843 } 759 }
844 760
845 if (status == AE_CTRL_TERMINATE) { 761 if (status == AE_CTRL_TERMINATE) {
@@ -858,7 +774,9 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
858 } 774 }
859 } 775 }
860 776
861 acpi_ps_pop_scope(parser_state, 777 acpi_ps_pop_scope(&
778 (walk_state->
779 parser_state),
862 &op, 780 &op,
863 &walk_state-> 781 &walk_state->
864 arg_types, 782 arg_types,
@@ -887,10 +805,252 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
887 } 805 }
888 } 806 }
889 807
890 acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, 808 acpi_ps_pop_scope(&(walk_state->parser_state), &op,
809 &walk_state->arg_types,
891 &walk_state->arg_count); 810 &walk_state->arg_count);
892 811
893 } while (op); 812 } while (op);
894 813
895 return_ACPI_STATUS(status); 814 return_ACPI_STATUS(status);
896} 815}
816
817/*******************************************************************************
818 *
819 * FUNCTION: acpi_ps_parse_loop
820 *
821 * PARAMETERS: walk_state - Current state
822 *
823 * RETURN: Status
824 *
825 * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
826 * a tree of ops.
827 *
828 ******************************************************************************/
829
830acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
831{
832 acpi_status status = AE_OK;
833 union acpi_parse_object *op = NULL; /* current op */
834 struct acpi_parse_state *parser_state;
835 u8 *aml_op_start = NULL;
836
837 ACPI_FUNCTION_TRACE_PTR(ps_parse_loop, walk_state);
838
839 if (walk_state->descending_callback == NULL) {
840 return_ACPI_STATUS(AE_BAD_PARAMETER);
841 }
842
843 parser_state = &walk_state->parser_state;
844 walk_state->arg_types = 0;
845
846#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
847
848 if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
849
850 /* We are restarting a preempted control method */
851
852 if (acpi_ps_has_completed_scope(parser_state)) {
853 /*
854 * We must check if a predicate to an IF or WHILE statement
855 * was just completed
856 */
857 if ((parser_state->scope->parse_scope.op) &&
858 ((parser_state->scope->parse_scope.op->common.
859 aml_opcode == AML_IF_OP)
860 || (parser_state->scope->parse_scope.op->common.
861 aml_opcode == AML_WHILE_OP))
862 && (walk_state->control_state)
863 && (walk_state->control_state->common.state ==
864 ACPI_CONTROL_PREDICATE_EXECUTING)) {
865 /*
866 * A predicate was just completed, get the value of the
867 * predicate and branch based on that value
868 */
869 walk_state->op = NULL;
870 status =
871 acpi_ds_get_predicate_value(walk_state,
872 ACPI_TO_POINTER
873 (TRUE));
874 if (ACPI_FAILURE(status)
875 && ((status & AE_CODE_MASK) !=
876 AE_CODE_CONTROL)) {
877 if (status == AE_AML_NO_RETURN_VALUE) {
878 ACPI_EXCEPTION((AE_INFO, status,
879 "Invoked method did not return a value"));
880
881 }
882
883 ACPI_EXCEPTION((AE_INFO, status,
884 "GetPredicate Failed"));
885 return_ACPI_STATUS(status);
886 }
887
888 status =
889 acpi_ps_next_parse_state(walk_state, op,
890 status);
891 }
892
893 acpi_ps_pop_scope(parser_state, &op,
894 &walk_state->arg_types,
895 &walk_state->arg_count);
896 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
897 "Popped scope, Op=%p\n", op));
898 } else if (walk_state->prev_op) {
899
900 /* We were in the middle of an op */
901
902 op = walk_state->prev_op;
903 walk_state->arg_types = walk_state->prev_arg_types;
904 }
905 }
906#endif
907
908 /* Iterative parsing loop, while there is more AML to process: */
909
910 while ((parser_state->aml < parser_state->aml_end) || (op)) {
911 aml_op_start = parser_state->aml;
912 if (!op) {
913 status =
914 acpi_ps_create_op(walk_state, aml_op_start, &op);
915 if (ACPI_FAILURE(status)) {
916 if (status == AE_CTRL_PARSE_CONTINUE) {
917 continue;
918 }
919
920 if (status == AE_CTRL_PARSE_PENDING) {
921 status = AE_OK;
922 }
923
924 status =
925 acpi_ps_complete_op(walk_state, &op,
926 status);
927 if (ACPI_FAILURE(status)) {
928 return_ACPI_STATUS(status);
929 }
930
931 continue;
932 }
933
934 op->common.aml_offset = walk_state->aml_offset;
935
936 if (walk_state->op_info) {
937 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
938 "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n",
939 (u32) op->common.aml_opcode,
940 walk_state->op_info->name, op,
941 parser_state->aml,
942 op->common.aml_offset));
943 }
944 }
945
946 /*
947 * Start arg_count at zero because we don't know if there are
948 * any args yet
949 */
950 walk_state->arg_count = 0;
951
952 /* Are there any arguments that must be processed? */
953
954 if (walk_state->arg_types) {
955
956 /* Get arguments */
957
958 status =
959 acpi_ps_get_arguments(walk_state, aml_op_start, op);
960 if (ACPI_FAILURE(status)) {
961 status =
962 acpi_ps_complete_op(walk_state, &op,
963 status);
964 if (ACPI_FAILURE(status)) {
965 return_ACPI_STATUS(status);
966 }
967
968 continue;
969 }
970 }
971
972 /* Check for arguments that need to be processed */
973
974 if (walk_state->arg_count) {
975 /*
976 * There are arguments (complex ones), push Op and
977 * prepare for argument
978 */
979 status = acpi_ps_push_scope(parser_state, op,
980 walk_state->arg_types,
981 walk_state->arg_count);
982 if (ACPI_FAILURE(status)) {
983 status =
984 acpi_ps_complete_op(walk_state, &op,
985 status);
986 if (ACPI_FAILURE(status)) {
987 return_ACPI_STATUS(status);
988 }
989
990 continue;
991 }
992
993 op = NULL;
994 continue;
995 }
996
997 /*
998 * All arguments have been processed -- Op is complete,
999 * prepare for next
1000 */
1001 walk_state->op_info =
1002 acpi_ps_get_opcode_info(op->common.aml_opcode);
1003 if (walk_state->op_info->flags & AML_NAMED) {
1004 if (acpi_gbl_depth) {
1005 acpi_gbl_depth--;
1006 }
1007
1008 if (op->common.aml_opcode == AML_REGION_OP) {
1009 /*
1010 * Skip parsing of control method or opregion body,
1011 * because we don't have enough info in the first pass
1012 * to parse them correctly.
1013 *
1014 * Completed parsing an op_region declaration, we now
1015 * know the length.
1016 */
1017 op->named.length =
1018 (u32) (parser_state->aml - op->named.data);
1019 }
1020 }
1021
1022 if (walk_state->op_info->flags & AML_CREATE) {
1023 /*
1024 * Backup to beginning of create_xXXfield declaration (1 for
1025 * Opcode)
1026 *
1027 * body_length is unknown until we parse the body
1028 */
1029 op->named.length =
1030 (u32) (parser_state->aml - op->named.data);
1031 }
1032
1033 /* This op complete, notify the dispatcher */
1034
1035 if (walk_state->ascending_callback != NULL) {
1036 walk_state->op = op;
1037 walk_state->opcode = op->common.aml_opcode;
1038
1039 status = walk_state->ascending_callback(walk_state);
1040 status =
1041 acpi_ps_next_parse_state(walk_state, op, status);
1042 if (status == AE_CTRL_PENDING) {
1043 status = AE_OK;
1044 }
1045 }
1046
1047 status = acpi_ps_complete_op(walk_state, &op, status);
1048 if (ACPI_FAILURE(status)) {
1049 return_ACPI_STATUS(status);
1050 }
1051
1052 } /* while parser_state->Aml */
1053
1054 status = acpi_ps_complete_final_op(walk_state, op, status);
1055 return_ACPI_STATUS(status);
1056}