warmboot.c (6966B)
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 * File: warmboot.c 8 * Purpose: Sample Warm Boot cache in the Linux filesystem. 9 */ 10 11 12 #include <shared/bsl.h> 13 14 #include <sal/core/boot.h> 15 #include <sal/core/libc.h> 16 #include <sal/appl/io.h> 17 #include <shared/bsl.h> 18 #include <soc/drv.h> 19 #include <soc/scache.h> 20 21 /* Required for WB to DRAM (and not a file) */ 22 #ifdef BCM_PETRA_SUPPORT 23 #include <soc/dpp/error.h> 24 #include <soc/dpp/drv.h> 25 #include <soc/dpp/ARAD/arad_dram.h> 26 #include <bcm_int/dpp/error.h> 27 #endif 28 29 #ifdef BCM_WARM_BOOT_SUPPORT 30 31 #if (defined(LINUX) && !defined(__KERNEL__)) || defined(UNIX) 32 33 #include <stdio.h> 34 35 static FILE *scache_fp[SOC_MAX_NUM_DEVICES]; 36 /* Non-NULL indicates file opened */ 37 static sal_mutex_t file_lock[SOC_MAX_NUM_DEVICES]; 38 #ifndef NO_FILEIO 39 static char *scache_nm[SOC_MAX_NUM_DEVICES]; 40 /* Non-NULL indicates file selected */ 41 #endif 42 43 STATIC int 44 appl_scache_file_read_func(int unit, uint8 *buf, int offset, int nbytes) 45 { 46 size_t result; 47 48 if (!scache_fp[unit]) { 49 return SOC_E_UNIT; 50 } 51 if (sal_mutex_take(file_lock[unit],sal_mutex_FOREVER)) 52 { 53 cli_out("Unit %d: Mutex take failed\n", unit); 54 return SOC_E_FAIL; 55 } 56 if (0 != fseek(scache_fp[unit], offset, SEEK_SET)) { 57 return SOC_E_FAIL; 58 } 59 60 result = fread(buf, 1, nbytes, scache_fp[unit]); 61 if (result != nbytes) { 62 sal_mutex_give(file_lock[unit]); 63 return SOC_E_MEMORY; 64 } 65 if ( sal_mutex_give(file_lock[unit])) 66 { 67 cli_out("Unit %d: Mutex give failed\n", unit); 68 return SOC_E_FAIL; 69 } 70 return SOC_E_NONE; 71 } 72 73 STATIC int 74 appl_scache_file_write_func(int unit, uint8 *buf, int offset, int nbytes) 75 { 76 size_t result; 77 78 if (!scache_fp[unit]) { 79 return SOC_E_UNIT; 80 } 81 if (sal_mutex_take(file_lock[unit],sal_mutex_FOREVER)) 82 { 83 cli_out("Unit %d: Mutex take failed\n", unit); 84 return SOC_E_FAIL; 85 } 86 if (0 != fseek(scache_fp[unit], offset, SEEK_SET)) { 87 return SOC_E_FAIL; 88 } 89 90 result = fwrite(buf, 1, nbytes, scache_fp[unit]); 91 if (result != nbytes) { 92 if ( sal_mutex_give(file_lock[unit])) 93 { 94 cli_out("Unit %d: Mutex give failed\n", unit); 95 return SOC_E_FAIL; 96 } 97 return SOC_E_MEMORY; 98 } 99 fflush(scache_fp[unit]); 100 if ( sal_mutex_give(file_lock[unit])) 101 { 102 cli_out("Unit %d: Mutex give failed\n", unit); 103 return SOC_E_FAIL; 104 } 105 106 return SOC_E_NONE; 107 } 108 109 int 110 appl_scache_file_close(int unit) 111 { 112 #ifndef NO_FILEIO 113 if (!scache_nm[unit]) { 114 cli_out("Unit %d: Scache file is not set\n", unit); 115 return -1; 116 } 117 if (sal_mutex_take(file_lock[unit],sal_mutex_FOREVER)) 118 { 119 cli_out("Unit %d: Mutex take failed\n", unit); 120 return SOC_E_FAIL; 121 } 122 if (scache_fp[unit]) { 123 sal_fclose(scache_fp[unit]); 124 scache_fp[unit] = 0; 125 } 126 sal_free(scache_nm[unit]); 127 scache_nm[unit] = NULL; 128 sal_mutex_destroy(file_lock[unit]); 129 file_lock[unit]=0; 130 #endif 131 return 0; 132 } 133 134 int 135 appl_scache_file_open(int unit, int warm_boot, char *filename) 136 { 137 #ifndef NO_FILEIO 138 if (scache_nm[unit]) { 139 appl_scache_file_close(unit); 140 scache_nm[unit] = NULL; 141 } 142 if (NULL == filename) { 143 return 0; /* No scache file */ 144 } 145 file_lock[unit] = sal_mutex_create("schan-file"); 146 if (sal_mutex_take(file_lock[unit],sal_mutex_FOREVER)) 147 { 148 cli_out("Unit %d: Mutex take failed\n", unit); 149 return SOC_E_FAIL; 150 } 151 152 if ((scache_fp[unit] = 153 sal_fopen(filename, warm_boot ? "r+" : "w+")) == 0) { 154 cli_out("Unit %d: Error opening scache file %s\n", unit,filename); 155 return -1; 156 } 157 scache_nm[unit] = 158 sal_strncpy((char *)sal_alloc(sal_strlen(filename) + 1, __FILE__), 159 filename, sal_strlen(filename)); 160 { 161 if (soc_switch_stable_register(unit, 162 &appl_scache_file_read_func, 163 &appl_scache_file_write_func, 164 NULL, NULL) < 0) { 165 cli_out("Unit %d: soc_switch_stable_register failure\n", unit); 166 return -1; 167 } 168 } 169 if ( sal_mutex_give(file_lock[unit])) 170 { 171 cli_out("Unit %d: Mutex give failed\n", unit); 172 return SOC_E_FAIL; 173 } 174 #endif /* NO_FILEIO */ 175 return 0; 176 } 177 178 #else /* (defined(LINUX) && !defined(__KERNEL__)) || defined(UNIX) */ 179 180 int 181 appl_scache_file_close(int unit) 182 { 183 return 0; 184 } 185 186 int 187 appl_scache_file_open(int unit, int warm_boot) 188 { 189 return 0; 190 } 191 192 #endif /* (defined(LINUX) && !defined(__KERNEL__)) || defined(UNIX) */ 193 194 /* 195 * Function: 196 * appl_warm_boot_event_handler_cb 197 * 198 * Purpose: 199 * Warm boot event handler call back routine for test purpose. 200 * Parameters: 201 * unit - (IN) BCM device number 202 * event - (IN) Switch event type 203 * argX - (IN) Event Arguments 204 * userdata - (IN) user supplied data 205 * Returns: 206 * BCM_E_XXX 207 */ 208 void 209 appl_warm_boot_event_handler_cb(int unit, soc_switch_event_t event, 210 uint32 arg1, uint32 arg2, uint32 arg3, 211 void *userdata) 212 { 213 switch (event) { 214 case SOC_SWITCH_EVENT_STABLE_FULL: 215 case SOC_SWITCH_EVENT_STABLE_ERROR: 216 case SOC_SWITCH_EVENT_UNCONTROLLED_SHUTDOWN: 217 assert(0); 218 case SOC_SWITCH_EVENT_WARM_BOOT_DOWNGRADE: 219 break; 220 default: 221 break; 222 } 223 return; 224 } 225 226 #ifdef BCM_PETRA_SUPPORT 227 int 228 _arad_user_buffer_dram_read_cb( 229 int unit, 230 uint8 *buf, 231 int offset, 232 int nbytes) { 233 234 int rv = BCM_E_NONE; 235 236 rv = handle_sand_result(soc_arad_user_buffer_dram_read( 237 unit, 238 0x0, 239 buf, 240 offset, 241 nbytes)); 242 243 return rv; 244 } 245 246 int 247 _arad_user_buffer_dram_write_cb( 248 int unit, 249 uint8 *buf, 250 int offset, 251 int nbytes) { 252 SOC_SAND_IF_ERR_RETURN( 253 soc_arad_user_buffer_dram_write( 254 unit, 255 0x0, 256 buf, 257 offset, 258 nbytes)); 259 260 return BCM_E_NONE; 261 } 262 263 /* 264 * Write function signature to register for the application provided 265 * stable for Level 2 Warm Boot in user buffer (dram) 266 */ 267 268 int 269 appl_scache_user_buffer(int unit) 270 { 271 if (soc_switch_stable_register(unit, 272 &_arad_user_buffer_dram_read_cb, 273 &_arad_user_buffer_dram_write_cb, 274 NULL, NULL) < 0) { 275 cli_out("Unit %d: soc_switch_stable_register failure\n", unit); 276 return -1; 277 } 278 279 return 0; 280 } 281 #endif /* BCM_PETRA_SUPPORT */ 282 283 #else /* BCM_WARM_BOOT_SUPPORT */ 284 int _warmboot_not_empty; 285 #endif /* BCM_WARM_BOOT_SUPPORT */ 286 287