1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3 *
4 * Module Name: dswscope - Scope stack manipulation
5 *
6 * Copyright (C) 2000 - 2023, Intel Corp.
7 *
8 *****************************************************************************/
9
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12 #include "acdispat.h"
13
14 #define _COMPONENT ACPI_DISPATCHER
15 ACPI_MODULE_NAME("dswscope")
16
17 /****************************************************************************
18 *
19 * FUNCTION: acpi_ds_scope_stack_clear
20 *
21 * PARAMETERS: walk_state - Current state
22 *
23 * RETURN: None
24 *
25 * DESCRIPTION: Pop (and free) everything on the scope stack except the
26 * root scope object (which remains at the stack top.)
27 *
28 ***************************************************************************/
acpi_ds_scope_stack_clear(struct acpi_walk_state * walk_state)29 void acpi_ds_scope_stack_clear(struct acpi_walk_state *walk_state)
30 {
31 union acpi_generic_state *scope_info;
32
33 ACPI_FUNCTION_NAME(ds_scope_stack_clear);
34
35 while (walk_state->scope_info) {
36
37 /* Pop a scope off the stack */
38
39 scope_info = walk_state->scope_info;
40 walk_state->scope_info = scope_info->scope.next;
41
42 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
43 "Popped object type (%s)\n",
44 acpi_ut_get_type_name(scope_info->common.
45 value)));
46
47 acpi_ut_delete_generic_state(scope_info);
48 }
49 }
50
51 /****************************************************************************
52 *
53 * FUNCTION: acpi_ds_scope_stack_push
54 *
55 * PARAMETERS: node - Name to be made current
56 * type - Type of frame being pushed
57 * walk_state - Current state
58 *
59 * RETURN: Status
60 *
61 * DESCRIPTION: Push the current scope on the scope stack, and make the
62 * passed Node current.
63 *
64 ***************************************************************************/
65
66 acpi_status
acpi_ds_scope_stack_push(struct acpi_namespace_node * node,acpi_object_type type,struct acpi_walk_state * walk_state)67 acpi_ds_scope_stack_push(struct acpi_namespace_node *node,
68 acpi_object_type type,
69 struct acpi_walk_state *walk_state)
70 {
71 union acpi_generic_state *scope_info;
72 union acpi_generic_state *old_scope_info;
73
74 ACPI_FUNCTION_TRACE(ds_scope_stack_push);
75
76 if (!node) {
77
78 /* Invalid scope */
79
80 ACPI_ERROR((AE_INFO, "Null scope parameter"));
81 return_ACPI_STATUS(AE_BAD_PARAMETER);
82 }
83
84 /* Make sure object type is valid */
85
86 if (!acpi_ut_valid_object_type(type)) {
87 ACPI_WARNING((AE_INFO, "Invalid object type: 0x%X", type));
88 }
89
90 /* Allocate a new scope object */
91
92 scope_info = acpi_ut_create_generic_state();
93 if (!scope_info) {
94 return_ACPI_STATUS(AE_NO_MEMORY);
95 }
96
97 /* Init new scope object */
98
99 scope_info->common.descriptor_type = ACPI_DESC_TYPE_STATE_WSCOPE;
100 scope_info->scope.node = node;
101 scope_info->common.value = (u16) type;
102
103 walk_state->scope_depth++;
104
105 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
106 "[%.2d] Pushed scope ",
107 (u32) walk_state->scope_depth));
108
109 old_scope_info = walk_state->scope_info;
110 if (old_scope_info) {
111 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC,
112 "[%4.4s] (%s)",
113 acpi_ut_get_node_name(old_scope_info->
114 scope.node),
115 acpi_ut_get_type_name(old_scope_info->
116 common.value)));
117 } else {
118 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, ACPI_NAMESPACE_ROOT));
119 }
120
121 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC,
122 ", New scope -> [%4.4s] (%s)\n",
123 acpi_ut_get_node_name(scope_info->scope.node),
124 acpi_ut_get_type_name(scope_info->common.value)));
125
126 /* Push new scope object onto stack */
127
128 acpi_ut_push_generic_state(&walk_state->scope_info, scope_info);
129 return_ACPI_STATUS(AE_OK);
130 }
131
132 /****************************************************************************
133 *
134 * FUNCTION: acpi_ds_scope_stack_pop
135 *
136 * PARAMETERS: walk_state - Current state
137 *
138 * RETURN: Status
139 *
140 * DESCRIPTION: Pop the scope stack once.
141 *
142 ***************************************************************************/
143
acpi_ds_scope_stack_pop(struct acpi_walk_state * walk_state)144 acpi_status acpi_ds_scope_stack_pop(struct acpi_walk_state *walk_state)
145 {
146 union acpi_generic_state *scope_info;
147 union acpi_generic_state *new_scope_info;
148
149 ACPI_FUNCTION_TRACE(ds_scope_stack_pop);
150
151 /*
152 * Pop scope info object off the stack.
153 */
154 scope_info = acpi_ut_pop_generic_state(&walk_state->scope_info);
155 if (!scope_info) {
156 return_ACPI_STATUS(AE_STACK_UNDERFLOW);
157 }
158
159 walk_state->scope_depth--;
160
161 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
162 "[%.2d] Popped scope [%4.4s] (%s), New scope -> ",
163 (u32) walk_state->scope_depth,
164 acpi_ut_get_node_name(scope_info->scope.node),
165 acpi_ut_get_type_name(scope_info->common.value)));
166
167 new_scope_info = walk_state->scope_info;
168 if (new_scope_info) {
169 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "[%4.4s] (%s)\n",
170 acpi_ut_get_node_name(new_scope_info->
171 scope.node),
172 acpi_ut_get_type_name(new_scope_info->
173 common.value)));
174 } else {
175 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "%s\n",
176 ACPI_NAMESPACE_ROOT));
177 }
178
179 acpi_ut_delete_generic_state(scope_info);
180 return_ACPI_STATUS(AE_OK);
181 }
182