1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /******************************************************************************* 3 * 4 * Module Name: utmisc - common utility procedures 5 * 6 ******************************************************************************/ 7 8 #include <acpi/acpi.h> 9 #include "accommon.h" 10 #include "acnamesp.h" 11 12 #define _COMPONENT ACPI_UTILITIES 13 ACPI_MODULE_NAME("utmisc") 14 15 /******************************************************************************* 16 * 17 * FUNCTION: acpi_ut_is_pci_root_bridge 18 * 19 * PARAMETERS: id - The HID/CID in string format 20 * 21 * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge 22 * 23 * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. 24 * 25 ******************************************************************************/ 26 u8 acpi_ut_is_pci_root_bridge(char *id) 27 { 28 29 /* 30 * Check if this is a PCI root bridge. 31 * ACPI 3.0+: check for a PCI Express root also. 32 */ 33 if (!(strcmp(id, 34 PCI_ROOT_HID_STRING)) || 35 !(strcmp(id, PCI_EXPRESS_ROOT_HID_STRING))) { 36 return (TRUE); 37 } 38 39 return (FALSE); 40 } 41 42 #if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP || defined ACPI_NAMES_APP) 43 /******************************************************************************* 44 * 45 * FUNCTION: acpi_ut_is_aml_table 46 * 47 * PARAMETERS: table - An ACPI table 48 * 49 * RETURN: TRUE if table contains executable AML; FALSE otherwise 50 * 51 * DESCRIPTION: Check ACPI Signature for a table that contains AML code. 52 * Currently, these are DSDT,SSDT,PSDT. All other table types are 53 * data tables that do not contain AML code. 54 * 55 ******************************************************************************/ 56 57 u8 acpi_ut_is_aml_table(struct acpi_table_header *table) 58 { 59 60 /* These are the only tables that contain executable AML */ 61 62 if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_DSDT) || 63 ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_PSDT) || 64 ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_SSDT) || 65 ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_OSDT) || 66 ACPI_IS_OEM_SIG(table->signature)) { 67 return (TRUE); 68 } 69 70 return (FALSE); 71 } 72 #endif 73 74 /******************************************************************************* 75 * 76 * FUNCTION: acpi_ut_dword_byte_swap 77 * 78 * PARAMETERS: value - Value to be converted 79 * 80 * RETURN: u32 integer with bytes swapped 81 * 82 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) 83 * 84 ******************************************************************************/ 85 86 u32 acpi_ut_dword_byte_swap(u32 value) 87 { 88 union { 89 u32 value; 90 u8 bytes[4]; 91 } out; 92 union { 93 u32 value; 94 u8 bytes[4]; 95 } in; 96 97 ACPI_FUNCTION_ENTRY(); 98 99 in.value = value; 100 101 out.bytes[0] = in.bytes[3]; 102 out.bytes[1] = in.bytes[2]; 103 out.bytes[2] = in.bytes[1]; 104 out.bytes[3] = in.bytes[0]; 105 106 return (out.value); 107 } 108 109 /******************************************************************************* 110 * 111 * FUNCTION: acpi_ut_set_integer_width 112 * 113 * PARAMETERS: Revision From DSDT header 114 * 115 * RETURN: None 116 * 117 * DESCRIPTION: Set the global integer bit width based upon the revision 118 * of the DSDT. For Revision 1 and 0, Integers are 32 bits. 119 * For Revision 2 and above, Integers are 64 bits. Yes, this 120 * makes a difference. 121 * 122 ******************************************************************************/ 123 124 void acpi_ut_set_integer_width(u8 revision) 125 { 126 127 if (revision < 2) { 128 129 /* 32-bit case */ 130 131 acpi_gbl_integer_bit_width = 32; 132 acpi_gbl_integer_nybble_width = 8; 133 acpi_gbl_integer_byte_width = 4; 134 } else { 135 /* 64-bit case (ACPI 2.0+) */ 136 137 acpi_gbl_integer_bit_width = 64; 138 acpi_gbl_integer_nybble_width = 16; 139 acpi_gbl_integer_byte_width = 8; 140 } 141 } 142 143 /******************************************************************************* 144 * 145 * FUNCTION: acpi_ut_create_update_state_and_push 146 * 147 * PARAMETERS: object - Object to be added to the new state 148 * action - Increment/Decrement 149 * state_list - List the state will be added to 150 * 151 * RETURN: Status 152 * 153 * DESCRIPTION: Create a new state and push it 154 * 155 ******************************************************************************/ 156 157 acpi_status 158 acpi_ut_create_update_state_and_push(union acpi_operand_object *object, 159 u16 action, 160 union acpi_generic_state **state_list) 161 { 162 union acpi_generic_state *state; 163 164 ACPI_FUNCTION_ENTRY(); 165 166 /* Ignore null objects; these are expected */ 167 168 if (!object) { 169 return (AE_OK); 170 } 171 172 state = acpi_ut_create_update_state(object, action); 173 if (!state) { 174 return (AE_NO_MEMORY); 175 } 176 177 acpi_ut_push_generic_state(state_list, state); 178 return (AE_OK); 179 } 180 181 /******************************************************************************* 182 * 183 * FUNCTION: acpi_ut_walk_package_tree 184 * 185 * PARAMETERS: source_object - The package to walk 186 * target_object - Target object (if package is being copied) 187 * walk_callback - Called once for each package element 188 * context - Passed to the callback function 189 * 190 * RETURN: Status 191 * 192 * DESCRIPTION: Walk through a package, including subpackages 193 * 194 ******************************************************************************/ 195 196 acpi_status 197 acpi_ut_walk_package_tree(union acpi_operand_object *source_object, 198 void *target_object, 199 acpi_pkg_callback walk_callback, void *context) 200 { 201 acpi_status status = AE_OK; 202 union acpi_generic_state *state_list = NULL; 203 union acpi_generic_state *state; 204 union acpi_operand_object *this_source_obj; 205 u32 this_index; 206 207 ACPI_FUNCTION_TRACE(ut_walk_package_tree); 208 209 state = acpi_ut_create_pkg_state(source_object, target_object, 0); 210 if (!state) { 211 return_ACPI_STATUS(AE_NO_MEMORY); 212 } 213 214 while (state) { 215 216 /* Get one element of the package */ 217 218 this_index = state->pkg.index; 219 this_source_obj = 220 state->pkg.source_object->package.elements[this_index]; 221 state->pkg.this_target_obj = 222 &state->pkg.source_object->package.elements[this_index]; 223 224 /* 225 * Check for: 226 * 1) An uninitialized package element. It is completely 227 * legal to declare a package and leave it uninitialized 228 * 2) Not an internal object - can be a namespace node instead 229 * 3) Any type other than a package. Packages are handled in else 230 * case below. 231 */ 232 if ((!this_source_obj) || 233 (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) != 234 ACPI_DESC_TYPE_OPERAND) || 235 (this_source_obj->common.type != ACPI_TYPE_PACKAGE)) { 236 status = 237 walk_callback(ACPI_COPY_TYPE_SIMPLE, 238 this_source_obj, state, context); 239 if (ACPI_FAILURE(status)) { 240 return_ACPI_STATUS(status); 241 } 242 243 state->pkg.index++; 244 while (state->pkg.index >= 245 state->pkg.source_object->package.count) { 246 /* 247 * We've handled all of the objects at this level, This means 248 * that we have just completed a package. That package may 249 * have contained one or more packages itself. 250 * 251 * Delete this state and pop the previous state (package). 252 */ 253 acpi_ut_delete_generic_state(state); 254 state = acpi_ut_pop_generic_state(&state_list); 255 256 /* Finished when there are no more states */ 257 258 if (!state) { 259 /* 260 * We have handled all of the objects in the top level 261 * package just add the length of the package objects 262 * and exit 263 */ 264 return_ACPI_STATUS(AE_OK); 265 } 266 267 /* 268 * Go back up a level and move the index past the just 269 * completed package object. 270 */ 271 state->pkg.index++; 272 } 273 } else { 274 /* This is a subobject of type package */ 275 276 status = 277 walk_callback(ACPI_COPY_TYPE_PACKAGE, 278 this_source_obj, state, context); 279 if (ACPI_FAILURE(status)) { 280 return_ACPI_STATUS(status); 281 } 282 283 /* 284 * Push the current state and create a new one 285 * The callback above returned a new target package object. 286 */ 287 acpi_ut_push_generic_state(&state_list, state); 288 state = 289 acpi_ut_create_pkg_state(this_source_obj, 290 state->pkg.this_target_obj, 291 0); 292 if (!state) { 293 294 /* Free any stacked Update State objects */ 295 296 while (state_list) { 297 state = 298 acpi_ut_pop_generic_state 299 (&state_list); 300 acpi_ut_delete_generic_state(state); 301 } 302 return_ACPI_STATUS(AE_NO_MEMORY); 303 } 304 } 305 } 306 307 /* We should never get here */ 308 309 ACPI_ERROR((AE_INFO, "State list did not terminate correctly")); 310 311 return_ACPI_STATUS(AE_AML_INTERNAL); 312 } 313 314 #ifdef ACPI_DEBUG_OUTPUT 315 /******************************************************************************* 316 * 317 * FUNCTION: acpi_ut_display_init_pathname 318 * 319 * PARAMETERS: type - Object type of the node 320 * obj_handle - Handle whose pathname will be displayed 321 * path - Additional path string to be appended. 322 * (NULL if no extra path) 323 * 324 * RETURN: acpi_status 325 * 326 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY 327 * 328 ******************************************************************************/ 329 330 void 331 acpi_ut_display_init_pathname(u8 type, 332 struct acpi_namespace_node *obj_handle, 333 const char *path) 334 { 335 acpi_status status; 336 struct acpi_buffer buffer; 337 338 ACPI_FUNCTION_ENTRY(); 339 340 /* Only print the path if the appropriate debug level is enabled */ 341 342 if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) { 343 return; 344 } 345 346 /* Get the full pathname to the node */ 347 348 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; 349 status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE); 350 if (ACPI_FAILURE(status)) { 351 return; 352 } 353 354 /* Print what we're doing */ 355 356 switch (type) { 357 case ACPI_TYPE_METHOD: 358 359 acpi_os_printf("Executing "); 360 break; 361 362 default: 363 364 acpi_os_printf("Initializing "); 365 break; 366 } 367 368 /* Print the object type and pathname */ 369 370 acpi_os_printf("%-12s %s", 371 acpi_ut_get_type_name(type), (char *)buffer.pointer); 372 373 /* Extra path is used to append names like _STA, _INI, etc. */ 374 375 if (path) { 376 acpi_os_printf(".%s", path); 377 } 378 acpi_os_printf("\n"); 379 380 ACPI_FREE(buffer.pointer); 381 } 382 #endif 383