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