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