mem_bulk_test.c (11657B)
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 * mem bulk tests 8 */ 9 10 #include <shared/bsl.h> 11 12 #include <sal/core/libc.h> 13 #include <stdarg.h> 14 15 #include <sal/types.h> 16 #include <soc/mem.h> 17 #include <soc/register.h> 18 #include <soc/cm.h> 19 20 #include <sal/appl/pci.h> 21 #include <sal/appl/sal.h> 22 #include <sal/core/boot.h> 23 #include <sal/core/time.h> 24 25 #include <soc/l2x.h> 26 #include <soc/l3x.h> 27 #include <soc/phyctrl.h> 28 #include <soc/phy.h> 29 #include <soc/error.h> 30 #include <soc/soc_mem_bulk.h> 31 32 #include <bcm/error.h> 33 #include <bcm/link.h> 34 35 #include <bcm_int/esw/mbcm.h> 36 37 #include <appl/diag/system.h> 38 #include <appl/diag/parse.h> 39 #include <appl/diag/test.h> 40 #include <appl/diag/progress.h> 41 42 #include "testlist.h" 43 /* Decimal point formatting */ 44 #define INT_FRAC_2PT(x) (x) / 100, (x) % 100 45 46 #define BULK_BUFMEM_SIZE 0x100000 47 48 typedef struct mem_bulk_op_s { 49 /* memory */ 50 soc_mem_t *mem; 51 52 /* index */ 53 int *index; 54 55 /* Copy number */ 56 int *copyno; 57 58 /* Data ptr*/ 59 uint32 **entry; 60 61 /* Data */ 62 uint32 *data; 63 64 } mem_bulk_op_t; 65 66 typedef struct bulk_test_s { 67 uint32 testMask; 68 int memTableID; 69 int testNum; 70 int sizeMem; 71 soc_mem_t test_mem; 72 mem_bulk_op_t buf_mem; 73 char *testName; 74 sal_usecs_t stime; 75 sal_usecs_t etime; 76 uint32 dataSize; 77 uint32 dataWidth; 78 char *dataUnit; 79 } bulk_test_t; 80 #if defined(BCM_ESW_SUPPORT) && defined(BCM_CMICX_SUPPORT) 81 int 82 mem_bulk_test_cleanup(int u, void *pa) 83 { 84 bulk_test_t *b = (bulk_test_t *) pa; 85 86 if (b) { 87 if (b->buf_mem.mem) { 88 sal_free(b->buf_mem.mem); 89 } 90 if (b->buf_mem.index) { 91 sal_free(b->buf_mem.index); 92 } 93 if (b->buf_mem.copyno) { 94 sal_free(b->buf_mem.copyno); 95 } 96 if (b->buf_mem.entry) { 97 sal_free(b->buf_mem.entry); 98 } 99 if (b->buf_mem.data) { 100 sal_free(b->buf_mem.data); 101 } 102 sal_free(b); 103 } 104 105 return 0; 106 } 107 108 int 109 mem_bulk_test_init(int u, args_t *a, void **pa) 110 { 111 bulk_test_t *b = 0; 112 int rv = SOC_E_FAIL; 113 parse_table_t pt; 114 soc_mem_t mem; 115 int count = 0; 116 const char mem_bulk_test_usage[] = 117 "MemTableID: Memory table selection\n" 118 " 0->L3_DEFIP_ALPM_LEVEL3m.\n" 119 " 1->L3_DEFIP_ALPM_LEVEL2m.\n" 120 " 2->L3_DEFIP_LEVEL1m.\n" 121 " 3->L3_DEFIP_PAIR_LEVEL1m.\n" 122 " 4->L3_DEFIP_ALPM_LEVEL3_HIT_ONLYm.\n" 123 " 5->L3_DEFIP_ALPM_LEVEL2_HIT_ONLYm.\n" 124 " 6->L3_DEFIP_ALPM_LEVEL3m.\n" 125 "Count : Number of operations (200 by default).\n"; 126 127 *pa = NULL; 128 129 if ((b = sal_alloc(sizeof (bulk_test_t), "bulk_test")) == NULL) { 130 goto done; 131 } 132 133 sal_memset(b, 0, sizeof (*b)); 134 135 *pa = (void *) b; 136 137 b->testMask = ~0; 138 b->testNum = 0; 139 b->sizeMem = 200; 140 141 parse_table_init(u, &pt); 142 parse_table_add(&pt, "TestMask", PQ_HEX|PQ_DFL, 0, 143 &b->testMask, NULL); 144 145 parse_table_add(&pt, "MemTableID", PQ_HEX|PQ_DFL, 0, 146 &b->memTableID, NULL); 147 148 parse_table_add(&pt, "Count", PQ_INT|PQ_DFL, 0, 149 &b->sizeMem, NULL); 150 151 if (parse_arg_eq(a, &pt) < 0 || ARG_CNT(a) != 0) { 152 test_error(u, 153 "%s: Invalid option: %s\n", 154 ARG_CMD(a), 155 ARG_CUR(a) ? ARG_CUR(a) : "*"); 156 parse_arg_eq_done(&pt); 157 goto done; 158 } 159 160 if (parse_arg_eq(a, &pt) < 0 || ARG_CNT(a) != 0) { 161 test_msg("%s", mem_bulk_test_usage); 162 test_error(u, 163 "%s: Invalid option: %s\n", 164 ARG_CMD(a), 165 ARG_CUR(a) ? ARG_CUR(a) : "*"); 166 parse_arg_eq_done(&pt); 167 rv = BCM_E_FAIL; 168 goto done; 169 } else { 170 cli_out("\n ------------- PRINTING TEST PARAMS ------------------"); 171 cli_out("\ntestMask = %0d", b->testMask); 172 cli_out("\nmemTableID = %0d", b->memTableID); 173 cli_out("\nsizeMem = %0d", b->sizeMem); 174 cli_out("\n -----------------------------------------------------\n"); 175 } 176 177 parse_arg_eq_done(&pt); 178 179 switch (b->memTableID) { 180 case 0: b->test_mem = L3_DEFIP_ALPM_LEVEL3m; break; 181 case 1: b->test_mem = L3_DEFIP_ALPM_LEVEL2m; break; 182 case 2: b->test_mem = L3_DEFIP_LEVEL1m; break; 183 case 3: b->test_mem = L3_DEFIP_PAIR_LEVEL1m; break; 184 case 4: b->test_mem = L3_DEFIP_ALPM_LEVEL3_HIT_ONLYm; break; 185 case 5: b->test_mem = L3_DEFIP_ALPM_LEVEL2_HIT_ONLYm; break; 186 case 6: b->test_mem = L3_DEFIP_ALPM_LEVEL3m; break; 187 default:b->test_mem = L3_DEFIP_ALPM_LEVEL3m; break; 188 } 189 190 mem = b->test_mem; 191 count = b->sizeMem; 192 if (!SOC_MEM_IS_VALID(u, mem)) { 193 rv = BCM_E_FAIL; 194 goto done; 195 } 196 197 if (count == 0) { 198 LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(u, 199 "Size of Table[%s] is ZERO\n"), 200 SOC_MEM_UFNAME(u, mem))); 201 goto done; 202 } 203 204 /* Allocate memory buffers */ 205 if ((b->buf_mem.mem = 206 sal_alloc(count * sizeof(soc_mem_t), "bulk_op_mem")) == NULL) { 207 cli_out("Not enough host memory\n"); 208 goto done; 209 } 210 211 if ((b->buf_mem.index = 212 sal_alloc(count * sizeof(int), "bulk_op_id")) == NULL) { 213 cli_out("Not enough host memory\n"); 214 goto done; 215 } 216 217 if ((b->buf_mem.copyno = 218 sal_alloc(count * sizeof(int), "bulk_op_copy")) == NULL) { 219 cli_out("Not enough host memory\n"); 220 goto done; 221 } 222 223 if ((b->buf_mem.entry = 224 sal_alloc(count * sizeof(uint32 *), "bulk_op_entry")) == NULL) { 225 cli_out("Not enough host memory\n"); 226 goto done; 227 } 228 229 if ((b->buf_mem.data = 230 sal_alloc(BULK_BUFMEM_SIZE * sizeof(uint32), "bulk_op_data")) == NULL) { 231 cli_out("Not enough host memory\n"); 232 goto done; 233 } 234 sal_memset(b->buf_mem.data, 0, BULK_BUFMEM_SIZE * sizeof(uint32)); 235 236 rv = 0; 237 238 done: 239 if (rv < 0) { 240 mem_bulk_test_cleanup(u, *pa); 241 } 242 243 return rv; 244 } 245 246 static int 247 mem_bulk_test_begin(bulk_test_t *b, 248 char *testName, 249 char *dataUnit, 250 uint32 dataSize, 251 uint32 dataWidth) 252 { 253 assert(b->testName == NULL); 254 255 if ((b->testMask & (1U << b->testNum)) == 0) { 256 return 0; 257 } 258 259 b->testName = testName; 260 b->dataSize = dataSize; 261 b->dataUnit = dataUnit; 262 b->dataWidth = dataWidth; 263 b->stime = sal_time_usecs(); 264 265 return 1; 266 } 267 268 static void 269 mem_bulk_test_end(bulk_test_t *b) 270 { 271 if (b->testName) { 272 uint32 per_sec, usec_per; 273 sal_usecs_t td; 274 char plus = ' ', lessthan = ' '; 275 276 b->etime = sal_time_usecs(); 277 td = SAL_USECS_SUB(b->etime, b->stime); 278 if (td == 0) { 279 td = 1; /* Non-zero value */ 280 plus = '+'; 281 lessthan = '<'; 282 } 283 per_sec = _shr_div_exp10(b->dataSize, td, 8); 284 usec_per = b->dataSize ? _shr_div_exp10(td, b->dataSize, 2) : 0; 285 cli_out ("\n Entry Size = %0d words\n", b->dataWidth); 286 cli_out("%2d) %-28s%7d.%02d%c %5s/sec ; %c%7d.%02d usec/%s\n", 287 b->testNum, 288 b->testName, 289 INT_FRAC_2PT(per_sec), 290 plus, 291 b->dataUnit, 292 lessthan, 293 INT_FRAC_2PT(usec_per), 294 b->dataUnit); 295 b->testName = 0; 296 } 297 b->testNum++; 298 } 299 300 static int 301 mem_bulk_test_validate(int unit, bulk_test_t *b, int count) 302 { 303 int rv = 0; 304 int i; 305 uint32 entry[SOC_MAX_MEM_WORDS]; 306 int size; 307 308 for (i = 0; i < count; i++) { 309 uint32 *data = b->buf_mem.entry[i]; 310 size = soc_mem_entry_words(unit, b->buf_mem.mem[i]); 311 rv = soc_mem_read(unit, b->buf_mem.mem[i], MEM_BLOCK_ANY, 312 b->buf_mem.index[i], entry); 313 if (rv == SOC_E_NONE) { 314 if (sal_memcmp(data, entry, size * sizeof(uint32)) != 0) { 315 LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, 316 "Data mismatch:[%s] index = %d \n"), 317 SOC_MEM_UFNAME(unit, b->buf_mem.mem[i]), b->buf_mem.index[i])); 318 rv = SOC_E_FAIL; 319 break; 320 } 321 } else { 322 break; 323 } 324 } 325 326 return rv; 327 } 328 329 int 330 mem_bulk_test(int unit, args_t *a, void *pa) 331 { 332 bulk_test_t *b = (bulk_test_t *) pa; 333 int rv = SOC_E_NONE; 334 int i; 335 soc_mem_t mem = 0; 336 soc_mem_blk_handle_t handle; 337 int size = 0; 338 uint8 skip_cache; 339 340 skip_cache = SOC_MEM_TEST_SKIP_CACHE(unit); 341 342 SOC_MEM_TEST_SKIP_CACHE_SET(unit, TRUE); 343 344 mem = b->test_mem; 345 if (!SOC_MEM_IS_VALID(unit, mem)) { 346 goto error; 347 } 348 cli_out("\nName of test mem: %s\n", 349 SOC_MEM_NAME(unit, mem)); 350 size = soc_mem_entry_words(unit, mem); 351 cli_out ("\nTotal num of writes = %0d\n", b->sizeMem); 352 for (i = 0; i < b->sizeMem; i++) { 353 uint32 *data; 354 b->buf_mem.mem[i] = mem; 355 b->buf_mem.index[i] = i; 356 b->buf_mem.copyno[i] = MEM_BLOCK_ALL; 357 b->buf_mem.entry[i] = &b->buf_mem.data[i * size]; 358 data = b->buf_mem.entry[i]; 359 rv = soc_mem_read(unit,mem, MEM_BLOCK_ANY, 360 i, data); 361 if (rv != SOC_E_NONE) { 362 LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, 363 "Memory Read Error = %d\n"), rv)); 364 goto error; 365 } 366 } 367 /* Get mem bulk handle */ 368 rv = soc_mem_bulk_op(unit, SOC_MEM_BULK_WRITE_INIT, &handle, 0, 0, 0, NULL); 369 370 if (rv != SOC_E_NONE) { 371 LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, 372 "Error in allocating bulk handle = %d\n"), rv)); 373 goto error; 374 } 375 376 /* Stage the entries to write */ 377 for (i = 0; i < b->sizeMem; i++) { 378 rv = soc_mem_bulk_op(unit, SOC_MEM_BULK_WRITE_STAGE, &handle, 379 b->buf_mem.mem[i], b->buf_mem.index[i], 380 b->buf_mem.copyno[i], b->buf_mem.entry[i]); 381 if (rv != SOC_E_NONE) { 382 LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, 383 "Error in staging bulk data = %d\n"), rv)); 384 goto error; 385 } 386 } 387 388 /* Bulk mem commit */ 389 if (mem_bulk_test_begin(b, "Mem bulk Commit", "Entry", 390 b->sizeMem, size)) { 391 rv = soc_mem_bulk_op(unit, SOC_MEM_BULK_WRITE_COMMIT, &handle, 0, 0, 0, NULL); 392 if (rv != SOC_E_NONE) { 393 LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, 394 "Error in commiting bulk data = %d\n"), rv)); 395 goto error; 396 } 397 mem_bulk_test_end(b); 398 rv = mem_bulk_test_validate(unit, b, b->sizeMem); 399 } 400 401 /* Bulk mem write */ 402 if (mem_bulk_test_begin(b, "Mem bulk Write", "Entry", 403 b->sizeMem, size)) { 404 rv = soc_mem_bulk_write(unit, b->buf_mem.mem, b->buf_mem.index, b->buf_mem.copyno, 405 b->buf_mem.entry, b->sizeMem); 406 if (rv != SOC_E_NONE) { 407 LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, 408 "Error in writing bulk data = %d\n"), rv)); 409 goto error; 410 } 411 mem_bulk_test_end(b); 412 rv = mem_bulk_test_validate(unit, b, b->sizeMem); 413 } 414 415 error: 416 SOC_MEM_TEST_SKIP_CACHE_SET(unit, skip_cache); 417 return rv; 418 } 419 #endif /* BCM_ESW_SUPPORT) && BCM_CMICX_SUPPORT */