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