Sync ACPICA with Intel's version 20140828.
[dragonfly.git] / sys / contrib / dev / acpica / source / components / debugger / dbstats.c
1 /*******************************************************************************
2  *
3  * Module Name: dbstats - Generation and display of ACPI table statistics
4  *
5  ******************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2014, 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  */