Home | History | Annotate | Line # | Download | only in debugger
dbstats.c revision 1.1.1.5
      1 /*******************************************************************************
      2  *
      3  * Module Name: dbstats - Generation and display of ACPI table statistics
      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 "acpi.h"
     45 #include "accommon.h"
     46 #include "acdebug.h"
     47 #include "acnamesp.h"
     48 
     49 #ifdef ACPI_DEBUGGER
     50 
     51 #define _COMPONENT          ACPI_CA_DEBUGGER
     52         ACPI_MODULE_NAME    ("dbstats")
     53 
     54 /* Local prototypes */
     55 
     56 static void
     57 AcpiDbCountNamespaceObjects (
     58     void);
     59 
     60 static void
     61 AcpiDbEnumerateObject (
     62     ACPI_OPERAND_OBJECT     *ObjDesc);
     63 
     64 static ACPI_STATUS
     65 AcpiDbClassifyOneObject (
     66     ACPI_HANDLE             ObjHandle,
     67     UINT32                  NestingLevel,
     68     void                    *Context,
     69     void                    **ReturnValue);
     70 
     71 #if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
     72 static void
     73 AcpiDbListInfo (
     74     ACPI_MEMORY_LIST        *List);
     75 #endif
     76 
     77 
     78 /*
     79  * Statistics subcommands
     80  */
     81 static ACPI_DB_ARGUMENT_INFO    AcpiDbStatTypes [] =
     82 {
     83     {"ALLOCATIONS"},
     84     {"OBJECTS"},
     85     {"MEMORY"},
     86     {"MISC"},
     87     {"TABLES"},
     88     {"SIZES"},
     89     {"STACK"},
     90     {NULL}           /* Must be null terminated */
     91 };
     92 
     93 #define CMD_STAT_ALLOCATIONS     0
     94 #define CMD_STAT_OBJECTS         1
     95 #define CMD_STAT_MEMORY          2
     96 #define CMD_STAT_MISC            3
     97 #define CMD_STAT_TABLES          4
     98 #define CMD_STAT_SIZES           5
     99 #define CMD_STAT_STACK           6
    100 
    101 
    102 #if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
    103 /*******************************************************************************
    104  *
    105  * FUNCTION:    AcpiDbListInfo
    106  *
    107  * PARAMETERS:  List            - Memory list/cache to be displayed
    108  *
    109  * RETURN:      None
    110  *
    111  * DESCRIPTION: Display information about the input memory list or cache.
    112  *
    113  ******************************************************************************/
    114 
    115 static void
    116 AcpiDbListInfo (
    117     ACPI_MEMORY_LIST        *List)
    118 {
    119 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
    120     UINT32                  Outstanding;
    121 #endif
    122 
    123     AcpiOsPrintf ("\n%s\n", List->ListName);
    124 
    125     /* MaxDepth > 0 indicates a cache object */
    126 
    127     if (List->MaxDepth > 0)
    128     {
    129         AcpiOsPrintf (
    130             "    Cache: [Depth    MaxD Avail  Size]                %8.2X %8.2X %8.2X %8.2X\n",
    131             List->CurrentDepth,
    132             List->MaxDepth,
    133             List->MaxDepth - List->CurrentDepth,
    134             (List->CurrentDepth * List->ObjectSize));
    135     }
    136 
    137 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
    138     if (List->MaxDepth > 0)
    139     {
    140         AcpiOsPrintf (
    141             "    Cache: [Requests Hits Misses ObjSize]             %8.2X %8.2X %8.2X %8.2X\n",
    142             List->Requests,
    143             List->Hits,
    144             List->Requests - List->Hits,
    145             List->ObjectSize);
    146     }
    147 
    148     Outstanding = AcpiDbGetCacheInfo (List);
    149 
    150     if (List->ObjectSize)
    151     {
    152         AcpiOsPrintf (
    153             "    Mem:   [Alloc    Free Max    CurSize Outstanding] %8.2X %8.2X %8.2X %8.2X %8.2X\n",
    154             List->TotalAllocated,
    155             List->TotalFreed,
    156             List->MaxOccupied,
    157             Outstanding * List->ObjectSize,
    158             Outstanding);
    159     }
    160     else
    161     {
    162         AcpiOsPrintf (
    163             "    Mem:   [Alloc Free Max CurSize Outstanding Total] %8.2X %8.2X %8.2X %8.2X %8.2X %8.2X\n",
    164             List->TotalAllocated,
    165             List->TotalFreed,
    166             List->MaxOccupied,
    167             List->CurrentTotalSize,
    168             Outstanding,
    169             List->TotalSize);
    170     }
    171 #endif
    172 }
    173 #endif
    174 
    175 
    176 /*******************************************************************************
    177  *
    178  * FUNCTION:    AcpiDbEnumerateObject
    179  *
    180  * PARAMETERS:  ObjDesc             - Object to be counted
    181  *
    182  * RETURN:      None
    183  *
    184  * DESCRIPTION: Add this object to the global counts, by object type.
    185  *              Limited recursion handles subobjects and packages, and this
    186  *              is probably acceptable within the AML debugger only.
    187  *
    188  ******************************************************************************/
    189 
    190 static void
    191 AcpiDbEnumerateObject (
    192     ACPI_OPERAND_OBJECT     *ObjDesc)
    193 {
    194     UINT32                  i;
    195 
    196 
    197     if (!ObjDesc)
    198     {
    199         return;
    200     }
    201 
    202     /* Enumerate this object first */
    203 
    204     AcpiGbl_NumObjects++;
    205 
    206     if (ObjDesc->Common.Type > ACPI_TYPE_NS_NODE_MAX)
    207     {
    208         AcpiGbl_ObjTypeCountMisc++;
    209     }
    210     else
    211     {
    212         AcpiGbl_ObjTypeCount [ObjDesc->Common.Type]++;
    213     }
    214 
    215     /* Count the sub-objects */
    216 
    217     switch (ObjDesc->Common.Type)
    218     {
    219     case ACPI_TYPE_PACKAGE:
    220 
    221         for (i = 0; i < ObjDesc->Package.Count; i++)
    222         {
    223             AcpiDbEnumerateObject (ObjDesc->Package.Elements[i]);
    224         }
    225         break;
    226 
    227     case ACPI_TYPE_DEVICE:
    228 
    229         AcpiDbEnumerateObject (ObjDesc->Device.NotifyList[0]);
    230         AcpiDbEnumerateObject (ObjDesc->Device.NotifyList[1]);
    231         AcpiDbEnumerateObject (ObjDesc->Device.Handler);
    232         break;
    233 
    234     case ACPI_TYPE_BUFFER_FIELD:
    235 
    236         if (AcpiNsGetSecondaryObject (ObjDesc))
    237         {
    238             AcpiGbl_ObjTypeCount [ACPI_TYPE_BUFFER_FIELD]++;
    239         }
    240         break;
    241 
    242     case ACPI_TYPE_REGION:
    243 
    244         AcpiGbl_ObjTypeCount [ACPI_TYPE_LOCAL_REGION_FIELD ]++;
    245         AcpiDbEnumerateObject (ObjDesc->Region.Handler);
    246         break;
    247 
    248     case ACPI_TYPE_POWER:
    249 
    250         AcpiDbEnumerateObject (ObjDesc->PowerResource.NotifyList[0]);
    251         AcpiDbEnumerateObject (ObjDesc->PowerResource.NotifyList[1]);
    252         break;
    253 
    254     case ACPI_TYPE_PROCESSOR:
    255 
    256         AcpiDbEnumerateObject (ObjDesc->Processor.NotifyList[0]);
    257         AcpiDbEnumerateObject (ObjDesc->Processor.NotifyList[1]);
    258         AcpiDbEnumerateObject (ObjDesc->Processor.Handler);
    259         break;
    260 
    261     case ACPI_TYPE_THERMAL:
    262 
    263         AcpiDbEnumerateObject (ObjDesc->ThermalZone.NotifyList[0]);
    264         AcpiDbEnumerateObject (ObjDesc->ThermalZone.NotifyList[1]);
    265         AcpiDbEnumerateObject (ObjDesc->ThermalZone.Handler);
    266         break;
    267 
    268     default:
    269 
    270         break;
    271     }
    272 }
    273 
    274 
    275 /*******************************************************************************
    276  *
    277  * FUNCTION:    AcpiDbClassifyOneObject
    278  *
    279  * PARAMETERS:  Callback for WalkNamespace
    280  *
    281  * RETURN:      Status
    282  *
    283  * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and
    284  *              the parent namespace node.
    285  *
    286  ******************************************************************************/
    287 
    288 static ACPI_STATUS
    289 AcpiDbClassifyOneObject (
    290     ACPI_HANDLE             ObjHandle,
    291     UINT32                  NestingLevel,
    292     void                    *Context,
    293     void                    **ReturnValue)
    294 {
    295     ACPI_NAMESPACE_NODE     *Node;
    296     ACPI_OPERAND_OBJECT     *ObjDesc;
    297     UINT32                  Type;
    298 
    299 
    300     AcpiGbl_NumNodes++;
    301 
    302     Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    303     ObjDesc = AcpiNsGetAttachedObject (Node);
    304 
    305     AcpiDbEnumerateObject (ObjDesc);
    306 
    307     Type = Node->Type;
    308     if (Type > ACPI_TYPE_NS_NODE_MAX)
    309     {
    310         AcpiGbl_NodeTypeCountMisc++;
    311     }
    312     else
    313     {
    314         AcpiGbl_NodeTypeCount [Type]++;
    315     }
    316 
    317     return (AE_OK);
    318 
    319 
    320 #ifdef ACPI_FUTURE_IMPLEMENTATION
    321 
    322     /* TBD: These need to be counted during the initial parsing phase */
    323 
    324     if (AcpiPsIsNamedOp (Op->Opcode))
    325     {
    326         NumNodes++;
    327     }
    328 
    329     if (IsMethod)
    330     {
    331         NumMethodElements++;
    332     }
    333 
    334     NumGrammarElements++;
    335     Op = AcpiPsGetDepthNext (Root, Op);
    336 
    337     SizeOfParseTree   = (NumGrammarElements - NumMethodElements) *
    338                             (UINT32) sizeof (ACPI_PARSE_OBJECT);
    339     SizeOfMethodTrees = NumMethodElements * (UINT32) sizeof (ACPI_PARSE_OBJECT);
    340     SizeOfNodeEntries = NumNodes * (UINT32) sizeof (ACPI_NAMESPACE_NODE);
    341     SizeOfAcpiObjects = NumNodes * (UINT32) sizeof (ACPI_OPERAND_OBJECT);
    342 #endif
    343 }
    344 
    345 
    346 /*******************************************************************************
    347  *
    348  * FUNCTION:    AcpiDbCountNamespaceObjects
    349  *
    350  * PARAMETERS:  None
    351  *
    352  * RETURN:      None
    353  *
    354  * DESCRIPTION: Count and classify the entire namespace, including all
    355  *              namespace nodes and attached objects.
    356  *
    357  ******************************************************************************/
    358 
    359 static void
    360 AcpiDbCountNamespaceObjects (
    361     void)
    362 {
    363     UINT32                  i;
    364 
    365 
    366     AcpiGbl_NumNodes = 0;
    367     AcpiGbl_NumObjects = 0;
    368 
    369     AcpiGbl_ObjTypeCountMisc = 0;
    370     for (i = 0; i < (ACPI_TYPE_NS_NODE_MAX -1); i++)
    371     {
    372         AcpiGbl_ObjTypeCount [i] = 0;
    373         AcpiGbl_NodeTypeCount [i] = 0;
    374     }
    375 
    376     (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    377                 ACPI_UINT32_MAX, FALSE, AcpiDbClassifyOneObject, NULL, NULL, NULL);
    378 }
    379 
    380 
    381 /*******************************************************************************
    382  *
    383  * FUNCTION:    AcpiDbDisplayStatistics
    384  *
    385  * PARAMETERS:  TypeArg         - Subcommand
    386  *
    387  * RETURN:      Status
    388  *
    389  * DESCRIPTION: Display various statistics
    390  *
    391  ******************************************************************************/
    392 
    393 ACPI_STATUS
    394 AcpiDbDisplayStatistics (
    395     char                    *TypeArg)
    396 {
    397     UINT32                  i;
    398     UINT32                  Temp;
    399 
    400 
    401     AcpiUtStrupr (TypeArg);
    402     Temp = AcpiDbMatchArgument (TypeArg, AcpiDbStatTypes);
    403     if (Temp == ACPI_TYPE_NOT_FOUND)
    404     {
    405         AcpiOsPrintf ("Invalid or unsupported argument\n");
    406         return (AE_OK);
    407     }
    408 
    409 
    410     switch (Temp)
    411     {
    412     case CMD_STAT_ALLOCATIONS:
    413 
    414 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
    415         AcpiUtDumpAllocationInfo ();
    416 #endif
    417         break;
    418 
    419     case CMD_STAT_TABLES:
    420 
    421         AcpiOsPrintf ("ACPI Table Information (not implemented):\n\n");
    422         break;
    423 
    424     case CMD_STAT_OBJECTS:
    425 
    426         AcpiDbCountNamespaceObjects ();
    427 
    428         AcpiOsPrintf ("\nObjects defined in the current namespace:\n\n");
    429 
    430         AcpiOsPrintf ("%16.16s %10.10s %10.10s\n",
    431             "ACPI_TYPE", "NODES", "OBJECTS");
    432 
    433         for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++)
    434         {
    435             AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", AcpiUtGetTypeName (i),
    436                 AcpiGbl_NodeTypeCount [i], AcpiGbl_ObjTypeCount [i]);
    437         }
    438         AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "Misc/Unknown",
    439             AcpiGbl_NodeTypeCountMisc, AcpiGbl_ObjTypeCountMisc);
    440 
    441         AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "TOTALS:",
    442             AcpiGbl_NumNodes, AcpiGbl_NumObjects);
    443         break;
    444 
    445     case CMD_STAT_MEMORY:
    446 
    447 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
    448         AcpiOsPrintf ("\n----Object Statistics (all in hex)---------\n");
    449 
    450         AcpiDbListInfo (AcpiGbl_GlobalList);
    451         AcpiDbListInfo (AcpiGbl_NsNodeList);
    452 #endif
    453 
    454 #ifdef ACPI_USE_LOCAL_CACHE
    455         AcpiOsPrintf ("\n----Cache Statistics (all in hex)---------\n");
    456         AcpiDbListInfo (AcpiGbl_OperandCache);
    457         AcpiDbListInfo (AcpiGbl_PsNodeCache);
    458         AcpiDbListInfo (AcpiGbl_PsNodeExtCache);
    459         AcpiDbListInfo (AcpiGbl_StateCache);
    460 #endif
    461 
    462         break;
    463 
    464     case CMD_STAT_MISC:
    465 
    466         AcpiOsPrintf ("\nMiscellaneous Statistics:\n\n");
    467         AcpiOsPrintf ("Calls to AcpiPsFind:..  ........% 7ld\n",
    468             AcpiGbl_PsFindCount);
    469         AcpiOsPrintf ("Calls to AcpiNsLookup:..........% 7ld\n",
    470             AcpiGbl_NsLookupCount);
    471 
    472         AcpiOsPrintf ("\n");
    473 
    474         AcpiOsPrintf ("Mutex usage:\n\n");
    475         for (i = 0; i < ACPI_NUM_MUTEX; i++)
    476         {
    477             AcpiOsPrintf ("%-28s:       % 7ld\n",
    478                 AcpiUtGetMutexName (i), AcpiGbl_MutexInfo[i].UseCount);
    479         }
    480         break;
    481 
    482     case CMD_STAT_SIZES:
    483 
    484         AcpiOsPrintf ("\nInternal object sizes:\n\n");
    485 
    486         AcpiOsPrintf ("Common           %3d\n", sizeof (ACPI_OBJECT_COMMON));
    487         AcpiOsPrintf ("Number           %3d\n", sizeof (ACPI_OBJECT_INTEGER));
    488         AcpiOsPrintf ("String           %3d\n", sizeof (ACPI_OBJECT_STRING));
    489         AcpiOsPrintf ("Buffer           %3d\n", sizeof (ACPI_OBJECT_BUFFER));
    490         AcpiOsPrintf ("Package          %3d\n", sizeof (ACPI_OBJECT_PACKAGE));
    491         AcpiOsPrintf ("BufferField      %3d\n", sizeof (ACPI_OBJECT_BUFFER_FIELD));
    492         AcpiOsPrintf ("Device           %3d\n", sizeof (ACPI_OBJECT_DEVICE));
    493         AcpiOsPrintf ("Event            %3d\n", sizeof (ACPI_OBJECT_EVENT));
    494         AcpiOsPrintf ("Method           %3d\n", sizeof (ACPI_OBJECT_METHOD));
    495         AcpiOsPrintf ("Mutex            %3d\n", sizeof (ACPI_OBJECT_MUTEX));
    496         AcpiOsPrintf ("Region           %3d\n", sizeof (ACPI_OBJECT_REGION));
    497         AcpiOsPrintf ("PowerResource    %3d\n", sizeof (ACPI_OBJECT_POWER_RESOURCE));
    498         AcpiOsPrintf ("Processor        %3d\n", sizeof (ACPI_OBJECT_PROCESSOR));
    499         AcpiOsPrintf ("ThermalZone      %3d\n", sizeof (ACPI_OBJECT_THERMAL_ZONE));
    500         AcpiOsPrintf ("RegionField      %3d\n", sizeof (ACPI_OBJECT_REGION_FIELD));
    501         AcpiOsPrintf ("BankField        %3d\n", sizeof (ACPI_OBJECT_BANK_FIELD));
    502         AcpiOsPrintf ("IndexField       %3d\n", sizeof (ACPI_OBJECT_INDEX_FIELD));
    503         AcpiOsPrintf ("Reference        %3d\n", sizeof (ACPI_OBJECT_REFERENCE));
    504         AcpiOsPrintf ("Notify           %3d\n", sizeof (ACPI_OBJECT_NOTIFY_HANDLER));
    505         AcpiOsPrintf ("AddressSpace     %3d\n", sizeof (ACPI_OBJECT_ADDR_HANDLER));
    506         AcpiOsPrintf ("Extra            %3d\n", sizeof (ACPI_OBJECT_EXTRA));
    507         AcpiOsPrintf ("Data             %3d\n", sizeof (ACPI_OBJECT_DATA));
    508 
    509         AcpiOsPrintf ("\n");
    510 
    511         AcpiOsPrintf ("ParseObject      %3d\n", sizeof (ACPI_PARSE_OBJ_COMMON));
    512         AcpiOsPrintf ("ParseObjectNamed %3d\n", sizeof (ACPI_PARSE_OBJ_NAMED));
    513         AcpiOsPrintf ("ParseObjectAsl   %3d\n", sizeof (ACPI_PARSE_OBJ_ASL));
    514         AcpiOsPrintf ("OperandObject    %3d\n", sizeof (ACPI_OPERAND_OBJECT));
    515         AcpiOsPrintf ("NamespaceNode    %3d\n", sizeof (ACPI_NAMESPACE_NODE));
    516         AcpiOsPrintf ("AcpiObject       %3d\n", sizeof (ACPI_OBJECT));
    517 
    518         AcpiOsPrintf ("\n");
    519 
    520         AcpiOsPrintf ("Generic State    %3d\n", sizeof (ACPI_GENERIC_STATE));
    521         AcpiOsPrintf ("Common State     %3d\n", sizeof (ACPI_COMMON_STATE));
    522         AcpiOsPrintf ("Control State    %3d\n", sizeof (ACPI_CONTROL_STATE));
    523         AcpiOsPrintf ("Update State     %3d\n", sizeof (ACPI_UPDATE_STATE));
    524         AcpiOsPrintf ("Scope State      %3d\n", sizeof (ACPI_SCOPE_STATE));
    525         AcpiOsPrintf ("Parse Scope      %3d\n", sizeof (ACPI_PSCOPE_STATE));
    526         AcpiOsPrintf ("Package State    %3d\n", sizeof (ACPI_PKG_STATE));
    527         AcpiOsPrintf ("Thread State     %3d\n", sizeof (ACPI_THREAD_STATE));
    528         AcpiOsPrintf ("Result Values    %3d\n", sizeof (ACPI_RESULT_VALUES));
    529         AcpiOsPrintf ("Notify Info      %3d\n", sizeof (ACPI_NOTIFY_INFO));
    530         break;
    531 
    532     case CMD_STAT_STACK:
    533 #if defined(ACPI_DEBUG_OUTPUT)
    534 
    535         Temp = (UINT32) ACPI_PTR_DIFF (AcpiGbl_EntryStackPointer, AcpiGbl_LowestStackPointer);
    536 
    537         AcpiOsPrintf ("\nSubsystem Stack Usage:\n\n");
    538         AcpiOsPrintf ("Entry Stack Pointer          %p\n", AcpiGbl_EntryStackPointer);
    539         AcpiOsPrintf ("Lowest Stack Pointer         %p\n", AcpiGbl_LowestStackPointer);
    540         AcpiOsPrintf ("Stack Use                    %X (%u)\n", Temp, Temp);
    541         AcpiOsPrintf ("Deepest Procedure Nesting    %u\n", AcpiGbl_DeepestNesting);
    542 #endif
    543         break;
    544 
    545     default:
    546 
    547         break;
    548     }
    549 
    550     AcpiOsPrintf ("\n");
    551     return (AE_OK);
    552 }
    553 
    554 #endif /* ACPI_DEBUGGER  */
    555