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