]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/contrib/dev/acpica/debugger/dbstats.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / contrib / dev / acpica / debugger / dbstats.c
1 /*******************************************************************************
2  *
3  * Module Name: dbstats - Generation and display of ACPI table statistics
4  *
5  ******************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2011, 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 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.SystemNotify);
231         AcpiDbEnumerateObject (ObjDesc->Device.DeviceNotify);
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.SystemNotify);
252         AcpiDbEnumerateObject (ObjDesc->PowerResource.DeviceNotify);
253         break;
254
255     case ACPI_TYPE_PROCESSOR:
256
257         AcpiDbEnumerateObject (ObjDesc->Processor.SystemNotify);
258         AcpiDbEnumerateObject (ObjDesc->Processor.DeviceNotify);
259         AcpiDbEnumerateObject (ObjDesc->Processor.Handler);
260         break;
261
262     case ACPI_TYPE_THERMAL:
263
264         AcpiDbEnumerateObject (ObjDesc->ThermalZone.SystemNotify);
265         AcpiDbEnumerateObject (ObjDesc->ThermalZone.DeviceNotify);
266         AcpiDbEnumerateObject (ObjDesc->ThermalZone.Handler);
267         break;
268
269     default:
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     if (!TypeArg)
402     {
403         AcpiOsPrintf ("The following subcommands are available:\n    ALLOCATIONS, OBJECTS, MEMORY, MISC, SIZES, TABLES\n");
404         return (AE_OK);
405     }
406
407     AcpiUtStrupr (TypeArg);
408     Temp = AcpiDbMatchArgument (TypeArg, AcpiDbStatTypes);
409     if (Temp == (UINT32) -1)
410     {
411         AcpiOsPrintf ("Invalid or unsupported argument\n");
412         return (AE_OK);
413     }
414
415
416     switch (Temp)
417     {
418     case CMD_STAT_ALLOCATIONS:
419
420 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
421         AcpiUtDumpAllocationInfo ();
422 #endif
423         break;
424
425     case CMD_STAT_TABLES:
426
427         AcpiOsPrintf ("ACPI Table Information (not implemented):\n\n");
428         break;
429
430     case CMD_STAT_OBJECTS:
431
432         AcpiDbCountNamespaceObjects ();
433
434         AcpiOsPrintf ("\nObjects defined in the current namespace:\n\n");
435
436         AcpiOsPrintf ("%16.16s %10.10s %10.10s\n",
437             "ACPI_TYPE", "NODES", "OBJECTS");
438
439         for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++)
440         {
441             AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", AcpiUtGetTypeName (i),
442                 AcpiGbl_NodeTypeCount [i], AcpiGbl_ObjTypeCount [i]);
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
489     case CMD_STAT_SIZES:
490
491         AcpiOsPrintf ("\nInternal object sizes:\n\n");
492
493         AcpiOsPrintf ("Common           %3d\n", sizeof (ACPI_OBJECT_COMMON));
494         AcpiOsPrintf ("Number           %3d\n", sizeof (ACPI_OBJECT_INTEGER));
495         AcpiOsPrintf ("String           %3d\n", sizeof (ACPI_OBJECT_STRING));
496         AcpiOsPrintf ("Buffer           %3d\n", sizeof (ACPI_OBJECT_BUFFER));
497         AcpiOsPrintf ("Package          %3d\n", sizeof (ACPI_OBJECT_PACKAGE));
498         AcpiOsPrintf ("BufferField      %3d\n", sizeof (ACPI_OBJECT_BUFFER_FIELD));
499         AcpiOsPrintf ("Device           %3d\n", sizeof (ACPI_OBJECT_DEVICE));
500         AcpiOsPrintf ("Event            %3d\n", sizeof (ACPI_OBJECT_EVENT));
501         AcpiOsPrintf ("Method           %3d\n", sizeof (ACPI_OBJECT_METHOD));
502         AcpiOsPrintf ("Mutex            %3d\n", sizeof (ACPI_OBJECT_MUTEX));
503         AcpiOsPrintf ("Region           %3d\n", sizeof (ACPI_OBJECT_REGION));
504         AcpiOsPrintf ("PowerResource    %3d\n", sizeof (ACPI_OBJECT_POWER_RESOURCE));
505         AcpiOsPrintf ("Processor        %3d\n", sizeof (ACPI_OBJECT_PROCESSOR));
506         AcpiOsPrintf ("ThermalZone      %3d\n", sizeof (ACPI_OBJECT_THERMAL_ZONE));
507         AcpiOsPrintf ("RegionField      %3d\n", sizeof (ACPI_OBJECT_REGION_FIELD));
508         AcpiOsPrintf ("BankField        %3d\n", sizeof (ACPI_OBJECT_BANK_FIELD));
509         AcpiOsPrintf ("IndexField       %3d\n", sizeof (ACPI_OBJECT_INDEX_FIELD));
510         AcpiOsPrintf ("Reference        %3d\n", sizeof (ACPI_OBJECT_REFERENCE));
511         AcpiOsPrintf ("Notify           %3d\n", sizeof (ACPI_OBJECT_NOTIFY_HANDLER));
512         AcpiOsPrintf ("AddressSpace     %3d\n", sizeof (ACPI_OBJECT_ADDR_HANDLER));
513         AcpiOsPrintf ("Extra            %3d\n", sizeof (ACPI_OBJECT_EXTRA));
514         AcpiOsPrintf ("Data             %3d\n", sizeof (ACPI_OBJECT_DATA));
515
516         AcpiOsPrintf ("\n");
517
518         AcpiOsPrintf ("ParseObject      %3d\n", sizeof (ACPI_PARSE_OBJ_COMMON));
519         AcpiOsPrintf ("ParseObjectNamed %3d\n", sizeof (ACPI_PARSE_OBJ_NAMED));
520         AcpiOsPrintf ("ParseObjectAsl   %3d\n", sizeof (ACPI_PARSE_OBJ_ASL));
521         AcpiOsPrintf ("OperandObject    %3d\n", sizeof (ACPI_OPERAND_OBJECT));
522         AcpiOsPrintf ("NamespaceNode    %3d\n", sizeof (ACPI_NAMESPACE_NODE));
523         AcpiOsPrintf ("AcpiObject       %3d\n", sizeof (ACPI_OBJECT));
524
525         break;
526
527
528     case CMD_STAT_STACK:
529 #if defined(ACPI_DEBUG_OUTPUT)
530
531         Temp = (UINT32) ACPI_PTR_DIFF (AcpiGbl_EntryStackPointer, AcpiGbl_LowestStackPointer);
532
533         AcpiOsPrintf ("\nSubsystem Stack Usage:\n\n");
534         AcpiOsPrintf ("Entry Stack Pointer          %p\n", AcpiGbl_EntryStackPointer);
535         AcpiOsPrintf ("Lowest Stack Pointer         %p\n", AcpiGbl_LowestStackPointer);
536         AcpiOsPrintf ("Stack Use                    %X (%u)\n", Temp, Temp);
537         AcpiOsPrintf ("Deepest Procedure Nesting    %u\n", AcpiGbl_DeepestNesting);
538 #endif
539         break;
540
541     default:
542         break;
543     }
544
545     AcpiOsPrintf ("\n");
546     return (AE_OK);
547 }
548
549 #endif /* ACPI_DEBUGGER  */