1/******************************************************************************
2 *
3 *  Copyright (C) 1999-2012 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19#include "gki_int.h"
20
21#if (GKI_DEBUG == TRUE)
22
23const INT8 * const OSTaskStates[] =
24{
25    (INT8 *)"DEAD",  /* 0 */
26    (INT8 *)"REDY",  /* 1 */
27    (INT8 *)"WAIT",  /* 2 */
28    (INT8 *)"",
29    (INT8 *)"DELY",  /* 4 */
30    (INT8 *)"",
31    (INT8 *)"",
32    (INT8 *)"",
33    (INT8 *)"SUSP",  /* 8 */
34};
35
36
37/*******************************************************************************
38**
39** Function         GKI_PrintBufferUsage
40**
41** Description      Displays Current Buffer Pool summary
42**
43** Returns          void
44**
45*******************************************************************************/
46void GKI_PrintBufferUsage(UINT8 *p_num_pools, UINT16 *p_cur_used)
47{
48    int i;
49    FREE_QUEUE_T    *p;
50    UINT8   num = gki_cb.com.curr_total_no_of_pools;
51    UINT16   cur[GKI_NUM_TOTAL_BUF_POOLS];
52
53    GKI_TRACE("");
54    GKI_TRACE("--- GKI Buffer Pool Summary (R - restricted, P - public) ---");
55
56    GKI_TRACE("POOL     SIZE  USED  MAXU  TOTAL");
57    GKI_TRACE("------------------------------");
58    for (i = 0; i < gki_cb.com.curr_total_no_of_pools; i++)
59    {
60        p = &gki_cb.com.freeq[i];
61        if ((1 << i) & gki_cb.com.pool_access_mask)
62        {
63            GKI_TRACE("%02d: (R), %4d, %3d, %3d, %3d",
64                        i, p->size, p->cur_cnt, p->max_cnt, p->total);
65        }
66        else
67        {
68            GKI_TRACE("%02d: (P), %4d, %3d, %3d, %3d",
69                        i, p->size, p->cur_cnt, p->max_cnt, p->total);
70        }
71        cur[i] = p->cur_cnt;
72    }
73    if (p_num_pools)
74        *p_num_pools = num;
75    if (p_cur_used)
76        memcpy(p_cur_used, cur, num*2);
77}
78
79/*******************************************************************************
80**
81** Function         GKI_PrintBuffer
82**
83** Description      Called internally by OSS to print the buffer pools
84**
85** Returns          void
86**
87*******************************************************************************/
88void GKI_PrintBuffer(void)
89{
90    UINT16 i;
91    for(i=0; i<GKI_NUM_TOTAL_BUF_POOLS; i++)
92	{
93		GKI_TRACE("pool:%4u free %4u cur %3u max %3u  total%3u", i, gki_cb.com.freeq[i].size,
94                    gki_cb.com.freeq[i].cur_cnt, gki_cb.com.freeq[i].max_cnt, gki_cb.com.freeq[i].total);
95    }
96}
97
98/*******************************************************************************
99**
100** Function         gki_calc_stack
101**
102** Description      This function tries to calculate the amount of
103**                  stack used by looking non magic num. Magic num is consider
104**                  the first byte in the stack.
105**
106** Returns          the number of unused byte on the stack. 4 in case of stack overrun
107**
108*******************************************************************************/
109UINT16 gki_calc_stack (UINT8 task)
110{
111    int    j, stacksize;
112    UINT32 MagicNum;
113    UINT32 *p;
114
115    stacksize = (int) gki_cb.com.OSStackSize[task];
116    p = (UINT32 *)gki_cb.com.OSStack[task]; /* assume stack is aligned, */
117    MagicNum = *p;
118
119    for(j = 0; j < stacksize; j++)
120    {
121        if(*p++ != MagicNum) break;
122    }
123
124    return (j * sizeof(UINT32));
125}
126
127/*******************************************************************************
128**
129** Function         GKI_print_task
130**
131** Description      Print task stack usage.
132**
133** Returns          void
134**
135*******************************************************************************/
136void GKI_print_task(void)
137{
138#ifdef _BT_WIN32
139	GKI_TRACE("Service not available under insight");
140#else
141    UINT8 TaskId;
142
143	GKI_TRACE("TID TASKNAME STATE FREE_STACK  STACK");
144	for(TaskId=0; TaskId < GKI_MAX_TASKS; TaskId++)
145	{
146		if (gki_cb.com.OSRdyTbl[TaskId] != TASK_DEAD)
147		{
148			GKI_TRACE("%2u   %-8s %-5s  0x%04X     0x%04X Bytes",
149				(UINT16)TaskId,  gki_cb.com.OSTName[TaskId],
150				OSTaskStates[gki_cb.com.OSRdyTbl[TaskId]],
151                gki_calc_stack(TaskId), gki_cb.com.OSStackSize[TaskId]);
152
153        }
154    }
155#endif
156}
157
158
159/*******************************************************************************
160**
161** Function         gki_print_buffer_statistics
162**
163** Description      Called internally by OSS to print the buffer pools statistics
164**
165** Returns          void
166**
167*******************************************************************************/
168void gki_print_buffer_statistics(FP_PRINT print, INT16 pool)
169{
170    UINT16           i;
171    BUFFER_HDR_T    *hdr;
172    UINT16           size,act_size,maxbuffs;
173    UINT32           *magic;
174
175    if (pool > GKI_NUM_TOTAL_BUF_POOLS || pool < 0)
176    {
177        print("Not a valid Buffer pool\n");
178        return;
179    }
180
181    size = gki_cb.com.freeq[pool].size;
182    maxbuffs = gki_cb.com.freeq[pool].total;
183    act_size = size + BUFFER_PADDING_SIZE;
184    print("Buffer Pool[%u] size=%u cur_cnt=%u max_cnt=%u  total=%u\n",
185        pool, gki_cb.com.freeq[pool].size,
186        gki_cb.com.freeq[pool].cur_cnt, gki_cb.com.freeq[pool].max_cnt, gki_cb.com.freeq[pool].total);
187
188    print("      Owner  State    Sanity\n");
189    print("----------------------------\n");
190    hdr = (BUFFER_HDR_T *)(gki_cb.com.pool_start[pool]);
191    for(i=0; i<maxbuffs; i++)
192    {
193        magic = (UINT32 *)((UINT8 *)hdr + BUFFER_HDR_SIZE + size);
194        print("%3d: 0x%02x %4d %10s\n", i, hdr->task_id, hdr->status, (*magic == MAGIC_NO)?"OK":"CORRUPTED");
195        hdr          = (BUFFER_HDR_T *)((UINT8 *)hdr + act_size);
196    }
197    return;
198}
199
200
201/*******************************************************************************
202**
203** Function         gki_print_used_bufs
204**
205** Description      Dumps used buffers in the particular pool
206**
207*******************************************************************************/
208GKI_API void gki_print_used_bufs (FP_PRINT print, UINT8 pool_id)
209{
210    UINT8        *p_start;
211    UINT16       buf_size;
212    UINT16       num_bufs;
213    BUFFER_HDR_T *p_hdr;
214    UINT16       i;
215    UINT32         *magic;
216    UINT16       *p;
217
218
219    if ((pool_id >= GKI_NUM_TOTAL_BUF_POOLS) || (gki_cb.com.pool_start[pool_id] != 0))
220    {
221        print("Not a valid Buffer pool\n");
222        return;
223    }
224
225    p_start = gki_cb.com.pool_start[pool_id];
226    buf_size = gki_cb.com.freeq[pool_id].size + BUFFER_PADDING_SIZE;
227    num_bufs = gki_cb.com.freeq[pool_id].total;
228
229    for (i = 0; i < num_bufs; i++, p_start += buf_size)
230    {
231        p_hdr = (BUFFER_HDR_T *)p_start;
232        magic = (UINT32 *)((UINT8 *)p_hdr + buf_size - sizeof(UINT32));
233        p     = (UINT16 *) p_hdr;
234
235        if (p_hdr->status != BUF_STATUS_FREE)
236        {
237            print ("%d:0x%x (Q:%d,Task:%s,Stat:%d,%s) %04x %04x %04x %04x %04x %04x %04x %04x\n",
238                i, p_hdr,
239                p_hdr->q_id,
240                GKI_map_taskname(p_hdr->task_id),
241                p_hdr->status,
242                (*magic == MAGIC_NO)? "OK" : "CORRUPTED",
243                p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
244        }
245    }
246}
247
248
249/*******************************************************************************
250**
251** Function         gki_print_task
252**
253** Description      This function prints the task states.
254**
255** Returns          void
256**
257*******************************************************************************/
258void gki_print_task (FP_PRINT print)
259{
260    UINT8 i;
261
262    print("TID VID TASKNAME STATE WAIT WAITFOR TIMEOUT STACK\n");
263    print("-------------------------------------------------\n");
264    for(i=0; i<GKI_MAX_TASKS; i++)
265    {
266        if (gki_cb.com.OSRdyTbl[i] != TASK_DEAD)
267        {
268            print("%2u  %-8s %-5s %04X    %04X %7u %u/%u Bytes\n",
269                (UINT16)i,  gki_cb.com.OSTName[i],
270                OSTaskStates[gki_cb.com.OSRdyTbl[i]],
271                gki_cb.com.OSWaitEvt[i], gki_cb.com.OSWaitForEvt[i],
272                gki_cb.com.OSWaitTmr[i], gki_calc_stack(i), gki_cb.com.OSStackSize[i]);
273        }
274    }
275}
276
277
278/*******************************************************************************
279**
280** Function         gki_print_exception
281**
282** Description      This function prints the exception information.
283**
284** Returns          void
285**
286*******************************************************************************/
287void gki_print_exception(FP_PRINT print)
288{
289    UINT16 i;
290    EXCEPTION_T *pExp;
291
292    print ("GKI Exceptions:\n");
293    for (i = 0; i < gki_cb.com.ExceptionCnt; i++)
294    {
295        pExp =     &gki_cb.com.Exception[i];
296        print("%d: Type=%d, Task=%d: %s\n", i,
297            (INT32)pExp->type, (INT32)pExp->taskid, (INT8 *)pExp->msg);
298    }
299}
300
301
302/*****************************************************************************/
303void gki_dump (UINT8 *s, UINT16 len, FP_PRINT print)
304{
305    UINT16 i, j;
306
307    for(i=0, j=0; i<len; i++)
308    {
309        if(j == 0)
310            print("\n%lX: %02X, ", &s[i], s[i]);
311        else if(j == 7)
312            print("%02X,  ", s[i]);
313        else
314            print("%02X, ", s[i]);
315        if(++j == 16)
316            j=0;
317    }
318    print("\n");
319}
320
321void gki_dump2 (UINT16 *s, UINT16 len, FP_PRINT print)
322{
323    UINT16 i, j;
324
325    for(i=0, j=0; i<len; i++)
326    {
327        if(j == 0)
328            print("\n%lX: %04X, ", &s[i], s[i]);
329        else
330            print("%04X, ", s[i]);
331        if(++j == 8)
332            j=0;
333    }
334    print("\n");
335}
336
337void gki_dump4 (UINT32 *s, UINT16 len, FP_PRINT print)
338{
339    UINT16 i, j;
340
341    for(i=0, j=0; i<len; i++)
342    {
343        if(j == 0)
344            print("\n%lX: %08lX, ", &s[i], s[i]);
345        else
346            print("%08lX, ", s[i]);
347        if(++j == 4)
348            j=0;
349    }
350    print("\n");
351}
352
353
354#endif
355