^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Module Name: psparse - Parser top level AML parse routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2000 - 2020, Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Parse the AML and build an operation tree as most interpreters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * like Perl, do. Parsing is done by hand rather than with a YACC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * generated parser to tightly constrain stack and dynamic memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * usage. At the same time, parsing is kept flexible and the code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * fairly compact by parsing based on a list of AML opcode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * templates in aml_op_info[]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <acpi/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "accommon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "acparser.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "acdispat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "amlcode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "acinterp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "acnamesp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define _COMPONENT ACPI_PARSER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) ACPI_MODULE_NAME("psparse")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * FUNCTION: acpi_ps_get_opcode_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * PARAMETERS: opcode - An AML opcode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * RETURN: Size of the opcode, in bytes (1 or 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * DESCRIPTION: Get the size of the current opcode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) u32 acpi_ps_get_opcode_size(u32 opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* Extended (2-byte) opcode if > 255 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (opcode > 0x00FF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return (2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* Otherwise, just a single byte opcode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * FUNCTION: acpi_ps_peek_opcode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * PARAMETERS: parser_state - A parser state object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * RETURN: Next AML opcode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * DESCRIPTION: Get next AML opcode (without incrementing AML pointer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) u16 acpi_ps_peek_opcode(struct acpi_parse_state * parser_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) u8 *aml;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) u16 opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) aml = parser_state->aml;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) opcode = (u16) ACPI_GET8(aml);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (opcode == AML_EXTENDED_PREFIX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* Extended opcode, get the second opcode byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) aml++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) opcode = (u16) ((opcode << 8) | ACPI_GET8(aml));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return (opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * FUNCTION: acpi_ps_complete_this_op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * PARAMETERS: walk_state - Current State
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * op - Op to complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * DESCRIPTION: Perform any cleanup at the completion of an Op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) acpi_ps_complete_this_op(struct acpi_walk_state *walk_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) union acpi_parse_object *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) union acpi_parse_object *prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) union acpi_parse_object *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) const struct acpi_opcode_info *parent_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) union acpi_parse_object *replacement_op = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) acpi_status status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ACPI_FUNCTION_TRACE_PTR(ps_complete_this_op, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* Check for null Op, can happen if AML code is corrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (!op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return_ACPI_STATUS(AE_OK); /* OK for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) acpi_ex_stop_trace_opcode(op, walk_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* Delete this op and the subtree below it if asked to */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) ACPI_PARSE_DELETE_TREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) || (walk_state->op_info->class == AML_CLASS_ARGUMENT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* Make sure that we only delete this subtree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (op->common.parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) prev = op->common.parent->common.value.arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (!prev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* Nothing more to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * Check if we need to replace the operator and its subtree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * with a return value op (placeholder op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) parent_info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) acpi_ps_get_opcode_info(op->common.parent->common.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) aml_opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) switch (parent_info->class) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case AML_CLASS_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) case AML_CLASS_CREATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * These opcodes contain term_arg operands. The current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * op must be replaced by a placeholder return op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) replacement_op =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) op->common.aml);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (!replacement_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) status = AE_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) case AML_CLASS_NAMED_OBJECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * These opcodes contain term_arg operands. The current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * op must be replaced by a placeholder return op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if ((op->common.parent->common.aml_opcode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) AML_REGION_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) || (op->common.parent->common.aml_opcode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) AML_DATA_REGION_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) || (op->common.parent->common.aml_opcode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) AML_BUFFER_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) || (op->common.parent->common.aml_opcode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) AML_PACKAGE_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) || (op->common.parent->common.aml_opcode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) AML_BANK_FIELD_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) || (op->common.parent->common.aml_opcode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) AML_VARIABLE_PACKAGE_OP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) replacement_op =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) op->common.aml);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (!replacement_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) status = AE_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if ((op->common.parent->common.aml_opcode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) AML_NAME_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) && (walk_state->pass_number <=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) ACPI_IMODE_LOAD_PASS2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if ((op->common.aml_opcode == AML_BUFFER_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) || (op->common.aml_opcode == AML_PACKAGE_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) || (op->common.aml_opcode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) AML_VARIABLE_PACKAGE_OP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) replacement_op =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) acpi_ps_alloc_op(op->common.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) aml_opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) op->common.aml);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (!replacement_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) status = AE_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) replacement_op->named.data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) op->named.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) replacement_op->named.length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) op->named.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) replacement_op =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) op->common.aml);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (!replacement_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) status = AE_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* We must unlink this op from the parent tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (prev == op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /* This op is the first in the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (replacement_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) replacement_op->common.parent =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) op->common.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) replacement_op->common.value.arg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) replacement_op->common.node = op->common.node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) op->common.parent->common.value.arg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) replacement_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) replacement_op->common.next = op->common.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) op->common.parent->common.value.arg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) op->common.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* Search the parent list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) while (prev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* Traverse all siblings in the parent's argument list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) next = prev->common.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (next == op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (replacement_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) replacement_op->common.parent =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) op->common.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) replacement_op->common.value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) arg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) replacement_op->common.node =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) op->common.node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) prev->common.next =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) replacement_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) replacement_op->common.next =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) op->common.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) prev->common.next =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) op->common.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) prev = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* Now we can actually delete the subtree rooted at Op */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) acpi_ps_delete_parse_tree(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * FUNCTION: acpi_ps_next_parse_state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * PARAMETERS: walk_state - Current state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * op - Current parse op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * callback_status - Status from previous operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * DESCRIPTION: Update the parser state based upon the return exception from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * the parser callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) acpi_ps_next_parse_state(struct acpi_walk_state *walk_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) union acpi_parse_object *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) acpi_status callback_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct acpi_parse_state *parser_state = &walk_state->parser_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) acpi_status status = AE_CTRL_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ACPI_FUNCTION_TRACE_PTR(ps_next_parse_state, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) switch (callback_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) case AE_CTRL_TERMINATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * A control method was terminated via a RETURN statement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * The walk of this method is complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) parser_state->aml = parser_state->aml_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) status = AE_CTRL_TERMINATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) case AE_CTRL_BREAK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) parser_state->aml = walk_state->aml_last_while;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) walk_state->control_state->common.value = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) status = AE_CTRL_BREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) case AE_CTRL_CONTINUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) parser_state->aml = walk_state->aml_last_while;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) status = AE_CTRL_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) case AE_CTRL_PENDING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) parser_state->aml = walk_state->aml_last_while;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) case AE_CTRL_SKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) parser_state->aml = parser_state->scope->parse_scope.pkg_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) case AE_CTRL_TRUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * Predicate of an IF was true, and we are at the matching ELSE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * Just close out this package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) parser_state->aml = acpi_ps_get_next_package_end(parser_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) status = AE_CTRL_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) case AE_CTRL_FALSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * Either an IF/WHILE Predicate was false or we encountered a BREAK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * opcode. In both cases, we do not execute the rest of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * package; We simply close out the parent (finishing the walk of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * this branch of the tree) and continue execution at the parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) parser_state->aml = parser_state->scope->parse_scope.pkg_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* In the case of a BREAK, just force a predicate (if any) to FALSE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) walk_state->control_state->common.value = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) status = AE_CTRL_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) case AE_CTRL_TRANSFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* A method call (invocation) -- transfer control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) status = AE_CTRL_TRANSFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) walk_state->prev_op = op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) walk_state->method_call_op = op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) walk_state->method_call_node =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) (op->common.value.arg)->common.node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* Will return value (if any) be used by the caller? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) walk_state->return_used =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) acpi_ds_is_result_used(op, walk_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) status = callback_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if ((callback_status & AE_CODE_MASK) == AE_CODE_CONTROL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * FUNCTION: acpi_ps_parse_aml
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * PARAMETERS: walk_state - Current state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * DESCRIPTION: Parse raw AML and return a tree of ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct acpi_thread_state *thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct acpi_thread_state *prev_walk_list = acpi_gbl_current_walk_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct acpi_walk_state *previous_walk_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ACPI_FUNCTION_TRACE(ps_parse_aml);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) "Entered with WalkState=%p Aml=%p size=%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) walk_state, walk_state->parser_state.aml,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) walk_state->parser_state.aml_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (!walk_state->parser_state.aml) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return_ACPI_STATUS(AE_BAD_ADDRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) /* Create and initialize a new thread state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) thread = acpi_ut_create_thread_state();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (!thread) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (walk_state->method_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* Executing a control method - additional cleanup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) acpi_ds_terminate_control_method(walk_state->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) method_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) walk_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) acpi_ds_delete_walk_state(walk_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return_ACPI_STATUS(AE_NO_MEMORY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) walk_state->thread = thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * If executing a method, the starting sync_level is this method's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * sync_level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (walk_state->method_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) walk_state->thread->current_sync_level =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) walk_state->method_desc->method.sync_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) acpi_ds_push_walk_state(walk_state, thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * This global allows the AML debugger to get a handle to the currently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * executing control method.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) acpi_gbl_current_walk_list = thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * Execute the walk loop as long as there is a valid Walk State. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * handles nested control method invocations without recursion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "State=%p\n", walk_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) while (walk_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * The parse_loop executes AML until the method terminates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * or calls another method.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) status = acpi_ps_parse_loop(walk_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) "Completed one call to walk loop, %s State=%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) acpi_format_exception(status), walk_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (walk_state->method_pathname && walk_state->method_is_nested) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* Optional object evaluation log */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ACPI_DEBUG_PRINT_RAW((ACPI_DB_EVALUATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) "%-26s: %*s%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) " Exit nested method",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) (walk_state->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) method_nesting_depth + 1) * 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) " ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) &walk_state->method_pathname[1]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ACPI_FREE(walk_state->method_pathname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) walk_state->method_is_nested = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (status == AE_CTRL_TRANSFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * A method call was detected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) * Transfer control to the called control method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) acpi_ds_call_control_method(thread, walk_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) acpi_ds_method_error(status, walk_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * If the transfer to the new method method call worked,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * a new walk state was created -- get it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) walk_state = acpi_ds_get_current_walk_state(thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) } else if (status == AE_CTRL_TERMINATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) } else if ((status != AE_OK) && (walk_state->method_desc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /* Either the method parse or actual execution failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) acpi_ex_exit_interpreter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (status == AE_ABORT_METHOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) acpi_ns_print_node_pathname(walk_state->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) method_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) "Aborting method");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) acpi_os_printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) ACPI_ERROR_METHOD("Aborting method",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) walk_state->method_node, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) acpi_ex_enter_interpreter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* Check for possible multi-thread reentrancy problem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if ((status == AE_ALREADY_EXISTS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) (!(walk_state->method_desc->method.info_flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) ACPI_METHOD_SERIALIZED))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * Method is not serialized and tried to create an object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * twice. The probable cause is that the method cannot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * handle reentrancy. Mark as "pending serialized" now, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * then mark "serialized" when the last thread exits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) walk_state->method_desc->method.info_flags |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) ACPI_METHOD_SERIALIZED_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /* We are done with this walk, move on to the parent if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) walk_state = acpi_ds_pop_walk_state(thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /* Reset the current scope to the beginning of scope stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) acpi_ds_scope_stack_clear(walk_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * If we just returned from the execution of a control method or if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * encountered an error during the method parse phase, there's lots of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * cleanup to do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) ACPI_PARSE_EXECUTE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) (ACPI_FAILURE(status))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) acpi_ds_terminate_control_method(walk_state->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) method_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) walk_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* Delete this walk state and all linked control states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) acpi_ps_cleanup_scope(&walk_state->parser_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) previous_walk_state = walk_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) "ReturnValue=%p, ImplicitValue=%p State=%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) walk_state->return_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) walk_state->implicit_return_obj, walk_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /* Check if we have restarted a preempted walk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) walk_state = acpi_ds_get_current_walk_state(thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (walk_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * There is another walk state, restart it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * If the method return value is not used by the parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * The object is deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (!previous_walk_state->return_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * In slack mode execution, if there is no return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * we should implicitly return zero (0) as a default value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (acpi_gbl_enable_interpreter_slack &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) !previous_walk_state->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) implicit_return_obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) previous_walk_state->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) implicit_return_obj =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) acpi_ut_create_integer_object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ((u64) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (!previous_walk_state->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) implicit_return_obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return_ACPI_STATUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) (AE_NO_MEMORY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /* Restart the calling control method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) acpi_ds_restart_control_method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) (walk_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) previous_walk_state->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) implicit_return_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * We have a valid return value, delete any implicit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) acpi_ds_clear_implicit_return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) (previous_walk_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) acpi_ds_restart_control_method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) (walk_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) previous_walk_state->return_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) walk_state->walk_type |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) ACPI_WALK_METHOD_RESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* On error, delete any return object or implicit return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) acpi_ut_remove_reference(previous_walk_state->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) acpi_ds_clear_implicit_return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) (previous_walk_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * Just completed a 1st-level method, save the final internal return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * value (if any)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) else if (previous_walk_state->caller_return_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (previous_walk_state->implicit_return_obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) *(previous_walk_state->caller_return_desc) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) previous_walk_state->implicit_return_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) /* NULL if no return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) *(previous_walk_state->caller_return_desc) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) previous_walk_state->return_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (previous_walk_state->return_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) /* Caller doesn't want it, must delete it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) acpi_ut_remove_reference(previous_walk_state->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (previous_walk_state->implicit_return_obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) /* Caller doesn't want it, must delete it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) acpi_ut_remove_reference(previous_walk_state->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) implicit_return_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) acpi_ds_delete_walk_state(previous_walk_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) /* Normal exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) acpi_ex_release_all_mutexes(thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) acpi_ut_delete_generic_state(ACPI_CAST_PTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) (union acpi_generic_state, thread));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) acpi_gbl_current_walk_list = prev_walk_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }