Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6595 | serge | 1 | /****************************************************************************** |
2 | * |
||
3 | * Module Name: psscope - Parser scope stack management routines |
||
4 | * |
||
5 | *****************************************************************************/ |
||
6 | |||
7 | /* |
||
8 | * Copyright (C) 2000 - 2015, 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 |
||
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 | } |