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