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

m0.c (8766B)


      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: 	m0.c
      8  * Purpose: 	ARM Cortex-M0 subsystem quad (M0SSQ) Support
      9  */
     10 
     11 #include <assert.h>
     12 #include <sal/core/libc.h>
     13 #include <shared/bsl.h>
     14 #include <bcm/error.h>
     15 #include <soc/types.h>
     16 #include <soc/drv.h>
     17 #include <appl/diag/shell.h>
     18 #include <appl/diag/system.h>
     19 
     20 #if defined(BCM_CMICX_SUPPORT)
     21 #include <soc/iproc.h>
     22 #include <shared/cmicfw/cmicx_link.h>
     23 #include <shared/cmicfw/iproc_fwconfig.h>
     24 
     25 #define M0FW_FILENAME_SIZE            (256)
     26 #define _SOC_M0FW_DEFAULT_PATHS_NUM   (7)
     27 
     28 #ifndef NO_FILEIO
     29 STATIC int
     30 _soc_m0fw_default_filename(int unit, char *filename) {
     31     int rv = SOC_E_NONE;
     32     int i = 0, found = 0;
     33     FILE *fp = NULL;
     34     char filepath[M0FW_FILENAME_SIZE] = {0};
     35 
     36     /* Search for M0 FW binary file in these locations */
     37     char paths[_SOC_M0FW_DEFAULT_PATHS_NUM][80] = \
     38                 {"../../rc/cmicfw/", "../rc/cmicfw", "rc/cmicfw/", "cmicfw/",
     39                  "../../../rc/cmicfw/","../../../../rc/cmicfw/", ""};
     40 
     41     if (sal_strlen(filename) > M0FW_FILENAME_SIZE) {
     42         cli_out("Filename cannot be longer than %d\n", M0FW_FILENAME_SIZE);
     43         return SOC_E_PARAM;
     44     }
     45 
     46     for(i = 0; i < _SOC_M0FW_DEFAULT_PATHS_NUM; i++) {
     47         sal_strncpy(filepath, paths[i], M0FW_FILENAME_SIZE-1);
     48         /* M0 FW binary filename is fixed */
     49         sal_strncat(filepath, filename, sal_strlen(filename));
     50         fp = sal_fopen(filepath, "rb");
     51         if (fp) {
     52             found = 1;
     53             strncpy(filename, filepath, M0FW_FILENAME_SIZE-1);
     54             sal_fclose(fp);
     55             break;
     56         }
     57     }
     58 
     59     if (!found) {
     60         rv = SOC_E_EXISTS;
     61     }
     62 
     63     return rv;
     64 }
     65 #endif /* NO_FILEIO */
     66 
     67 
     68 char m0_usage[] =
     69     "Parameters: <command> [<ucore>] [<address>] [<file>]\n"
     70 #ifndef COMPILER_STRING_CONST_LIMIT
     71     "\tcommand = [load/status/stats]\n"
     72     "\tucore   = Cortex-M0 ucore number to be loaded.\n"
     73     "\taddress = offset of shared SRAM to load binary file\n"
     74     "\tfile    = binary file name\n"
     75 #endif
     76     ;
     77 
     78 cmd_result_t
     79 m0_cmd(int unit, args_t *a)
     80 /*
     81  * Function: 	m0_cmd
     82  * Purpose:	Load a file into M0SSQ Cortex-M0 Private TCM
     83  * Parameters:	unit - unit
     84  *		a - args, each of the files to be displayed.
     85  * Returns:	CMD_OK/CMD_FAIL/CMD_USAGE
     86  */
     87 {
     88     cmd_result_t rv = CMD_OK;
     89     char *c;
     90     int ucnum;
     91     soc_stat_t          *stat;
     92 #if defined (BCM_ESW_SUPPORT) || defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT)
     93     soc_ls_heartbeat_t ls_hbeat;
     94 #endif /* BCM_ESW_SUPPORT || BCM_DNXF_SUPPORT */
     95 #ifndef NO_FILEIO
     96     int err;
     97     uint32 buf[64], addr;
     98     int fsize = 0, reqsize = 0, size = 0, i;
     99     int buf_size = sizeof(buf);
    100     int big_pio, big_packet, big_other;
    101     char filename[M0FW_FILENAME_SIZE] = {0};
    102 #endif
    103 
    104 #ifndef NO_FILEIO
    105 #ifndef NO_CTRL_C
    106     jmp_buf ctrl_c;
    107 #endif
    108     FILE * volatile fp = NULL;
    109 #endif
    110 
    111     /* check for simulation*/
    112     if (SAL_BOOT_BCMSIM) {
    113         return(rv);
    114     }
    115 
    116     if (!soc_feature(unit, soc_feature_cmicx)) {
    117         return (CMD_FAIL);
    118     }
    119 
    120     if (!sh_check_attached("m0", unit)) {
    121         return(CMD_FAIL);
    122     }
    123 
    124     if (!ARG_CNT(a)) {
    125         return(CMD_USAGE);
    126     }
    127 
    128     stat = SOC_STAT(unit);
    129     c = ARG_GET(a);
    130 
    131     if (!sal_strcasecmp(c, "load")) {
    132         c = ARG_GET(a);
    133         if (!isint(c)) {
    134             cli_out("%s: Error: uC Num not specified\n", ARG_CMD(a));
    135             return(CMD_USAGE);
    136         }
    137 
    138         ucnum = parse_integer(c);
    139         if (ucnum < 0 || ucnum > 3 /* SOC_INFO(unit).num_ucs */) {
    140             cli_out("Invalid uCnum number: %d, must be in the range 0 to 3", ucnum);
    141             return(CMD_FAIL);
    142         }
    143 
    144 #ifndef NO_FILEIO
    145         c = ARG_GET(a);
    146         if (!isint(c)) {
    147             cli_out("%s: Error: Address offset not specified\n", ARG_CMD(a));
    148             return(CMD_USAGE);
    149         }
    150         addr = parse_address(c);
    151 #endif
    152 
    153         c = ARG_GET(a);
    154 
    155         if (c == NULL) {
    156             cli_out("%s: Error: No file specified\n", ARG_CMD(a));
    157             return(CMD_USAGE);
    158         }
    159 
    160 #ifdef NO_FILEIO
    161         cli_out("no filesystem\n");
    162 #else
    163         if (sal_strlen(c) > M0FW_FILENAME_SIZE) {
    164             cli_out("Filename cannot be longer than %d\n", M0FW_FILENAME_SIZE);
    165             return(CMD_FAIL);
    166         }
    167 
    168         sal_strncpy(filename, c, sal_strlen(c));
    169 
    170         /* Check if file can be opened */
    171         fp = sal_fopen(filename, "rb");
    172 
    173         if (fp) {
    174             sal_fclose((FILE *)fp);
    175             fp = NULL;
    176         } else {
    177             /* Search for M0 FW binary file in default locations */
    178             err = _soc_m0fw_default_filename(unit, filename);
    179             if (err != SOC_E_NONE) {
    180                 cli_out("%s: Error: M0 Firmware file not found!!\n", ARG_CMD(a));
    181                 return (CMD_FAIL);
    182             }
    183         }
    184         cli_out("Loading M0 Firmware located at %s\n", filename);
    185 #endif /* NO_FILEIO */
    186 
    187 #ifdef NO_FILEIO
    188         cli_out("no filesystem\n");
    189 #else
    190 #ifndef NO_CTRL_C
    191         if (!setjmp(ctrl_c)) {
    192              sh_push_ctrl_c(&ctrl_c);
    193 #endif
    194              /* See if we can open the file before doing anything else */
    195             fp = sal_fopen(filename, "rb");
    196             if (!fp) {
    197                 cli_out("%s: Error: Unable to open file: %s\n",
    198                         ARG_CMD(a), filename);
    199                 rv = CMD_FAIL;
    200 #ifndef NO_CTRL_C
    201                 sh_pop_ctrl_c();
    202 #endif
    203                 return rv;
    204             }
    205 
    206             addr += soc_iproc_percore_membase_get(unit, ucnum);
    207 
    208             fsize = sal_fsize(fp);
    209 
    210             if (fsize <= 0) {
    211                 cli_out("%s: Error: file size is not valid: size = %d\n",
    212                         ARG_CMD(a), fsize);
    213                 sal_fclose((FILE *)fp);
    214 #ifndef NO_CTRL_C
    215                 sh_pop_ctrl_c();
    216 #endif
    217                 return CMD_FAIL;
    218             }
    219             soc_endian_get(unit, &big_pio, &big_packet, &big_other);
    220             do {
    221                 reqsize = (fsize > buf_size) ? buf_size : fsize;
    222                 fsize -= reqsize;
    223                 size = sal_fread(buf, 1 , reqsize, fp);
    224                 if (size < reqsize) {
    225                     cli_out("%s: Error: file read failed : requested = %d, read = %d\n",
    226                         ARG_CMD(a), reqsize, size);
    227                     sal_fclose((FILE *)fp);
    228 #ifndef NO_CTRL_C
    229                     sh_pop_ctrl_c();
    230 #endif
    231                     return CMD_FAIL;
    232                 }
    233 
    234                 for (i = 0; i < ((size + 3) / 4); i++) {
    235                     if (big_other) {
    236                         buf[i] = ((buf[i] & 0xff) << 24) | ((buf[i] & 0xff00) << 8) | ((buf[i] >> 8) & 0xff00) | ((buf[i] >> 24) & 0xff);
    237                     } else {
    238                         if (SOC_IS_DNX(unit) || SOC_IS_DNXF(unit) || SOC_IS_ESW(unit)) {
    239 #ifndef LE_HOST
    240                             buf[i] = ((buf[i] & 0xff) << 24) | ((buf[i] & 0xff00) << 8) | ((buf[i] >> 8) & 0xff00) | ((buf[i] >> 24) & 0xff);
    241 #endif
    242                         }
    243                     }
    244                     soc_cm_iproc_write(unit, addr, buf[i]);
    245                     addr += 4;
    246                 }
    247             } while(fsize);
    248 
    249             sal_fclose((FILE *)fp);
    250             fp = NULL;
    251 
    252 #ifndef NO_CTRL_C
    253         } else if (fp) {
    254             sal_fclose((FILE *)fp);
    255             fp = NULL;
    256             rv = CMD_INTR;
    257         }
    258         sh_pop_ctrl_c();
    259 #endif
    260 #endif /* NO_FILEIO */
    261         sal_usleep(10000);
    262     } else if (!sal_strcasecmp(c, "status")) {
    263 #if defined (BCM_ESW_SUPPORT) || defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT)
    264        int st = 0;
    265         st = soc_cmicx_linkscan_heartbeat(unit, &ls_hbeat);
    266         cli_out("M0 FW is %s\n", ((st == SOC_E_NONE) ? "Running" : "NOT Running"));
    267         cli_out("M0 FW Version is %d.%d\n",
    268                 (ls_hbeat.m0_fw_version >> 16), (ls_hbeat.m0_fw_version & 0xFFFF));
    269         cli_out("Host FW Version is %d.%d\n",
    270                 (ls_hbeat.host_fw_version >> 16), (ls_hbeat.host_fw_version & 0xFFFF));
    271         if (ls_hbeat.host_fw_version != ls_hbeat.m0_fw_version) {
    272             cli_out("Host and M0 FW Versions do not match!!!\n");
    273         }
    274 #endif /* BCM_ESW_SUPPORT || BCM_DNXF_SUPPORT */
    275     } else if (!sal_strcasecmp(c, "stats")) {
    276         cli_out("M0: msg=%d resp=%d intr=%d\n",
    277                 stat->m0_msg, stat->m0_resp,
    278                 stat->m0_intr);
    279 
    280         cli_out("Uc sw programmable total intr=%d\n",
    281              stat->uc_sw_prg_intr);
    282 
    283         cli_out("M0 sw programmable intr: u0=%d u1=%d u2=%d u3=%d\n",
    284              stat->m0_u0_sw_intr, stat->m0_u1_sw_intr,
    285              stat->m0_u2_sw_intr, stat->m0_u3_sw_intr);
    286     }
    287 
    288     return(rv);
    289 }
    290 #endif /* CMICX support */