Branch data Line data Source code
1 : : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 : : /******************************************************************************
3 : : *
4 : : * Module Name: psobject - Support for parse objects
5 : : *
6 : : * Copyright (C) 2000 - 2020, Intel Corp.
7 : : *
8 : : *****************************************************************************/
9 : :
10 : : #include <acpi/acpi.h>
11 : : #include "accommon.h"
12 : : #include "acparser.h"
13 : : #include "amlcode.h"
14 : : #include "acconvert.h"
15 : : #include "acnamesp.h"
16 : :
17 : : #define _COMPONENT ACPI_PARSER
18 : : ACPI_MODULE_NAME("psobject")
19 : :
20 : : /* Local prototypes */
21 : : static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
22 : :
23 : : /*******************************************************************************
24 : : *
25 : : * FUNCTION: acpi_ps_get_aml_opcode
26 : : *
27 : : * PARAMETERS: walk_state - Current state
28 : : *
29 : : * RETURN: Status
30 : : *
31 : : * DESCRIPTION: Extract the next AML opcode from the input stream.
32 : : *
33 : : ******************************************************************************/
34 : :
35 : 232401 : static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
36 : : {
37 : 232401 : ACPI_ERROR_ONLY(u32 aml_offset);
38 : :
39 : 232401 : ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
40 : :
41 : 232401 : walk_state->aml = walk_state->parser_state.aml;
42 : 232401 : walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
43 : :
44 : : /*
45 : : * First cut to determine what we have found:
46 : : * 1) A valid AML opcode
47 : : * 2) A name string
48 : : * 3) An unknown/invalid opcode
49 : : */
50 : 232401 : walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
51 : :
52 [ + - + ]: 232401 : switch (walk_state->op_info->class) {
53 : 6266 : case AML_CLASS_ASCII:
54 : : case AML_CLASS_PREFIX:
55 : : /*
56 : : * Starts with a valid prefix or ASCII char, this is a name
57 : : * string. Convert the bare name string to a namepath.
58 : : */
59 : 6266 : walk_state->opcode = AML_INT_NAMEPATH_OP;
60 : 6266 : walk_state->arg_types = ARGP_NAMESTRING;
61 : 6266 : break;
62 : :
63 : 0 : case AML_CLASS_UNKNOWN:
64 : :
65 : : /* The opcode is unrecognized. Complain and skip unknown opcodes */
66 : :
67 [ # # ]: 0 : if (walk_state->pass_number == 2) {
68 : 0 : ACPI_ERROR_ONLY(aml_offset =
69 : : (u32)ACPI_PTR_DIFF(walk_state->aml,
70 : : walk_state->
71 : : parser_state.
72 : : aml_start));
73 : :
74 : 0 : ACPI_ERROR((AE_INFO,
75 : : "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
76 : : walk_state->opcode,
77 : : (u32)(aml_offset +
78 : : sizeof(struct acpi_table_header))));
79 : :
80 : : ACPI_DUMP_BUFFER((walk_state->parser_state.aml - 16),
81 : 0 : 48);
82 : :
83 : : #ifdef ACPI_ASL_COMPILER
84 : : /*
85 : : * This is executed for the disassembler only. Output goes
86 : : * to the disassembled ASL output file.
87 : : */
88 : : acpi_os_printf
89 : : ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
90 : : walk_state->opcode,
91 : : (u32)(aml_offset +
92 : : sizeof(struct acpi_table_header)));
93 : :
94 : : ACPI_ERROR((AE_INFO,
95 : : "Aborting disassembly, AML byte code is corrupt"));
96 : :
97 : : /* Dump the context surrounding the invalid opcode */
98 : :
99 : : acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
100 : : aml - 16), 48, DB_BYTE_DISPLAY,
101 : : (aml_offset +
102 : : sizeof(struct acpi_table_header) -
103 : : 16));
104 : : acpi_os_printf(" */\n");
105 : :
106 : : /*
107 : : * Just abort the disassembly, cannot continue because the
108 : : * parser is essentially lost. The disassembler can then
109 : : * randomly fail because an ill-constructed parse tree
110 : : * can result.
111 : : */
112 : : return_ACPI_STATUS(AE_AML_BAD_OPCODE);
113 : : #endif
114 : : }
115 : :
116 : : /* Increment past one-byte or two-byte opcode */
117 : :
118 : 0 : walk_state->parser_state.aml++;
119 [ # # ]: 0 : if (walk_state->opcode > 0xFF) { /* Can only happen if first byte is 0x5B */
120 : 0 : walk_state->parser_state.aml++;
121 : : }
122 : :
123 : : return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
124 : :
125 : 226135 : default:
126 : :
127 : : /* Found opcode info, this is a normal opcode */
128 : :
129 : 452270 : walk_state->parser_state.aml +=
130 : 226135 : acpi_ps_get_opcode_size(walk_state->opcode);
131 : 226135 : walk_state->arg_types = walk_state->op_info->parse_args;
132 : 226135 : break;
133 : : }
134 : :
135 : : return_ACPI_STATUS(AE_OK);
136 : : }
137 : :
138 : : /*******************************************************************************
139 : : *
140 : : * FUNCTION: acpi_ps_build_named_op
141 : : *
142 : : * PARAMETERS: walk_state - Current state
143 : : * aml_op_start - Begin of named Op in AML
144 : : * unnamed_op - Early Op (not a named Op)
145 : : * op - Returned Op
146 : : *
147 : : * RETURN: Status
148 : : *
149 : : * DESCRIPTION: Parse a named Op
150 : : *
151 : : ******************************************************************************/
152 : :
153 : : acpi_status
154 : 3770 : acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
155 : : u8 *aml_op_start,
156 : : union acpi_parse_object *unnamed_op,
157 : : union acpi_parse_object **op)
158 : : {
159 : 3770 : acpi_status status = AE_OK;
160 : 3770 : union acpi_parse_object *arg = NULL;
161 : :
162 : 3770 : ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
163 : :
164 : 3770 : unnamed_op->common.value.arg = NULL;
165 : 3770 : unnamed_op->common.arg_list_length = 0;
166 : 3770 : unnamed_op->common.aml_opcode = walk_state->opcode;
167 : :
168 : : /*
169 : : * Get and append arguments until we find the node that contains
170 : : * the name (the type ARGP_NAME).
171 : : */
172 [ + + ]: 5668 : while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
173 : : (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) {
174 : 1898 : ASL_CV_CAPTURE_COMMENTS(walk_state);
175 : 1898 : status =
176 : 1898 : acpi_ps_get_next_arg(walk_state,
177 : : &(walk_state->parser_state),
178 : : GET_CURRENT_ARG_TYPE(walk_state->
179 : : arg_types), &arg);
180 [ - + ]: 1898 : if (ACPI_FAILURE(status)) {
181 : 0 : return_ACPI_STATUS(status);
182 : : }
183 : :
184 : 1898 : acpi_ps_append_arg(unnamed_op, arg);
185 : 1898 : INCREMENT_ARG_LIST(walk_state->arg_types);
186 : : }
187 : :
188 : : /* are there any inline comments associated with the name_seg?? If so, save this. */
189 : :
190 : 3770 : ASL_CV_CAPTURE_COMMENTS(walk_state);
191 : :
192 : : #ifdef ACPI_ASL_COMPILER
193 : : if (acpi_gbl_current_inline_comment != NULL) {
194 : : unnamed_op->common.name_comment =
195 : : acpi_gbl_current_inline_comment;
196 : : acpi_gbl_current_inline_comment = NULL;
197 : : }
198 : : #endif
199 : :
200 : : /*
201 : : * Make sure that we found a NAME and didn't run out of arguments
202 : : */
203 [ + - ]: 3770 : if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
204 : : return_ACPI_STATUS(AE_AML_NO_OPERAND);
205 : : }
206 : :
207 : : /* We know that this arg is a name, move to next arg */
208 : :
209 : 3770 : INCREMENT_ARG_LIST(walk_state->arg_types);
210 : :
211 : : /*
212 : : * Find the object. This will either insert the object into
213 : : * the namespace or simply look it up
214 : : */
215 : 3770 : walk_state->op = NULL;
216 : :
217 : 3770 : status = walk_state->descending_callback(walk_state, op);
218 [ - + ]: 3770 : if (ACPI_FAILURE(status)) {
219 [ # # ]: 0 : if (status != AE_CTRL_TERMINATE) {
220 : 0 : ACPI_EXCEPTION((AE_INFO, status,
221 : : "During name lookup/catalog"));
222 : : }
223 : 0 : return_ACPI_STATUS(status);
224 : : }
225 : :
226 [ + - ]: 3770 : if (!*op) {
227 : : return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
228 : : }
229 : :
230 : 3770 : status = acpi_ps_next_parse_state(walk_state, *op, status);
231 [ - + ]: 3770 : if (ACPI_FAILURE(status)) {
232 [ # # ]: 0 : if (status == AE_CTRL_PENDING) {
233 : 0 : status = AE_CTRL_PARSE_PENDING;
234 : : }
235 : 0 : return_ACPI_STATUS(status);
236 : : }
237 : :
238 : 3770 : acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
239 : :
240 : : #ifdef ACPI_ASL_COMPILER
241 : :
242 : : /* save any comments that might be associated with unnamed_op. */
243 : :
244 : : (*op)->common.inline_comment = unnamed_op->common.inline_comment;
245 : : (*op)->common.end_node_comment = unnamed_op->common.end_node_comment;
246 : : (*op)->common.close_brace_comment =
247 : : unnamed_op->common.close_brace_comment;
248 : : (*op)->common.name_comment = unnamed_op->common.name_comment;
249 : : (*op)->common.comment_list = unnamed_op->common.comment_list;
250 : : (*op)->common.end_blk_comment = unnamed_op->common.end_blk_comment;
251 : : (*op)->common.cv_filename = unnamed_op->common.cv_filename;
252 : : (*op)->common.cv_parent_filename =
253 : : unnamed_op->common.cv_parent_filename;
254 : : (*op)->named.aml = unnamed_op->common.aml;
255 : :
256 : : unnamed_op->common.inline_comment = NULL;
257 : : unnamed_op->common.end_node_comment = NULL;
258 : : unnamed_op->common.close_brace_comment = NULL;
259 : : unnamed_op->common.name_comment = NULL;
260 : : unnamed_op->common.comment_list = NULL;
261 : : unnamed_op->common.end_blk_comment = NULL;
262 : : #endif
263 : :
264 [ + + ]: 3770 : if ((*op)->common.aml_opcode == AML_REGION_OP ||
265 : : (*op)->common.aml_opcode == AML_DATA_REGION_OP) {
266 : : /*
267 : : * Defer final parsing of an operation_region body, because we don't
268 : : * have enough info in the first pass to parse it correctly (i.e.,
269 : : * there may be method calls within the term_arg elements of the body.)
270 : : *
271 : : * However, we must continue parsing because the opregion is not a
272 : : * standalone package -- we don't know where the end is at this point.
273 : : *
274 : : * (Length is unknown until parse of the body complete)
275 : : */
276 : 104 : (*op)->named.data = aml_op_start;
277 : 104 : (*op)->named.length = 0;
278 : : }
279 : :
280 : : return_ACPI_STATUS(AE_OK);
281 : : }
282 : :
283 : : /*******************************************************************************
284 : : *
285 : : * FUNCTION: acpi_ps_create_op
286 : : *
287 : : * PARAMETERS: walk_state - Current state
288 : : * aml_op_start - Op start in AML
289 : : * new_op - Returned Op
290 : : *
291 : : * RETURN: Status
292 : : *
293 : : * DESCRIPTION: Get Op from AML
294 : : *
295 : : ******************************************************************************/
296 : :
297 : : acpi_status
298 : 232401 : acpi_ps_create_op(struct acpi_walk_state *walk_state,
299 : : u8 *aml_op_start, union acpi_parse_object **new_op)
300 : : {
301 : 232401 : acpi_status status = AE_OK;
302 : 232401 : union acpi_parse_object *op;
303 : 232401 : union acpi_parse_object *named_op = NULL;
304 : 232401 : union acpi_parse_object *parent_scope;
305 : 232401 : u8 argument_count;
306 : 232401 : const struct acpi_opcode_info *op_info;
307 : :
308 : 232401 : ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
309 : :
310 : 232401 : status = acpi_ps_get_aml_opcode(walk_state);
311 [ + - ]: 232401 : if (status == AE_CTRL_PARSE_CONTINUE) {
312 : : return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
313 : : }
314 [ + - ]: 232401 : if (ACPI_FAILURE(status)) {
315 : : return_ACPI_STATUS(status);
316 : : }
317 : :
318 : : /* Create Op structure and append to parent's argument list */
319 : :
320 : 232401 : walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
321 : 232401 : op = acpi_ps_alloc_op(walk_state->opcode, aml_op_start);
322 [ + - ]: 232401 : if (!op) {
323 : : return_ACPI_STATUS(AE_NO_MEMORY);
324 : : }
325 : :
326 [ + + ]: 232401 : if (walk_state->op_info->flags & AML_NAMED) {
327 : 3770 : status =
328 : 3770 : acpi_ps_build_named_op(walk_state, aml_op_start, op,
329 : : &named_op);
330 : 3770 : acpi_ps_free_op(op);
331 : :
332 : : #ifdef ACPI_ASL_COMPILER
333 : : if (acpi_gbl_disasm_flag
334 : : && walk_state->opcode == AML_EXTERNAL_OP
335 : : && status == AE_NOT_FOUND) {
336 : : /*
337 : : * If parsing of AML_EXTERNAL_OP's name path fails, then skip
338 : : * past this opcode and keep parsing. This is a much better
339 : : * alternative than to abort the entire disassembler. At this
340 : : * point, the parser_state is at the end of the namepath of the
341 : : * external declaration opcode. Setting walk_state->Aml to
342 : : * walk_state->parser_state.Aml + 2 moves increments the
343 : : * walk_state->Aml past the object type and the paramcount of the
344 : : * external opcode.
345 : : */
346 : : walk_state->aml = walk_state->parser_state.aml + 2;
347 : : walk_state->parser_state.aml = walk_state->aml;
348 : : return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
349 : : }
350 : : #endif
351 [ + - ]: 3770 : if (ACPI_FAILURE(status)) {
352 : : return_ACPI_STATUS(status);
353 : : }
354 : :
355 : 3770 : *new_op = named_op;
356 : 3770 : return_ACPI_STATUS(AE_OK);
357 : : }
358 : :
359 : : /* Not a named opcode, just allocate Op and append to parent */
360 : :
361 [ + + ]: 228631 : if (walk_state->op_info->flags & AML_CREATE) {
362 : : /*
363 : : * Backup to beginning of create_XXXfield declaration
364 : : * body_length is unknown until we parse the body
365 : : */
366 : 182 : op->named.data = aml_op_start;
367 : 182 : op->named.length = 0;
368 : : }
369 : :
370 [ - + ]: 228631 : if (walk_state->opcode == AML_BANK_FIELD_OP) {
371 : : /*
372 : : * Backup to beginning of bank_field declaration
373 : : * body_length is unknown until we parse the body
374 : : */
375 : 0 : op->named.data = aml_op_start;
376 : 0 : op->named.length = 0;
377 : : }
378 : :
379 : 228631 : parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
380 : 228631 : acpi_ps_append_arg(parent_scope, op);
381 : :
382 [ + + ]: 228631 : if (parent_scope) {
383 : 227786 : op_info =
384 : 227786 : acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
385 [ + + ]: 227786 : if (op_info->flags & AML_HAS_TARGET) {
386 : 103272 : argument_count =
387 : 103272 : acpi_ps_get_argument_count(op_info->type);
388 [ + + ]: 103272 : if (parent_scope->common.arg_list_length >
389 : : argument_count) {
390 : 20670 : op->common.flags |= ACPI_PARSEOP_TARGET;
391 : : }
392 : : }
393 : :
394 : : /*
395 : : * Special case for both Increment() and Decrement(), where
396 : : * the lone argument is both a source and a target.
397 : : */
398 : 124514 : else if ((parent_scope->common.aml_opcode == AML_INCREMENT_OP)
399 [ + + ]: 124514 : || (parent_scope->common.aml_opcode ==
400 : : AML_DECREMENT_OP)) {
401 : 3354 : op->common.flags |= ACPI_PARSEOP_TARGET;
402 : : }
403 : : }
404 : :
405 [ + - ]: 228631 : if (walk_state->descending_callback != NULL) {
406 : : /*
407 : : * Find the object. This will either insert the object into
408 : : * the namespace or simply look it up
409 : : */
410 : 228631 : walk_state->op = *new_op = op;
411 : :
412 : 228631 : status = walk_state->descending_callback(walk_state, &op);
413 : 228631 : status = acpi_ps_next_parse_state(walk_state, op, status);
414 [ + + ]: 228631 : if (status == AE_CTRL_PENDING) {
415 : 26 : status = AE_CTRL_PARSE_PENDING;
416 : : }
417 : : }
418 : :
419 : : return_ACPI_STATUS(status);
420 : : }
421 : :
422 : : /*******************************************************************************
423 : : *
424 : : * FUNCTION: acpi_ps_complete_op
425 : : *
426 : : * PARAMETERS: walk_state - Current state
427 : : * op - Returned Op
428 : : * status - Parse status before complete Op
429 : : *
430 : : * RETURN: Status
431 : : *
432 : : * DESCRIPTION: Complete Op
433 : : *
434 : : ******************************************************************************/
435 : :
436 : : acpi_status
437 : 220948 : acpi_ps_complete_op(struct acpi_walk_state *walk_state,
438 : : union acpi_parse_object **op, acpi_status status)
439 : : {
440 : 220948 : acpi_status status2;
441 : :
442 : 220948 : ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
443 : :
444 : : /*
445 : : * Finished one argument of the containing scope
446 : : */
447 : 220948 : walk_state->parser_state.scope->parse_scope.arg_count--;
448 : :
449 : : /* Close this Op (will result in parse subtree deletion) */
450 : :
451 : 220948 : status2 = acpi_ps_complete_this_op(walk_state, *op);
452 [ + - ]: 220948 : if (ACPI_FAILURE(status2)) {
453 : : return_ACPI_STATUS(status2);
454 : : }
455 : :
456 : 220948 : *op = NULL;
457 : :
458 [ + + - + : 220948 : switch (status) {
- + ]
459 : : case AE_OK:
460 : :
461 : : break;
462 : :
463 : 364 : case AE_CTRL_TRANSFER:
464 : :
465 : : /* We are about to transfer to a called method */
466 : :
467 : 364 : walk_state->prev_op = NULL;
468 : 364 : walk_state->prev_arg_types = walk_state->arg_types;
469 : 364 : return_ACPI_STATUS(status);
470 : :
471 : 11141 : case AE_CTRL_END:
472 : :
473 : 11141 : acpi_ps_pop_scope(&(walk_state->parser_state), op,
474 : : &walk_state->arg_types,
475 : : &walk_state->arg_count);
476 : :
477 [ + - ]: 11141 : if (*op) {
478 : 11141 : walk_state->op = *op;
479 : 22282 : walk_state->op_info =
480 : 11141 : acpi_ps_get_opcode_info((*op)->common.aml_opcode);
481 : 11141 : walk_state->opcode = (*op)->common.aml_opcode;
482 : :
483 : 11141 : status = walk_state->ascending_callback(walk_state);
484 : 11141 : (void)acpi_ps_next_parse_state(walk_state, *op, status);
485 : :
486 : 11141 : status2 = acpi_ps_complete_this_op(walk_state, *op);
487 [ + - ]: 11141 : if (ACPI_FAILURE(status2)) {
488 : : return_ACPI_STATUS(status2);
489 : : }
490 : : }
491 : :
492 : : break;
493 : :
494 : : case AE_CTRL_BREAK:
495 : : case AE_CTRL_CONTINUE:
496 : :
497 : : /* Pop off scopes until we find the While */
498 : :
499 [ # # # # ]: 0 : while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
500 : 0 : acpi_ps_pop_scope(&(walk_state->parser_state), op,
501 : : &walk_state->arg_types,
502 : : &walk_state->arg_count);
503 : : }
504 : :
505 : : /* Close this iteration of the While loop */
506 : :
507 : 0 : walk_state->op = *op;
508 : 0 : walk_state->op_info =
509 : 0 : acpi_ps_get_opcode_info((*op)->common.aml_opcode);
510 : 0 : walk_state->opcode = (*op)->common.aml_opcode;
511 : :
512 : 0 : status = walk_state->ascending_callback(walk_state);
513 : 0 : (void)acpi_ps_next_parse_state(walk_state, *op, status);
514 : :
515 : 0 : status2 = acpi_ps_complete_this_op(walk_state, *op);
516 [ # # ]: 0 : if (ACPI_FAILURE(status2)) {
517 : : return_ACPI_STATUS(status2);
518 : : }
519 : :
520 : : break;
521 : :
522 : 260 : case AE_CTRL_TERMINATE:
523 : :
524 : : /* Clean up */
525 : 1482 : do {
526 [ + + ]: 1482 : if (*op) {
527 : 260 : status2 =
528 : 260 : acpi_ps_complete_this_op(walk_state, *op);
529 [ - + ]: 260 : if (ACPI_FAILURE(status2)) {
530 : 0 : return_ACPI_STATUS(status2);
531 : : }
532 : :
533 : 260 : acpi_ut_delete_generic_state
534 : : (acpi_ut_pop_generic_state
535 : : (&walk_state->control_state));
536 : : }
537 : :
538 : 1482 : acpi_ps_pop_scope(&(walk_state->parser_state), op,
539 : : &walk_state->arg_types,
540 : : &walk_state->arg_count);
541 : :
542 [ + + ]: 1482 : } while (*op);
543 : :
544 : : return_ACPI_STATUS(AE_OK);
545 : :
546 : 0 : default: /* All other non-AE_OK status */
547 : :
548 : 0 : do {
549 [ # # ]: 0 : if (*op) {
550 : : /*
551 : : * These Opcodes need to be removed from the namespace because they
552 : : * get created even if these opcodes cannot be created due to
553 : : * errors.
554 : : */
555 : 0 : if (((*op)->common.aml_opcode == AML_REGION_OP)
556 [ # # ]: 0 : || ((*op)->common.aml_opcode ==
557 : : AML_DATA_REGION_OP)) {
558 : 0 : acpi_ns_delete_children((*op)->common.
559 : : node);
560 : 0 : acpi_ns_remove_node((*op)->common.node);
561 : 0 : (*op)->common.node = NULL;
562 : 0 : acpi_ps_delete_parse_tree(*op);
563 : : }
564 : :
565 : 0 : status2 =
566 : 0 : acpi_ps_complete_this_op(walk_state, *op);
567 [ # # ]: 0 : if (ACPI_FAILURE(status2)) {
568 : 0 : return_ACPI_STATUS(status2);
569 : : }
570 : : }
571 : :
572 : 0 : acpi_ps_pop_scope(&(walk_state->parser_state), op,
573 : : &walk_state->arg_types,
574 : : &walk_state->arg_count);
575 : :
576 [ # # ]: 0 : } while (*op);
577 : :
578 : : #if 0
579 : : /*
580 : : * TBD: Cleanup parse ops on error
581 : : */
582 : : if (*op == NULL) {
583 : : acpi_ps_pop_scope(parser_state, op,
584 : : &walk_state->arg_types,
585 : : &walk_state->arg_count);
586 : : }
587 : : #endif
588 : 0 : walk_state->prev_op = NULL;
589 : 0 : walk_state->prev_arg_types = walk_state->arg_types;
590 : :
591 [ # # ]: 0 : if (walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL) {
592 : : /*
593 : : * There was something that went wrong while executing code at the
594 : : * module-level. We need to skip parsing whatever caused the
595 : : * error and keep going. One runtime error during the table load
596 : : * should not cause the entire table to not be loaded. This is
597 : : * because there could be correct AML beyond the parts that caused
598 : : * the runtime error.
599 : : */
600 : 0 : ACPI_INFO(("Ignoring error and continuing table load"));
601 : 0 : return_ACPI_STATUS(AE_OK);
602 : : }
603 : : return_ACPI_STATUS(status);
604 : : }
605 : :
606 : : /* This scope complete? */
607 : :
608 [ + + ]: 219362 : if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
609 : 169429 : acpi_ps_pop_scope(&(walk_state->parser_state), op,
610 : : &walk_state->arg_types,
611 : : &walk_state->arg_count);
612 : 169429 : ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
613 : : } else {
614 : 49933 : *op = NULL;
615 : : }
616 : :
617 : : return_ACPI_STATUS(AE_OK);
618 : : }
619 : :
620 : : /*******************************************************************************
621 : : *
622 : : * FUNCTION: acpi_ps_complete_final_op
623 : : *
624 : : * PARAMETERS: walk_state - Current state
625 : : * op - Current Op
626 : : * status - Current parse status before complete last
627 : : * Op
628 : : *
629 : : * RETURN: Status
630 : : *
631 : : * DESCRIPTION: Complete last Op.
632 : : *
633 : : ******************************************************************************/
634 : :
635 : : acpi_status
636 : 2262 : acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
637 : : union acpi_parse_object *op, acpi_status status)
638 : : {
639 : 2262 : acpi_status status2;
640 : :
641 : 2262 : ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
642 : :
643 : : /*
644 : : * Complete the last Op (if not completed), and clear the scope stack.
645 : : * It is easily possible to end an AML "package" with an unbounded number
646 : : * of open scopes (such as when several ASL blocks are closed with
647 : : * sequential closing braces). We want to terminate each one cleanly.
648 : : */
649 : : ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
650 : 2262 : op));
651 : 2262 : do {
652 [ - + ]: 2262 : if (op) {
653 [ # # ]: 0 : if (walk_state->ascending_callback != NULL) {
654 : 0 : walk_state->op = op;
655 : 0 : walk_state->op_info =
656 : 0 : acpi_ps_get_opcode_info(op->common.
657 : : aml_opcode);
658 : 0 : walk_state->opcode = op->common.aml_opcode;
659 : :
660 : 0 : status =
661 : 0 : walk_state->ascending_callback(walk_state);
662 : 0 : status =
663 : 0 : acpi_ps_next_parse_state(walk_state, op,
664 : : status);
665 [ # # ]: 0 : if (status == AE_CTRL_PENDING) {
666 : 0 : status =
667 : 0 : acpi_ps_complete_op(walk_state, &op,
668 : : AE_OK);
669 [ # # ]: 0 : if (ACPI_FAILURE(status)) {
670 : 0 : return_ACPI_STATUS(status);
671 : : }
672 : : }
673 : :
674 [ # # ]: 0 : if (status == AE_CTRL_TERMINATE) {
675 : : status = AE_OK;
676 : :
677 : : /* Clean up */
678 : 0 : do {
679 [ # # ]: 0 : if (op) {
680 : 0 : status2 =
681 : 0 : acpi_ps_complete_this_op
682 : : (walk_state, op);
683 [ # # ]: 0 : if (ACPI_FAILURE
684 : : (status2)) {
685 : 0 : return_ACPI_STATUS
686 : : (status2);
687 : : }
688 : : }
689 : :
690 : 0 : acpi_ps_pop_scope(&
691 : : (walk_state->
692 : : parser_state),
693 : : &op,
694 : : &walk_state->
695 : : arg_types,
696 : : &walk_state->
697 : : arg_count);
698 : :
699 [ # # ]: 0 : } while (op);
700 : :
701 : : return_ACPI_STATUS(status);
702 : : }
703 : :
704 [ # # ]: 0 : else if (ACPI_FAILURE(status)) {
705 : :
706 : : /* First error is most important */
707 : :
708 : 0 : (void)
709 : 0 : acpi_ps_complete_this_op(walk_state,
710 : : op);
711 : 0 : return_ACPI_STATUS(status);
712 : : }
713 : : }
714 : :
715 : 0 : status2 = acpi_ps_complete_this_op(walk_state, op);
716 [ # # ]: 0 : if (ACPI_FAILURE(status2)) {
717 : 0 : return_ACPI_STATUS(status2);
718 : : }
719 : : }
720 : :
721 : 2262 : acpi_ps_pop_scope(&(walk_state->parser_state), &op,
722 : : &walk_state->arg_types,
723 : : &walk_state->arg_count);
724 : :
725 [ - + ]: 2262 : } while (op);
726 : :
727 : : return_ACPI_STATUS(status);
728 : : }
|