1 /****************************************************************************** 2 * 3 * Module Name: nsdump - table dumping routines for debug 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2019, 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_NAME_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 %2.2X ", 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 (" %.2hX", 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 %.2hd\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 ObjType = ACPI_TYPE_INVALID; /* Terminate loop after next pass */ 656 } 657 658 Cleanup: 659 AcpiOsPrintf ("\n"); 660 return (AE_OK); 661 } 662 663 664 /******************************************************************************* 665 * 666 * FUNCTION: AcpiNsDumpObjects 667 * 668 * PARAMETERS: Type - Object type to be dumped 669 * DisplayType - 0 or ACPI_DISPLAY_SUMMARY 670 * MaxDepth - Maximum depth of dump. Use ACPI_UINT32_MAX 671 * for an effectively unlimited depth. 672 * OwnerId - Dump only objects owned by this ID. Use 673 * ACPI_UINT32_MAX to match all owners. 674 * StartHandle - Where in namespace to start/end search 675 * 676 * RETURN: None 677 * 678 * DESCRIPTION: Dump typed objects within the loaded namespace. Uses 679 * AcpiNsWalkNamespace in conjunction with AcpiNsDumpOneObject. 680 * 681 ******************************************************************************/ 682 683 void 684 AcpiNsDumpObjects ( 685 ACPI_OBJECT_TYPE Type, 686 UINT8 DisplayType, 687 UINT32 MaxDepth, 688 ACPI_OWNER_ID OwnerId, 689 ACPI_HANDLE StartHandle) 690 { 691 ACPI_WALK_INFO Info; 692 ACPI_STATUS Status; 693 694 695 ACPI_FUNCTION_ENTRY (); 696 697 698 /* 699 * Just lock the entire namespace for the duration of the dump. 700 * We don't want any changes to the namespace during this time, 701 * especially the temporary nodes since we are going to display 702 * them also. 703 */ 704 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 705 if (ACPI_FAILURE (Status)) 706 { 707 AcpiOsPrintf ("Could not acquire namespace mutex\n"); 708 return; 709 } 710 711 Info.Count = 0; 712 Info.DebugLevel = ACPI_LV_TABLES; 713 Info.OwnerId = OwnerId; 714 Info.DisplayType = DisplayType; 715 716 (void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth, 717 ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES, 718 AcpiNsDumpOneObject, NULL, (void *) &Info, NULL); 719 720 AcpiOsPrintf ("\nNamespace node count: %u\n\n", Info.Count); 721 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 722 } 723 724 725 /******************************************************************************* 726 * 727 * FUNCTION: AcpiNsDumpOneObjectPath, AcpiNsGetMaxDepth 728 * 729 * PARAMETERS: ObjHandle - Node to be dumped 730 * Level - Nesting level of the handle 731 * Context - Passed into WalkNamespace 732 * ReturnValue - Not used 733 * 734 * RETURN: Status 735 * 736 * DESCRIPTION: Dump the full pathname to a namespace object. AcpNsGetMaxDepth 737 * computes the maximum nesting depth in the namespace tree, in 738 * order to simplify formatting in AcpiNsDumpOneObjectPath. 739 * These procedures are UserFunctions called by AcpiNsWalkNamespace. 740 * 741 ******************************************************************************/ 742 743 static ACPI_STATUS 744 AcpiNsDumpOneObjectPath ( 745 ACPI_HANDLE ObjHandle, 746 UINT32 Level, 747 void *Context, 748 void **ReturnValue) 749 { 750 UINT32 MaxLevel = *((UINT32 *) Context); 751 char *Pathname; 752 ACPI_NAMESPACE_NODE *Node; 753 int PathIndent; 754 755 756 if (!ObjHandle) 757 { 758 return (AE_OK); 759 } 760 761 Node = AcpiNsValidateHandle (ObjHandle); 762 if (!Node) 763 { 764 /* Ignore bad node during namespace walk */ 765 766 return (AE_OK); 767 } 768 769 Pathname = AcpiNsGetNormalizedPathname (Node, TRUE); 770 771 PathIndent = 1; 772 if (Level <= MaxLevel) 773 { 774 PathIndent = MaxLevel - Level + 1; 775 } 776 777 AcpiOsPrintf ("%2d%*s%-12s%*s", 778 Level, Level, " ", AcpiUtGetTypeName (Node->Type), 779 PathIndent, " "); 780 781 AcpiOsPrintf ("%s\n", &Pathname[1]); 782 ACPI_FREE (Pathname); 783 return (AE_OK); 784 } 785 786 787 static ACPI_STATUS 788 AcpiNsGetMaxDepth ( 789 ACPI_HANDLE ObjHandle, 790 UINT32 Level, 791 void *Context, 792 void **ReturnValue) 793 { 794 UINT32 *MaxLevel = (UINT32 *) Context; 795 796 797 if (Level > *MaxLevel) 798 { 799 *MaxLevel = Level; 800 } 801 return (AE_OK); 802 } 803 804 805 /******************************************************************************* 806 * 807 * FUNCTION: AcpiNsDumpObjectPaths 808 * 809 * PARAMETERS: Type - Object type to be dumped 810 * DisplayType - 0 or ACPI_DISPLAY_SUMMARY 811 * MaxDepth - Maximum depth of dump. Use ACPI_UINT32_MAX 812 * for an effectively unlimited depth. 813 * OwnerId - Dump only objects owned by this ID. Use 814 * ACPI_UINT32_MAX to match all owners. 815 * StartHandle - Where in namespace to start/end search 816 * 817 * RETURN: None 818 * 819 * DESCRIPTION: Dump full object pathnames within the loaded namespace. Uses 820 * AcpiNsWalkNamespace in conjunction with AcpiNsDumpOneObjectPath. 821 * 822 ******************************************************************************/ 823 824 void 825 AcpiNsDumpObjectPaths ( 826 ACPI_OBJECT_TYPE Type, 827 UINT8 DisplayType, 828 UINT32 MaxDepth, 829 ACPI_OWNER_ID OwnerId, 830 ACPI_HANDLE StartHandle) 831 { 832 ACPI_STATUS Status; 833 UINT32 MaxLevel = 0; 834 835 836 ACPI_FUNCTION_ENTRY (); 837 838 839 /* 840 * Just lock the entire namespace for the duration of the dump. 841 * We don't want any changes to the namespace during this time, 842 * especially the temporary nodes since we are going to display 843 * them also. 844 */ 845 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 846 if (ACPI_FAILURE (Status)) 847 { 848 AcpiOsPrintf ("Could not acquire namespace mutex\n"); 849 return; 850 } 851 852 /* Get the max depth of the namespace tree, for formatting later */ 853 854 (void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth, 855 ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES, 856 AcpiNsGetMaxDepth, NULL, (void *) &MaxLevel, NULL); 857 858 /* Now dump the entire namespace */ 859 860 (void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth, 861 ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES, 862 AcpiNsDumpOneObjectPath, NULL, (void *) &MaxLevel, NULL); 863 864 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 865 } 866 867 868 /******************************************************************************* 869 * 870 * FUNCTION: AcpiNsDumpEntry 871 * 872 * PARAMETERS: Handle - Node to be dumped 873 * DebugLevel - Output level 874 * 875 * RETURN: None 876 * 877 * DESCRIPTION: Dump a single Node 878 * 879 ******************************************************************************/ 880 881 void 882 AcpiNsDumpEntry ( 883 ACPI_HANDLE Handle, 884 UINT32 DebugLevel) 885 { 886 ACPI_WALK_INFO Info; 887 888 889 ACPI_FUNCTION_ENTRY (); 890 891 892 Info.DebugLevel = DebugLevel; 893 Info.OwnerId = ACPI_OWNER_ID_MAX; 894 Info.DisplayType = ACPI_DISPLAY_SUMMARY; 895 896 (void) AcpiNsDumpOneObject (Handle, 1, &Info, NULL); 897 } 898 899 900 #ifdef ACPI_ASL_COMPILER 901 /******************************************************************************* 902 * 903 * FUNCTION: AcpiNsDumpTables 904 * 905 * PARAMETERS: SearchBase - Root of subtree to be dumped, or 906 * NS_ALL to dump the entire namespace 907 * MaxDepth - Maximum depth of dump. Use INT_MAX 908 * for an effectively unlimited depth. 909 * 910 * RETURN: None 911 * 912 * DESCRIPTION: Dump the name space, or a portion of it. 913 * 914 ******************************************************************************/ 915 916 void 917 AcpiNsDumpTables ( 918 ACPI_HANDLE SearchBase, 919 UINT32 MaxDepth) 920 { 921 ACPI_HANDLE SearchHandle = SearchBase; 922 923 924 ACPI_FUNCTION_TRACE (NsDumpTables); 925 926 927 if (!AcpiGbl_RootNode) 928 { 929 /* 930 * If the name space has not been initialized, 931 * there is nothing to dump. 932 */ 933 ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, 934 "namespace not initialized!\n")); 935 return_VOID; 936 } 937 938 if (ACPI_NS_ALL == SearchBase) 939 { 940 /* Entire namespace */ 941 942 SearchHandle = AcpiGbl_RootNode; 943 ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "\\\n")); 944 } 945 946 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, MaxDepth, 947 ACPI_OWNER_ID_MAX, SearchHandle); 948 return_VOID; 949 } 950 #endif 951 #endif 952