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