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_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*******************************************************************************/
39void 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*******************************************************************************/
74void 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*******************************************************************************/
95uint16_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*******************************************************************************/
120void 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*******************************************************************************/
148void 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*******************************************************************************/
185void 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*******************************************************************************/
229void 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*******************************************************************************/
254void 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/*****************************************************************************/
267void 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
282void 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
295void 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