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

scache_dictionary.c (10369B)


      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  *
      7  * Purpose: Level 2 Warm Boot cache dictionary management    
      8  */
      9 
     10 #include <soc/error.h>
     11 
     12 #ifdef BCM_WARM_BOOT_SUPPORT
     13 
     14 #include <sal/core/libc.h>
     15 #include <soc/drv.h>
     16 #include <soc/scache.h>
     17 #include <soc/scache_dictionary.h>
     18 
     19 #define SOC_WB_VERSION_1_0                  SOC_SCACHE_VERSION(1,0)
     20 #define SOC_WB_DEFAULT_VERSION              SOC_WB_VERSION_1_0
     21 
     22 #define SOC_SCACHE_DICTIONARY_ENTRY_MAX_1_0 64
     23 #define SOC_SCACHE_DICTIONARY_ENTRY_MAX     SOC_SCACHE_DICTIONARY_ENTRY_MAX_1_0
     24 
     25 static uint16 soc_scache_dictionary_version[SOC_MAX_NUM_DEVICES];
     26 static soc_scache_dictionary_entry_t *soc_scache_dictionary[SOC_MAX_NUM_DEVICES];
     27 
     28 #define SOC_SCACHE_DICTIONARY_ENTRY_EMPTY(_u, d_ptr, idx)                 \
     29     ((d_ptr[idx].owner == 0) && (d_ptr[idx].key == 0) &&                 \
     30      (sal_strlen(d_ptr[idx].name) == 0))
     31 
     32 #define SOC_SCACHE_DICTIONARY_ENTRY_MATCH(_u, d_ptr, idx, _o, _k, _n)     \
     33     ((d_ptr[idx].owner == _o) && (d_ptr[idx].key == _k) &&               \
     34      (sal_strncmp(d_ptr[idx].name, _n, SOC_SCACHE_DICTIONARY_ENTRY_NAME_MAX) == 0))
     35 
     36 #define SOC_SCACHE_DICTIONARY_ENTRY_GET(_u, d_ptr, idx, _v)               \
     37     do {                                                                  \
     38         if (_v) *_v = d_ptr[idx].value;                                   \
     39     } while (0)
     40 
     41 #define SOC_SCACHE_DICTIONARY_ENTRY_SET(_u, d_ptr, idx, _o, _k, _n, _v)   \
     42     do {                                                                  \
     43         int _l = sal_strlen(_n) + 1;                                      \
     44         if (_l <= SOC_SCACHE_DICTIONARY_ENTRY_NAME_MAX) {                 \
     45             d_ptr[idx].owner = _o;                                        \
     46             d_ptr[idx].key = _k;                                          \
     47             sal_strncpy(d_ptr[idx].name, _n, _l);                         \
     48             d_ptr[idx].value = _v;                                        \
     49         }                                                                 \
     50     } while (0)
     51 
     52 #define SOC_SCACHE_DICTIONARY_ENTRY_SET_VALUE(_u, d_ptr, idx, _v)         \
     53     do {                                                                  \
     54         d_ptr[idx].value = _v;                                            \
     55     } while (0)
     56 
     57 
     58 STATIC void
     59 soc_scache_dictionary_init(int unit, uint8 *scache_ptr, uint16 version)
     60 {
     61     soc_scache_dictionary[unit] = (soc_scache_dictionary_entry_t *)scache_ptr;
     62     soc_scache_dictionary_version[unit] = version;
     63 }
     64 
     65 STATIC int
     66 soc_scache_dictionary_size(int unit, uint16 version)
     67 {
     68     int dictionary_size = 0;
     69     if (version >= SOC_WB_VERSION_1_0) {
     70         dictionary_size = SOC_SCACHE_DICTIONARY_ENTRY_MAX_1_0;
     71     } else {
     72         dictionary_size = SOC_SCACHE_DICTIONARY_ENTRY_MAX;
     73     }
     74     return dictionary_size;
     75 }
     76 
     77 STATIC int
     78 soc_scache_dictionary_alloc_size(int unit, uint16 version)
     79 {
     80     int dictionary_size = 0;
     81     dictionary_size = soc_scache_dictionary_size(unit, version);
     82     return dictionary_size * sizeof(soc_scache_dictionary_entry_t);
     83 }
     84 
     85 int
     86 soc_scache_dictionary_alloc(int unit)
     87 {
     88     int rv = SOC_E_NONE;
     89     int stable_size = 0;
     90     uint8 *scache_ptr = NULL;
     91     soc_scache_handle_t scache_handle;
     92     uint32 alloc_size = 0;
     93     uint16 default_ver = SOC_WB_DEFAULT_VERSION;
     94 
     95     SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
     96     if (!stable_size) {
     97         /* stable not allocated */
     98         return SOC_E_NONE;
     99     }
    100 
    101     alloc_size = soc_scache_dictionary_alloc_size(unit, default_ver);
    102 
    103     SOC_SCACHE_HANDLE_SET(scache_handle, unit,
    104                           SOC_SCACHE_DICTIONARY_HANDLE, 0);
    105 
    106     rv = soc_versioned_scache_ptr_get(unit, scache_handle,
    107                                       TRUE, &alloc_size, &scache_ptr,
    108                                       default_ver, NULL);
    109     /* Proceed with Level 1 Warm Boot */
    110     if (SOC_FAILURE(rv) && (rv != SOC_E_NOT_FOUND)) {
    111         return rv;
    112     }
    113 
    114     if (SOC_SUCCESS(rv) && scache_ptr) {
    115         sal_memset(scache_ptr, 0, alloc_size);
    116         soc_scache_dictionary_init(unit, scache_ptr, default_ver);
    117     }
    118 
    119     return SOC_E_NONE;
    120 }
    121 
    122 int
    123 soc_scache_dictionary_recover(int unit)
    124 {
    125     int rv = SOC_E_NONE;
    126     uint8 *scache_ptr;
    127     soc_scache_handle_t scache_handle;
    128     uint32 alloc_size = 0;
    129     uint16 default_ver = SOC_WB_DEFAULT_VERSION;
    130     uint16 recovered_ver = 0;
    131 
    132     SOC_SCACHE_HANDLE_SET(scache_handle, unit,
    133                           SOC_SCACHE_DICTIONARY_HANDLE, 0);
    134     rv = soc_versioned_scache_ptr_get(unit, scache_handle,
    135                                       FALSE, &alloc_size, &scache_ptr,
    136                                       default_ver, &recovered_ver);
    137     if (SOC_SUCCESS(rv)) {
    138         soc_scache_dictionary_init(unit, scache_ptr, recovered_ver);
    139     }
    140 
    141     return SOC_E_NONE;
    142 }
    143 
    144 int
    145 soc_scache_dictionary_sync(int unit)
    146 {
    147     int rv = SOC_E_NONE;
    148     int stable_size = 0;
    149     uint8 *scache_ptr = NULL;
    150     soc_scache_handle_t scache_handle;
    151     uint32 alloc_size = 0;
    152     uint16 default_ver = SOC_WB_DEFAULT_VERSION;
    153     soc_scache_dictionary_entry_t *dictionary_ptr;
    154 
    155     SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
    156     if (!stable_size) {
    157         /* stable not allocated */
    158         return SOC_E_NONE;
    159     }
    160 
    161     alloc_size = soc_scache_dictionary_alloc_size(unit, default_ver);
    162 
    163     SOC_SCACHE_HANDLE_SET(scache_handle, unit,
    164                           SOC_SCACHE_DICTIONARY_HANDLE, 0);
    165     rv = soc_versioned_scache_ptr_get(unit, scache_handle,
    166                                       TRUE, &alloc_size, &scache_ptr,
    167                                       default_ver, NULL);
    168     if (SOC_FAILURE(rv)) {
    169         return rv;
    170     }
    171 
    172     if (SOC_SUCCESS(rv) && scache_ptr) {
    173         soc_scache_dictionary_init(unit, scache_ptr, default_ver);
    174         dictionary_ptr = (soc_scache_dictionary_entry_t *)scache_ptr;
    175 
    176         SOC_SCACHE_DICTIONARY_ENTRY_SET(unit, dictionary_ptr, 0, 
    177                         0, 0, ssden_SOC_MAX_NUM_PORTS, SOC_MAX_NUM_PORTS);
    178         SOC_SCACHE_DICTIONARY_ENTRY_SET(unit, dictionary_ptr, 1, 
    179                         0, 0, ssden_SOC_MAX_NUM_PP_PORTS, SOC_MAX_NUM_PP_PORTS);
    180         SOC_SCACHE_DICTIONARY_ENTRY_SET(unit, dictionary_ptr, 2, 
    181                         0, 0, ssden_SOC_MAX_NUM_BLKS, SOC_MAX_NUM_BLKS);
    182         SOC_SCACHE_DICTIONARY_ENTRY_SET(unit, dictionary_ptr, 3, 
    183                         0, 0, ssden_SOC_MAX_NUM_PIPES, SOC_MAX_NUM_PIPES);
    184         SOC_SCACHE_DICTIONARY_ENTRY_SET(unit, dictionary_ptr, 4, 
    185                         0, 0, ssden_SOC_MAX_MEM_BYTES, SOC_MAX_MEM_BYTES);
    186         SOC_SCACHE_DICTIONARY_ENTRY_SET(unit, dictionary_ptr, 5, 
    187                         0, 0, ssden_SOC_PBMP_PORT_MAX, SOC_PBMP_PORT_MAX);
    188     }
    189 
    190     return SOC_E_NONE;
    191 }
    192 
    193 STATIC int
    194 soc_scache_dictionary_entry_get_real(int unit, const char *name, int *value)
    195 {
    196     int rv = SOC_E_NONE;
    197     uint8 *scache_ptr;
    198     soc_scache_handle_t scache_handle;
    199     uint32 alloc_size = 0;
    200     uint16 version = 0;
    201     uint16 default_ver = SOC_WB_DEFAULT_VERSION;
    202     uint16 recovered_ver = 0;
    203     int dictionary_size, i;
    204     soc_scache_dictionary_entry_t *dictionary_ptr;
    205 
    206     SOC_SCACHE_HANDLE_SET(scache_handle, unit,
    207                           SOC_SCACHE_DICTIONARY_HANDLE, 0);
    208     rv = soc_versioned_scache_ptr_get(unit, scache_handle,
    209                                       FALSE, &alloc_size, &scache_ptr,
    210                                       default_ver, &recovered_ver);
    211     if (SOC_FAILURE(rv)) {
    212         return rv;
    213     }
    214 
    215     if (SOC_SUCCESS(rv) && scache_ptr) {
    216         version = SOC_WARM_BOOT(unit) ? recovered_ver : default_ver;
    217         dictionary_size = soc_scache_dictionary_size(unit, version);
    218         dictionary_ptr = (soc_scache_dictionary_entry_t *)scache_ptr;
    219         for (i = 0; i < dictionary_size; i++) {
    220             if (SOC_SCACHE_DICTIONARY_ENTRY_MATCH(unit, dictionary_ptr, i, 
    221                                                   0, 0, name)) {
    222                 SOC_SCACHE_DICTIONARY_ENTRY_GET(unit, dictionary_ptr, i, value);
    223                 return SOC_E_NONE;
    224             }
    225         }
    226     }
    227 
    228     return SOC_E_NOT_FOUND;
    229 }
    230 
    231 int
    232 soc_scache_dictionary_entry_get(int unit, const char *name, int defl)
    233 {
    234     int rv, value;
    235     if ((rv = soc_scache_dictionary_entry_get_real(unit, name, &value)) < 0) {
    236         return defl;
    237     }
    238     return value;
    239 }
    240 
    241 int
    242 soc_scache_dictionary_entry_set(int unit, char *name, int value)
    243 {
    244     int rv = SOC_E_NONE;
    245     uint8 *scache_ptr;
    246     soc_scache_handle_t scache_handle;
    247     uint32 alloc_size = 0;
    248     uint16 version = 0;
    249     uint16 default_ver = SOC_WB_DEFAULT_VERSION;
    250     uint16 recovered_ver = 0;
    251     int dictionary_size, i, first_empty = -1;
    252     soc_scache_dictionary_entry_t *dictionary_ptr;
    253 
    254     SOC_SCACHE_HANDLE_SET(scache_handle, unit,
    255                           SOC_SCACHE_DICTIONARY_HANDLE, 0);
    256     rv = soc_versioned_scache_ptr_get(unit, scache_handle,
    257                                       FALSE, &alloc_size, &scache_ptr,
    258                                       default_ver, &recovered_ver);
    259     if (SOC_FAILURE(rv)) {
    260         return rv;
    261     }
    262 
    263     if (SOC_SUCCESS(rv) && scache_ptr) {
    264         version = SOC_WARM_BOOT(unit) ? recovered_ver : default_ver;
    265         dictionary_size = soc_scache_dictionary_size(unit, version);
    266         dictionary_ptr = (soc_scache_dictionary_entry_t *)scache_ptr;
    267         for (i = 0; i < dictionary_size; i++) {
    268             if (SOC_SCACHE_DICTIONARY_ENTRY_MATCH(unit, dictionary_ptr, i, 
    269                                                   0, 0, name)) {
    270                 SOC_SCACHE_DICTIONARY_ENTRY_SET_VALUE(unit, dictionary_ptr, i, 
    271                                                       value);
    272                 return SOC_E_NONE;
    273             }
    274             if ((first_empty < 0) && 
    275                 SOC_SCACHE_DICTIONARY_ENTRY_EMPTY(unit, dictionary_ptr, i)) {
    276                 first_empty = i;
    277             }
    278         }
    279         if (first_empty < 0) {
    280             return SOC_E_FULL;
    281         }
    282 
    283         SOC_SCACHE_DICTIONARY_ENTRY_SET(unit, dictionary_ptr, first_empty, 
    284                         0, 0, name, value);
    285     }
    286 
    287     return rv;
    288 }
    289 #else /* !BCM_WARM_BOOT_SUPPORT */
    290 int soc_common_scache_dictionary_not_empty;
    291 #endif /* !BCM_WARM_BOOT_SUPPORT */
    292