diff options
Diffstat (limited to 'src/vendorcode/cavium/bdk/libbdk-dram')
8 files changed, 143 insertions, 164 deletions
diff --git a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-address.c b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-address.c index 94d7d76752..acefe1751c 100644 --- a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-address.c +++ b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-address.c @@ -72,9 +72,9 @@ bdk_dram_address_extract_info(uint64_t address, int *node, int *lmc, int *dimm, /* LMC number is probably aliased */ if (l2c_ctl.s.disidxalias) - *lmc = EXTRACT(address, 7, xbits); + *lmc = EXTRACT(address, 7, xbits); else - *lmc = EXTRACT(address, 7, xbits) ^ EXTRACT(address, bitno, xbits) ^ EXTRACT(address, 12, xbits); + *lmc = EXTRACT(address, 7, xbits) ^ EXTRACT(address, bitno, xbits) ^ EXTRACT(address, 12, xbits); /* Figure out the bank field width */ BDK_CSR_INIT(lmcx_config, *node, BDK_LMCX_CONFIG(*lmc)); @@ -176,7 +176,7 @@ bdk_dram_address_construct_info(bdk_node_t node, int lmc, int dimm, BDK_CSR_INIT(l2c_ctl, node, BDK_L2C_CTL); int new_lmc = lmc; if (!l2c_ctl.s.disidxalias) - new_lmc ^= EXTRACT(address, bitno, xbits) ^ EXTRACT(address, 12, xbits); + new_lmc ^= EXTRACT(address, bitno, xbits) ^ EXTRACT(address, 12, xbits); INSERT(address, new_lmc, 7, xbits); return address; diff --git a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-config.c b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-config.c index 3465c5d98b..5c104231dc 100644 --- a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-config.c +++ b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-config.c @@ -37,7 +37,9 @@ * ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. ***********************license end**************************************/ #include <bdk.h> -#include <unistd.h> +#include <string.h> +#include <libbdk-hal/bdk-config.h> +#include <libbdk-hal/bdk-l2c.h> BDK_REQUIRE_DEFINE(DRAM_CONFIG); @@ -73,22 +75,6 @@ int bdk_dram_config(int node, int ddr_clock_override) } /** - * Do DRAM configuration tuning - * - * @param node Node to tune - * - * @return Success or Fail - */ -int bdk_dram_tune(int node) -{ - int ret; - BDK_TRACE(DRAM, "N%d: Starting DRAM tuning\n", node); - ret = libdram_tune(node); - BDK_TRACE(DRAM, "N%d: DRAM tuning returned %d\n", node, ret); - return ret; -} - -/** * Do all the DRAM Margin tests * * @param node Node to test @@ -144,7 +130,9 @@ uint64_t bdk_dram_get_top_of_bdk(void) * the address to make it a physical offset. Doing this simplifies the * address checks and calculations which only work with physical offsets. */ - uint64_t top_of_bdk = (bdk_ptr_to_phys(sbrk(0)) & bdk_build_mask(40)); + /* FIXME(dhendrix): we only care about node 0 */ +// uint64_t top_of_bdk = (bdk_ptr_to_phys(sbrk(0)) & bdk_build_mask(40)); + uint64_t top_of_bdk = 0; uint64_t l2_size = bdk_l2c_get_cache_size_bytes(bdk_numa_master()); if (top_of_bdk <= l2_size) { diff --git a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-size.c b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-size.c index 122afb2a18..8cd4594818 100644 --- a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-size.c +++ b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-size.c @@ -37,6 +37,8 @@ * ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. ***********************license end**************************************/ #include <bdk.h> +#include <libbdk-hal/bdk-utils.h> + /** * Return the number of LMC controllers in use @@ -92,7 +94,7 @@ static int __bdk_dram_is_lmc_in_dreset(bdk_node_t node, int lmc) * * @param node Node to probe * - */ + */ uint32_t __bdk_dram_get_row_mask(bdk_node_t node, int lmc) { // PROTECT!!! @@ -108,7 +110,7 @@ uint32_t __bdk_dram_get_row_mask(bdk_node_t node, int lmc) * * @param node Node to probe * - */ + */ uint32_t __bdk_dram_get_col_mask(bdk_node_t node, int lmc) { // PROTECT!!! @@ -124,7 +126,7 @@ uint32_t __bdk_dram_get_col_mask(bdk_node_t node, int lmc) * * @param node Node to probe * - */ + */ // all DDR3, and DDR4 x16 today, use only 3 bank bits; DDR4 x4 and x8 always have 4 bank bits // NOTE: this will change in the future, when DDR4 x16 devices can come with 16 banks!! FIXME!! int __bdk_dram_get_num_bank_bits(bdk_node_t node, int lmc) @@ -181,9 +183,6 @@ int __bdk_dram_is_rdimm(bdk_node_t node, int lmc) */ uint64_t bdk_dram_get_size_mbytes(int node) { - if (bdk_is_platform(BDK_PLATFORM_EMULATOR)) - return 2 << 10; /* 2GB is available on t88 and t81 - ** some t83 models have 8gb, but it is too long to init */ /* Return zero if dram isn't enabled */ if (!__bdk_is_dram_enabled(node)) return 0; @@ -192,21 +191,13 @@ uint64_t bdk_dram_get_size_mbytes(int node) const int num_dram_controllers = __bdk_dram_get_num_lmc(node); for (int lmc = 0; lmc < num_dram_controllers; lmc++) { - if (bdk_is_platform(BDK_PLATFORM_ASIM)) - { - /* Asim doesn't simulate the rank detection, fake 4GB per controller */ - memsize += 4ull << 30; - } - else - { - // PROTECT!!! - if (__bdk_dram_is_lmc_in_dreset(node, lmc)) // check LMCn - return 0; - BDK_CSR_INIT(lmcx_config, node, BDK_LMCX_CONFIG(lmc)); - int num_ranks = bdk_pop(lmcx_config.s.init_status); - uint64_t rank_size = 1ull << (28 + lmcx_config.s.pbank_lsb - lmcx_config.s.rank_ena); - memsize += rank_size * num_ranks; - } + // PROTECT!!! + if (__bdk_dram_is_lmc_in_dreset(node, lmc)) // check LMCn + return 0; + BDK_CSR_INIT(lmcx_config, node, BDK_LMCX_CONFIG(lmc)); + int num_ranks = bdk_pop(lmcx_config.s.init_status); + uint64_t rank_size = 1ull << (28 + lmcx_config.s.pbank_lsb - lmcx_config.s.rank_ena); + memsize += rank_size * num_ranks; } return memsize >> 20; } diff --git a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-addrbus.c b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-addrbus.c index 9fe8570454..834ade4c40 100644 --- a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-addrbus.c +++ b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-addrbus.c @@ -37,6 +37,7 @@ * ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. ***********************license end**************************************/ #include "bdk.h" +#include <libbdk-hal/bdk-utils.h> /* Used for all memory reads/writes related to the test */ #define READ64(address) __bdk_dram_read64(address) diff --git a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-databus.c b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-databus.c index c3fa1ffd8d..b7a6f96880 100644 --- a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-databus.c +++ b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-databus.c @@ -38,6 +38,8 @@ ***********************license end**************************************/ #include "bdk.h" +#include <libbdk-hal/bdk-utils.h> + /* Used for all memory reads/writes related to the test */ #define READ64(address) __bdk_dram_read64(address) #define WRITE64(address, data) __bdk_dram_write64(address, data) @@ -97,7 +99,7 @@ static int read_data_bus_burst(uint64_t address, int bursts) */ static int write_data_bus_burst(uint64_t address, int bursts) { - BDK_TRACE(DRAM_TEST, "[0x%016lx:0x%016lx] Writing incrementing digits\n", + BDK_TRACE(DRAM_TEST, "[0x%016llx:0x%016llx] Writing incrementing digits\n", address, address + 127); /* Loop over the burst so people using a scope have time to capture traces */ @@ -164,7 +166,7 @@ static int read_data_bus_walk(uint64_t address, int burst, uint64_t pattern) */ static void write_data_bus_walk(uint64_t address, int burst, uint64_t pattern) { - BDK_TRACE(DRAM_TEST, "[0x%016lx:0x%016lx] Writing walking pattern 0x%016lx\n", + BDK_TRACE(DRAM_TEST, "[0x%016llx:0x%016llx] Writing walking pattern 0x%016llx\n", address, address + 127, pattern); uint64_t a = address; diff --git a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-fastscan.c b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-fastscan.c index 46e205dd80..c89ef76103 100644 --- a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-fastscan.c +++ b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-fastscan.c @@ -37,6 +37,7 @@ * ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. ***********************license end**************************************/ #include "bdk.h" +#include <libbdk-hal/bdk-utils.h> /* Used for all memory reads/writes related to the test */ #define READ64(address) __bdk_dram_read64(address) diff --git a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-patfil.c b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-patfil.c index e6c4b57721..6315172101 100644 --- a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-patfil.c +++ b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test-patfil.c @@ -37,6 +37,8 @@ * ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. ***********************license end**************************************/ #include "bdk.h" +#include <libbdk-hal/bdk-rng.h> +#include <libbdk-hal/bdk-utils.h> // choose prediction-based algorithms for mem_xor and mem_rows tests #define USE_PREDICTION_CODE_VERSIONS 1 // change to 0 to go back to the original versions @@ -286,7 +288,7 @@ static int test_mem_march_c(uint64_t area, uint64_t max_address, uint64_t patter int failures = 0; /* Pass 1 ascending addresses, fill memory with pattern. */ - BDK_TRACE(DRAM_TEST, " [0x%016lx:0x%016lx] Phase1, address incrementing, pattern 0x%016lx\n", area, max_address-1, pattern); + BDK_TRACE(DRAM_TEST, " [0x%016llx:0x%016llx] Phase1, address incrementing, pattern 0x%016llx\n", area, max_address-1, pattern); for (uint64_t address = area; address < max_address; address += 8) WRITE64(address, pattern); @@ -294,7 +296,7 @@ static int test_mem_march_c(uint64_t area, uint64_t max_address, uint64_t patter BDK_DCACHE_INVALIDATE; /* Pass 2: ascending addresses, read pattern and write ~pattern */ - BDK_TRACE(DRAM_TEST, " [0x%016lx:0x%016lx] Phase2, address incrementing, pattern 0x%016lx\n", area, max_address-1, ~pattern); + BDK_TRACE(DRAM_TEST, " [0x%016llx:0x%016llx] Phase2, address incrementing, pattern 0x%016llx\n", area, max_address-1, ~pattern); for (uint64_t address = area; address < max_address; address += 8) { uint64_t data = READ64(address); @@ -307,7 +309,7 @@ static int test_mem_march_c(uint64_t area, uint64_t max_address, uint64_t patter BDK_DCACHE_INVALIDATE; /* Pass 3: ascending addresses, read ~pattern and write pattern. */ - BDK_TRACE(DRAM_TEST, " [0x%016lx:0x%016lx] Phase3, address incrementing, pattern 0x%016lx\n", area, max_address-1, pattern); + BDK_TRACE(DRAM_TEST, " [0x%016llx:0x%016llx] Phase3, address incrementing, pattern 0x%016llx\n", area, max_address-1, pattern); for (uint64_t address = area; address < max_address; address += 8) { uint64_t data = READ64(address); @@ -320,7 +322,7 @@ static int test_mem_march_c(uint64_t area, uint64_t max_address, uint64_t patter BDK_DCACHE_INVALIDATE; /* Pass 4: descending addresses, read pattern and write ~pattern. */ - BDK_TRACE(DRAM_TEST, " [0x%016lx:0x%016lx] Phase4, address decrementing, pattern 0x%016lx\n", area, max_address-1, ~pattern); + BDK_TRACE(DRAM_TEST, " [0x%016llx:0x%016llx] Phase4, address decrementing, pattern 0x%016llx\n", area, max_address-1, ~pattern); uint64_t end = max_address - sizeof(uint64_t); for (uint64_t address = end; address >= area; address -= 8) { @@ -334,7 +336,7 @@ static int test_mem_march_c(uint64_t area, uint64_t max_address, uint64_t patter BDK_DCACHE_INVALIDATE; /* Pass 5: descending addresses, read ~pattern and write pattern. */ - BDK_TRACE(DRAM_TEST, " [0x%016lx:0x%016lx] Phase5, address decrementing, pattern 0x%016lx\n", area, max_address-1, pattern); + BDK_TRACE(DRAM_TEST, " [0x%016llx:0x%016llx] Phase5, address decrementing, pattern 0x%016llx\n", area, max_address-1, pattern); for (uint64_t address = end; address >= area; address -= 8) { uint64_t data = READ64(address); @@ -347,7 +349,7 @@ static int test_mem_march_c(uint64_t area, uint64_t max_address, uint64_t patter BDK_DCACHE_INVALIDATE; /* Pass 6: ascending addresses, read pattern. */ - BDK_TRACE(DRAM_TEST, " [0x%016lx:0x%016lx] Phase6, address incrementing\n", area, max_address-1); + BDK_TRACE(DRAM_TEST, " [0x%016llx:0x%016llx] Phase6, address incrementing\n", area, max_address-1); for (uint64_t address = area; address < max_address; address += 8) { uint64_t data = READ64(address); @@ -660,7 +662,7 @@ int __bdk_dram_test_mem_xor(uint64_t area, uint64_t max_address, int bursts) WRITE64(address1 , p); WRITE64(address1 + offset, p); address1 += 8; - p += pincr; + p += pincr; } __bdk_dram_flush_to_mem_range(area, max_address); BDK_DCACHE_INVALIDATE; @@ -674,7 +676,7 @@ int __bdk_dram_test_mem_xor(uint64_t area, uint64_t max_address, int bursts) address1 = area; this_pattern = bdk_rng_get_random64(); - pattern2 ^= this_pattern; + pattern2 ^= this_pattern; while (address1 < area2) { @@ -693,13 +695,13 @@ int __bdk_dram_test_mem_xor(uint64_t area, uint64_t max_address, int bursts) BDK_DCACHE_INVALIDATE; /* Look for differences from the expected pattern in both areas. - * If there is a mismatch, reset the appropriate memory location - * with the correct pattern. Failing to do so + * If there is a mismatch, reset the appropriate memory location + * with the correct pattern. Failing to do so * means that on all subsequent passes the erroring locations - * will be out of sync, giving spurious errors. + * will be out of sync, giving spurious errors. */ address1 = area; - ppred = pbase; + ppred = pbase; while (address1 < area2) { @@ -712,21 +714,21 @@ int __bdk_dram_test_mem_xor(uint64_t area, uint64_t max_address, int bursts) d1 = READ64(address1 ); d2 = READ64(address1 + offset); - p = ppred ^ pattern2; + p = ppred ^ pattern2; if (bdk_unlikely(d1 != p)) { - failures += __bdk_dram_retry_failure(burst, address1, d1, p); + failures += __bdk_dram_retry_failure(burst, address1, d1, p); // Synchronize the area, adjusting for the error. //WRITE64(address1, p); // retries should do this } if (bdk_unlikely(d2 != p)) { - failures += __bdk_dram_retry_failure(burst, address1 + offset, d2, p); + failures += __bdk_dram_retry_failure(burst, address1 + offset, d2, p); // Synchronize the area, adjusting for the error. //WRITE64(address1 + offset, p); // retries should do this } address1 += 8; - ppred += pincr; + ppred += pincr; } /* while (address1 < area2) */ } /* for (int burst = 0; burst < bursts; burst++) */ @@ -761,7 +763,7 @@ int __bdk_dram_test_mem_rows(uint64_t area, uint64_t max_address, int bursts) WRITE64(address1 , pattern2); WRITE64(address1 + offset, pattern2); address1 += 8; - pattern2 = ~pattern2; // flip for next slots + pattern2 = ~pattern2; // flip for next slots } __bdk_dram_flush_to_mem_range(area, max_address); @@ -771,7 +773,7 @@ int __bdk_dram_test_mem_rows(uint64_t area, uint64_t max_address, int bursts) for (burst = 0; burst < bursts; burst++) { /* Invert the data, applying the change to both memory areas. Thus on - * alternate passes, the data flips from 0 to 1 and vice versa. + * alternate passes, the data flips from 0 to 1 and vice versa. */ address1 = area; @@ -796,8 +798,8 @@ int __bdk_dram_test_mem_rows(uint64_t area, uint64_t max_address, int bursts) * out of sync giving spurious errors. */ address1 = area; - pattern1 = ~pattern1; // flip the starting pattern to match above loop - pattern2 = pattern1; // slots have been flipped by the above loop + pattern1 = ~pattern1; // flip the starting pattern to match above loop + pattern2 = pattern1; // slots have been flipped by the above loop while (address1 < area2) { @@ -810,18 +812,18 @@ int __bdk_dram_test_mem_rows(uint64_t area, uint64_t max_address, int bursts) d2 = READ64(address1 + offset); if (bdk_unlikely(d1 != pattern2)) { - failures += __bdk_dram_retry_failure(burst, address1, d1, pattern2); + failures += __bdk_dram_retry_failure(burst, address1, d1, pattern2); // Synchronize the area, adjusting for the error. //WRITE64(address1, pattern2); // retries should do this } if (bdk_unlikely(d2 != pattern2)) { - failures += __bdk_dram_retry_failure(burst, address1 + offset, d2, pattern2); + failures += __bdk_dram_retry_failure(burst, address1 + offset, d2, pattern2); // Synchronize the two areas, adjusting for the error. //WRITE64(address1 + offset, pattern2); // retries should do this } address1 += 8; - pattern2 = ~pattern2; // flip for next pair of slots + pattern2 = ~pattern2; // flip for next pair of slots } } return failures; diff --git a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test.c b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test.c index 53137502fc..4f54b69516 100644 --- a/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test.c +++ b/src/vendorcode/cavium/bdk/libbdk-dram/bdk-dram-test.c @@ -40,6 +40,14 @@ #include "libbdk-arch/bdk-csrs-gti.h" #include "libbdk-arch/bdk-csrs-ocx.h" +#include <bdk-minimal.h> /* for printf --> printk */ +#include <libbdk-dram/bdk-dram-test.h> +#include <libbdk-hal/bdk-atomic.h> +#include <libbdk-hal/bdk-clock.h> +#include <libbdk-hal/bdk-utils.h> +#include <libbdk-os/bdk-init.h> +#include <libbdk-os/bdk-thread.h> + /* This code is an optional part of the BDK. It is only linked in if BDK_REQUIRE() needs it */ BDK_REQUIRE_DEFINE(DRAM_TEST); @@ -170,7 +178,7 @@ static void dram_test_thread(int arg, void *arg1) start_address = bdk_numa_get_address(test_node, start_address); end_address = bdk_numa_get_address(test_node, end_address); /* Test the region */ - BDK_TRACE(DRAM_TEST, " Node %d, core %d, Testing [0x%011lx:0x%011lx]\n", + BDK_TRACE(DRAM_TEST, " Node %d, core %d, Testing [0x%011llx:0x%011llx]\n", bdk_numa_local(), bdk_get_core_num() & 127, start_address, end_address - 1); test_info->test_func(start_address, end_address, bursts); @@ -197,7 +205,7 @@ static int __bdk_dram_run_test(const dram_test_info_t *test_info, uint64_t start { /* Figure out the addess of the byte one off the top of memory */ uint64_t max_address = bdk_dram_get_size_mbytes(bdk_numa_local()); - BDK_TRACE(DRAM_TEST, "DRAM available per node: %lu MB\n", max_address); + BDK_TRACE(DRAM_TEST, "DRAM available per node: %llu MB\n", max_address); max_address <<= 20; /* Make sure we have enough */ @@ -218,13 +226,13 @@ static int __bdk_dram_run_test(const dram_test_info_t *test_info, uint64_t start if (max_address > (1ull << 43)) /* 43 bits in CN9XXX */ max_address = 1ull << 43; } - BDK_TRACE(DRAM_TEST, "DRAM max address: 0x%011lx\n", max_address-1); + BDK_TRACE(DRAM_TEST, "DRAM max address: 0x%011llx\n", max_address-1); /* Make sure the start address is lower than the top of memory */ if (start_address >= max_address) { - bdk_error("Start address is larger than the amount of memory: 0x%011lx versus 0x%011lx\n", - start_address, max_address); + bdk_error("Start address is larger than the amount of memory: 0x%011llx versus 0x%011llx\n", + start_address, max_address); return -1; } if (length == (uint64_t)-1) @@ -260,8 +268,8 @@ static int __bdk_dram_run_test(const dram_test_info_t *test_info, uint64_t start } } if (!(flags & BDK_DRAM_TEST_NO_BANNERS)) - printf("Starting Test \"%s\" for [0x%011lx:0x%011lx] using %d core(s)\n", - test_info->name, start_address, end_address - 1, total_cores_all_nodes); + printf("Starting Test \"%s\" for [0x%011llx:0x%011llx] using %d core(s)\n", + test_info->name, start_address, end_address - 1, total_cores_all_nodes); /* Remember the LMC perf counters for stats after the test */ uint64_t start_dram_dclk[BDK_NUMA_MAX_NODES][4]; @@ -332,15 +340,15 @@ static int __bdk_dram_run_test(const dram_test_info_t *test_info, uint64_t start /* Poke the watchdog */ BDK_CSR_WRITE(bdk_numa_local(), BDK_GTI_CWD_POKEX(0), 0); - /* disable progress output when batch mode is ON */ + /* disable progress output when batch mode is ON */ if (!(flags & BDK_DRAM_TEST_NO_PROGRESS)) { /* Report progress percentage */ int percent_x10 = (work_address - start_address) * 1000 / (end_address - start_address); - printf(" %3d.%d%% complete, testing [0x%011lx:0x%011lx]\r", + printf(" %3d.%d%% complete, testing [0x%011llx:0x%011llx]\r", percent_x10 / 10, percent_x10 % 10, work_address, work_address + size - 1); fflush(stdout); - } + } work_address += size; @@ -357,17 +365,8 @@ static int __bdk_dram_run_test(const dram_test_info_t *test_info, uint64_t start { if (per_node >= max_cores) break; - int run_node = (flags & BDK_DRAM_TEST_USE_CCPI) ? node ^ 1 : node; BDK_TRACE(DRAM_TEST, "Starting thread %d on node %d for memory test\n", per_node, node); - if (bdk_thread_create(run_node, 0, dram_test_thread, per_node, (void *)test_info, 0)) - { - bdk_error("Failed to create thread %d for memory test on node %d\n", per_node, node); - } - else - { - per_node++; - total_count++; - } + dram_test_thread(per_node, (void *)test_info); } } } @@ -384,7 +383,6 @@ static int __bdk_dram_run_test(const dram_test_info_t *test_info, uint64_t start uint64_t period = bdk_clock_get_rate(bdk_numa_local(), BDK_CLOCK_TIME) * TIMEOUT_SECS; // FIXME? uint64_t timeout = bdk_clock_get_count(BDK_CLOCK_TIME) + period; do { - bdk_thread_yield(); cur_count = bdk_atomic_get64(&dram_test_thread_done); cur_time = bdk_clock_get_count(BDK_CLOCK_TIME); if (cur_time >= timeout) { @@ -430,7 +428,7 @@ static int __bdk_dram_run_test(const dram_test_info_t *test_info, uint64_t start if (!(flags & BDK_DRAM_TEST_NO_PROGRESS)) { /* Report progress percentage as complete */ - printf(" %3d.%d%% complete, testing [0x%011lx:0x%011lx]\n", + printf(" %3d.%d%% complete, testing [0x%011llx:0x%011llx]\n", 100, 0, start_address, end_address - 1); fflush(stdout); } @@ -450,7 +448,7 @@ static int __bdk_dram_run_test(const dram_test_info_t *test_info, uint64_t start if (dclk == 0) dclk = 1; uint64_t percent_x10 = ops * 1000 / dclk; - printf(" Node %d, LMC%d: ops %lu, cycles %lu, used %lu.%lu%%\n", + printf(" Node %d, LMC%d: ops %llu, cycles %llu, used %llu.%llu%%\n", node, i, ops, dclk, percent_x10 / 10, percent_x10 % 10); } } @@ -471,7 +469,7 @@ static int __bdk_dram_run_test(const dram_test_info_t *test_info, uint64_t start if (total == 0) continue; uint64_t percent_x10 = busy * 1000 / total; - printf(" Node %d, CCPI%d: busy %lu, total %lu, used %lu.%lu%%\n", + printf(" Node %d, CCPI%d: busy %llu, total %llu, used %llu.%llu%%\n", node, link, busy, total, percent_x10 / 10, percent_x10 % 10); } } @@ -543,11 +541,13 @@ int bdk_dram_test(int test, uint64_t start_address, uint64_t length, bdk_dram_te /* Clear ECC error counters before starting the test */ for (int chan = 0; chan < BDK_MAX_MEM_CHANS; chan++) { - bdk_atomic_set64(&__bdk_dram_ecc_single_bit_errors[chan], 0); - bdk_atomic_set64(&__bdk_dram_ecc_double_bit_errors[chan], 0); + bdk_atomic_set64(&__bdk_dram_ecc_single_bit_errors[chan], 0); + bdk_atomic_set64(&__bdk_dram_ecc_double_bit_errors[chan], 0); } /* Make sure at least one core from each node is running */ + /* FIXME(dhendrix): we only care about core0 on node0 for now */ +#if 0 for (bdk_node_t node = BDK_NODE_0; node < BDK_NUMA_MAX_NODES; node++) { if (flags & (1<<node)) @@ -557,17 +557,11 @@ int bdk_dram_test(int test, uint64_t start_address, uint64_t length, bdk_dram_te bdk_init_cores(use_node, 1); } } +#endif /* This returns any data compare errors found */ int errors = __bdk_dram_run_test(&TEST_INFO[test], start_address, length, flags); - /* Poll for any errors right now to make sure any ECC errors are reported */ - for (bdk_node_t node = BDK_NODE_0; node < BDK_NUMA_MAX_NODES; node++) - { - if (bdk_numa_exists(node) && bdk_error_check) - bdk_error_check(node); - } - /* Check ECC error counters after the test */ int64_t ecc_single = 0; int64_t ecc_double = 0; @@ -582,14 +576,14 @@ int bdk_dram_test(int test, uint64_t start_address, uint64_t length, bdk_dram_te /* Always print any ECC errors */ if (ecc_single || ecc_double) { - printf("Test \"%s\": ECC errors, %ld/%ld/%ld/%ld corrected, %ld/%ld/%ld/%ld uncorrected\n", - name, - ecc_single_errs[0], ecc_single_errs[1], ecc_single_errs[2], ecc_single_errs[3], - ecc_double_errs[0], ecc_double_errs[1], ecc_double_errs[2], ecc_double_errs[3]); + printf("Test \"%s\": ECC errors, %lld/%lld/%lld/%lld corrected, %lld/%lld/%lld/%lld uncorrected\n", + name, + ecc_single_errs[0], ecc_single_errs[1], ecc_single_errs[2], ecc_single_errs[3], + ecc_double_errs[0], ecc_double_errs[1], ecc_double_errs[2], ecc_double_errs[3]); } if (errors || ecc_double || ecc_single) { - printf("Test \"%s\": FAIL: %ld single, %ld double, %d compare errors\n", - name, ecc_single, ecc_double, errors); + printf("Test \"%s\": FAIL: %lld single, %lld double, %d compare errors\n", + name, ecc_single, ecc_double, errors); } else BDK_TRACE(DRAM_TEST, "Test \"%s\": PASS\n", name); @@ -610,7 +604,7 @@ static void __bdk_dram_report_address_decode(uint64_t address, char *buffer, int bdk_dram_address_extract_info(address, &node, &lmc, &dimm, &prank, &lrank, &bank, &row, &col); snprintf(buffer, len, "[0x%011lx] (N%d,LMC%d,DIMM%d,Rank%d/%d,Bank%02d,Row 0x%05x,Col 0x%04x)", - address, node, lmc, dimm, prank, lrank, bank, row, col); + address, node, lmc, dimm, prank, lrank, bank, row, col); } /** @@ -632,22 +626,22 @@ static void __bdk_dram_report_address_decode_new(uint64_t address, uint64_t orig for (int i = 0; i < 8; i++) { bits = xor & 0xffULL; xor >>= 8; - if (bits) { - if (byte != 8) { - byte = 9; // means more than 1 byte-lane was present + if (bits) { + if (byte != 8) { + byte = 9; // means more than 1 byte-lane was present print_bits = orig_xor; // print the full original - break; // quit now - } else { - byte = i; // keep checking + break; // quit now + } else { + byte = i; // keep checking print_bits = bits; - } - } + } + } } - + bdk_dram_address_extract_info(address, &node, &lmc, &dimm, &prank, &lrank, &bank, &row, &col); snprintf(buffer, len, "N%d.LMC%d: CMP byte %d xor 0x%02lx (DIMM%d,Rank%d/%d,Bank%02d,Row 0x%05x,Col 0x%04x)[0x%011lx]", - node, lmc, byte, print_bits, dimm, prank, lrank, bank, row, col, address); + node, lmc, byte, print_bits, dimm, prank, lrank, bank, row, col, address); } /** @@ -671,15 +665,15 @@ void __bdk_dram_report_error(uint64_t address, uint64_t data, uint64_t correct, if (errors < MAX_ERRORS_TO_REPORT) { - if (fails < 0) { - snprintf(failbuf, sizeof(failbuf), " "); - } else { + if (fails < 0) { + snprintf(failbuf, sizeof(failbuf), " "); + } else { int percent_x10 = fails * 1000 / RETRY_LIMIT; - snprintf(failbuf, sizeof(failbuf), ", retries failed %3d.%d%%", + snprintf(failbuf, sizeof(failbuf), ", retries failed %3d.%d%%", percent_x10 / 10, percent_x10 % 10); - } + } - __bdk_dram_report_address_decode_new(address, xor, buffer, sizeof(buffer)); + __bdk_dram_report_address_decode_new(address, xor, buffer, sizeof(buffer)); bdk_error("%s%s\n", buffer, failbuf); if (errors == MAX_ERRORS_TO_REPORT-1) @@ -702,26 +696,26 @@ void __bdk_dram_report_error(uint64_t address, uint64_t data, uint64_t correct, * @return Zero if a message was logged, non-zero if the error limit has been reached */ void __bdk_dram_report_error2(uint64_t address1, uint64_t data1, uint64_t address2, uint64_t data2, - int burst, int fails) + int burst, int fails) { int64_t errors = bdk_atomic_fetch_and_add64(&dram_test_thread_errors, 1); if (errors < MAX_ERRORS_TO_REPORT) { - char buffer1[80], buffer2[80]; - char failbuf[32]; - - if (fails < 0) { - snprintf(failbuf, sizeof(failbuf), " "); - } else { - snprintf(failbuf, sizeof(failbuf), ", retried %d failed %d", RETRY_LIMIT, fails); - } - __bdk_dram_report_address_decode(address1, buffer1, sizeof(buffer1)); - __bdk_dram_report_address_decode(address2, buffer2, sizeof(buffer2)); - - bdk_error("compare: data1: 0x%016lx, xor: 0x%016lx%s\n" - " %s\n %s\n", - data1, data1 ^ data2, failbuf, - buffer1, buffer2); + char buffer1[80], buffer2[80]; + char failbuf[32]; + + if (fails < 0) { + snprintf(failbuf, sizeof(failbuf), " "); + } else { + snprintf(failbuf, sizeof(failbuf), ", retried %d failed %d", RETRY_LIMIT, fails); + } + __bdk_dram_report_address_decode(address1, buffer1, sizeof(buffer1)); + __bdk_dram_report_address_decode(address2, buffer2, sizeof(buffer2)); + + bdk_error("compare: data1: 0x%016llx, xor: 0x%016llx%s\n" + " %s\n %s\n", + data1, data1 ^ data2, failbuf, + buffer1, buffer2); if (errors == MAX_ERRORS_TO_REPORT-1) bdk_error("No further DRAM errors will be reported\n"); @@ -741,23 +735,23 @@ int __bdk_dram_retry_failure(int burst, uint64_t address, uint64_t data, uint64_ // bypass the retries if we are already over the limit... if (bdk_atomic_get64(&dram_test_thread_errors) < MAX_ERRORS_TO_REPORT) { - /* Try re-reading the memory location. A transient error may fail - * on one read and work on another. Keep on retrying even when a - * read succeeds. - */ - for (int i = 0; i < RETRY_LIMIT; i++) { + /* Try re-reading the memory location. A transient error may fail + * on one read and work on another. Keep on retrying even when a + * read succeeds. + */ + for (int i = 0; i < RETRY_LIMIT; i++) { - __bdk_dram_flush_to_mem(address); - BDK_DCACHE_INVALIDATE; + __bdk_dram_flush_to_mem(address); + BDK_DCACHE_INVALIDATE; - uint64_t new = __bdk_dram_read64(address); + uint64_t new = __bdk_dram_read64(address); - if (new != expected) { - refail++; - } - } + if (new != expected) { + refail++; + } + } } else - refail = -1; + refail = -1; // this will increment the errors always, but maybe not print... __bdk_dram_report_error(address, data, expected, burst, refail); @@ -779,20 +773,20 @@ int __bdk_dram_retry_failure2(int burst, uint64_t address1, uint64_t data1, uint // bypass the retries if we are already over the limit... if (bdk_atomic_get64(&dram_test_thread_errors) < MAX_ERRORS_TO_REPORT) { - for (int i = 0; i < RETRY_LIMIT; i++) { - __bdk_dram_flush_to_mem(address1); - __bdk_dram_flush_to_mem(address2); - BDK_DCACHE_INVALIDATE; + for (int i = 0; i < RETRY_LIMIT; i++) { + __bdk_dram_flush_to_mem(address1); + __bdk_dram_flush_to_mem(address2); + BDK_DCACHE_INVALIDATE; - uint64_t d1 = __bdk_dram_read64(address1); - uint64_t d2 = __bdk_dram_read64(address2); + uint64_t d1 = __bdk_dram_read64(address1); + uint64_t d2 = __bdk_dram_read64(address2); - if (d1 != d2) { - refail++; - } - } + if (d1 != d2) { + refail++; + } + } } else - refail = -1; + refail = -1; // this will increment the errors always, but maybe not print... __bdk_dram_report_error2(address1, data1, address2, data2, burst, refail); @@ -854,7 +848,7 @@ void bdk_dram_test_inject_error(uint64_t address, int bit) BDK_CSR_WRITE(node, BDK_LMCX_CHAR_MASK2(lmc), 0); /* Read back the data, which should now cause an error */ - printf("Loading the injected error address 0x%lx, node=%d, lmc=%d, dimm=%d, rank=%d/%d, bank=%d, row=%d, col=%d\n", + printf("Loading the injected error address 0x%llx, node=%d, lmc=%d, dimm=%d, rank=%d/%d, bank=%d, row=%d, col=%d\n", address, node, lmc, dimm, prank, lrank, bank, row, col); __bdk_dram_read64(aligned_address); } |