1 /******************************************************************************* 2 * 3 * Module Name: utmisc - common utility procedures 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 MERCHANTIBILITY 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_NAME (Table->Signature, ACPI_SIG_DSDT) || 110 ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) || 111 ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT) || 112 ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_OSDT)) 113 { 114 return (TRUE); 115 } 116 117 return (FALSE); 118 } 119 #endif 120 121 122 /******************************************************************************* 123 * 124 * FUNCTION: AcpiUtDwordByteSwap 125 * 126 * PARAMETERS: Value - Value to be converted 127 * 128 * RETURN: UINT32 integer with bytes swapped 129 * 130 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) 131 * 132 ******************************************************************************/ 133 134 UINT32 135 AcpiUtDwordByteSwap ( 136 UINT32 Value) 137 { 138 union 139 { 140 UINT32 Value; 141 UINT8 Bytes[4]; 142 } Out; 143 union 144 { 145 UINT32 Value; 146 UINT8 Bytes[4]; 147 } In; 148 149 150 ACPI_FUNCTION_ENTRY (); 151 152 153 In.Value = Value; 154 155 Out.Bytes[0] = In.Bytes[3]; 156 Out.Bytes[1] = In.Bytes[2]; 157 Out.Bytes[2] = In.Bytes[1]; 158 Out.Bytes[3] = In.Bytes[0]; 159 160 return (Out.Value); 161 } 162 163 164 /******************************************************************************* 165 * 166 * FUNCTION: AcpiUtSetIntegerWidth 167 * 168 * PARAMETERS: Revision From DSDT header 169 * 170 * RETURN: None 171 * 172 * DESCRIPTION: Set the global integer bit width based upon the revision 173 * of the DSDT. For Revision 1 and 0, Integers are 32 bits. 174 * For Revision 2 and above, Integers are 64 bits. Yes, this 175 * makes a difference. 176 * 177 ******************************************************************************/ 178 179 void 180 AcpiUtSetIntegerWidth ( 181 UINT8 Revision) 182 { 183 184 if (Revision < 2) 185 { 186 /* 32-bit case */ 187 188 AcpiGbl_IntegerBitWidth = 32; 189 AcpiGbl_IntegerNybbleWidth = 8; 190 AcpiGbl_IntegerByteWidth = 4; 191 } 192 else 193 { 194 /* 64-bit case (ACPI 2.0+) */ 195 196 AcpiGbl_IntegerBitWidth = 64; 197 AcpiGbl_IntegerNybbleWidth = 16; 198 AcpiGbl_IntegerByteWidth = 8; 199 } 200 } 201 202 203 /******************************************************************************* 204 * 205 * FUNCTION: AcpiUtCreateUpdateStateAndPush 206 * 207 * PARAMETERS: Object - Object to be added to the new state 208 * Action - Increment/Decrement 209 * StateList - List the state will be added to 210 * 211 * RETURN: Status 212 * 213 * DESCRIPTION: Create a new state and push it 214 * 215 ******************************************************************************/ 216 217 ACPI_STATUS 218 AcpiUtCreateUpdateStateAndPush ( 219 ACPI_OPERAND_OBJECT *Object, 220 UINT16 Action, 221 ACPI_GENERIC_STATE **StateList) 222 { 223 ACPI_GENERIC_STATE *State; 224 225 226 ACPI_FUNCTION_ENTRY (); 227 228 229 /* Ignore null objects; these are expected */ 230 231 if (!Object) 232 { 233 return (AE_OK); 234 } 235 236 State = AcpiUtCreateUpdateState (Object, Action); 237 if (!State) 238 { 239 return (AE_NO_MEMORY); 240 } 241 242 AcpiUtPushGenericState (StateList, State); 243 return (AE_OK); 244 } 245 246 247 /******************************************************************************* 248 * 249 * FUNCTION: AcpiUtWalkPackageTree 250 * 251 * PARAMETERS: SourceObject - The package to walk 252 * TargetObject - Target object (if package is being copied) 253 * WalkCallback - Called once for each package element 254 * Context - Passed to the callback function 255 * 256 * RETURN: Status 257 * 258 * DESCRIPTION: Walk through a package 259 * 260 ******************************************************************************/ 261 262 ACPI_STATUS 263 AcpiUtWalkPackageTree ( 264 ACPI_OPERAND_OBJECT *SourceObject, 265 void *TargetObject, 266 ACPI_PKG_CALLBACK WalkCallback, 267 void *Context) 268 { 269 ACPI_STATUS Status = AE_OK; 270 ACPI_GENERIC_STATE *StateList = NULL; 271 ACPI_GENERIC_STATE *State; 272 UINT32 ThisIndex; 273 ACPI_OPERAND_OBJECT *ThisSourceObj; 274 275 276 ACPI_FUNCTION_TRACE (UtWalkPackageTree); 277 278 279 State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0); 280 if (!State) 281 { 282 return_ACPI_STATUS (AE_NO_MEMORY); 283 } 284 285 while (State) 286 { 287 /* Get one element of the package */ 288 289 ThisIndex = State->Pkg.Index; 290 ThisSourceObj = (ACPI_OPERAND_OBJECT *) 291 State->Pkg.SourceObject->Package.Elements[ThisIndex]; 292 293 /* 294 * Check for: 295 * 1) An uninitialized package element. It is completely 296 * legal to declare a package and leave it uninitialized 297 * 2) Not an internal object - can be a namespace node instead 298 * 3) Any type other than a package. Packages are handled in else 299 * case below. 300 */ 301 if ((!ThisSourceObj) || 302 (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != 303 ACPI_DESC_TYPE_OPERAND) || 304 (ThisSourceObj->Common.Type != ACPI_TYPE_PACKAGE)) 305 { 306 Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj, 307 State, Context); 308 if (ACPI_FAILURE (Status)) 309 { 310 return_ACPI_STATUS (Status); 311 } 312 313 State->Pkg.Index++; 314 while (State->Pkg.Index >= 315 State->Pkg.SourceObject->Package.Count) 316 { 317 /* 318 * We've handled all of the objects at this level, This means 319 * that we have just completed a package. That package may 320 * have contained one or more packages itself. 321 * 322 * Delete this state and pop the previous state (package). 323 */ 324 AcpiUtDeleteGenericState (State); 325 State = AcpiUtPopGenericState (&StateList); 326 327 /* Finished when there are no more states */ 328 329 if (!State) 330 { 331 /* 332 * We have handled all of the objects in the top level 333 * package just add the length of the package objects 334 * and exit 335 */ 336 return_ACPI_STATUS (AE_OK); 337 } 338 339 /* 340 * Go back up a level and move the index past the just 341 * completed package object. 342 */ 343 State->Pkg.Index++; 344 } 345 } 346 else 347 { 348 /* This is a subobject of type package */ 349 350 Status = WalkCallback ( 351 ACPI_COPY_TYPE_PACKAGE, ThisSourceObj, State, Context); 352 if (ACPI_FAILURE (Status)) 353 { 354 return_ACPI_STATUS (Status); 355 } 356 357 /* 358 * Push the current state and create a new one 359 * The callback above returned a new target package object. 360 */ 361 AcpiUtPushGenericState (&StateList, State); 362 State = AcpiUtCreatePkgState ( 363 ThisSourceObj, State->Pkg.ThisTargetObj, 0); 364 if (!State) 365 { 366 /* Free any stacked Update State objects */ 367 368 while (StateList) 369 { 370 State = AcpiUtPopGenericState (&StateList); 371 AcpiUtDeleteGenericState (State); 372 } 373 return_ACPI_STATUS (AE_NO_MEMORY); 374 } 375 } 376 } 377 378 /* We should never get here */ 379 380 return_ACPI_STATUS (AE_AML_INTERNAL); 381 } 382 383 384 #ifdef ACPI_DEBUG_OUTPUT 385 /******************************************************************************* 386 * 387 * FUNCTION: AcpiUtDisplayInitPathname 388 * 389 * PARAMETERS: Type - Object type of the node 390 * ObjHandle - Handle whose pathname will be displayed 391 * Path - Additional path string to be appended. 392 * (NULL if no extra path) 393 * 394 * RETURN: ACPI_STATUS 395 * 396 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY 397 * 398 ******************************************************************************/ 399 400 void 401 AcpiUtDisplayInitPathname ( 402 UINT8 Type, 403 ACPI_NAMESPACE_NODE *ObjHandle, 404 const char *Path) 405 { 406 ACPI_STATUS Status; 407 ACPI_BUFFER Buffer; 408 409 410 ACPI_FUNCTION_ENTRY (); 411 412 413 /* Only print the path if the appropriate debug level is enabled */ 414 415 if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES)) 416 { 417 return; 418 } 419 420 /* Get the full pathname to the node */ 421 422 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 423 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE); 424 if (ACPI_FAILURE (Status)) 425 { 426 return; 427 } 428 429 /* Print what we're doing */ 430 431 switch (Type) 432 { 433 case ACPI_TYPE_METHOD: 434 435 AcpiOsPrintf ("Executing "); 436 break; 437 438 default: 439 440 AcpiOsPrintf ("Initializing "); 441 break; 442 } 443 444 /* Print the object type and pathname */ 445 446 AcpiOsPrintf ("%-12s %s", 447 AcpiUtGetTypeName (Type), (char *) Buffer.Pointer); 448 449 /* Extra path is used to append names like _STA, _INI, etc. */ 450 451 if (Path) 452 { 453 AcpiOsPrintf (".%s", Path); 454 } 455 AcpiOsPrintf ("\n"); 456 457 ACPI_FREE (Buffer.Pointer); 458 } 459 #endif 460