sram.c (10477B)
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 * Triumph external SRAM CLI command 8 */ 9 10 #include <shared/bsl.h> 11 12 #include <soc/defs.h> 13 #include <shared/bsl.h> 14 #if defined(BCM_TRIUMPH_SUPPORT) 15 16 #include <appl/diag/system.h> 17 #include <bcm/error.h> 18 #include <soc/triumph.h> 19 20 static int 21 parse_string_backwards(char *end, uint32 *value, int *adj) 22 { 23 int i, shift = 0; 24 25 *value = 0; 26 *adj = 0; 27 28 for (i = 0; i < 6; i++) { 29 char ch = *--end; 30 int nibble = 31 ((ch >= 'a') && (ch <= 'f'))? (ch - 'a' + 10): 32 ((ch >= 'A') && (ch <= 'F'))? (ch - 'A' + 10): 33 ((ch >= '0') && (ch <= '9'))? (ch - '0'): 34 -1; 35 if (nibble == -1) { 36 if (i < 4) { 37 return -1; 38 } else if (i==4) { 39 uint32 hi, lo; 40 int j, phi=0, plo=0; 41 42 lo = *value & 0xff; 43 hi = (*value >> 8) & 0xff; 44 for (j = 0; j < 8; j++) { 45 phi ^= ((hi >> j) & 1); 46 plo ^= ((lo >> j) & 1); 47 } 48 *value = (lo) | (plo << 8) | (hi << 9) | (phi << 17); 49 return 1; 50 } else if ((i==5) && (ch == '_')) { 51 *adj += 1; 52 return 0; 53 } 54 } 55 *value |= (nibble << shift); 56 shift += 4; 57 } 58 return 0; 59 } 60 61 static int 62 parse_72_bits_to_4_words(char *s, uint32 *value) 63 { 64 char * end = s + sal_strlen(s); 65 int sum = 0; 66 int i, adj, rv; 67 68 if (sal_strlen(s) == 0) { 69 return -1; 70 } 71 72 for (i = 0; i < 4; i++) { 73 if ((rv = parse_string_backwards(end, &value[i], &adj)) < 0) { 74 return -1; 75 } 76 if (rv==1) sum += 1; 77 value[i] &= 0x3ffff; 78 end = end - 5 - adj; 79 } 80 81 if ((sum != 0) && (sum != 4)) return -1; 82 83 return 0; 84 } 85 86 char cmd_sram_usage[] = 87 "Usages:\n\t" 88 " sram hse|cse <addr0> <data0>\n\t" 89 " [addr1] [data1] [Testmode] [Adrmode] [Latency] [W2R] [R2W]\n\t" 90 " [wdoebr] [wdoebf] [wdmr] [wdmf] [rdmr] [rdmf]\n\n\t" 91 " - Test external SRAM\n" 92 ; 93 94 cmd_result_t 95 cmd_sram(int unit, args_t *a) 96 { 97 char *subcmd; 98 parse_table_t pt; 99 char *ds0 = NULL, *ds1 = NULL; 100 int rv, mode = 0; 101 int addr0 = -1, addr1 = -1; 102 int test_mode = 3; 103 int adr_mode = 2; 104 int late = 0, w2r = 0, r2w = 0; 105 int wdoebr = 0, wdoebf = 0, wdmr = 0, wdmf = 0, rdmr = 0, rdmf = 0; 106 #ifdef BCM_TRIUMPH_SUPPORT 107 tr_ext_sram_bist_t tr_sram_bist; 108 #endif /* BCM_TRIUMPH_SUPPORT */ 109 110 if (!sh_check_attached(ARG_CMD(a), unit)) { 111 return CMD_FAIL; 112 } 113 114 if (!soc_feature(unit, soc_feature_esm_support)) { 115 cli_out("Command only valid for BCM566xx devices\n"); 116 return CMD_FAIL; 117 } 118 119 if ((subcmd = ARG_GET(a)) == NULL) { 120 return CMD_USAGE; 121 } 122 123 if (soc_feature(unit, soc_feature_esm_support)) { 124 if (!sal_strcasecmp(subcmd, "es0")) { 125 mode = 0; 126 } else if (!sal_strcasecmp(subcmd, "es1")) { 127 /* coverity[assignment] */ 128 mode = 1; 129 } else { 130 return CMD_USAGE; 131 } 132 } 133 134 parse_table_init(unit, &pt); 135 parse_table_add(&pt, "Testmode", PQ_DFL|PQ_HEX, 0, &test_mode, NULL); 136 parse_table_add(&pt, "Adrmode", PQ_DFL|PQ_HEX, 0, &adr_mode, NULL); 137 parse_table_add(&pt, "Addr0", PQ_DFL|PQ_HEX, 0, &addr0, NULL); 138 parse_table_add(&pt, "Addr1", PQ_DFL|PQ_HEX, 0, &addr1, NULL); 139 parse_table_add(&pt, "Data0", PQ_DFL|PQ_STRING, 0, &ds0, NULL); 140 parse_table_add(&pt, "Data1", PQ_DFL|PQ_STRING, 0, &ds1, NULL); 141 parse_table_add(&pt, "Latency", PQ_DFL|PQ_INT, 0, &late, NULL); 142 parse_table_add(&pt, "W2R", PQ_DFL|PQ_INT, 0, &w2r, NULL); 143 parse_table_add(&pt, "R2W", PQ_DFL|PQ_INT, 0, &r2w, NULL); 144 parse_table_add(&pt, "WDOEBR", PQ_DFL|PQ_INT, 0, &wdoebr, NULL); 145 parse_table_add(&pt, "WDOEBF", PQ_DFL|PQ_INT, 0, &wdoebf, NULL); 146 parse_table_add(&pt, "WDMR", PQ_DFL|PQ_INT, 0, &wdmr, NULL); 147 parse_table_add(&pt, "WDMF", PQ_DFL|PQ_INT, 0, &wdmf, NULL); 148 parse_table_add(&pt, "RDMR", PQ_DFL|PQ_INT, 0, &rdmr, NULL); 149 parse_table_add(&pt, "RDMF", PQ_DFL|PQ_INT, 0, &rdmf, NULL); 150 if (parse_arg_eq(a, &pt) < 0) { 151 cli_out("%s ERROR: parsing arguments\n", ARG_CMD(a)); 152 parse_arg_eq_done(&pt); 153 return CMD_FAIL; 154 } 155 156 if ((ds0 == NULL) || (addr0 == -1)) { 157 parse_arg_eq_done(&pt); 158 return CMD_USAGE; 159 } 160 161 #ifdef BCM_TRIUMPH_SUPPORT 162 if (soc_feature(unit, soc_feature_esm_support)) { 163 uint32 data[4]; 164 sal_memset(&tr_sram_bist, 0, sizeof(tr_ext_sram_bist_t)); 165 166 rv = soc_triumph_ext_sram_enable_set(unit, mode, TRUE, TRUE); 167 if (rv < 0) { 168 cli_out("Fail to enable LTE for test.\n"); 169 parse_arg_eq_done(&pt); 170 return CMD_FAIL; 171 } 172 /* coverity[uninit_use_in_call : FALSE] */ 173 174 /* coverity[uninit_use_in_call] */ 175 if ((rv = parse_72_bits_to_4_words(ds0, &data[0])) != 0) { 176 cli_out("Wrong data input format, see example below:\n\n"); 177 cli_out("Use data0=12345_0abcd_12345_0abcd for raw data,\n"); 178 cli_out("or data0=1234_abcd_1234_abcd for inserting"); 179 cli_out(" 1 parity bit/byte.\n"); 180 parse_arg_eq_done(&pt); 181 return CMD_FAIL; 182 } 183 tr_sram_bist.d0f_0 = data[0]; 184 tr_sram_bist.d0f_1 = data[1]; 185 tr_sram_bist.d0r_0 = data[2]; 186 tr_sram_bist.d0r_1 = data[3]; 187 LOG_INFO(BSL_LS_APPL_TESTS, 188 (BSL_META_U(unit, 189 "Program data register ES0_DTU_LTE_D0:\n"))); 190 LOG_INFO(BSL_LS_APPL_TESTS, 191 (BSL_META_U(unit, 192 "D0R_1 = 0x%x, D0R_0 = 0x%x, D0F_1 = 0x%x, D0F_0 = 0x%x\n"), 193 tr_sram_bist.d0r_1, tr_sram_bist.d0r_0, 194 tr_sram_bist.d0f_1, tr_sram_bist.d0f_1)); 195 LOG_INFO(BSL_LS_APPL_TESTS, 196 (BSL_META_U(unit, 197 "Program address register CSE_DTU_LTE_ADR0:\n"))); 198 LOG_INFO(BSL_LS_APPL_TESTS, 199 (BSL_META_U(unit, 200 "DTU_LTE_ADR0 = 0x%x\n"), (addr0 & 0xfffff))); 201 if (ds1 && (addr1 != -1)) { 202 if ((rv = parse_72_bits_to_4_words(ds1, data)) != 0) { 203 cli_out("Wrong data input format, see example below:\n\n"); 204 cli_out("Use data1=12345_0abcd_12345_0abcd for raw data,\n"); 205 cli_out("or data1=1234_abcd_1234_abcd for inserting"); 206 cli_out(" 1 parity bit/byte.\n"); 207 parse_arg_eq_done(&pt); 208 return CMD_FAIL; 209 } 210 tr_sram_bist.d1f_0 = data[0]; 211 tr_sram_bist.d1f_1 = data[1]; 212 tr_sram_bist.d1r_0 = data[2]; 213 tr_sram_bist.d1r_1 = data[3]; 214 LOG_INFO(BSL_LS_APPL_TESTS, 215 (BSL_META_U(unit, 216 "Program data register CSE_DTU_LTE_D1:\n"))); 217 LOG_INFO(BSL_LS_APPL_TESTS, 218 (BSL_META_U(unit, 219 "D1R_1 = 0x%x, D1R_0 = 0x%x, D1F_1 = 0x%x, D1F_0 = 0x%x\n"), 220 tr_sram_bist.d1r_1, tr_sram_bist.d1r_0, 221 tr_sram_bist.d1f_1, tr_sram_bist.d1f_0)); 222 LOG_INFO(BSL_LS_APPL_TESTS, 223 (BSL_META_U(unit, 224 "Program address register CSE_DTU_LTE_ADR1:\n"))); 225 LOG_INFO(BSL_LS_APPL_TESTS, 226 (BSL_META_U(unit, 227 "DTU_LTE_ADR1 = 0x%x\n"), (addr1 & 0xfffff))); 228 } 229 230 tr_sram_bist.adr0 = addr0; 231 tr_sram_bist.adr1 = addr1; 232 tr_sram_bist.loop_mode = test_mode; 233 tr_sram_bist.adr_mode = adr_mode; 234 tr_sram_bist.em_latency = late; 235 tr_sram_bist.w2r_nops = w2r; 236 tr_sram_bist.r2w_nops = r2w; 237 tr_sram_bist.wdoebr = wdoebr; 238 tr_sram_bist.wdoebf = wdoebf; 239 tr_sram_bist.wdmr = wdmr; 240 tr_sram_bist.wdmf = wdmf; 241 tr_sram_bist.rdmr = rdmr; 242 tr_sram_bist.rdmf = rdmf; 243 } 244 #endif /* BCM_TRIUMPH_SUPPORT */ 245 parse_arg_eq_done(&pt); 246 247 LOG_INFO(BSL_LS_APPL_TESTS, 248 (BSL_META_U(unit, 249 "Start the test with...\n"))); 250 LOG_INFO(BSL_LS_APPL_TESTS, 251 (BSL_META_U(unit, 252 "test_mode = %d, adr_mode = %d, latency7 = %d\n"), 253 (test_mode & 3), (adr_mode & 3), late & 7)); 254 LOG_INFO(BSL_LS_APPL_TESTS, 255 (BSL_META_U(unit, 256 "wdoebr = 0x%x, wdoebf = 0x%x wdmr = 0x%x\n"), 257 wdoebr, wdoebf, wdmr)); 258 LOG_INFO(BSL_LS_APPL_TESTS, 259 (BSL_META_U(unit, 260 "wdmf = 0x%x, rdmr = 0x%x rdmf = 0x%x\n"), 261 wdmf, rdmr, rdmf)); 262 263 #ifdef BCM_TRIUMPH_SUPPORT 264 if (soc_feature(unit, soc_feature_esm_support)) { 265 soc_triumph_ext_sram_bist_setup(unit, mode, &tr_sram_bist); 266 rv = soc_triumph_ext_sram_op(unit, mode, &tr_sram_bist, NULL); 267 if (rv < 0) { 268 cli_out("Fail to run LTE %s test.\n", subcmd); 269 (void) soc_triumph_ext_sram_enable_set(unit, mode, FALSE, FALSE); 270 return CMD_FAIL; 271 } 272 if ((tr_sram_bist.err_cnt != 0) || (tr_sram_bist.err_bitmap != 0)) { 273 cli_out("unit %d: %s ext SRAM has %d errors with bitmap 0x%02x\n", 274 unit, subcmd, tr_sram_bist.err_cnt, 275 tr_sram_bist.err_bitmap); 276 cli_out("Error Address: 0x%x\n", tr_sram_bist.err_adr); 277 cli_out("Error Data:\n"); 278 cli_out("ERR_DR_1=0x%x ERR_DR_0=0x%x ERR_DF_1=0x%x ERR_DF_0=0x%x\n", 279 tr_sram_bist.err_dr_1, tr_sram_bist.err_dr_0, 280 tr_sram_bist.err_df_1, tr_sram_bist.err_df_0); 281 } else { 282 cli_out("%s LTE test finished successfully\n", subcmd); 283 } 284 285 if ((rv = soc_triumph_ext_sram_enable_set(unit, mode, FALSE, FALSE)) < 286 0) { 287 cli_out("Fail to disable LTE after test.\n"); 288 (void) soc_triumph_ext_sram_enable_set(unit, mode, FALSE, FALSE); 289 return CMD_FAIL; 290 } 291 } 292 #endif /* BCM_TRIUMPH_SUPPORT */ 293 294 return CMD_OK; 295 } 296 297 #endif /* BCM_TRIUMPH_SUPPORT */