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