openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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 }