1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
4 * Module Name: psscope - Parser scope stack management routines
6 * Copyright (C) 2000 - 2020, Intel Corp.
8 *****************************************************************************/
10 #include <acpi/acpi.h>
14 #define _COMPONENT ACPI_PARSER
15 ACPI_MODULE_NAME("psscope")
17 /*******************************************************************************
19 * FUNCTION: acpi_ps_get_parent_scope
21 * PARAMETERS: parser_state - Current parser state object
23 * RETURN: Pointer to an Op object
25 * DESCRIPTION: Get parent of current op being parsed
27 ******************************************************************************/
28 union acpi_parse_object
*acpi_ps_get_parent_scope(struct acpi_parse_state
32 return (parser_state
->scope
->parse_scope
.op
);
35 /*******************************************************************************
37 * FUNCTION: acpi_ps_has_completed_scope
39 * PARAMETERS: parser_state - Current parser state object
41 * RETURN: Boolean, TRUE = scope completed.
43 * DESCRIPTION: Is parsing of current argument complete? Determined by
44 * 1) AML pointer is at or beyond the end of the scope
45 * 2) The scope argument count has reached zero.
47 ******************************************************************************/
49 u8
acpi_ps_has_completed_scope(struct acpi_parse_state
* parser_state
)
53 ((parser_state
->aml
>= parser_state
->scope
->parse_scope
.arg_end
54 || !parser_state
->scope
->parse_scope
.arg_count
)));
57 /*******************************************************************************
59 * FUNCTION: acpi_ps_init_scope
61 * PARAMETERS: parser_state - Current parser state object
62 * root - the Root Node of this new scope
66 * DESCRIPTION: Allocate and init a new scope object
68 ******************************************************************************/
71 acpi_ps_init_scope(struct acpi_parse_state
* parser_state
,
72 union acpi_parse_object
* root_op
)
74 union acpi_generic_state
*scope
;
76 ACPI_FUNCTION_TRACE_PTR(ps_init_scope
, root_op
);
78 scope
= acpi_ut_create_generic_state();
80 return_ACPI_STATUS(AE_NO_MEMORY
);
83 scope
->common
.descriptor_type
= ACPI_DESC_TYPE_STATE_RPSCOPE
;
84 scope
->parse_scope
.op
= root_op
;
85 scope
->parse_scope
.arg_count
= ACPI_VAR_ARGS
;
86 scope
->parse_scope
.arg_end
= parser_state
->aml_end
;
87 scope
->parse_scope
.pkg_end
= parser_state
->aml_end
;
89 parser_state
->scope
= scope
;
90 parser_state
->start_op
= root_op
;
92 return_ACPI_STATUS(AE_OK
);
95 /*******************************************************************************
97 * FUNCTION: acpi_ps_push_scope
99 * PARAMETERS: parser_state - Current parser state object
100 * op - Current op to be pushed
101 * remaining_args - List of args remaining
102 * arg_count - Fixed or variable number of args
106 * DESCRIPTION: Push current op to begin parsing its argument
108 ******************************************************************************/
111 acpi_ps_push_scope(struct acpi_parse_state
*parser_state
,
112 union acpi_parse_object
*op
,
113 u32 remaining_args
, u32 arg_count
)
115 union acpi_generic_state
*scope
;
117 ACPI_FUNCTION_TRACE_PTR(ps_push_scope
, op
);
119 scope
= acpi_ut_create_generic_state();
121 return_ACPI_STATUS(AE_NO_MEMORY
);
124 scope
->common
.descriptor_type
= ACPI_DESC_TYPE_STATE_PSCOPE
;
125 scope
->parse_scope
.op
= op
;
126 scope
->parse_scope
.arg_list
= remaining_args
;
127 scope
->parse_scope
.arg_count
= arg_count
;
128 scope
->parse_scope
.pkg_end
= parser_state
->pkg_end
;
130 /* Push onto scope stack */
132 acpi_ut_push_generic_state(&parser_state
->scope
, scope
);
134 if (arg_count
== ACPI_VAR_ARGS
) {
136 /* Multiple arguments */
138 scope
->parse_scope
.arg_end
= parser_state
->pkg_end
;
140 /* Single argument */
142 scope
->parse_scope
.arg_end
= ACPI_TO_POINTER(ACPI_MAX_PTR
);
145 return_ACPI_STATUS(AE_OK
);
148 /*******************************************************************************
150 * FUNCTION: acpi_ps_pop_scope
152 * PARAMETERS: parser_state - Current parser state object
153 * op - Where the popped op is returned
154 * arg_list - Where the popped "next argument" is
156 * arg_count - Count of objects in arg_list
160 * DESCRIPTION: Return to parsing a previous op
162 ******************************************************************************/
165 acpi_ps_pop_scope(struct acpi_parse_state
*parser_state
,
166 union acpi_parse_object
**op
, u32
* arg_list
, u32
* arg_count
)
168 union acpi_generic_state
*scope
= parser_state
->scope
;
170 ACPI_FUNCTION_TRACE(ps_pop_scope
);
172 /* Only pop the scope if there is in fact a next scope */
174 if (scope
->common
.next
) {
175 scope
= acpi_ut_pop_generic_state(&parser_state
->scope
);
177 /* Return to parsing previous op */
179 *op
= scope
->parse_scope
.op
;
180 *arg_list
= scope
->parse_scope
.arg_list
;
181 *arg_count
= scope
->parse_scope
.arg_count
;
182 parser_state
->pkg_end
= scope
->parse_scope
.pkg_end
;
184 /* All done with this scope state structure */
186 acpi_ut_delete_generic_state(scope
);
188 /* Empty parse stack, prepare to fetch next opcode */
195 ACPI_DEBUG_PRINT((ACPI_DB_PARSE
,
196 "Popped Op %p Args %X\n", *op
, *arg_count
));
200 /*******************************************************************************
202 * FUNCTION: acpi_ps_cleanup_scope
204 * PARAMETERS: parser_state - Current parser state object
208 * DESCRIPTION: Destroy available list, remaining stack levels, and return
211 ******************************************************************************/
213 void acpi_ps_cleanup_scope(struct acpi_parse_state
*parser_state
)
215 union acpi_generic_state
*scope
;
217 ACPI_FUNCTION_TRACE_PTR(ps_cleanup_scope
, parser_state
);
223 /* Delete anything on the scope stack */
225 while (parser_state
->scope
) {
226 scope
= acpi_ut_pop_generic_state(&parser_state
->scope
);
227 acpi_ut_delete_generic_state(scope
);