1 /******************************************************************************* 2 * 3 * Module Name: utmisc - common utility procedures 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2022, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "acpi.h" 45 #include "accommon.h" 46 #include "acnamesp.h" 47 48 49 #define _COMPONENT ACPI_UTILITIES 50 ACPI_MODULE_NAME ("utmisc") 51 52 53 /******************************************************************************* 54 * 55 * FUNCTION: AcpiUtIsPciRootBridge 56 * 57 * PARAMETERS: Id - The HID/CID in string format 58 * 59 * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge 60 * 61 * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. 62 * 63 ******************************************************************************/ 64 65 BOOLEAN 66 AcpiUtIsPciRootBridge ( 67 char *Id) 68 { 69 70 /* 71 * Check if this is a PCI root bridge. 72 * ACPI 3.0+: check for a PCI Express root also. 73 */ 74 if (!(strcmp (Id, 75 PCI_ROOT_HID_STRING)) || 76 77 !(strcmp (Id, 78 PCI_EXPRESS_ROOT_HID_STRING))) 79 { 80 return (TRUE); 81 } 82 83 return (FALSE); 84 } 85 86 87 #if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP || defined ACPI_NAMES_APP) 88 /******************************************************************************* 89 * 90 * FUNCTION: AcpiUtIsAmlTable 91 * 92 * PARAMETERS: Table - An ACPI table 93 * 94 * RETURN: TRUE if table contains executable AML; FALSE otherwise 95 * 96 * DESCRIPTION: Check ACPI Signature for a table that contains AML code. 97 * Currently, these are DSDT,SSDT,PSDT. All other table types are 98 * data tables that do not contain AML code. 99 * 100 ******************************************************************************/ 101 102 BOOLEAN 103 AcpiUtIsAmlTable ( 104 ACPI_TABLE_HEADER *Table) 105 { 106 107 /* These are the only tables that contain executable AML */ 108 109 if (ACPI_COMPARE_NAMESEG (Table->Signature, ACPI_SIG_DSDT) || 110 ACPI_COMPARE_NAMESEG (Table->Signature, ACPI_SIG_PSDT) || 111 ACPI_COMPARE_NAMESEG (Table->Signature, ACPI_SIG_SSDT) || 112 ACPI_COMPARE_NAMESEG (Table->Signature, ACPI_SIG_OSDT) || 113 ACPI_IS_OEM_SIG (Table->Signature)) 114 { 115 return (TRUE); 116 } 117 118 return (FALSE); 119 } 120 #endif 121 122 123 /******************************************************************************* 124 * 125 * FUNCTION: AcpiUtDwordByteSwap 126 * 127 * PARAMETERS: Value - Value to be converted 128 * 129 * RETURN: UINT32 integer with bytes swapped 130 * 131 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) 132 * 133 ******************************************************************************/ 134 135 UINT32 136 AcpiUtDwordByteSwap ( 137 UINT32 Value) 138 { 139 union 140 { 141 UINT32 Value; 142 UINT8 Bytes[4]; 143 } Out; 144 union 145 { 146 UINT32 Value; 147 UINT8 Bytes[4]; 148 } In; 149 150 151 ACPI_FUNCTION_ENTRY (); 152 153 154 In.Value = Value; 155 156 Out.Bytes[0] = In.Bytes[3]; 157 Out.Bytes[1] = In.Bytes[2]; 158 Out.Bytes[2] = In.Bytes[1]; 159 Out.Bytes[3] = In.Bytes[0]; 160 161 return (Out.Value); 162 } 163 164 165 /******************************************************************************* 166 * 167 * FUNCTION: AcpiUtSetIntegerWidth 168 * 169 * PARAMETERS: Revision From DSDT header 170 * 171 * RETURN: None 172 * 173 * DESCRIPTION: Set the global integer bit width based upon the revision 174 * of the DSDT. For Revision 1 and 0, Integers are 32 bits. 175 * For Revision 2 and above, Integers are 64 bits. Yes, this 176 * makes a difference. 177 * 178 ******************************************************************************/ 179 180 void 181 AcpiUtSetIntegerWidth ( 182 UINT8 Revision) 183 { 184 185 if (Revision < 2) 186 { 187 /* 32-bit case */ 188 189 AcpiGbl_IntegerBitWidth = 32; 190 AcpiGbl_IntegerNybbleWidth = 8; 191 AcpiGbl_IntegerByteWidth = 4; 192 } 193 else 194 { 195 /* 64-bit case (ACPI 2.0+) */ 196 197 AcpiGbl_IntegerBitWidth = 64; 198 AcpiGbl_IntegerNybbleWidth = 16; 199 AcpiGbl_IntegerByteWidth = 8; 200 } 201 } 202 203 204 /******************************************************************************* 205 * 206 * FUNCTION: AcpiUtCreateUpdateStateAndPush 207 * 208 * PARAMETERS: Object - Object to be added to the new state 209 * Action - Increment/Decrement 210 * StateList - List the state will be added to 211 * 212 * RETURN: Status 213 * 214 * DESCRIPTION: Create a new state and push it 215 * 216 ******************************************************************************/ 217 218 ACPI_STATUS 219 AcpiUtCreateUpdateStateAndPush ( 220 ACPI_OPERAND_OBJECT *Object, 221 UINT16 Action, 222 ACPI_GENERIC_STATE **StateList) 223 { 224 ACPI_GENERIC_STATE *State; 225 226 227 ACPI_FUNCTION_ENTRY (); 228 229 230 /* Ignore null objects; these are expected */ 231 232 if (!Object) 233 { 234 return (AE_OK); 235 } 236 237 State = AcpiUtCreateUpdateState (Object, Action); 238 if (!State) 239 { 240 return (AE_NO_MEMORY); 241 } 242 243 AcpiUtPushGenericState (StateList, State); 244 return (AE_OK); 245 } 246 247 248 /******************************************************************************* 249 * 250 * FUNCTION: AcpiUtWalkPackageTree 251 * 252 * PARAMETERS: SourceObject - The package to walk 253 * TargetObject - Target object (if package is being copied) 254 * WalkCallback - Called once for each package element 255 * Context - Passed to the callback function 256 * 257 * RETURN: Status 258 * 259 * DESCRIPTION: Walk through a package, including subpackages 260 * 261 ******************************************************************************/ 262 263 ACPI_STATUS 264 AcpiUtWalkPackageTree ( 265 ACPI_OPERAND_OBJECT *SourceObject, 266 void *TargetObject, 267 ACPI_PKG_CALLBACK WalkCallback, 268 void *Context) 269 { 270 ACPI_STATUS Status = AE_OK; 271 ACPI_GENERIC_STATE *StateList = NULL; 272 ACPI_GENERIC_STATE *State; 273 ACPI_OPERAND_OBJECT *ThisSourceObj; 274 UINT32 ThisIndex; 275 276 277 ACPI_FUNCTION_TRACE (UtWalkPackageTree); 278 279 280 State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0); 281 if (!State) 282 { 283 return_ACPI_STATUS (AE_NO_MEMORY); 284 } 285 286 while (State) 287 { 288 /* Get one element of the package */ 289 290 ThisIndex = State->Pkg.Index; 291 ThisSourceObj = 292 State->Pkg.SourceObject->Package.Elements[ThisIndex]; 293 State->Pkg.ThisTargetObj = 294 &State->Pkg.SourceObject->Package.Elements[ThisIndex]; 295 296 /* 297 * Check for: 298 * 1) An uninitialized package element. It is completely 299 * legal to declare a package and leave it uninitialized 300 * 2) Not an internal object - can be a namespace node instead 301 * 3) Any type other than a package. Packages are handled in else 302 * case below. 303 */ 304 if ((!ThisSourceObj) || 305 (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != 306 ACPI_DESC_TYPE_OPERAND) || 307 (ThisSourceObj->Common.Type != ACPI_TYPE_PACKAGE)) 308 { 309 Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj, 310 State, Context); 311 if (ACPI_FAILURE (Status)) 312 { 313 return_ACPI_STATUS (Status); 314 } 315 316 State->Pkg.Index++; 317 while (State->Pkg.Index >= 318 State->Pkg.SourceObject->Package.Count) 319 { 320 /* 321 * We've handled all of the objects at this level, This means 322 * that we have just completed a package. That package may 323 * have contained one or more packages itself. 324 * 325 * Delete this state and pop the previous state (package). 326 */ 327 AcpiUtDeleteGenericState (State); 328 State = AcpiUtPopGenericState (&StateList); 329 330 /* Finished when there are no more states */ 331 332 if (!State) 333 { 334 /* 335 * We have handled all of the objects in the top level 336 * package just add the length of the package objects 337 * and exit 338 */ 339 return_ACPI_STATUS (AE_OK); 340 } 341 342 /* 343 * Go back up a level and move the index past the just 344 * completed package object. 345 */ 346 State->Pkg.Index++; 347 } 348 } 349 else 350 { 351 /* This is a subobject of type package */ 352 353 Status = WalkCallback ( 354 ACPI_COPY_TYPE_PACKAGE, ThisSourceObj, State, Context); 355 if (ACPI_FAILURE (Status)) 356 { 357 return_ACPI_STATUS (Status); 358 } 359 360 /* 361 * Push the current state and create a new one 362 * The callback above returned a new target package object. 363 */ 364 AcpiUtPushGenericState (&StateList, State); 365 State = AcpiUtCreatePkgState ( 366 ThisSourceObj, State->Pkg.ThisTargetObj, 0); 367 if (!State) 368 { 369 /* Free any stacked Update State objects */ 370 371 while (StateList) 372 { 373 State = AcpiUtPopGenericState (&StateList); 374 AcpiUtDeleteGenericState (State); 375 } 376 return_ACPI_STATUS (AE_NO_MEMORY); 377 } 378 } 379 } 380 381 /* We should never get here */ 382 383 ACPI_ERROR ((AE_INFO, 384 "State list did not terminate correctly")); 385 386 return_ACPI_STATUS (AE_AML_INTERNAL); 387 } 388 389 390 #ifdef ACPI_DEBUG_OUTPUT 391 /******************************************************************************* 392 * 393 * FUNCTION: AcpiUtDisplayInitPathname 394 * 395 * PARAMETERS: Type - Object type of the node 396 * ObjHandle - Handle whose pathname will be displayed 397 * Path - Additional path string to be appended. 398 * (NULL if no extra path) 399 * 400 * RETURN: ACPI_STATUS 401 * 402 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY 403 * 404 ******************************************************************************/ 405 406 void 407 AcpiUtDisplayInitPathname ( 408 UINT8 Type, 409 ACPI_NAMESPACE_NODE *ObjHandle, 410 const char *Path) 411 { 412 ACPI_STATUS Status; 413 ACPI_BUFFER Buffer; 414 415 416 ACPI_FUNCTION_ENTRY (); 417 418 419 /* Only print the path if the appropriate debug level is enabled */ 420 421 if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES)) 422 { 423 return; 424 } 425 426 /* Get the full pathname to the node */ 427 428 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 429 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE); 430 if (ACPI_FAILURE (Status)) 431 { 432 return; 433 } 434 435 /* Print what we're doing */ 436 437 switch (Type) 438 { 439 case ACPI_TYPE_METHOD: 440 441 AcpiOsPrintf ("Executing "); 442 break; 443 444 default: 445 446 AcpiOsPrintf ("Initializing "); 447 break; 448 } 449 450 /* Print the object type and pathname */ 451 452 AcpiOsPrintf ("%-12s %s", 453 AcpiUtGetTypeName (Type), (char *) Buffer.Pointer); 454 455 /* Extra path is used to append names like _STA, _INI, etc. */ 456 457 if (Path) 458 { 459 AcpiOsPrintf (".%s", Path); 460 } 461 AcpiOsPrintf ("\n"); 462 463 ACPI_FREE (Buffer.Pointer); 464 } 465 #endif 466