1/******************************************************************************
2 *
3 * Module Name: psscope - Parser scope stack management routines
4 *              $Revision: 1.1.1.1 $
5 *
6 *****************************************************************************/
7
8/*
9 *  Copyright (C) 2000, 2001 R. Byron Moore
10 *
11 *  This program is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License as published by
13 *  the Free Software Foundation; either version 2 of the License, or
14 *  (at your option) any later version.
15 *
16 *  This program is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *  GNU General Public License for more details.
20 *
21 *  You should have received a copy of the GNU General Public License
22 *  along with this program; if not, write to the Free Software
23 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24 */
25
26
27#include "acpi.h"
28#include "acparser.h"
29
30#define _COMPONENT          ACPI_PARSER
31	 MODULE_NAME         ("psscope")
32
33
34/*******************************************************************************
35 *
36 * FUNCTION:    Acpi_ps_get_parent_scope
37 *
38 * PARAMETERS:  Parser_state        - Current parser state object
39 *
40 * RETURN:      Pointer to an Op object
41 *
42 * DESCRIPTION: Get parent of current op being parsed
43 *
44 ******************************************************************************/
45
46acpi_parse_object *
47acpi_ps_get_parent_scope (
48	acpi_parse_state        *parser_state)
49{
50	return (parser_state->scope->parse_scope.op);
51}
52
53
54/*******************************************************************************
55 *
56 * FUNCTION:    Acpi_ps_has_completed_scope
57 *
58 * PARAMETERS:  Parser_state        - Current parser state object
59 *
60 * RETURN:      Boolean, TRUE = scope completed.
61 *
62 * DESCRIPTION: Is parsing of current argument complete?  Determined by
63 *              1) AML pointer is at or beyond the end of the scope
64 *              2) The scope argument count has reached zero.
65 *
66 ******************************************************************************/
67
68u8
69acpi_ps_has_completed_scope (
70	acpi_parse_state        *parser_state)
71{
72	return ((u8) ((parser_state->aml >= parser_state->scope->parse_scope.arg_end ||
73			   !parser_state->scope->parse_scope.arg_count)));
74}
75
76
77/*******************************************************************************
78 *
79 * FUNCTION:    Acpi_ps_init_scope
80 *
81 * PARAMETERS:  Parser_state        - Current parser state object
82 *              Root                - the Root Node of this new scope
83 *
84 * RETURN:      Status
85 *
86 * DESCRIPTION: Allocate and init a new scope object
87 *
88 ******************************************************************************/
89
90acpi_status
91acpi_ps_init_scope (
92	acpi_parse_state        *parser_state,
93	acpi_parse_object       *root_op)
94{
95	acpi_generic_state      *scope;
96
97
98	FUNCTION_TRACE_PTR ("Ps_init_scope", root_op);
99
100
101	scope = acpi_ut_create_generic_state ();
102	if (!scope) {
103		return_ACPI_STATUS (AE_NO_MEMORY);
104	}
105
106	scope->common.data_type     = ACPI_DESC_TYPE_STATE_RPSCOPE;
107	scope->parse_scope.op       = root_op;
108	scope->parse_scope.arg_count = ACPI_VAR_ARGS;
109	scope->parse_scope.arg_end  = parser_state->aml_end;
110	scope->parse_scope.pkg_end  = parser_state->aml_end;
111
112	parser_state->scope         = scope;
113	parser_state->start_op      = root_op;
114
115	return_ACPI_STATUS (AE_OK);
116}
117
118
119/*******************************************************************************
120 *
121 * FUNCTION:    Acpi_ps_push_scope
122 *
123 * PARAMETERS:  Parser_state        - Current parser state object
124 *              Op                  - Current op to be pushed
125 *              Remaining_args      - List of args remaining
126 *              Arg_count           - Fixed or variable number of args
127 *
128 * RETURN:      Status
129 *
130 * DESCRIPTION: Push current op to begin parsing its argument
131 *
132 ******************************************************************************/
133
134acpi_status
135acpi_ps_push_scope (
136	acpi_parse_state        *parser_state,
137	acpi_parse_object       *op,
138	u32                     remaining_args,
139	u32                     arg_count)
140{
141	acpi_generic_state      *scope;
142
143
144	FUNCTION_TRACE_PTR ("Ps_push_scope", op);
145
146
147	scope = acpi_ut_create_generic_state ();
148	if (!scope) {
149		return (AE_NO_MEMORY);
150	}
151
152
153	scope->common.data_type        = ACPI_DESC_TYPE_STATE_PSCOPE;
154	scope->parse_scope.op          = op;
155	scope->parse_scope.arg_list    = remaining_args;
156	scope->parse_scope.arg_count   = arg_count;
157	scope->parse_scope.pkg_end     = parser_state->pkg_end;
158
159	/* Push onto scope stack */
160
161	acpi_ut_push_generic_state (&parser_state->scope, scope);
162
163
164	if (arg_count == ACPI_VAR_ARGS) {
165		/* multiple arguments */
166
167		scope->parse_scope.arg_end = parser_state->pkg_end;
168	}
169
170	else {
171		/* single argument */
172
173		scope->parse_scope.arg_end = ACPI_MAX_AML;
174	}
175
176	return_ACPI_STATUS (AE_OK);
177}
178
179
180/*******************************************************************************
181 *
182 * FUNCTION:    Acpi_ps_pop_scope
183 *
184 * PARAMETERS:  Parser_state        - Current parser state object
185 *              Op                  - Where the popped op is returned
186 *              Arg_list            - Where the popped "next argument" is
187 *                                    returned
188 *              Arg_count           - Count of objects in Arg_list
189 *
190 * RETURN:      Status
191 *
192 * DESCRIPTION: Return to parsing a previous op
193 *
194 ******************************************************************************/
195
196void
197acpi_ps_pop_scope (
198	acpi_parse_state        *parser_state,
199	acpi_parse_object       **op,
200	u32                     *arg_list,
201	u32                     *arg_count)
202{
203	acpi_generic_state      *scope = parser_state->scope;
204
205
206	FUNCTION_TRACE ("Ps_pop_scope");
207
208
209	/*
210	 * Only pop the scope if there is in fact a next scope
211	 */
212	if (scope->common.next) {
213		scope = acpi_ut_pop_generic_state (&parser_state->scope);
214
215		/* return to parsing previous op */
216
217		*op                     = scope->parse_scope.op;
218		*arg_list               = scope->parse_scope.arg_list;
219		*arg_count              = scope->parse_scope.arg_count;
220		parser_state->pkg_end   = scope->parse_scope.pkg_end;
221
222		/* All done with this scope state structure */
223
224		acpi_ut_delete_generic_state (scope);
225	}
226
227	else {
228		/* empty parse stack, prepare to fetch next opcode */
229
230		*op                     = NULL;
231		*arg_list               = 0;
232		*arg_count              = 0;
233	}
234
235
236	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped Op %p Args %X\n", *op, *arg_count));
237	return_VOID;
238}
239
240
241/*******************************************************************************
242 *
243 * FUNCTION:    Acpi_ps_cleanup_scope
244 *
245 * PARAMETERS:  Parser_state        - Current parser state object
246 *
247 * RETURN:      Status
248 *
249 * DESCRIPTION: Destroy available list, remaining stack levels, and return
250 *              root scope
251 *
252 ******************************************************************************/
253
254void
255acpi_ps_cleanup_scope (
256	acpi_parse_state        *parser_state)
257{
258	acpi_generic_state      *scope;
259
260	FUNCTION_TRACE_PTR ("Ps_cleanup_scope", parser_state);
261
262
263	if (!parser_state) {
264		return;
265	}
266
267
268	/* Delete anything on the scope stack */
269
270	while (parser_state->scope) {
271		scope = acpi_ut_pop_generic_state (&parser_state->scope);
272		acpi_ut_delete_generic_state (scope);
273	}
274
275	return_VOID;
276}
277
278