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 ***************************************************************************/ 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 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 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