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

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