1 /******************************************************************************
3 * Module Name: psobject - Support for parse objects
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2016, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
44 #include <acpi/acpi.h>
49 #define _COMPONENT ACPI_PARSER
50 ACPI_MODULE_NAME("psobject")
52 /* Local prototypes */
53 static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
55 /*******************************************************************************
57 * FUNCTION: acpi_ps_get_aml_opcode
59 * PARAMETERS: walk_state - Current state
63 * DESCRIPTION: Extract the next AML opcode from the input stream.
65 ******************************************************************************/
67 static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
71 ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
73 walk_state->aml = walk_state->parser_state.aml;
74 walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
77 * First cut to determine what we have found:
78 * 1) A valid AML opcode
80 * 3) An unknown/invalid opcode
82 walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
84 switch (walk_state->op_info->class) {
86 case AML_CLASS_PREFIX:
88 * Starts with a valid prefix or ASCII char, this is a name
89 * string. Convert the bare name string to a namepath.
91 walk_state->opcode = AML_INT_NAMEPATH_OP;
92 walk_state->arg_types = ARGP_NAMESTRING;
95 case AML_CLASS_UNKNOWN:
97 /* The opcode is unrecognized. Complain and skip unknown opcodes */
99 if (walk_state->pass_number == 2) {
100 aml_offset = (u32)ACPI_PTR_DIFF(walk_state->aml,
102 parser_state.aml_start);
105 "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
108 sizeof(struct acpi_table_header))));
110 ACPI_DUMP_BUFFER((walk_state->parser_state.aml - 16),
113 #ifdef ACPI_ASL_COMPILER
115 * This is executed for the disassembler only. Output goes
116 * to the disassembled ASL output file.
119 ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
122 sizeof(struct acpi_table_header)));
125 "Aborting disassembly, AML byte code is corrupt"));
127 /* Dump the context surrounding the invalid opcode */
129 acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
130 aml - 16), 48, DB_BYTE_DISPLAY,
132 sizeof(struct acpi_table_header) -
134 acpi_os_printf(" */\n");
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
142 return_ACPI_STATUS(AE_AML_BAD_OPCODE);
146 /* Increment past one-byte or two-byte opcode */
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++;
153 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
157 /* Found opcode info, this is a normal opcode */
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;
165 return_ACPI_STATUS(AE_OK);
168 /*******************************************************************************
170 * FUNCTION: acpi_ps_build_named_op
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)
179 * DESCRIPTION: Parse a named Op
181 ******************************************************************************/
184 acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
186 union acpi_parse_object *unnamed_op,
187 union acpi_parse_object **op)
189 acpi_status status = AE_OK;
190 union acpi_parse_object *arg = NULL;
192 ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
194 unnamed_op->common.value.arg = NULL;
195 unnamed_op->common.arg_list_length = 0;
196 unnamed_op->common.aml_opcode = walk_state->opcode;
199 * Get and append arguments until we find the node that contains
200 * the name (the type ARGP_NAME).
202 while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
203 (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) {
205 acpi_ps_get_next_arg(walk_state,
206 &(walk_state->parser_state),
207 GET_CURRENT_ARG_TYPE(walk_state->
209 if (ACPI_FAILURE(status)) {
210 return_ACPI_STATUS(status);
213 acpi_ps_append_arg(unnamed_op, arg);
214 INCREMENT_ARG_LIST(walk_state->arg_types);
218 * Make sure that we found a NAME and didn't run out of arguments
220 if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
221 return_ACPI_STATUS(AE_AML_NO_OPERAND);
224 /* We know that this arg is a name, move to next arg */
226 INCREMENT_ARG_LIST(walk_state->arg_types);
229 * Find the object. This will either insert the object into
230 * the namespace or simply look it up
232 walk_state->op = NULL;
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"));
240 return_ACPI_STATUS(status);
244 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
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;
252 return_ACPI_STATUS(status);
255 acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
257 if ((*op)->common.aml_opcode == AML_REGION_OP ||
258 (*op)->common.aml_opcode == AML_DATA_REGION_OP) {
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.)
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.
267 * (Length is unknown until parse of the body complete)
269 (*op)->named.data = aml_op_start;
270 (*op)->named.length = 0;
273 return_ACPI_STATUS(AE_OK);
276 /*******************************************************************************
278 * FUNCTION: acpi_ps_create_op
280 * PARAMETERS: walk_state - Current state
281 * aml_op_start - Op start in AML
282 * new_op - Returned Op
286 * DESCRIPTION: Get Op from AML
288 ******************************************************************************/
291 acpi_ps_create_op(struct acpi_walk_state *walk_state,
292 u8 *aml_op_start, union acpi_parse_object **new_op)
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;
299 const struct acpi_opcode_info *op_info;
301 ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
303 status = acpi_ps_get_aml_opcode(walk_state);
304 if (status == AE_CTRL_PARSE_CONTINUE) {
305 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
307 if (ACPI_FAILURE(status)) {
308 return_ACPI_STATUS(status);
311 /* Create Op structure and append to parent's argument list */
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);
316 return_ACPI_STATUS(AE_NO_MEMORY);
319 if (walk_state->op_info->flags & AML_NAMED) {
321 acpi_ps_build_named_op(walk_state, aml_op_start, op,
324 if (ACPI_FAILURE(status)) {
325 return_ACPI_STATUS(status);
329 return_ACPI_STATUS(AE_OK);
332 /* Not a named opcode, just allocate Op and append to parent */
334 if (walk_state->op_info->flags & AML_CREATE) {
336 * Backup to beginning of create_XXXfield declaration
337 * body_length is unknown until we parse the body
339 op->named.data = aml_op_start;
340 op->named.length = 0;
343 if (walk_state->opcode == AML_BANK_FIELD_OP) {
345 * Backup to beginning of bank_field declaration
346 * body_length is unknown until we parse the body
348 op->named.data = aml_op_start;
349 op->named.length = 0;
352 parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
353 acpi_ps_append_arg(parent_scope, op);
357 acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
358 if (op_info->flags & AML_HAS_TARGET) {
360 acpi_ps_get_argument_count(op_info->type);
361 if (parent_scope->common.arg_list_length >
363 op->common.flags |= ACPI_PARSEOP_TARGET;
365 } else if (parent_scope->common.aml_opcode == AML_INCREMENT_OP) {
366 op->common.flags |= ACPI_PARSEOP_TARGET;
370 if (walk_state->descending_callback != NULL) {
372 * Find the object. This will either insert the object into
373 * the namespace or simply look it up
375 walk_state->op = *new_op = op;
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;
384 return_ACPI_STATUS(status);
387 /*******************************************************************************
389 * FUNCTION: acpi_ps_complete_op
391 * PARAMETERS: walk_state - Current state
393 * status - Parse status before complete Op
397 * DESCRIPTION: Complete Op
399 ******************************************************************************/
402 acpi_ps_complete_op(struct acpi_walk_state *walk_state,
403 union acpi_parse_object **op, acpi_status status)
407 ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
410 * Finished one argument of the containing scope
412 walk_state->parser_state.scope->parse_scope.arg_count--;
414 /* Close this Op (will result in parse subtree deletion) */
416 status2 = acpi_ps_complete_this_op(walk_state, *op);
417 if (ACPI_FAILURE(status2)) {
418 return_ACPI_STATUS(status2);
428 case AE_CTRL_TRANSFER:
430 /* We are about to transfer to a called method */
432 walk_state->prev_op = NULL;
433 walk_state->prev_arg_types = walk_state->arg_types;
434 return_ACPI_STATUS(status);
438 acpi_ps_pop_scope(&(walk_state->parser_state), op,
439 &walk_state->arg_types,
440 &walk_state->arg_count);
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;
448 status = walk_state->ascending_callback(walk_state);
450 acpi_ps_next_parse_state(walk_state, *op, status);
452 status2 = acpi_ps_complete_this_op(walk_state, *op);
453 if (ACPI_FAILURE(status2)) {
454 return_ACPI_STATUS(status2);
462 case AE_CTRL_CONTINUE:
464 /* Pop off scopes until we find the While */
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);
472 /* Close this iteration of the While loop */
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;
479 status = walk_state->ascending_callback(walk_state);
480 status = acpi_ps_next_parse_state(walk_state, *op, status);
482 status2 = acpi_ps_complete_this_op(walk_state, *op);
483 if (ACPI_FAILURE(status2)) {
484 return_ACPI_STATUS(status2);
490 case AE_CTRL_TERMINATE:
496 acpi_ps_complete_this_op(walk_state, *op);
497 if (ACPI_FAILURE(status2)) {
498 return_ACPI_STATUS(status2);
501 acpi_ut_delete_generic_state
502 (acpi_ut_pop_generic_state
503 (&walk_state->control_state));
506 acpi_ps_pop_scope(&(walk_state->parser_state), op,
507 &walk_state->arg_types,
508 &walk_state->arg_count);
512 return_ACPI_STATUS(AE_OK);
514 default: /* All other non-AE_OK status */
519 acpi_ps_complete_this_op(walk_state, *op);
520 if (ACPI_FAILURE(status2)) {
521 return_ACPI_STATUS(status2);
525 acpi_ps_pop_scope(&(walk_state->parser_state), op,
526 &walk_state->arg_types,
527 &walk_state->arg_count);
533 * TBD: Cleanup parse ops on error
536 acpi_ps_pop_scope(parser_state, op,
537 &walk_state->arg_types,
538 &walk_state->arg_count);
541 walk_state->prev_op = NULL;
542 walk_state->prev_arg_types = walk_state->arg_types;
543 return_ACPI_STATUS(status);
546 /* This scope complete? */
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));
557 return_ACPI_STATUS(AE_OK);
560 /*******************************************************************************
562 * FUNCTION: acpi_ps_complete_final_op
564 * PARAMETERS: walk_state - Current state
566 * status - Current parse status before complete last
571 * DESCRIPTION: Complete last Op.
573 ******************************************************************************/
576 acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
577 union acpi_parse_object *op, acpi_status status)
581 ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
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.
589 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
593 if (walk_state->ascending_callback != NULL) {
595 walk_state->op_info =
596 acpi_ps_get_opcode_info(op->common.
598 walk_state->opcode = op->common.aml_opcode;
601 walk_state->ascending_callback(walk_state);
603 acpi_ps_next_parse_state(walk_state, op,
605 if (status == AE_CTRL_PENDING) {
607 acpi_ps_complete_op(walk_state, &op,
609 if (ACPI_FAILURE(status)) {
610 return_ACPI_STATUS(status);
614 if (status == AE_CTRL_TERMINATE) {
621 acpi_ps_complete_this_op
641 return_ACPI_STATUS(status);
644 else if (ACPI_FAILURE(status)) {
646 /* First error is most important */
649 acpi_ps_complete_this_op(walk_state,
651 return_ACPI_STATUS(status);
655 status2 = acpi_ps_complete_this_op(walk_state, op);
656 if (ACPI_FAILURE(status2)) {
657 return_ACPI_STATUS(status2);
661 acpi_ps_pop_scope(&(walk_state->parser_state), &op,
662 &walk_state->arg_types,
663 &walk_state->arg_count);
667 return_ACPI_STATUS(status);