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