Branch data Line data Source code
1 : : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 : : /****************************************************************************** 3 : : * 4 : : * Module Name: psscope - Parser scope stack management routines 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 : : 14 : : #define _COMPONENT ACPI_PARSER 15 : : ACPI_MODULE_NAME("psscope") 16 : : 17 : : /******************************************************************************* 18 : : * 19 : : * FUNCTION: acpi_ps_get_parent_scope 20 : : * 21 : : * PARAMETERS: parser_state - Current parser state object 22 : : * 23 : : * RETURN: Pointer to an Op object 24 : : * 25 : : * DESCRIPTION: Get parent of current op being parsed 26 : : * 27 : : ******************************************************************************/ 28 : 28437 : union acpi_parse_object *acpi_ps_get_parent_scope(struct acpi_parse_state 29 : : *parser_state) 30 : : { 31 : : 32 : 28437 : return (parser_state->scope->parse_scope.op); 33 : : } 34 : : 35 : : /******************************************************************************* 36 : : * 37 : : * FUNCTION: acpi_ps_has_completed_scope 38 : : * 39 : : * PARAMETERS: parser_state - Current parser state object 40 : : * 41 : : * RETURN: Boolean, TRUE = scope completed. 42 : : * 43 : : * DESCRIPTION: Is parsing of current argument complete? Determined by 44 : : * 1) AML pointer is at or beyond the end of the scope 45 : : * 2) The scope argument count has reached zero. 46 : : * 47 : : ******************************************************************************/ 48 : : 49 : 27633 : u8 acpi_ps_has_completed_scope(struct acpi_parse_state * parser_state) 50 : : { 51 : : 52 : 55266 : return ((u8) 53 : 27633 : ((parser_state->aml >= parser_state->scope->parse_scope.arg_end 54 [ + + + + ]: 27633 : || !parser_state->scope->parse_scope.arg_count))); 55 : : } 56 : : 57 : : /******************************************************************************* 58 : : * 59 : : * FUNCTION: acpi_ps_init_scope 60 : : * 61 : : * PARAMETERS: parser_state - Current parser state object 62 : : * root - the Root Node of this new scope 63 : : * 64 : : * RETURN: Status 65 : : * 66 : : * DESCRIPTION: Allocate and init a new scope object 67 : : * 68 : : ******************************************************************************/ 69 : : 70 : : acpi_status 71 : 531 : acpi_ps_init_scope(struct acpi_parse_state * parser_state, 72 : : union acpi_parse_object * root_op) 73 : : { 74 : 531 : union acpi_generic_state *scope; 75 : : 76 : 531 : ACPI_FUNCTION_TRACE_PTR(ps_init_scope, root_op); 77 : : 78 : 531 : scope = acpi_ut_create_generic_state(); 79 [ + - ]: 531 : if (!scope) { 80 : : return_ACPI_STATUS(AE_NO_MEMORY); 81 : : } 82 : : 83 : 531 : scope->common.descriptor_type = ACPI_DESC_TYPE_STATE_RPSCOPE; 84 : 531 : scope->parse_scope.op = root_op; 85 : 531 : scope->parse_scope.arg_count = ACPI_VAR_ARGS; 86 : 531 : scope->parse_scope.arg_end = parser_state->aml_end; 87 : 531 : scope->parse_scope.pkg_end = parser_state->aml_end; 88 : : 89 : 531 : parser_state->scope = scope; 90 : 531 : parser_state->start_op = root_op; 91 : : 92 : 531 : return_ACPI_STATUS(AE_OK); 93 : : } 94 : : 95 : : /******************************************************************************* 96 : : * 97 : : * FUNCTION: acpi_ps_push_scope 98 : : * 99 : : * PARAMETERS: parser_state - Current parser state object 100 : : * op - Current op to be pushed 101 : : * remaining_args - List of args remaining 102 : : * arg_count - Fixed or variable number of args 103 : : * 104 : : * RETURN: Status 105 : : * 106 : : * DESCRIPTION: Push current op to begin parsing its argument 107 : : * 108 : : ******************************************************************************/ 109 : : 110 : : acpi_status 111 : 22383 : acpi_ps_push_scope(struct acpi_parse_state *parser_state, 112 : : union acpi_parse_object *op, 113 : : u32 remaining_args, u32 arg_count) 114 : : { 115 : 22383 : union acpi_generic_state *scope; 116 : : 117 : 22383 : ACPI_FUNCTION_TRACE_PTR(ps_push_scope, op); 118 : : 119 : 22383 : scope = acpi_ut_create_generic_state(); 120 [ + - ]: 22383 : if (!scope) { 121 : : return_ACPI_STATUS(AE_NO_MEMORY); 122 : : } 123 : : 124 : 22383 : scope->common.descriptor_type = ACPI_DESC_TYPE_STATE_PSCOPE; 125 : 22383 : scope->parse_scope.op = op; 126 : 22383 : scope->parse_scope.arg_list = remaining_args; 127 : 22383 : scope->parse_scope.arg_count = arg_count; 128 : 22383 : scope->parse_scope.pkg_end = parser_state->pkg_end; 129 : : 130 : : /* Push onto scope stack */ 131 : : 132 : 22383 : acpi_ut_push_generic_state(&parser_state->scope, scope); 133 : : 134 [ + + ]: 22383 : if (arg_count == ACPI_VAR_ARGS) { 135 : : 136 : : /* Multiple arguments */ 137 : : 138 : 1719 : scope->parse_scope.arg_end = parser_state->pkg_end; 139 : : } else { 140 : : /* Single argument */ 141 : : 142 : 20664 : scope->parse_scope.arg_end = ACPI_TO_POINTER(ACPI_MAX_PTR); 143 : : } 144 : : 145 : : return_ACPI_STATUS(AE_OK); 146 : : } 147 : : 148 : : /******************************************************************************* 149 : : * 150 : : * FUNCTION: acpi_ps_pop_scope 151 : : * 152 : : * PARAMETERS: parser_state - Current parser state object 153 : : * op - Where the popped op is returned 154 : : * arg_list - Where the popped "next argument" is 155 : : * returned 156 : : * arg_count - Count of objects in arg_list 157 : : * 158 : : * RETURN: Status 159 : : * 160 : : * DESCRIPTION: Return to parsing a previous op 161 : : * 162 : : ******************************************************************************/ 163 : : 164 : : void 165 : 23388 : acpi_ps_pop_scope(struct acpi_parse_state *parser_state, 166 : : union acpi_parse_object **op, u32 * arg_list, u32 * arg_count) 167 : : { 168 : 23388 : union acpi_generic_state *scope = parser_state->scope; 169 : : 170 : 23388 : ACPI_FUNCTION_TRACE(ps_pop_scope); 171 : : 172 : : /* Only pop the scope if there is in fact a next scope */ 173 : : 174 [ + + ]: 23388 : if (scope->common.next) { 175 : 22383 : scope = acpi_ut_pop_generic_state(&parser_state->scope); 176 : : 177 : : /* Return to parsing previous op */ 178 : : 179 : 22383 : *op = scope->parse_scope.op; 180 : 22383 : *arg_list = scope->parse_scope.arg_list; 181 : 22383 : *arg_count = scope->parse_scope.arg_count; 182 : 22383 : parser_state->pkg_end = scope->parse_scope.pkg_end; 183 : : 184 : : /* All done with this scope state structure */ 185 : : 186 : 22383 : acpi_ut_delete_generic_state(scope); 187 : : } else { 188 : : /* Empty parse stack, prepare to fetch next opcode */ 189 : : 190 : 1005 : *op = NULL; 191 : 1005 : *arg_list = 0; 192 : 1005 : *arg_count = 0; 193 : : } 194 : : 195 : : ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 196 : 23388 : "Popped Op %p Args %X\n", *op, *arg_count)); 197 : 23388 : return_VOID; 198 : : } 199 : : 200 : : /******************************************************************************* 201 : : * 202 : : * FUNCTION: acpi_ps_cleanup_scope 203 : : * 204 : : * PARAMETERS: parser_state - Current parser state object 205 : : * 206 : : * RETURN: None 207 : : * 208 : : * DESCRIPTION: Destroy available list, remaining stack levels, and return 209 : : * root scope 210 : : * 211 : : ******************************************************************************/ 212 : : 213 : 531 : void acpi_ps_cleanup_scope(struct acpi_parse_state *parser_state) 214 : : { 215 : 531 : union acpi_generic_state *scope; 216 : : 217 : 531 : ACPI_FUNCTION_TRACE_PTR(ps_cleanup_scope, parser_state); 218 : : 219 [ + - ]: 531 : if (!parser_state) { 220 : : return_VOID; 221 : : } 222 : : 223 : : /* Delete anything on the scope stack */ 224 : : 225 [ + + ]: 1062 : while (parser_state->scope) { 226 : 531 : scope = acpi_ut_pop_generic_state(&parser_state->scope); 227 : 531 : acpi_ut_delete_generic_state(scope); 228 : : } 229 : : 230 : : return_VOID; 231 : : }