soc_ser_log.c (20342B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * File: soc_ser_log.c 7 * Purpose: SER logging using a circular buffer 8 */ 9 10 #include <shared/bsl.h> 11 #include <shared/alloc.h> 12 13 #include <soc/soc_ser_log.h> 14 #include <soc/soc_log_buf.h> 15 #include <soc/error.h> 16 #include <sal/appl/sal.h> 17 #include <soc/util.h> 18 19 static char _soc_ser_log_buffer[SOC_MAX_NUM_DEVICES][_SOC_SER_LOG_BUFFER_SIZE]; 20 21 static void *_soc_ser_log_buffer_ptr[SOC_MAX_NUM_DEVICES]; 22 23 typedef struct _soc_ser_log_criteria_s { 24 soc_mem_t mem; 25 int index; 26 sal_usecs_t time; 27 } _soc_ser_log_criteria_t; 28 29 int 30 soc_ser_log_get_entry_size(int unit, int id, int *size) 31 { 32 int rc = SOC_E_NONE; 33 if (id == 0) { 34 return SOC_E_PARAM; 35 } 36 37 rc = soc_log_buf_entry_get_size(_soc_ser_log_buffer_ptr[unit], id, size); 38 39 return rc; 40 } 41 42 int 43 soc_ser_log_get_entry(int unit, int id, int size, void *entry) 44 { 45 int entry_size; 46 int rc = SOC_E_NONE; 47 48 if (id == 0) { 49 return SOC_E_PARAM; 50 } 51 52 rc = soc_log_buf_entry_get_size(_soc_ser_log_buffer_ptr[unit], 53 id, &entry_size); 54 55 if ((entry_size > size) || (SOC_E_NONE != rc)) { 56 return SOC_E_PARAM; 57 } 58 59 rc = soc_log_buf_entry_read(_soc_ser_log_buffer_ptr[unit], 60 id, 0, entry_size, entry); 61 62 return rc; 63 } 64 65 static int 66 _soc_ser_bus_buffer_log_match(void *criteria, void *entry) 67 { 68 soc_ser_log_tlv_hdr_t *tlv_hdr = entry; 69 soc_ser_log_tlv_memory_t *tlv_mem; 70 soc_ser_log_tlv_memory_t entry_data; 71 uint32 *hwbase = criteria; 72 int found_mem = 0; 73 74 sal_memset(&entry_data, 0, sizeof(_soc_ser_log_criteria_t)); 75 76 while ((tlv_hdr->type != 0) && !found_mem) { 77 if (tlv_hdr->type == SOC_SER_LOG_TLV_MEMORY) { 78 tlv_mem = (soc_ser_log_tlv_memory_t*)(((char*)tlv_hdr) + 79 sizeof(soc_ser_log_tlv_hdr_t)); 80 entry_data.hwbase = tlv_mem->hwbase; 81 found_mem = 1; 82 } 83 tlv_hdr = (soc_ser_log_tlv_hdr_t*)((char*)tlv_hdr + 84 tlv_hdr->length + sizeof(soc_ser_log_tlv_hdr_t)); 85 } 86 87 if (found_mem && (*hwbase == entry_data.hwbase)) { 88 return 1; 89 } 90 91 return 0; 92 } 93 94 int 95 soc_ser_bus_buffer_log_find(int unit, uint32 hwbase) 96 { 97 int rv = SOC_E_NONE; 98 char *buffer; 99 100 if (_soc_ser_log_buffer_ptr[unit] == NULL) { 101 return SOC_E_PARAM; 102 } 103 104 buffer = sal_alloc(_SOC_SER_LOG_BUFFER_SIZE, "ser log info"); 105 if (NULL == buffer) { 106 return (SOC_E_MEMORY); 107 } 108 109 rv = soc_log_buf_search(_soc_ser_log_buffer_ptr[unit], buffer, 110 _SOC_SER_LOG_BUFFER_SIZE, &hwbase, &_soc_ser_bus_buffer_log_match); 111 112 sal_free(buffer); 113 114 if (rv > 0) { 115 /* if rv > 0, it means the rv is the log id, and hwbase is found. 116 Overwrite the rv to error type */ 117 rv = SOC_E_NONE; 118 } 119 return rv; 120 } 121 122 static int 123 _soc_ser_log_match_entry(void *criteria, void *entry) 124 { 125 _soc_ser_log_criteria_t *crit = criteria; 126 soc_ser_log_tlv_hdr_t *tlv_hdr = entry; 127 soc_ser_log_tlv_memory_t *tlv_mem; 128 soc_ser_log_tlv_generic_t *tlv_gen; 129 _soc_ser_log_criteria_t entry_data; 130 int found_gen = 0; 131 int found_mem = 0; 132 133 sal_memset(&entry_data, 0, sizeof(_soc_ser_log_criteria_t)); 134 135 while ((tlv_hdr->type != 0) && !(found_gen && found_mem)) { 136 if (tlv_hdr->type == SOC_SER_LOG_TLV_GENERIC) { 137 tlv_gen = (soc_ser_log_tlv_generic_t*)(((char*)tlv_hdr) + 138 sizeof(soc_ser_log_tlv_hdr_t)); 139 entry_data.time = tlv_gen->time; 140 found_gen = 1; 141 } else if (tlv_hdr->type == SOC_SER_LOG_TLV_MEMORY) { 142 tlv_mem = (soc_ser_log_tlv_memory_t*)(((char*)tlv_hdr) + 143 sizeof(soc_ser_log_tlv_hdr_t)); 144 entry_data.index = tlv_mem->index; 145 entry_data.mem = tlv_mem->memory; 146 found_mem = 1; 147 } 148 tlv_hdr = (soc_ser_log_tlv_hdr_t*)((char*)tlv_hdr + 149 tlv_hdr->length + sizeof(soc_ser_log_tlv_hdr_t)); 150 } 151 152 if ((found_gen && found_mem) && 153 (crit->mem == entry_data.mem) && 154 (crit->index == entry_data.index) && 155 (SAL_USECS_SUB(crit->time, entry_data.time) <= 0)) { 156 return 1; 157 } 158 159 return 0; 160 } 161 162 int 163 soc_ser_log_find_recent(int unit, soc_mem_t mem, int index, sal_usecs_t time) 164 { 165 int rv = SOC_E_NONE; 166 char *buffer; 167 _soc_ser_log_criteria_t criteria; 168 169 if (_soc_ser_log_buffer_ptr[unit] == NULL) { 170 return 0; 171 } 172 173 buffer = sal_alloc(_SOC_SER_LOG_BUFFER_SIZE, "ser log info"); 174 if (NULL == buffer) { 175 return (SOC_E_MEMORY); 176 } 177 178 criteria.mem = mem; 179 criteria.index = index; 180 /* Check within the last 5 seconds */ 181 criteria.time = SAL_USECS_SUB(time, SECOND_USEC * 5); 182 183 rv = soc_log_buf_search(_soc_ser_log_buffer_ptr[unit], buffer, 184 _SOC_SER_LOG_BUFFER_SIZE, &criteria, &_soc_ser_log_match_entry); 185 186 sal_free(buffer); 187 return rv; 188 } 189 190 int 191 soc_ser_log_create_entry(int unit, int size) 192 { 193 /* if someone tries to add an entry to a non-existant log, 194 * return the invalid id 195 */ 196 if (_soc_ser_log_buffer_ptr[unit] == NULL) { 197 return 0; 198 } 199 return soc_log_buf_add(_soc_ser_log_buffer_ptr[unit], size); 200 } 201 202 /* Add tlv to a log, if it already exists overwrite it */ 203 int 204 soc_ser_log_add_tlv(int unit, int id, soc_ser_log_tlv_type_t type, 205 int size, void * buffer) 206 { 207 int offset = 0; 208 int entry_size = 0; 209 int rc = SOC_E_NONE; 210 soc_ser_log_tlv_hdr_t tlv_hdr; 211 212 soc_log_buf_entry_read(_soc_ser_log_buffer_ptr[unit], 213 id, offset, sizeof(soc_ser_log_tlv_hdr_t), &tlv_hdr); 214 while ((tlv_hdr.type != 0) && 215 (tlv_hdr.type != type)) { 216 offset = offset + tlv_hdr.length + sizeof(soc_ser_log_tlv_hdr_t); 217 soc_log_buf_entry_read(_soc_ser_log_buffer_ptr[unit], id, offset, 218 sizeof(soc_ser_log_tlv_hdr_t), &tlv_hdr); 219 if (tlv_hdr.type == type) { 220 break; 221 } 222 } 223 /* If we're adding rather than overwriting, make sure we have room */ 224 rc = soc_log_buf_entry_get_size(_soc_ser_log_buffer_ptr[unit], id, &entry_size); 225 226 if (((tlv_hdr.type != type) && 227 (entry_size < (offset + sizeof(soc_ser_log_tlv_hdr_t) + size))) 228 || SOC_E_NONE != rc) { 229 return SOC_E_PARAM; 230 } 231 232 /* If we're trying to overwrite, but with a different size tlv, error */ 233 if ((tlv_hdr.type == type) && (tlv_hdr.length != size)) { 234 return SOC_E_PARAM; 235 } 236 237 tlv_hdr.type = type; 238 tlv_hdr.length = size; 239 soc_log_buf_entry_write(_soc_ser_log_buffer_ptr[unit], 240 id, offset, sizeof(soc_ser_log_tlv_hdr_t), &tlv_hdr); 241 offset += sizeof(soc_ser_log_tlv_hdr_t); 242 soc_log_buf_entry_write(_soc_ser_log_buffer_ptr[unit], 243 id, offset, size, buffer); 244 245 return SOC_E_NONE; 246 } 247 248 int 249 soc_ser_log_mod_tlv(int unit, 250 int id, 251 soc_ser_log_tlv_type_t type, 252 int size, 253 void * buffer) 254 { 255 int offset = 0; 256 soc_ser_log_tlv_hdr_t tlv_hdr; 257 258 soc_log_buf_entry_read(_soc_ser_log_buffer_ptr[unit], 259 id, offset, sizeof(soc_ser_log_tlv_hdr_t), &tlv_hdr); 260 while (tlv_hdr.type != type) { 261 if (tlv_hdr.type == 0) { 262 return SOC_E_PARAM; 263 } 264 offset = offset + tlv_hdr.length + sizeof(soc_ser_log_tlv_hdr_t); 265 soc_log_buf_entry_read(_soc_ser_log_buffer_ptr[unit], 266 id, offset, sizeof(soc_ser_log_tlv_hdr_t), &tlv_hdr); 267 } 268 if (size != tlv_hdr.length) { 269 return SOC_E_PARAM; 270 } 271 272 soc_log_buf_entry_write(_soc_ser_log_buffer_ptr[unit], id, offset + 273 sizeof(soc_ser_log_tlv_hdr_t), size, buffer); 274 return SOC_E_NONE; 275 } 276 277 int 278 soc_ser_log_get_tlv(int unit, 279 int id, 280 soc_ser_log_tlv_type_t type, 281 int size, 282 void * buffer) 283 { 284 int offset = 0; 285 soc_ser_log_tlv_hdr_t tlv_hdr; 286 287 soc_log_buf_entry_read(_soc_ser_log_buffer_ptr[unit], 288 id, offset, sizeof(soc_ser_log_tlv_hdr_t), &tlv_hdr); 289 while (tlv_hdr.type != type) { 290 if (tlv_hdr.type == 0) { 291 return SOC_E_PARAM; 292 } 293 offset = offset + tlv_hdr.length + sizeof(soc_ser_log_tlv_hdr_t); 294 soc_log_buf_entry_read(_soc_ser_log_buffer_ptr[unit], 295 id, offset, sizeof(soc_ser_log_tlv_hdr_t), &tlv_hdr); 296 } 297 298 if (size < tlv_hdr.length) { 299 return SOC_E_PARAM; 300 } 301 302 soc_log_buf_entry_read(_soc_ser_log_buffer_ptr[unit], 303 id, offset+sizeof(soc_ser_log_tlv_hdr_t), tlv_hdr.length, buffer); 304 return SOC_E_NONE; 305 } 306 307 /* print an entry */ 308 int 309 soc_ser_log_print_entry(int unit, void *buffer) 310 { 311 soc_ser_log_tlv_hdr_t *tlv_hdr = buffer; 312 313 while (tlv_hdr->type != 0) { 314 soc_ser_log_print_tlv(unit, (char*)tlv_hdr); 315 tlv_hdr = (soc_ser_log_tlv_hdr_t*)((char*)tlv_hdr + 316 tlv_hdr->length + sizeof(soc_ser_log_tlv_hdr_t)); 317 } 318 319 return SOC_E_NONE; 320 } 321 322 #define _SOC_SER_LOG_PARITY_TYPE_NAME(pt) ( \ 323 ((pt) == SOC_PARITY_TYPE_NONE)? "NONE" : \ 324 ((pt) == SOC_PARITY_TYPE_GENERIC)? "GENERIC" : \ 325 ((pt) == SOC_PARITY_TYPE_PARITY)? "PARITY" : \ 326 ((pt) == SOC_PARITY_TYPE_ECC)? "ECC" : \ 327 ((pt) == SOC_PARITY_TYPE_HASH)? "HASH" : \ 328 ((pt) == SOC_PARITY_TYPE_EDATABUF)? "EDATABUF" : \ 329 ((pt) == SOC_PARITY_TYPE_COUNTER)? "COUNTER" : \ 330 ((pt) == SOC_PARITY_TYPE_MXQPORT)? "MXQPORT" : \ 331 ((pt) == SOC_PARITY_TYPE_SER)? "SER" : \ 332 "NONE") 333 334 #define _SOC_SER_LOG_CORRECTED_TYPE(ct) ( \ 335 ((ct) == SOC_SER_UNKNOWN)? "UNKNOWN" : \ 336 ((ct) == SOC_SER_UNCORRECTED)? "NO" : \ 337 ((ct) == SOC_SER_CORRECTED)? "YES" : \ 338 "UNKNOWN") 339 340 #define _SOC_SER_LOG_SER_RESPONSE_TYPE(rf) ( \ 341 ((rf) & SOC_MEM_FLAG_SER_ENTRY_CLEAR)? "SER_ENTRY_CLEAR" : \ 342 ((rf) & SOC_MEM_FLAG_SER_CACHE_RESTORE)? "SER_CACHE_RESTORE" : \ 343 ((rf) & SOC_MEM_FLAG_SER_WRITE_CACHE_RESTORE)? "SER_WRITE_CACHE_RESTORE" : \ 344 ((rf) & SOC_MEM_FLAG_SER_ECC_CORRECTABLE)? "SER_ECC_CORRECTABLE" : \ 345 ((rf) & SOC_MEM_FLAG_SER_SPECIAL)? "SER_SPECIAL" : \ 346 "UNKNOWN") 347 348 #define _SOC_SER_LOG_ACC_TYPE(at) ( \ 349 ((at) == SOC_SER_LOG_ACC_ANY)? "ACC_ANY" : \ 350 ((at) == SOC_SER_LOG_ACC_GROUP)? "ACC_GROUP" : \ 351 ((at) == SOC_SER_LOG_ACC_X)? "ACC_X" : \ 352 ((at) == SOC_SER_LOG_ACC_Y)? "ACC_Y" : \ 353 ((at) == SOC_SER_LOG_ACC_SBS)? "ACC_SBS" : \ 354 "UNKNOWN") 355 356 int 357 soc_ser_log_print_tlv(int unit, void *buffer) 358 { 359 soc_ser_log_tlv_hdr_t *tlv_hdr = buffer; 360 char *data = (char*)buffer + sizeof(soc_ser_log_tlv_hdr_t); 361 int index; 362 #ifdef _SOC_SER_ENABLE_CLI_DBG 363 soc_mem_t mem; 364 soc_reg_t reg; 365 #endif 366 soc_ser_parity_type_t parity_type; 367 soc_ser_correct_t ct; 368 soc_ser_log_flag_t flags; 369 soc_ser_log_acc_type_t at; 370 int ser_response_flag; 371 372 LOG_CLI((BSL_META_U(unit, "Tlv Header:\n"))); 373 LOG_CLI((BSL_META_U(unit, "\ttype: %d\n"), (int)(tlv_hdr->type))); 374 LOG_CLI((BSL_META_U(unit, "\tlength: %d\n"), (int)(tlv_hdr->length))); 375 LOG_CLI((BSL_META_U(unit, "\tvalue: \n"))); 376 LOG_CLI((BSL_META_U(unit, "Tlv Data:\n"))); 377 switch (tlv_hdr->type) { 378 case SOC_SER_LOG_TLV_MEMORY: 379 LOG_CLI((BSL_META_U(unit, "\tSOC_SER_LOG_TLV_MEMORY\n"))); 380 #ifdef _SOC_SER_ENABLE_CLI_DBG 381 mem = (int)(((soc_ser_log_tlv_memory_t*)(data))->memory); 382 LOG_CLI((BSL_META_U(unit, "\t\tmemory: %d (%s)\n"), 383 (int)(((soc_ser_log_tlv_memory_t*)(data))->memory), 384 SOC_MEM_NAME(unit, mem))); 385 #else 386 LOG_CLI((BSL_META_U(unit, "\t\tmemory: %d\n"), 387 (int)(((soc_ser_log_tlv_memory_t*)(data))->memory))); 388 #endif 389 LOG_CLI((BSL_META_U(unit, "\t\tindex: %d\n"), 390 (int)(((soc_ser_log_tlv_memory_t*)(data))->index))); 391 LOG_CLI((BSL_META_U(unit, "\t\thwbase: %d\n"), 392 (int)(((soc_ser_log_tlv_memory_t*)(data))->hwbase))); 393 break; 394 case SOC_SER_LOG_TLV_REGISTER: 395 LOG_CLI((BSL_META_U(unit, "\tSOC_SER_LOG_TLV_REGISTER\n"))); 396 #ifdef _SOC_SER_ENABLE_CLI_DBG 397 reg = (int)(((soc_ser_log_tlv_register_t*)(data))->reg); 398 LOG_CLI((BSL_META_U(unit, "\t\tregister: %d (%s)\n"), 399 (int)(((soc_ser_log_tlv_register_t*)(data))->reg), 400 SOC_REG_NAME(unit, reg))); 401 #else 402 LOG_CLI((BSL_META_U(unit, "\t\tregister: %d\n"), 403 (int)(((soc_ser_log_tlv_register_t*)(data))->reg))); 404 #endif 405 LOG_CLI((BSL_META_U(unit, "\t\tindex: %d\n"), 406 (int)(((soc_ser_log_tlv_register_t*)(data))->index))); 407 LOG_CLI((BSL_META_U(unit, "\t\tport: %d\n"), 408 (int)(((soc_ser_log_tlv_register_t*)(data))->port))); 409 break; 410 case SOC_SER_LOG_TLV_CONTENTS: 411 LOG_CLI((BSL_META_U(unit, "\tSOC_SER_LOG_TLV_CONTENTS\n"))); 412 for (index = 0; index < tlv_hdr->length; index++) { 413 if ((index%16) == 0) { 414 LOG_CLI((BSL_META_U(unit, "\t\t"))); 415 } 416 LOG_CLI((BSL_META_U(unit, "%02x "), *((char*)(data + index)))); 417 if ((index%16)==15) { 418 LOG_CLI((BSL_META_U(unit, "\n"))); 419 } 420 } 421 LOG_CLI((BSL_META_U(unit, "\n"))); 422 break; 423 case SOC_SER_LOG_TLV_SER_FIFO: 424 LOG_CLI((BSL_META_U(unit, "\tSOC_SER_LOG_TLV_SER_FIFO\n"))); 425 for (index = 0; index < tlv_hdr->length; index++) { 426 LOG_CLI((BSL_META_U(unit, "%02x "), *((char*)(data + index)))); 427 if ((index%16)==15) { 428 LOG_CLI((BSL_META_U(unit, "\n"))); 429 } 430 } 431 LOG_CLI((BSL_META_U(unit, "\n"))); 432 break; 433 case SOC_SER_LOG_TLV_CACHE: 434 LOG_CLI((BSL_META_U(unit, "\tSOC_SER_LOG_TLV_CACHE\n"))); 435 for (index = 0; index < tlv_hdr->length; index++) { 436 if ((index%16) == 0) { 437 LOG_CLI((BSL_META_U(unit, "\t\t"))); 438 } 439 LOG_CLI((BSL_META_U(unit, "%02x "), *((char*)(data + index)))); 440 if ((index%16)==15) { 441 LOG_CLI((BSL_META_U(unit, "\n"))); 442 } 443 } 444 LOG_CLI((BSL_META_U(unit, "\n"))); 445 break; 446 case SOC_SER_LOG_TLV_GENERIC: 447 LOG_CLI((BSL_META_U(unit, "\tSOC_SER_LOG_TLV_GENERIC\n"))); 448 flags = (int)(((soc_ser_log_tlv_generic_t*)(data))->flags); 449 LOG_CLI((BSL_META_U(unit, "\t\tflags: %d (%s %s %s)\n"), 450 (int)(((soc_ser_log_tlv_generic_t*)(data))->flags), 451 (flags & SOC_SER_LOG_FLAG_MULTIBIT)? "MULTIPLE_1" : "MULTIPLE_0", 452 (flags & SOC_SER_LOG_FLAG_DOUBLEBIT)? ", DOUBLE_BIT" : ", SINGLE_BIT", 453 (flags & SOC_SER_LOG_FLAG_ERR_SRC)? ", ERR_SRC_CPU" : " ")); 454 LOG_CLI((BSL_META_U(unit, "\t\ttime: %u\n"), 455 ((soc_ser_log_tlv_generic_t*)(data))->time)); 456 LOG_CLI((BSL_META_U(unit, "\t\tboot_count: %d\n"), 457 (int)(((soc_ser_log_tlv_generic_t*)(data))->boot_count))); 458 LOG_CLI((BSL_META_U(unit, "\t\taddress: %d (0x%8x)\n"), 459 (int)(((soc_ser_log_tlv_generic_t*)(data))->address), 460 (int)(((soc_ser_log_tlv_generic_t*)(data))->address))); 461 at = (int)(((soc_ser_log_tlv_generic_t*)(data))->acc_type); 462 LOG_CLI((BSL_META_U(unit, "\t\tacc_type: %d (%s)\n"), 463 (int)(((soc_ser_log_tlv_generic_t*)(data))->acc_type), 464 _SOC_SER_LOG_ACC_TYPE(at))); 465 LOG_CLI((BSL_META_U(unit, "\t\tpipe_num: %d\n"), 466 (int)(((soc_ser_log_tlv_generic_t*)(data))->pipe_num))); 467 LOG_CLI((BSL_META_U(unit, "\t\tinst: %d\n"), 468 (int)(((soc_ser_log_tlv_generic_t*)(data))->inst))); 469 LOG_CLI((BSL_META_U(unit, "\t\thw_cache: %d\n"), 470 (int)(((soc_ser_log_tlv_generic_t*)(data))->hw_cache))); 471 LOG_CLI((BSL_META_U(unit, "\t\tblock_type: %d\n"), 472 (int)(((soc_ser_log_tlv_generic_t*)(data))->block_type))); 473 parity_type = (int)(((soc_ser_log_tlv_generic_t*)(data))->parity_type); 474 LOG_CLI((BSL_META_U(unit, "\t\tparity_type: %d (%s)\n"), 475 (int)(((soc_ser_log_tlv_generic_t*)(data))->parity_type), 476 _SOC_SER_LOG_PARITY_TYPE_NAME(parity_type))); 477 ser_response_flag = (int)(((soc_ser_log_tlv_generic_t*)(data))->ser_response_flag); 478 LOG_CLI((BSL_META_U(unit, "\t\tser_response_flag: %d (%s)\n"), 479 (int)(((soc_ser_log_tlv_generic_t*)(data))->ser_response_flag), 480 _SOC_SER_LOG_SER_RESPONSE_TYPE(ser_response_flag))); 481 ct = (int)(((soc_ser_log_tlv_generic_t*)(data))->corrected); 482 LOG_CLI((BSL_META_U(unit, "\t\tcorrected: %d (%s)\n"), 483 (int)(((soc_ser_log_tlv_generic_t*)(data))->corrected), 484 _SOC_SER_LOG_CORRECTED_TYPE(ct))); 485 break; 486 default: 487 LOG_CLI((BSL_META_U(unit, "\tUnknown type\n"))); 488 } 489 return SOC_E_NONE; 490 } 491 492 /* print everything */ 493 int 494 soc_ser_log_print_all(int unit) 495 { 496 int id = 0; 497 do { 498 id = soc_log_buf_get_next_id(_soc_ser_log_buffer_ptr[unit], id); 499 500 if (id == 0) { 501 return SOC_E_NONE; 502 } 503 504 SOC_IF_ERROR_RETURN(soc_ser_log_print_one(unit, id)); 505 } while (1); 506 return SOC_E_NONE; 507 } 508 509 /* print log for specified id */ 510 int 511 soc_ser_log_print_one(int unit, int id) 512 { 513 int size; 514 int rc = SOC_E_NONE; 515 char *buffer; 516 517 if (id == 0) { 518 return SOC_E_PARAM; 519 } 520 521 buffer = sal_alloc(_SOC_SER_LOG_BUFFER_SIZE, "ser log info"); 522 if (NULL == buffer) { 523 return (SOC_E_MEMORY); 524 } 525 526 rc = soc_ser_log_get_entry_size(unit, id, &size); 527 if ((size <= 0) || (size > _SOC_SER_LOG_BUFFER_SIZE) 528 || (SOC_E_NONE != rc)) { 529 sal_free(buffer); 530 return SOC_E_INTERNAL; 531 } 532 533 soc_ser_log_get_entry(unit, id, size, buffer); 534 LOG_ERROR(BSL_LS_SOC_COMMON, 535 (BSL_META_U(unit, 536 "\nLog Entry ID:%d\n"), id)); 537 soc_ser_log_print_entry(unit, buffer); 538 539 sal_free(buffer); 540 return SOC_E_NONE; 541 } 542 543 int 544 soc_ser_log_find_tlv(void *buffer, soc_ser_log_tlv_type_t type) 545 { 546 soc_ser_log_tlv_hdr_t *tlv_hdr = buffer; 547 int offset = 0; 548 549 while ((tlv_hdr->type != type) && (tlv_hdr->type != 0)) { 550 offset += tlv_hdr->length + sizeof(soc_ser_log_tlv_hdr_t); 551 tlv_hdr = (soc_ser_log_tlv_hdr_t*)((char*)tlv_hdr + 552 tlv_hdr->length + sizeof(soc_ser_log_tlv_hdr_t)); 553 } 554 555 if (tlv_hdr->type == 0) { 556 return SOC_E_PARAM; 557 } 558 return offset; 559 } 560 561 int 562 soc_ser_log_invalidate(int unit) 563 { 564 sal_mutex_t mut = soc_log_buf_get_mutex(_soc_ser_log_buffer_ptr[unit]); 565 if (mut == 0) { 566 return SOC_E_INTERNAL; 567 } 568 soc_log_buf_set_mutex(_soc_ser_log_buffer_ptr[unit], 0); 569 570 sal_mutex_destroy(mut); 571 return SOC_E_NONE; 572 } 573 574 int 575 soc_ser_log_init(int unit, void *location, int size) 576 { 577 int buffer_length; 578 sal_mutex_t mut = NULL; 579 static int init_done[SOC_MAX_NUM_DEVICES]; 580 int rv; 581 582 if(unit >= SOC_MAX_NUM_DEVICES) 583 { 584 LOG_ERROR(BSL_LS_SOC_COMMON, 585 (BSL_META_U(unit, 586 "SER Logging failed to check parameter Unit(%d)\n"), unit)); 587 return SOC_E_PARAM; 588 } 589 590 if(1 == init_done[unit]) 591 { 592 LOG_DEBUG(BSL_LS_SOC_COMMON, 593 (BSL_META_U(unit, 594 "SER Logging had been initialized\n"))); 595 return SOC_E_NONE; 596 } 597 598 mut = sal_mutex_create("SER_LOG_MUTEX"); 599 if (mut == NULL) { 600 LOG_ERROR(BSL_LS_SOC_COMMON, 601 (BSL_META_U(unit, 602 "SER Logging failed to create mutex\n"))); 603 return SOC_E_RESOURCE; 604 } 605 606 if (location == NULL) { 607 _soc_ser_log_buffer_ptr[unit] = _soc_ser_log_buffer[unit]; 608 buffer_length = _SOC_SER_LOG_BUFFER_SIZE; 609 } else { 610 _soc_ser_log_buffer_ptr[unit] = location; 611 buffer_length = size; 612 } 613 rv = soc_log_buf_init(_soc_ser_log_buffer_ptr[unit], buffer_length, mut); 614 if (SOC_FAILURE(rv)) { 615 sal_mutex_destroy(mut); 616 return SOC_E_PARAM; 617 } 618 619 init_done[unit] = 1; 620 621 return SOC_E_NONE; 622 } 623 624 int 625 soc_ser_log_get_boot_count(int unit) 626 { 627 return soc_log_buf_get_boot_count(_soc_ser_log_buffer_ptr[unit]); 628 }