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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 /*****************************************************************************/ 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 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 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