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