195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
295b482a8SLen Brown /******************************************************************************
395b482a8SLen Brown *
495b482a8SLen Brown * Module Name: psscope - Parser scope stack management routines
595b482a8SLen Brown *
6*612c2932SBob Moore * Copyright (C) 2000 - 2023, Intel Corp.
795b482a8SLen Brown *
895857638SErik Schmauss *****************************************************************************/
995b482a8SLen Brown
1095b482a8SLen Brown #include <acpi/acpi.h>
11e2f7a777SLen Brown #include "accommon.h"
12e2f7a777SLen Brown #include "acparser.h"
1395b482a8SLen Brown
1495b482a8SLen Brown #define _COMPONENT ACPI_PARSER
1595b482a8SLen Brown ACPI_MODULE_NAME("psscope")
1695b482a8SLen Brown
1795b482a8SLen Brown /*******************************************************************************
1895b482a8SLen Brown *
1995b482a8SLen Brown * FUNCTION: acpi_ps_get_parent_scope
2095b482a8SLen Brown *
2195b482a8SLen Brown * PARAMETERS: parser_state - Current parser state object
2295b482a8SLen Brown *
2395b482a8SLen Brown * RETURN: Pointer to an Op object
2495b482a8SLen Brown *
2595b482a8SLen Brown * DESCRIPTION: Get parent of current op being parsed
2695b482a8SLen Brown *
2795b482a8SLen Brown ******************************************************************************/
acpi_ps_get_parent_scope(struct acpi_parse_state * parser_state)2895b482a8SLen Brown union acpi_parse_object *acpi_ps_get_parent_scope(struct acpi_parse_state
2995b482a8SLen Brown *parser_state)
3095b482a8SLen Brown {
3195b482a8SLen Brown
3295b482a8SLen Brown return (parser_state->scope->parse_scope.op);
3395b482a8SLen Brown }
3495b482a8SLen Brown
3595b482a8SLen Brown /*******************************************************************************
3695b482a8SLen Brown *
3795b482a8SLen Brown * FUNCTION: acpi_ps_has_completed_scope
3895b482a8SLen Brown *
3995b482a8SLen Brown * PARAMETERS: parser_state - Current parser state object
4095b482a8SLen Brown *
4195b482a8SLen Brown * RETURN: Boolean, TRUE = scope completed.
4295b482a8SLen Brown *
4395b482a8SLen Brown * DESCRIPTION: Is parsing of current argument complete? Determined by
4495b482a8SLen Brown * 1) AML pointer is at or beyond the end of the scope
4595b482a8SLen Brown * 2) The scope argument count has reached zero.
4695b482a8SLen Brown *
4795b482a8SLen Brown ******************************************************************************/
4895b482a8SLen Brown
acpi_ps_has_completed_scope(struct acpi_parse_state * parser_state)4995b482a8SLen Brown u8 acpi_ps_has_completed_scope(struct acpi_parse_state * parser_state)
5095b482a8SLen Brown {
5195b482a8SLen Brown
5295b482a8SLen Brown return ((u8)
5395b482a8SLen Brown ((parser_state->aml >= parser_state->scope->parse_scope.arg_end
5495b482a8SLen Brown || !parser_state->scope->parse_scope.arg_count)));
5595b482a8SLen Brown }
5695b482a8SLen Brown
5795b482a8SLen Brown /*******************************************************************************
5895b482a8SLen Brown *
5995b482a8SLen Brown * FUNCTION: acpi_ps_init_scope
6095b482a8SLen Brown *
6195b482a8SLen Brown * PARAMETERS: parser_state - Current parser state object
62ba494beeSBob Moore * root - the Root Node of this new scope
6395b482a8SLen Brown *
6495b482a8SLen Brown * RETURN: Status
6595b482a8SLen Brown *
6695b482a8SLen Brown * DESCRIPTION: Allocate and init a new scope object
6795b482a8SLen Brown *
6895b482a8SLen Brown ******************************************************************************/
6995b482a8SLen Brown
7095b482a8SLen Brown acpi_status
acpi_ps_init_scope(struct acpi_parse_state * parser_state,union acpi_parse_object * root_op)7195b482a8SLen Brown acpi_ps_init_scope(struct acpi_parse_state * parser_state,
7295b482a8SLen Brown union acpi_parse_object * root_op)
7395b482a8SLen Brown {
7495b482a8SLen Brown union acpi_generic_state *scope;
7595b482a8SLen Brown
7695b482a8SLen Brown ACPI_FUNCTION_TRACE_PTR(ps_init_scope, root_op);
7795b482a8SLen Brown
7895b482a8SLen Brown scope = acpi_ut_create_generic_state();
7995b482a8SLen Brown if (!scope) {
8095b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY);
8195b482a8SLen Brown }
8295b482a8SLen Brown
8395b482a8SLen Brown scope->common.descriptor_type = ACPI_DESC_TYPE_STATE_RPSCOPE;
8495b482a8SLen Brown scope->parse_scope.op = root_op;
8595b482a8SLen Brown scope->parse_scope.arg_count = ACPI_VAR_ARGS;
8695b482a8SLen Brown scope->parse_scope.arg_end = parser_state->aml_end;
8795b482a8SLen Brown scope->parse_scope.pkg_end = parser_state->aml_end;
8895b482a8SLen Brown
8995b482a8SLen Brown parser_state->scope = scope;
9095b482a8SLen Brown parser_state->start_op = root_op;
9195b482a8SLen Brown
9295b482a8SLen Brown return_ACPI_STATUS(AE_OK);
9395b482a8SLen Brown }
9495b482a8SLen Brown
9595b482a8SLen Brown /*******************************************************************************
9695b482a8SLen Brown *
9795b482a8SLen Brown * FUNCTION: acpi_ps_push_scope
9895b482a8SLen Brown *
9995b482a8SLen Brown * PARAMETERS: parser_state - Current parser state object
100ba494beeSBob Moore * op - Current op to be pushed
10195b482a8SLen Brown * remaining_args - List of args remaining
10295b482a8SLen Brown * arg_count - Fixed or variable number of args
10395b482a8SLen Brown *
10495b482a8SLen Brown * RETURN: Status
10595b482a8SLen Brown *
10695b482a8SLen Brown * DESCRIPTION: Push current op to begin parsing its argument
10795b482a8SLen Brown *
10895b482a8SLen Brown ******************************************************************************/
10995b482a8SLen Brown
11095b482a8SLen Brown acpi_status
acpi_ps_push_scope(struct acpi_parse_state * parser_state,union acpi_parse_object * op,u32 remaining_args,u32 arg_count)11195b482a8SLen Brown acpi_ps_push_scope(struct acpi_parse_state *parser_state,
11295b482a8SLen Brown union acpi_parse_object *op,
11395b482a8SLen Brown u32 remaining_args, u32 arg_count)
11495b482a8SLen Brown {
11595b482a8SLen Brown union acpi_generic_state *scope;
11695b482a8SLen Brown
11795b482a8SLen Brown ACPI_FUNCTION_TRACE_PTR(ps_push_scope, op);
11895b482a8SLen Brown
11995b482a8SLen Brown scope = acpi_ut_create_generic_state();
12095b482a8SLen Brown if (!scope) {
12195b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY);
12295b482a8SLen Brown }
12395b482a8SLen Brown
12495b482a8SLen Brown scope->common.descriptor_type = ACPI_DESC_TYPE_STATE_PSCOPE;
12595b482a8SLen Brown scope->parse_scope.op = op;
12695b482a8SLen Brown scope->parse_scope.arg_list = remaining_args;
12795b482a8SLen Brown scope->parse_scope.arg_count = arg_count;
12895b482a8SLen Brown scope->parse_scope.pkg_end = parser_state->pkg_end;
12995b482a8SLen Brown
13095b482a8SLen Brown /* Push onto scope stack */
13195b482a8SLen Brown
13295b482a8SLen Brown acpi_ut_push_generic_state(&parser_state->scope, scope);
13395b482a8SLen Brown
13495b482a8SLen Brown if (arg_count == ACPI_VAR_ARGS) {
13595b482a8SLen Brown
13695b482a8SLen Brown /* Multiple arguments */
13795b482a8SLen Brown
13895b482a8SLen Brown scope->parse_scope.arg_end = parser_state->pkg_end;
13995b482a8SLen Brown } else {
14095b482a8SLen Brown /* Single argument */
14195b482a8SLen Brown
14295b482a8SLen Brown scope->parse_scope.arg_end = ACPI_TO_POINTER(ACPI_MAX_PTR);
14395b482a8SLen Brown }
14495b482a8SLen Brown
14595b482a8SLen Brown return_ACPI_STATUS(AE_OK);
14695b482a8SLen Brown }
14795b482a8SLen Brown
14895b482a8SLen Brown /*******************************************************************************
14995b482a8SLen Brown *
15095b482a8SLen Brown * FUNCTION: acpi_ps_pop_scope
15195b482a8SLen Brown *
15295b482a8SLen Brown * PARAMETERS: parser_state - Current parser state object
153ba494beeSBob Moore * op - Where the popped op is returned
15495b482a8SLen Brown * arg_list - Where the popped "next argument" is
15595b482a8SLen Brown * returned
15695b482a8SLen Brown * arg_count - Count of objects in arg_list
15795b482a8SLen Brown *
15895b482a8SLen Brown * RETURN: Status
15995b482a8SLen Brown *
16095b482a8SLen Brown * DESCRIPTION: Return to parsing a previous op
16195b482a8SLen Brown *
16295b482a8SLen Brown ******************************************************************************/
16395b482a8SLen Brown
16495b482a8SLen Brown void
acpi_ps_pop_scope(struct acpi_parse_state * parser_state,union acpi_parse_object ** op,u32 * arg_list,u32 * arg_count)16595b482a8SLen Brown acpi_ps_pop_scope(struct acpi_parse_state *parser_state,
16695b482a8SLen Brown union acpi_parse_object **op, u32 * arg_list, u32 * arg_count)
16795b482a8SLen Brown {
16895b482a8SLen Brown union acpi_generic_state *scope = parser_state->scope;
16995b482a8SLen Brown
17095b482a8SLen Brown ACPI_FUNCTION_TRACE(ps_pop_scope);
17195b482a8SLen Brown
17295b482a8SLen Brown /* Only pop the scope if there is in fact a next scope */
17395b482a8SLen Brown
17495b482a8SLen Brown if (scope->common.next) {
17595b482a8SLen Brown scope = acpi_ut_pop_generic_state(&parser_state->scope);
17695b482a8SLen Brown
17795b482a8SLen Brown /* Return to parsing previous op */
17895b482a8SLen Brown
17995b482a8SLen Brown *op = scope->parse_scope.op;
18095b482a8SLen Brown *arg_list = scope->parse_scope.arg_list;
18195b482a8SLen Brown *arg_count = scope->parse_scope.arg_count;
18295b482a8SLen Brown parser_state->pkg_end = scope->parse_scope.pkg_end;
18395b482a8SLen Brown
18495b482a8SLen Brown /* All done with this scope state structure */
18595b482a8SLen Brown
18695b482a8SLen Brown acpi_ut_delete_generic_state(scope);
18795b482a8SLen Brown } else {
18895b482a8SLen Brown /* Empty parse stack, prepare to fetch next opcode */
18995b482a8SLen Brown
19095b482a8SLen Brown *op = NULL;
19195b482a8SLen Brown *arg_list = 0;
19295b482a8SLen Brown *arg_count = 0;
19395b482a8SLen Brown }
19495b482a8SLen Brown
19595b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
19695b482a8SLen Brown "Popped Op %p Args %X\n", *op, *arg_count));
19795b482a8SLen Brown return_VOID;
19895b482a8SLen Brown }
19995b482a8SLen Brown
20095b482a8SLen Brown /*******************************************************************************
20195b482a8SLen Brown *
20295b482a8SLen Brown * FUNCTION: acpi_ps_cleanup_scope
20395b482a8SLen Brown *
20495b482a8SLen Brown * PARAMETERS: parser_state - Current parser state object
20595b482a8SLen Brown *
20695b482a8SLen Brown * RETURN: None
20795b482a8SLen Brown *
20895b482a8SLen Brown * DESCRIPTION: Destroy available list, remaining stack levels, and return
20995b482a8SLen Brown * root scope
21095b482a8SLen Brown *
21195b482a8SLen Brown ******************************************************************************/
21295b482a8SLen Brown
acpi_ps_cleanup_scope(struct acpi_parse_state * parser_state)21395b482a8SLen Brown void acpi_ps_cleanup_scope(struct acpi_parse_state *parser_state)
21495b482a8SLen Brown {
21595b482a8SLen Brown union acpi_generic_state *scope;
21695b482a8SLen Brown
21795b482a8SLen Brown ACPI_FUNCTION_TRACE_PTR(ps_cleanup_scope, parser_state);
21895b482a8SLen Brown
21995b482a8SLen Brown if (!parser_state) {
22095b482a8SLen Brown return_VOID;
22195b482a8SLen Brown }
22295b482a8SLen Brown
22395b482a8SLen Brown /* Delete anything on the scope stack */
22495b482a8SLen Brown
22595b482a8SLen Brown while (parser_state->scope) {
22695b482a8SLen Brown scope = acpi_ut_pop_generic_state(&parser_state->scope);
22795b482a8SLen Brown acpi_ut_delete_generic_state(scope);
22895b482a8SLen Brown }
22995b482a8SLen Brown
23095b482a8SLen Brown return_VOID;
23195b482a8SLen Brown }
232