mbist_cpu.c (10435B)
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 * TR test for MBIST. 8 * The test has no CLI parameters. Simply call tr 505 from command line. 9 */ 10 #include <appl/diag/system.h> 11 #include <shared/alloc.h> 12 #include <sal/core/alloc.h> 13 #include <shared/bsl.h> 14 15 #include <soc/cm.h> 16 #include <soc/dma.h> 17 #include <soc/drv.h> 18 #include <soc/dcb.h> 19 #include <soc/cmicm.h> 20 #include <soc/cmic.h> 21 22 #include <sal/types.h> 23 #include <appl/diag/parse.h> 24 #include <appl/diag/system.h> 25 #include <bcm/port.h> 26 #include <bcm/vlan.h> 27 #include <bcm/link.h> 28 29 #include "testlist.h" 30 31 #ifdef BCM_TRIDENT2_SUPPORT 32 #include "mbist_cpu.h" 33 #include "td2p_mbist_cpu.h" 34 35 typedef struct mbist_cpu_test_s { 36 mbist_cpu_t *mbist_array; 37 uint32 total_mbist_count; 38 uint32 total_initial_failures; 39 uint32 total_final_failures; 40 uint32 total_failures; 41 uint64 reset_tap_control; 42 soc_reg_t tap_control; 43 soc_reg_t tap_write_data; 44 soc_reg_t tap_read_data; 45 uint32 bad_input; 46 uint32 test_fail; 47 } mbist_cpu_test_t; 48 49 static mbist_cpu_test_t *mbist_cpu_test_parray[SOC_MAX_NUM_DEVICES]; 50 51 /* 52 * Function: 53 * get_mbist_array 54 * Purpose: 55 * Populate members of mbist_cpu_test_t depending on the chip under test. 56 * Parameters: 57 * unit: StrataSwitch Unit #. 58 * 59 * Returns: 60 * Nothing 61 */ 62 63 static void 64 get_mbist_array(int unit) 65 { 66 uint16 dev_id; 67 uint8 rev_id; 68 69 mbist_cpu_test_t *mbist_cpu_p = mbist_cpu_test_parray[unit]; 70 71 soc_cm_get_id (unit, &dev_id, &rev_id); 72 73 if (dev_id == BCM56860_DEVICE_ID) { 74 cli_out("\nPopulating memory array for Trident2+"); 75 mbist_cpu_p->tap_control = TOP_UC_TAP_CONTROLr; 76 mbist_cpu_p->tap_write_data = TOP_UC_TAP_WRITE_DATAr; 77 mbist_cpu_p->tap_read_data = TOP_UC_TAP_READ_DATAr; 78 mbist_cpu_p->total_mbist_count = TD2P_TOTAL_MBIST_COUNT; 79 mbist_cpu_p->mbist_array = td2p_mbist_array; 80 COMPILER_64_SET(mbist_cpu_p->reset_tap_control, 0x0, 81 TD2P_RESET_TAP_CONTROL); 82 } else { 83 cli_out("\nUnsupported chip"); 84 mbist_cpu_p->bad_input = 1; 85 } 86 } 87 88 /* 89 * Function: 90 * run_mbist 91 * Purpose: 92 * Run a MBIST for a memory controller and if it fails run MBISTs for 93 * individual memories. Function is recursive. 94 * Parameters: 95 * unit: StrataSwitch Unit #. 96 * mbist_cpu_p: Pointer to structure of type mbist_cpu_t. 97 * 98 * Returns: 99 * Nothing 100 */ 101 102 static void 103 run_mbist(int unit, mbist_cpu_t *mbist_p) 104 { 105 uint32 idx_mbist_opcodes; 106 uint32 idx_tap_control = 0; 107 uint32 idx_tap_data = 0; 108 uint32 idx_tap_data_loop_cnt = 0; 109 uint32 idx_initial_mbist_status_cnt = 0; 110 uint32 idx_final_mbist_status_cnt = 0; 111 int i; 112 int j; 113 uint64 rdata; 114 uint32 rdata32; 115 uint32 fail = 0; 116 uint64 data_0x40000000_64; 117 118 mbist_cpu_test_t *mbist_cpu_p = mbist_cpu_test_parray[unit]; 119 120 cli_out("\n---- START MBIST %s ----", mbist_p->mbist_name); 121 122 COMPILER_64_SET(data_0x40000000_64, 0x0, 0x40000000); 123 124 for (idx_mbist_opcodes = 0; 125 idx_mbist_opcodes < mbist_p->total_opcodes; 126 idx_mbist_opcodes++) { 127 switch (mbist_p->mbist_opcodes[idx_mbist_opcodes]) { 128 case WRITE_TAP_CONTROL: 129 WRITE_TOP_UC_TAP_CONTROLr(unit, 130 mbist_p->tap_control[idx_tap_control]); 131 idx_tap_control++; 132 break; 133 case RESET_TAP_CONTROL: 134 (void) soc_reg_set(unit, mbist_cpu_p->tap_control, 0, 0, 135 mbist_cpu_p->reset_tap_control); 136 break; 137 case READ_TAP_CONTROL: 138 (void) soc_reg_get(unit, mbist_cpu_p->tap_control, 0, 0, &rdata); 139 break; 140 case WRITE_TAP_DATA: 141 WRITE_TOP_UC_TAP_WRITE_DATAr(unit, 142 mbist_p->tap_data[idx_tap_data]); 143 (void) soc_reg_set(unit, mbist_cpu_p->tap_control, 0, 0, 144 mbist_cpu_p->reset_tap_control); 145 idx_tap_data++; 146 break; 147 case WRITE_TAP_DATA_0x40000000: 148 (void) soc_reg_set(unit, mbist_cpu_p->tap_write_data, 0, 0, 149 data_0x40000000_64); 150 (void) soc_reg_set(unit, mbist_cpu_p->tap_control, 0, 0, 151 mbist_cpu_p->reset_tap_control); 152 break; 153 case WRITE_TAP_DATA_0x40000000_LOOP: 154 for (i = 0; i < mbist_p-> 155 tap_data_loop_cnt[idx_tap_data_loop_cnt]; 156 i++) { 157 (void) soc_reg_set(unit, mbist_cpu_p->tap_write_data, 0, 0, 158 data_0x40000000_64); 159 (void) soc_reg_set(unit, mbist_cpu_p->tap_control, 0, 0, 160 mbist_cpu_p->reset_tap_control); 161 } 162 idx_tap_data_loop_cnt++; 163 break; 164 case READ_TAP_DATA: 165 (void) soc_reg_get(unit, mbist_cpu_p->tap_read_data, 166 0, 0, &rdata); 167 break; 168 case MBIST_WAIT: 169 sal_usleep(50000); 170 break; 171 case CHECK_INITIAL_MBIST_STATUS: 172 (void) soc_reg_get(unit, mbist_cpu_p->tap_read_data, 173 0, 0, &rdata); 174 COMPILER_64_TO_32_LO(rdata32, rdata); 175 176 if (rdata32 177 == mbist_p->initial_mbist_status 178 [idx_initial_mbist_status_cnt]) { 179 cli_out("\nGot expected initial MBIST status for " 180 "%s", mbist_p->mbist_name); 181 } else { 182 test_error(unit, "\n*ERROR: Expected initial MBIST status = 0x%08x" 183 ", Actual initial MBIST status = 0x%08x", 184 mbist_p->initial_mbist_status 185 [idx_initial_mbist_status_cnt], 186 rdata32); 187 fail = 1; 188 mbist_cpu_p->test_fail = 1; 189 mbist_cpu_p->total_initial_failures++; 190 mbist_cpu_p->total_failures++; 191 } 192 193 idx_initial_mbist_status_cnt++; 194 break; 195 case CHECK_FINAL_MBIST_STATUS: 196 (void) soc_reg_get(unit, mbist_cpu_p->tap_read_data, 0, 0, &rdata); 197 COMPILER_64_TO_32_LO(rdata32, rdata); 198 if (rdata32 199 == mbist_p->final_mbist_status 200 [idx_final_mbist_status_cnt]) { 201 cli_out("\nGot expected final MBIST status for " 202 "%s", mbist_p->mbist_name); 203 } else { 204 test_error(unit, "\n*ERROR: Expected final MBIST status = 0x%08x" 205 ", Actual final MBIST status = 0x%08x", 206 mbist_p->final_mbist_status 207 [idx_final_mbist_status_cnt], 208 rdata32); 209 fail = 1; 210 mbist_cpu_p->test_fail = 1; 211 mbist_cpu_p->total_final_failures++; 212 mbist_cpu_p->total_failures++; 213 } 214 idx_final_mbist_status_cnt++; 215 break; 216 } 217 } 218 cli_out("\n---- END MBIST %s ----", mbist_p->mbist_name); 219 220 if ((fail == 1) && (mbist_p->waterfall == 1)) { 221 for (j = 0; j < mbist_p->num_mem; j++) { 222 run_mbist(unit, &mbist_p->mbist_wf_array[j]); 223 } 224 } 225 } 226 227 /* 228 * Function: 229 * mbist_cpu_test_init 230 * Purpose: 231 * Test init function. 232 * 233 * Parameters: 234 * unit: StrataSwitch Unit #. 235 */ 236 237 int 238 mbist_cpu_test_init(int unit, args_t *a, void **pa) 239 { 240 mbist_cpu_test_t *mbist_cpu_p = mbist_cpu_test_parray[unit]; 241 242 cli_out("\nCalling mbist_cpu_test_init"); 243 244 mbist_cpu_p = sal_alloc(sizeof(mbist_cpu_test_t), "mbist_cpu_test"); 245 sal_memset(mbist_cpu_p, 0, sizeof(mbist_cpu_test_t)); 246 mbist_cpu_test_parray[unit] = mbist_cpu_p; 247 248 mbist_cpu_p->bad_input = 0; 249 mbist_cpu_p->test_fail = 0; 250 mbist_cpu_p->total_initial_failures = 0; 251 mbist_cpu_p->total_final_failures = 0; 252 mbist_cpu_p->total_failures = 0; 253 254 get_mbist_array(unit); 255 256 return 0; 257 } 258 259 /* 260 * Function: 261 * mbist_cpu_test_init 262 * Purpose: 263 * Runs all MBISTs. 264 * 265 * Parameters: 266 * unit: StrataSwitch Unit #. 267 */ 268 269 int 270 mbist_cpu_test(int unit, args_t *a, void *pa) 271 { 272 int i; 273 mbist_cpu_test_t *mbist_cpu_p = mbist_cpu_test_parray[unit]; 274 275 cli_out("\nCalling mbist_cpu_test"); 276 277 (void) soc_mem_scan_stop(unit); 278 (void) bcm_linkscan_enable_set(unit, 0); 279 soc_counter_stop(unit); 280 281 if (mbist_cpu_p->bad_input == 1) { 282 goto done; 283 } 284 285 for (i = 0; i < mbist_cpu_p->total_mbist_count; i++) { 286 run_mbist(unit, &mbist_cpu_p->mbist_array[i]); 287 } 288 289 done: 290 291 return 0; 292 } 293 294 /* 295 * Function: 296 * mbist_cpu_test_init 297 * Purpose: 298 * Logs failure counts and frees memory. 299 * 300 * Parameters: 301 * unit: StrataSwitch Unit #. 302 */ 303 304 305 int 306 mbist_cpu_test_done(int unit, void *pa) 307 { 308 int rv; 309 310 mbist_cpu_test_t *mbist_cpu_p = mbist_cpu_test_parray[unit]; 311 312 cli_out("\nCalling mbist_cpu_test_done"); 313 314 if (mbist_cpu_p->bad_input == 1) { 315 goto done; 316 } 317 318 cli_out("\nTotal failures = %0d", mbist_cpu_p->total_failures); 319 cli_out("\nTotal initial failures = %0d", 320 mbist_cpu_p->total_initial_failures); 321 cli_out("\nTotal final failures = %0d", 322 mbist_cpu_p->total_final_failures); 323 324 done: 325 326 if (mbist_cpu_p->bad_input == 1) { 327 mbist_cpu_p->test_fail = 1; 328 } 329 330 if (mbist_cpu_p->test_fail == 1) { 331 rv = BCM_E_FAIL; 332 } else { 333 rv = BCM_E_NONE; 334 } 335 336 if (mbist_cpu_p->test_fail == 0) { 337 cli_out("\n********* All MBIST tests passed *********"); 338 } else { 339 test_error(unit, "********** ERROR: MBIST test failed *********"); 340 } 341 cli_out("\n"); 342 343 sal_free(mbist_cpu_p); 344 return rv; 345 } 346 #endif 347 /* BCM_TRIDENT2_SUPPORT */