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