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