1 /****************************************************************************** 2 * 3 * Module Name: psscope - Parser scope stack management routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2017, 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 48 #define _COMPONENT ACPI_PARSER 49 ACPI_MODULE_NAME("psscope") 50 51 /******************************************************************************* 52 * 53 * FUNCTION: acpi_ps_get_parent_scope 54 * 55 * PARAMETERS: parser_state - Current parser state object 56 * 57 * RETURN: Pointer to an Op object 58 * 59 * DESCRIPTION: Get parent of current op being parsed 60 * 61 ******************************************************************************/ 62 union acpi_parse_object *acpi_ps_get_parent_scope(struct acpi_parse_state 63 *parser_state) 64 { 65 66 return (parser_state->scope->parse_scope.op); 67 } 68 69 /******************************************************************************* 70 * 71 * FUNCTION: acpi_ps_has_completed_scope 72 * 73 * PARAMETERS: parser_state - Current parser state object 74 * 75 * RETURN: Boolean, TRUE = scope completed. 76 * 77 * DESCRIPTION: Is parsing of current argument complete? Determined by 78 * 1) AML pointer is at or beyond the end of the scope 79 * 2) The scope argument count has reached zero. 80 * 81 ******************************************************************************/ 82 83 u8 acpi_ps_has_completed_scope(struct acpi_parse_state * parser_state) 84 { 85 86 return ((u8) 87 ((parser_state->aml >= parser_state->scope->parse_scope.arg_end 88 || !parser_state->scope->parse_scope.arg_count))); 89 } 90 91 /******************************************************************************* 92 * 93 * FUNCTION: acpi_ps_init_scope 94 * 95 * PARAMETERS: parser_state - Current parser state object 96 * root - the Root Node of this new scope 97 * 98 * RETURN: Status 99 * 100 * DESCRIPTION: Allocate and init a new scope object 101 * 102 ******************************************************************************/ 103 104 acpi_status 105 acpi_ps_init_scope(struct acpi_parse_state * parser_state, 106 union acpi_parse_object * root_op) 107 { 108 union acpi_generic_state *scope; 109 110 ACPI_FUNCTION_TRACE_PTR(ps_init_scope, root_op); 111 112 scope = acpi_ut_create_generic_state(); 113 if (!scope) { 114 return_ACPI_STATUS(AE_NO_MEMORY); 115 } 116 117 scope->common.descriptor_type = ACPI_DESC_TYPE_STATE_RPSCOPE; 118 scope->parse_scope.op = root_op; 119 scope->parse_scope.arg_count = ACPI_VAR_ARGS; 120 scope->parse_scope.arg_end = parser_state->aml_end; 121 scope->parse_scope.pkg_end = parser_state->aml_end; 122 123 parser_state->scope = scope; 124 parser_state->start_op = root_op; 125 126 return_ACPI_STATUS(AE_OK); 127 } 128 129 /******************************************************************************* 130 * 131 * FUNCTION: acpi_ps_push_scope 132 * 133 * PARAMETERS: parser_state - Current parser state object 134 * op - Current op to be pushed 135 * remaining_args - List of args remaining 136 * arg_count - Fixed or variable number of args 137 * 138 * RETURN: Status 139 * 140 * DESCRIPTION: Push current op to begin parsing its argument 141 * 142 ******************************************************************************/ 143 144 acpi_status 145 acpi_ps_push_scope(struct acpi_parse_state *parser_state, 146 union acpi_parse_object *op, 147 u32 remaining_args, u32 arg_count) 148 { 149 union acpi_generic_state *scope; 150 151 ACPI_FUNCTION_TRACE_PTR(ps_push_scope, op); 152 153 scope = acpi_ut_create_generic_state(); 154 if (!scope) { 155 return_ACPI_STATUS(AE_NO_MEMORY); 156 } 157 158 scope->common.descriptor_type = ACPI_DESC_TYPE_STATE_PSCOPE; 159 scope->parse_scope.op = op; 160 scope->parse_scope.arg_list = remaining_args; 161 scope->parse_scope.arg_count = arg_count; 162 scope->parse_scope.pkg_end = parser_state->pkg_end; 163 164 /* Push onto scope stack */ 165 166 acpi_ut_push_generic_state(&parser_state->scope, scope); 167 168 if (arg_count == ACPI_VAR_ARGS) { 169 170 /* Multiple arguments */ 171 172 scope->parse_scope.arg_end = parser_state->pkg_end; 173 } else { 174 /* Single argument */ 175 176 scope->parse_scope.arg_end = ACPI_TO_POINTER(ACPI_MAX_PTR); 177 } 178 179 return_ACPI_STATUS(AE_OK); 180 } 181 182 /******************************************************************************* 183 * 184 * FUNCTION: acpi_ps_pop_scope 185 * 186 * PARAMETERS: parser_state - Current parser state object 187 * op - Where the popped op is returned 188 * arg_list - Where the popped "next argument" is 189 * returned 190 * arg_count - Count of objects in arg_list 191 * 192 * RETURN: Status 193 * 194 * DESCRIPTION: Return to parsing a previous op 195 * 196 ******************************************************************************/ 197 198 void 199 acpi_ps_pop_scope(struct acpi_parse_state *parser_state, 200 union acpi_parse_object **op, u32 * arg_list, u32 * arg_count) 201 { 202 union acpi_generic_state *scope = parser_state->scope; 203 204 ACPI_FUNCTION_TRACE(ps_pop_scope); 205 206 /* Only pop the scope if there is in fact a next scope */ 207 208 if (scope->common.next) { 209 scope = acpi_ut_pop_generic_state(&parser_state->scope); 210 211 /* Return to parsing previous op */ 212 213 *op = scope->parse_scope.op; 214 *arg_list = scope->parse_scope.arg_list; 215 *arg_count = scope->parse_scope.arg_count; 216 parser_state->pkg_end = scope->parse_scope.pkg_end; 217 218 /* All done with this scope state structure */ 219 220 acpi_ut_delete_generic_state(scope); 221 } else { 222 /* Empty parse stack, prepare to fetch next opcode */ 223 224 *op = NULL; 225 *arg_list = 0; 226 *arg_count = 0; 227 } 228 229 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 230 "Popped Op %p Args %X\n", *op, *arg_count)); 231 return_VOID; 232 } 233 234 /******************************************************************************* 235 * 236 * FUNCTION: acpi_ps_cleanup_scope 237 * 238 * PARAMETERS: parser_state - Current parser state object 239 * 240 * RETURN: None 241 * 242 * DESCRIPTION: Destroy available list, remaining stack levels, and return 243 * root scope 244 * 245 ******************************************************************************/ 246 247 void acpi_ps_cleanup_scope(struct acpi_parse_state *parser_state) 248 { 249 union acpi_generic_state *scope; 250 251 ACPI_FUNCTION_TRACE_PTR(ps_cleanup_scope, parser_state); 252 253 if (!parser_state) { 254 return_VOID; 255 } 256 257 /* Delete anything on the scope stack */ 258 259 while (parser_state->scope) { 260 scope = acpi_ut_pop_generic_state(&parser_state->scope); 261 acpi_ut_delete_generic_state(scope); 262 } 263 264 return_VOID; 265 } 266