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