1 /****************************************************************************** 2 * 3 * Module Name: nsdump - table dumping routines for debug 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2020, 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 #include "acoutput.h" 48 49 50 #define _COMPONENT ACPI_NAMESPACE 51 ACPI_MODULE_NAME ("nsdump") 52 53 /* Local prototypes */ 54 55 #ifdef ACPI_OBSOLETE_FUNCTIONS 56 void 57 AcpiNsDumpRootDevices ( 58 void); 59 60 static ACPI_STATUS 61 AcpiNsDumpOneDevice ( 62 ACPI_HANDLE ObjHandle, 63 UINT32 Level, 64 void *Context, 65 void **ReturnValue); 66 #endif 67 68 69 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) 70 71 static ACPI_STATUS 72 AcpiNsDumpOneObjectPath ( 73 ACPI_HANDLE ObjHandle, 74 UINT32 Level, 75 void *Context, 76 void **ReturnValue); 77 78 static ACPI_STATUS 79 AcpiNsGetMaxDepth ( 80 ACPI_HANDLE ObjHandle, 81 UINT32 Level, 82 void *Context, 83 void **ReturnValue); 84 85 86 /******************************************************************************* 87 * 88 * FUNCTION: AcpiNsPrintPathname 89 * 90 * PARAMETERS: NumSegments - Number of ACPI name segments 91 * Pathname - The compressed (internal) path 92 * 93 * RETURN: None 94 * 95 * DESCRIPTION: Print an object's full namespace pathname 96 * 97 ******************************************************************************/ 98 99 void 100 AcpiNsPrintPathname ( 101 UINT32 NumSegments, 102 const char *Pathname) 103 { 104 UINT32 i; 105 106 107 ACPI_FUNCTION_NAME (NsPrintPathname); 108 109 110 /* Check if debug output enabled */ 111 112 if (!ACPI_IS_DEBUG_ENABLED (ACPI_LV_NAMES, ACPI_NAMESPACE)) 113 { 114 return; 115 } 116 117 /* Print the entire name */ 118 119 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[")); 120 121 while (NumSegments) 122 { 123 for (i = 0; i < 4; i++) 124 { 125 isprint ((int) Pathname[i]) ? 126 AcpiOsPrintf ("%c", Pathname[i]) : 127 AcpiOsPrintf ("?"); 128 } 129 130 Pathname += ACPI_NAMESEG_SIZE; 131 NumSegments--; 132 if (NumSegments) 133 { 134 AcpiOsPrintf ("."); 135 } 136 } 137 138 AcpiOsPrintf ("]\n"); 139 } 140 141 142 #ifdef ACPI_OBSOLETE_FUNCTIONS 143 /* Not used at this time, perhaps later */ 144 145 /******************************************************************************* 146 * 147 * FUNCTION: AcpiNsDumpPathname 148 * 149 * PARAMETERS: Handle - Object 150 * Msg - Prefix message 151 * Level - Desired debug level 152 * Component - Caller's component ID 153 * 154 * RETURN: None 155 * 156 * DESCRIPTION: Print an object's full namespace pathname 157 * Manages allocation/freeing of a pathname buffer 158 * 159 ******************************************************************************/ 160 161 void 162 AcpiNsDumpPathname ( 163 ACPI_HANDLE Handle, 164 const char *Msg, 165 UINT32 Level, 166 UINT32 Component) 167 { 168 169 ACPI_FUNCTION_TRACE (NsDumpPathname); 170 171 172 /* Do this only if the requested debug level and component are enabled */ 173 174 if (!ACPI_IS_DEBUG_ENABLED (Level, Component)) 175 { 176 return_VOID; 177 } 178 179 /* Convert handle to a full pathname and print it (with supplied message) */ 180 181 AcpiNsPrintNodePathname (Handle, Msg); 182 AcpiOsPrintf ("\n"); 183 return_VOID; 184 } 185 #endif 186 187 188 /******************************************************************************* 189 * 190 * FUNCTION: AcpiNsDumpOneObject 191 * 192 * PARAMETERS: ObjHandle - Node to be dumped 193 * Level - Nesting level of the handle 194 * Context - Passed into WalkNamespace 195 * ReturnValue - Not used 196 * 197 * RETURN: Status 198 * 199 * DESCRIPTION: Dump a single Node 200 * This procedure is a UserFunction called by AcpiNsWalkNamespace. 201 * 202 ******************************************************************************/ 203 204 ACPI_STATUS 205 AcpiNsDumpOneObject ( 206 ACPI_HANDLE ObjHandle, 207 UINT32 Level, 208 void *Context, 209 void **ReturnValue) 210 { 211 ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context; 212 ACPI_NAMESPACE_NODE *ThisNode; 213 ACPI_OPERAND_OBJECT *ObjDesc = NULL; 214 ACPI_OBJECT_TYPE ObjType; 215 ACPI_OBJECT_TYPE Type; 216 UINT32 BytesToDump; 217 UINT32 DbgLevel; 218 UINT32 i; 219 220 221 ACPI_FUNCTION_NAME (NsDumpOneObject); 222 223 224 /* Is output enabled? */ 225 226 if (!(AcpiDbgLevel & Info->DebugLevel)) 227 { 228 return (AE_OK); 229 } 230 231 if (!ObjHandle) 232 { 233 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n")); 234 return (AE_OK); 235 } 236 237 ThisNode = AcpiNsValidateHandle (ObjHandle); 238 if (!ThisNode) 239 { 240 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Invalid object handle %p\n", 241 ObjHandle)); 242 return (AE_OK); 243 } 244 245 Type = ThisNode->Type; 246 Info->Count++; 247 248 /* Check if the owner matches */ 249 250 if ((Info->OwnerId != ACPI_OWNER_ID_MAX) && 251 (Info->OwnerId != ThisNode->OwnerId)) 252 { 253 return (AE_OK); 254 } 255 256 if (!(Info->DisplayType & ACPI_DISPLAY_SHORT)) 257 { 258 /* Indent the object according to the level */ 259 260 AcpiOsPrintf ("%2d%*s", (UINT32) Level - 1, (int) Level * 2, " "); 261 262 /* Check the node type and name */ 263 264 if (Type > ACPI_TYPE_LOCAL_MAX) 265 { 266 ACPI_WARNING ((AE_INFO, 267 "Invalid ACPI Object Type 0x%08X", Type)); 268 } 269 270 AcpiOsPrintf ("%4.4s", AcpiUtGetNodeName (ThisNode)); 271 } 272 273 /* Now we can print out the pertinent information */ 274 275 AcpiOsPrintf (" %-12s %p %3.3X ", 276 AcpiUtGetTypeName (Type), ThisNode, ThisNode->OwnerId); 277 278 DbgLevel = AcpiDbgLevel; 279 AcpiDbgLevel = 0; 280 ObjDesc = AcpiNsGetAttachedObject (ThisNode); 281 AcpiDbgLevel = DbgLevel; 282 283 /* Temp nodes are those nodes created by a control method */ 284 285 if (ThisNode->Flags & ANOBJ_TEMPORARY) 286 { 287 AcpiOsPrintf ("(T) "); 288 } 289 290 switch (Info->DisplayType & ACPI_DISPLAY_MASK) 291 { 292 case ACPI_DISPLAY_SUMMARY: 293 294 if (!ObjDesc) 295 { 296 /* No attached object. Some types should always have an object */ 297 298 switch (Type) 299 { 300 case ACPI_TYPE_INTEGER: 301 case ACPI_TYPE_PACKAGE: 302 case ACPI_TYPE_BUFFER: 303 case ACPI_TYPE_STRING: 304 case ACPI_TYPE_METHOD: 305 306 AcpiOsPrintf ("<No attached object>"); 307 break; 308 309 default: 310 311 break; 312 } 313 314 AcpiOsPrintf ("\n"); 315 return (AE_OK); 316 } 317 318 switch (Type) 319 { 320 case ACPI_TYPE_PROCESSOR: 321 322 AcpiOsPrintf ("ID %02X Len %02X Addr %8.8X%8.8X\n", 323 ObjDesc->Processor.ProcId, ObjDesc->Processor.Length, 324 ACPI_FORMAT_UINT64 (ObjDesc->Processor.Address)); 325 break; 326 327 case ACPI_TYPE_DEVICE: 328 329 AcpiOsPrintf ("Notify Object: %p\n", ObjDesc); 330 break; 331 332 case ACPI_TYPE_METHOD: 333 334 AcpiOsPrintf ("Args %X Len %.4X Aml %p\n", 335 (UINT32) ObjDesc->Method.ParamCount, 336 ObjDesc->Method.AmlLength, ObjDesc->Method.AmlStart); 337 break; 338 339 case ACPI_TYPE_INTEGER: 340 341 AcpiOsPrintf ("= %8.8X%8.8X\n", 342 ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value)); 343 break; 344 345 case ACPI_TYPE_PACKAGE: 346 347 if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) 348 { 349 AcpiOsPrintf ("Elements %.2X\n", 350 ObjDesc->Package.Count); 351 } 352 else 353 { 354 AcpiOsPrintf ("[Length not yet evaluated]\n"); 355 } 356 break; 357 358 case ACPI_TYPE_BUFFER: 359 360 if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) 361 { 362 AcpiOsPrintf ("Len %.2X", 363 ObjDesc->Buffer.Length); 364 365 /* Dump some of the buffer */ 366 367 if (ObjDesc->Buffer.Length > 0) 368 { 369 AcpiOsPrintf (" ="); 370 for (i = 0; (i < ObjDesc->Buffer.Length && i < 12); i++) 371 { 372 AcpiOsPrintf (" %2.2X", ObjDesc->Buffer.Pointer[i]); 373 } 374 } 375 AcpiOsPrintf ("\n"); 376 } 377 else 378 { 379 AcpiOsPrintf ("[Length not yet evaluated]\n"); 380 } 381 break; 382 383 case ACPI_TYPE_STRING: 384 385 AcpiOsPrintf ("Len %.2X ", ObjDesc->String.Length); 386 AcpiUtPrintString (ObjDesc->String.Pointer, 80); 387 AcpiOsPrintf ("\n"); 388 break; 389 390 case ACPI_TYPE_REGION: 391 392 AcpiOsPrintf ("[%s]", 393 AcpiUtGetRegionName (ObjDesc->Region.SpaceId)); 394 if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID) 395 { 396 AcpiOsPrintf (" Addr %8.8X%8.8X Len %.4X\n", 397 ACPI_FORMAT_UINT64 (ObjDesc->Region.Address), 398 ObjDesc->Region.Length); 399 } 400 else 401 { 402 AcpiOsPrintf (" [Address/Length not yet evaluated]\n"); 403 } 404 break; 405 406 case ACPI_TYPE_LOCAL_REFERENCE: 407 408 AcpiOsPrintf ("[%s]\n", AcpiUtGetReferenceName (ObjDesc)); 409 break; 410 411 case ACPI_TYPE_BUFFER_FIELD: 412 413 if (ObjDesc->BufferField.BufferObj && 414 ObjDesc->BufferField.BufferObj->Buffer.Node) 415 { 416 AcpiOsPrintf ("Buf [%4.4s]", 417 AcpiUtGetNodeName ( 418 ObjDesc->BufferField.BufferObj->Buffer.Node)); 419 } 420 break; 421 422 case ACPI_TYPE_LOCAL_REGION_FIELD: 423 424 AcpiOsPrintf ("Rgn [%4.4s]", 425 AcpiUtGetNodeName ( 426 ObjDesc->CommonField.RegionObj->Region.Node)); 427 break; 428 429 case ACPI_TYPE_LOCAL_BANK_FIELD: 430 431 AcpiOsPrintf ("Rgn [%4.4s] Bnk [%4.4s]", 432 AcpiUtGetNodeName ( 433 ObjDesc->CommonField.RegionObj->Region.Node), 434 AcpiUtGetNodeName ( 435 ObjDesc->BankField.BankObj->CommonField.Node)); 436 break; 437 438 case ACPI_TYPE_LOCAL_INDEX_FIELD: 439 440 AcpiOsPrintf ("Idx [%4.4s] Dat [%4.4s]", 441 AcpiUtGetNodeName ( 442 ObjDesc->IndexField.IndexObj->CommonField.Node), 443 AcpiUtGetNodeName ( 444 ObjDesc->IndexField.DataObj->CommonField.Node)); 445 break; 446 447 case ACPI_TYPE_LOCAL_ALIAS: 448 case ACPI_TYPE_LOCAL_METHOD_ALIAS: 449 450 AcpiOsPrintf ("Target %4.4s (%p)\n", 451 AcpiUtGetNodeName (ObjDesc), ObjDesc); 452 break; 453 454 default: 455 456 AcpiOsPrintf ("Object %p\n", ObjDesc); 457 break; 458 } 459 460 /* Common field handling */ 461 462 switch (Type) 463 { 464 case ACPI_TYPE_BUFFER_FIELD: 465 case ACPI_TYPE_LOCAL_REGION_FIELD: 466 case ACPI_TYPE_LOCAL_BANK_FIELD: 467 case ACPI_TYPE_LOCAL_INDEX_FIELD: 468 469 AcpiOsPrintf (" Off %.3X Len %.2X Acc %.2X\n", 470 (ObjDesc->CommonField.BaseByteOffset * 8) 471 + ObjDesc->CommonField.StartFieldBitOffset, 472 ObjDesc->CommonField.BitLength, 473 ObjDesc->CommonField.AccessByteWidth); 474 break; 475 476 default: 477 478 break; 479 } 480 break; 481 482 case ACPI_DISPLAY_OBJECTS: 483 484 AcpiOsPrintf ("O:%p", ObjDesc); 485 if (!ObjDesc) 486 { 487 /* No attached object, we are done */ 488 489 AcpiOsPrintf ("\n"); 490 return (AE_OK); 491 } 492 493 AcpiOsPrintf ("(R%u)", ObjDesc->Common.ReferenceCount); 494 495 switch (Type) 496 { 497 case ACPI_TYPE_METHOD: 498 499 /* Name is a Method and its AML offset/length are set */ 500 501 AcpiOsPrintf (" M:%p-%X\n", ObjDesc->Method.AmlStart, 502 ObjDesc->Method.AmlLength); 503 break; 504 505 case ACPI_TYPE_INTEGER: 506 507 AcpiOsPrintf (" I:%8.8X8.8%X\n", 508 ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value)); 509 break; 510 511 case ACPI_TYPE_STRING: 512 513 AcpiOsPrintf (" S:%p-%X\n", ObjDesc->String.Pointer, 514 ObjDesc->String.Length); 515 break; 516 517 case ACPI_TYPE_BUFFER: 518 519 AcpiOsPrintf (" B:%p-%X\n", ObjDesc->Buffer.Pointer, 520 ObjDesc->Buffer.Length); 521 break; 522 523 default: 524 525 AcpiOsPrintf ("\n"); 526 break; 527 } 528 break; 529 530 default: 531 AcpiOsPrintf ("\n"); 532 break; 533 } 534 535 /* If debug turned off, done */ 536 537 if (!(AcpiDbgLevel & ACPI_LV_VALUES)) 538 { 539 return (AE_OK); 540 } 541 542 /* If there is an attached object, display it */ 543 544 DbgLevel = AcpiDbgLevel; 545 AcpiDbgLevel = 0; 546 ObjDesc = AcpiNsGetAttachedObject (ThisNode); 547 AcpiDbgLevel = DbgLevel; 548 549 /* Dump attached objects */ 550 551 while (ObjDesc) 552 { 553 ObjType = ACPI_TYPE_INVALID; 554 AcpiOsPrintf ("Attached Object %p: ", ObjDesc); 555 556 /* Decode the type of attached object and dump the contents */ 557 558 switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)) 559 { 560 case ACPI_DESC_TYPE_NAMED: 561 562 AcpiOsPrintf ("(Ptr to Node)\n"); 563 BytesToDump = sizeof (ACPI_NAMESPACE_NODE); 564 ACPI_DUMP_BUFFER (ObjDesc, BytesToDump); 565 break; 566 567 case ACPI_DESC_TYPE_OPERAND: 568 569 ObjType = ObjDesc->Common.Type; 570 571 if (ObjType > ACPI_TYPE_LOCAL_MAX) 572 { 573 AcpiOsPrintf ( 574 "(Pointer to ACPI Object type %.2X [UNKNOWN])\n", 575 ObjType); 576 577 BytesToDump = 32; 578 } 579 else 580 { 581 AcpiOsPrintf ( 582 "(Pointer to ACPI Object type %.2X [%s])\n", 583 ObjType, AcpiUtGetTypeName (ObjType)); 584 585 BytesToDump = sizeof (ACPI_OPERAND_OBJECT); 586 } 587 588 ACPI_DUMP_BUFFER (ObjDesc, BytesToDump); 589 break; 590 591 default: 592 593 break; 594 } 595 596 /* If value is NOT an internal object, we are done */ 597 598 if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND) 599 { 600 goto Cleanup; 601 } 602 603 /* Valid object, get the pointer to next level, if any */ 604 605 switch (ObjType) 606 { 607 case ACPI_TYPE_BUFFER: 608 case ACPI_TYPE_STRING: 609 /* 610 * NOTE: takes advantage of common fields between string/buffer 611 */ 612 BytesToDump = ObjDesc->String.Length; 613 ObjDesc = (void *) ObjDesc->String.Pointer; 614 615 AcpiOsPrintf ("(Buffer/String pointer %p length %X)\n", 616 ObjDesc, BytesToDump); 617 ACPI_DUMP_BUFFER (ObjDesc, BytesToDump); 618 goto Cleanup; 619 620 case ACPI_TYPE_BUFFER_FIELD: 621 622 ObjDesc = (ACPI_OPERAND_OBJECT *) ObjDesc->BufferField.BufferObj; 623 break; 624 625 case ACPI_TYPE_PACKAGE: 626 627 ObjDesc = (void *) ObjDesc->Package.Elements; 628 break; 629 630 case ACPI_TYPE_METHOD: 631 632 ObjDesc = (void *) ObjDesc->Method.AmlStart; 633 break; 634 635 case ACPI_TYPE_LOCAL_REGION_FIELD: 636 637 ObjDesc = (void *) ObjDesc->Field.RegionObj; 638 break; 639 640 case ACPI_TYPE_LOCAL_BANK_FIELD: 641 642 ObjDesc = (void *) ObjDesc->BankField.RegionObj; 643 break; 644 645 case ACPI_TYPE_LOCAL_INDEX_FIELD: 646 647 ObjDesc = (void *) ObjDesc->IndexField.IndexObj; 648 break; 649 650 default: 651 652 goto Cleanup; 653 } 654 } 655 656 Cleanup: 657 AcpiOsPrintf ("\n"); 658 return (AE_OK); 659 } 660 661 662 /******************************************************************************* 663 * 664 * FUNCTION: AcpiNsDumpObjects 665 * 666 * PARAMETERS: Type - Object type to be dumped 667 * DisplayType - 0 or ACPI_DISPLAY_SUMMARY 668 * MaxDepth - Maximum depth of dump. Use ACPI_UINT32_MAX 669 * for an effectively unlimited depth. 670 * OwnerId - Dump only objects owned by this ID. Use 671 * ACPI_UINT32_MAX to match all owners. 672 * StartHandle - Where in namespace to start/end search 673 * 674 * RETURN: None 675 * 676 * DESCRIPTION: Dump typed objects within the loaded namespace. Uses 677 * AcpiNsWalkNamespace in conjunction with AcpiNsDumpOneObject. 678 * 679 ******************************************************************************/ 680 681 void 682 AcpiNsDumpObjects ( 683 ACPI_OBJECT_TYPE Type, 684 UINT8 DisplayType, 685 UINT32 MaxDepth, 686 ACPI_OWNER_ID OwnerId, 687 ACPI_HANDLE StartHandle) 688 { 689 ACPI_WALK_INFO Info; 690 ACPI_STATUS Status; 691 692 693 ACPI_FUNCTION_ENTRY (); 694 695 696 /* 697 * Just lock the entire namespace for the duration of the dump. 698 * We don't want any changes to the namespace during this time, 699 * especially the temporary nodes since we are going to display 700 * them also. 701 */ 702 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 703 if (ACPI_FAILURE (Status)) 704 { 705 AcpiOsPrintf ("Could not acquire namespace mutex\n"); 706 return; 707 } 708 709 Info.Count = 0; 710 Info.DebugLevel = ACPI_LV_TABLES; 711 Info.OwnerId = OwnerId; 712 Info.DisplayType = DisplayType; 713 714 (void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth, 715 ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES, 716 AcpiNsDumpOneObject, NULL, (void *) &Info, NULL); 717 718 AcpiOsPrintf ("\nNamespace node count: %u\n\n", Info.Count); 719 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 720 } 721 722 723 /******************************************************************************* 724 * 725 * FUNCTION: AcpiNsDumpOneObjectPath, AcpiNsGetMaxDepth 726 * 727 * PARAMETERS: ObjHandle - Node to be dumped 728 * Level - Nesting level of the handle 729 * Context - Passed into WalkNamespace 730 * ReturnValue - Not used 731 * 732 * RETURN: Status 733 * 734 * DESCRIPTION: Dump the full pathname to a namespace object. AcpNsGetMaxDepth 735 * computes the maximum nesting depth in the namespace tree, in 736 * order to simplify formatting in AcpiNsDumpOneObjectPath. 737 * These procedures are UserFunctions called by AcpiNsWalkNamespace. 738 * 739 ******************************************************************************/ 740 741 static ACPI_STATUS 742 AcpiNsDumpOneObjectPath ( 743 ACPI_HANDLE ObjHandle, 744 UINT32 Level, 745 void *Context, 746 void **ReturnValue) 747 { 748 UINT32 MaxLevel = *((UINT32 *) Context); 749 char *Pathname; 750 ACPI_NAMESPACE_NODE *Node; 751 int PathIndent; 752 753 754 if (!ObjHandle) 755 { 756 return (AE_OK); 757 } 758 759 Node = AcpiNsValidateHandle (ObjHandle); 760 if (!Node) 761 { 762 /* Ignore bad node during namespace walk */ 763 764 return (AE_OK); 765 } 766 767 Pathname = AcpiNsGetNormalizedPathname (Node, TRUE); 768 769 PathIndent = 1; 770 if (Level <= MaxLevel) 771 { 772 PathIndent = MaxLevel - Level + 1; 773 } 774 775 AcpiOsPrintf ("%2d%*s%-12s%*s", 776 Level, Level, " ", AcpiUtGetTypeName (Node->Type), 777 PathIndent, " "); 778 779 AcpiOsPrintf ("%s\n", &Pathname[1]); 780 ACPI_FREE (Pathname); 781 return (AE_OK); 782 } 783 784 785 static ACPI_STATUS 786 AcpiNsGetMaxDepth ( 787 ACPI_HANDLE ObjHandle, 788 UINT32 Level, 789 void *Context, 790 void **ReturnValue) 791 { 792 UINT32 *MaxLevel = (UINT32 *) Context; 793 794 795 if (Level > *MaxLevel) 796 { 797 *MaxLevel = Level; 798 } 799 return (AE_OK); 800 } 801 802 803 /******************************************************************************* 804 * 805 * FUNCTION: AcpiNsDumpObjectPaths 806 * 807 * PARAMETERS: Type - Object type to be dumped 808 * DisplayType - 0 or ACPI_DISPLAY_SUMMARY 809 * MaxDepth - Maximum depth of dump. Use ACPI_UINT32_MAX 810 * for an effectively unlimited depth. 811 * OwnerId - Dump only objects owned by this ID. Use 812 * ACPI_UINT32_MAX to match all owners. 813 * StartHandle - Where in namespace to start/end search 814 * 815 * RETURN: None 816 * 817 * DESCRIPTION: Dump full object pathnames within the loaded namespace. Uses 818 * AcpiNsWalkNamespace in conjunction with AcpiNsDumpOneObjectPath. 819 * 820 ******************************************************************************/ 821 822 void 823 AcpiNsDumpObjectPaths ( 824 ACPI_OBJECT_TYPE Type, 825 UINT8 DisplayType, 826 UINT32 MaxDepth, 827 ACPI_OWNER_ID OwnerId, 828 ACPI_HANDLE StartHandle) 829 { 830 ACPI_STATUS Status; 831 UINT32 MaxLevel = 0; 832 833 834 ACPI_FUNCTION_ENTRY (); 835 836 837 /* 838 * Just lock the entire namespace for the duration of the dump. 839 * We don't want any changes to the namespace during this time, 840 * especially the temporary nodes since we are going to display 841 * them also. 842 */ 843 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 844 if (ACPI_FAILURE (Status)) 845 { 846 AcpiOsPrintf ("Could not acquire namespace mutex\n"); 847 return; 848 } 849 850 /* Get the max depth of the namespace tree, for formatting later */ 851 852 (void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth, 853 ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES, 854 AcpiNsGetMaxDepth, NULL, (void *) &MaxLevel, NULL); 855 856 /* Now dump the entire namespace */ 857 858 (void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth, 859 ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES, 860 AcpiNsDumpOneObjectPath, NULL, (void *) &MaxLevel, NULL); 861 862 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 863 } 864 865 866 /******************************************************************************* 867 * 868 * FUNCTION: AcpiNsDumpEntry 869 * 870 * PARAMETERS: Handle - Node to be dumped 871 * DebugLevel - Output level 872 * 873 * RETURN: None 874 * 875 * DESCRIPTION: Dump a single Node 876 * 877 ******************************************************************************/ 878 879 void 880 AcpiNsDumpEntry ( 881 ACPI_HANDLE Handle, 882 UINT32 DebugLevel) 883 { 884 ACPI_WALK_INFO Info; 885 886 887 ACPI_FUNCTION_ENTRY (); 888 889 890 Info.DebugLevel = DebugLevel; 891 Info.OwnerId = ACPI_OWNER_ID_MAX; 892 Info.DisplayType = ACPI_DISPLAY_SUMMARY; 893 894 (void) AcpiNsDumpOneObject (Handle, 1, &Info, NULL); 895 } 896 897 898 #ifdef ACPI_ASL_COMPILER 899 /******************************************************************************* 900 * 901 * FUNCTION: AcpiNsDumpTables 902 * 903 * PARAMETERS: SearchBase - Root of subtree to be dumped, or 904 * NS_ALL to dump the entire namespace 905 * MaxDepth - Maximum depth of dump. Use INT_MAX 906 * for an effectively unlimited depth. 907 * 908 * RETURN: None 909 * 910 * DESCRIPTION: Dump the name space, or a portion of it. 911 * 912 ******************************************************************************/ 913 914 void 915 AcpiNsDumpTables ( 916 ACPI_HANDLE SearchBase, 917 UINT32 MaxDepth) 918 { 919 ACPI_HANDLE SearchHandle = SearchBase; 920 921 922 ACPI_FUNCTION_TRACE (NsDumpTables); 923 924 925 if (!AcpiGbl_RootNode) 926 { 927 /* 928 * If the name space has not been initialized, 929 * there is nothing to dump. 930 */ 931 ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, 932 "namespace not initialized!\n")); 933 return_VOID; 934 } 935 936 if (ACPI_NS_ALL == SearchBase) 937 { 938 /* Entire namespace */ 939 940 SearchHandle = AcpiGbl_RootNode; 941 ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "\\\n")); 942 } 943 944 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, MaxDepth, 945 ACPI_OWNER_ID_MAX, SearchHandle); 946 return_VOID; 947 } 948 #endif 949 #endif 950