Merge tag 'for-5.1-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[linux-2.6-microblaze.git] / drivers / acpi / acpica / psscope.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: psscope - Parser scope stack management routines
5  *
6  * Copyright (C) 2000 - 2019, Intel Corp.
7  *
8  *****************************************************************************/
9
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12 #include "acparser.h"
13
14 #define _COMPONENT          ACPI_PARSER
15 ACPI_MODULE_NAME("psscope")
16
17 /*******************************************************************************
18  *
19  * FUNCTION:    acpi_ps_get_parent_scope
20  *
21  * PARAMETERS:  parser_state        - Current parser state object
22  *
23  * RETURN:      Pointer to an Op object
24  *
25  * DESCRIPTION: Get parent of current op being parsed
26  *
27  ******************************************************************************/
28 union acpi_parse_object *acpi_ps_get_parent_scope(struct acpi_parse_state
29                                                   *parser_state)
30 {
31
32         return (parser_state->scope->parse_scope.op);
33 }
34
35 /*******************************************************************************
36  *
37  * FUNCTION:    acpi_ps_has_completed_scope
38  *
39  * PARAMETERS:  parser_state        - Current parser state object
40  *
41  * RETURN:      Boolean, TRUE = scope completed.
42  *
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.
46  *
47  ******************************************************************************/
48
49 u8 acpi_ps_has_completed_scope(struct acpi_parse_state * parser_state)
50 {
51
52         return ((u8)
53                 ((parser_state->aml >= parser_state->scope->parse_scope.arg_end
54                   || !parser_state->scope->parse_scope.arg_count)));
55 }
56
57 /*******************************************************************************
58  *
59  * FUNCTION:    acpi_ps_init_scope
60  *
61  * PARAMETERS:  parser_state        - Current parser state object
62  *              root                - the Root Node of this new scope
63  *
64  * RETURN:      Status
65  *
66  * DESCRIPTION: Allocate and init a new scope object
67  *
68  ******************************************************************************/
69
70 acpi_status
71 acpi_ps_init_scope(struct acpi_parse_state * parser_state,
72                    union acpi_parse_object * root_op)
73 {
74         union acpi_generic_state *scope;
75
76         ACPI_FUNCTION_TRACE_PTR(ps_init_scope, root_op);
77
78         scope = acpi_ut_create_generic_state();
79         if (!scope) {
80                 return_ACPI_STATUS(AE_NO_MEMORY);
81         }
82
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;
88
89         parser_state->scope = scope;
90         parser_state->start_op = root_op;
91
92         return_ACPI_STATUS(AE_OK);
93 }
94
95 /*******************************************************************************
96  *
97  * FUNCTION:    acpi_ps_push_scope
98  *
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
103  *
104  * RETURN:      Status
105  *
106  * DESCRIPTION: Push current op to begin parsing its argument
107  *
108  ******************************************************************************/
109
110 acpi_status
111 acpi_ps_push_scope(struct acpi_parse_state *parser_state,
112                    union acpi_parse_object *op,
113                    u32 remaining_args, u32 arg_count)
114 {
115         union acpi_generic_state *scope;
116
117         ACPI_FUNCTION_TRACE_PTR(ps_push_scope, op);
118
119         scope = acpi_ut_create_generic_state();
120         if (!scope) {
121                 return_ACPI_STATUS(AE_NO_MEMORY);
122         }
123
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;
129
130         /* Push onto scope stack */
131
132         acpi_ut_push_generic_state(&parser_state->scope, scope);
133
134         if (arg_count == ACPI_VAR_ARGS) {
135
136                 /* Multiple arguments */
137
138                 scope->parse_scope.arg_end = parser_state->pkg_end;
139         } else {
140                 /* Single argument */
141
142                 scope->parse_scope.arg_end = ACPI_TO_POINTER(ACPI_MAX_PTR);
143         }
144
145         return_ACPI_STATUS(AE_OK);
146 }
147
148 /*******************************************************************************
149  *
150  * FUNCTION:    acpi_ps_pop_scope
151  *
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
155  *                                    returned
156  *              arg_count           - Count of objects in arg_list
157  *
158  * RETURN:      Status
159  *
160  * DESCRIPTION: Return to parsing a previous op
161  *
162  ******************************************************************************/
163
164 void
165 acpi_ps_pop_scope(struct acpi_parse_state *parser_state,
166                   union acpi_parse_object **op, u32 * arg_list, u32 * arg_count)
167 {
168         union acpi_generic_state *scope = parser_state->scope;
169
170         ACPI_FUNCTION_TRACE(ps_pop_scope);
171
172         /* Only pop the scope if there is in fact a next scope */
173
174         if (scope->common.next) {
175                 scope = acpi_ut_pop_generic_state(&parser_state->scope);
176
177                 /* Return to parsing previous op */
178
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;
183
184                 /* All done with this scope state structure */
185
186                 acpi_ut_delete_generic_state(scope);
187         } else {
188                 /* Empty parse stack, prepare to fetch next opcode */
189
190                 *op = NULL;
191                 *arg_list = 0;
192                 *arg_count = 0;
193         }
194
195         ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
196                           "Popped Op %p Args %X\n", *op, *arg_count));
197         return_VOID;
198 }
199
200 /*******************************************************************************
201  *
202  * FUNCTION:    acpi_ps_cleanup_scope
203  *
204  * PARAMETERS:  parser_state        - Current parser state object
205  *
206  * RETURN:      None
207  *
208  * DESCRIPTION: Destroy available list, remaining stack levels, and return
209  *              root scope
210  *
211  ******************************************************************************/
212
213 void acpi_ps_cleanup_scope(struct acpi_parse_state *parser_state)
214 {
215         union acpi_generic_state *scope;
216
217         ACPI_FUNCTION_TRACE_PTR(ps_cleanup_scope, parser_state);
218
219         if (!parser_state) {
220                 return_VOID;
221         }
222
223         /* Delete anything on the scope stack */
224
225         while (parser_state->scope) {
226                 scope = acpi_ut_pop_generic_state(&parser_state->scope);
227                 acpi_ut_delete_generic_state(scope);
228         }
229
230         return_VOID;
231 }