| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504 |
- // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
- /*
- * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
- */
- #define LOG_CATEGORY UCLASS_RAM
- #include <common.h>
- #include <console.h>
- #include <init.h>
- #include <log.h>
- #include <rand.h>
- #include <watchdog.h>
- #include <asm/global_data.h>
- #include <asm/io.h>
- #include <linux/log2.h>
- #include "stm32mp1_tests.h"
- #define ADDR_INVALID 0xFFFFFFFF
- #define PATTERN_DEFAULT "-"
- DECLARE_GLOBAL_DATA_PTR;
- static int get_bufsize(char *string, int argc, char *argv[], int arg_nb,
- size_t *bufsize, size_t default_size, size_t min_size)
- {
- unsigned long value;
- if (argc > arg_nb) {
- if (strict_strtoul(argv[arg_nb], 0, &value) < 0) {
- sprintf(string, "invalid %d parameter %s",
- arg_nb, argv[arg_nb]);
- return -1;
- }
- if (value > STM32_DDR_SIZE || value < min_size) {
- sprintf(string, "invalid size %s (min=%d)",
- argv[arg_nb], min_size);
- return -1;
- }
- if (value & (min_size - 1)) {
- sprintf(string, "unaligned size %s (min=%d)",
- argv[arg_nb], min_size);
- return -1;
- }
- *bufsize = value;
- } else {
- if (default_size != STM32_DDR_SIZE)
- *bufsize = default_size;
- else
- *bufsize = get_ram_size((long *)STM32_DDR_BASE,
- STM32_DDR_SIZE);
- }
- return 0;
- }
- static int get_nb_loop(char *string, int argc, char *argv[], int arg_nb,
- u32 *nb_loop, u32 default_nb_loop)
- {
- unsigned long value;
- if (argc > arg_nb) {
- if (strict_strtoul(argv[arg_nb], 0, &value) < 0) {
- sprintf(string, "invalid %d parameter %s",
- arg_nb, argv[arg_nb]);
- return -1;
- }
- if (value == 0)
- printf("WARNING: infinite loop requested\n");
- *nb_loop = value;
- } else {
- *nb_loop = default_nb_loop;
- }
- return 0;
- }
- static int get_addr(char *string, int argc, char *argv[], int arg_nb,
- u32 *addr)
- {
- unsigned long value;
- if (argc > arg_nb) {
- if (strict_strtoul(argv[arg_nb], 16, &value) < 0) {
- sprintf(string, "invalid %d parameter %s",
- arg_nb, argv[arg_nb]);
- return -1;
- }
- if (value < STM32_DDR_BASE) {
- sprintf(string, "too low address %s", argv[arg_nb]);
- return -1;
- }
- if (value & 0x3 && value != ADDR_INVALID) {
- sprintf(string, "unaligned address %s",
- argv[arg_nb]);
- return -1;
- }
- *addr = value;
- } else {
- *addr = STM32_DDR_BASE;
- }
- return 0;
- }
- static int get_pattern(char *string, int argc, char *argv[], int arg_nb,
- u32 *pattern, u32 default_pattern)
- {
- unsigned long value;
- if (argc > arg_nb) {
- if (!strcmp(argv[arg_nb], PATTERN_DEFAULT)) {
- *pattern = default_pattern;
- return 0;
- }
- if (strict_strtoul(argv[arg_nb], 16, &value) < 0) {
- sprintf(string, "invalid %d parameter %s",
- arg_nb, argv[arg_nb]);
- return -1;
- }
- *pattern = value;
- } else {
- *pattern = default_pattern;
- }
- return 0;
- }
- static u32 check_addr(u32 addr, u32 value)
- {
- u32 data = readl(addr);
- if (value != data) {
- printf("0x%08x: 0x%08x <=> 0x%08x", addr, data, value);
- data = readl(addr);
- printf("(2nd read: 0x%08x)", data);
- if (value == data)
- printf("- read error");
- else
- printf("- write error");
- printf("\n");
- return -1;
- }
- return 0;
- }
- static int progress(u32 offset)
- {
- if (!(offset & 0xFFFFFF)) {
- putc('.');
- if (ctrlc()) {
- printf("\ntest interrupted!\n");
- return 1;
- }
- }
- return 0;
- }
- static int test_loop_end(u32 *loop, u32 nb_loop, u32 progress)
- {
- (*loop)++;
- if (nb_loop && *loop >= nb_loop)
- return 1;
- if ((*loop) % progress)
- return 0;
- /* allow to interrupt the test only for progress step */
- if (ctrlc()) {
- printf("test interrupted!\n");
- return 1;
- }
- printf("loop #%d\n", *loop);
- schedule();
- return 0;
- }
- /**********************************************************************
- *
- * Function: memTestDataBus()
- *
- * Description: Test the data bus wiring in a memory region by
- * performing a walking 1's test at a fixed address
- * within that region. The address is selected
- * by the caller.
- *
- * Notes:
- *
- * Returns: 0 if the test succeeds.
- * A non-zero result is the first pattern that failed.
- *
- **********************************************************************/
- static u32 databus(u32 *address)
- {
- u32 pattern;
- u32 read_value;
- /* Perform a walking 1's test at the given address. */
- for (pattern = 1; pattern != 0; pattern <<= 1) {
- /* Write the test pattern. */
- writel(pattern, address);
- /* Read it back (immediately is okay for this test). */
- read_value = readl(address);
- log_debug("%x: %x <=> %x\n",
- (u32)address, read_value, pattern);
- if (read_value != pattern)
- return pattern;
- }
- return 0;
- }
- /**********************************************************************
- *
- * Function: memTestAddressBus()
- *
- * Description: Test the address bus wiring in a memory region by
- * performing a walking 1's test on the relevant bits
- * of the address and checking for aliasing. This test
- * will find single-bit address failures such as stuck
- * -high, stuck-low, and shorted pins. The base address
- * and size of the region are selected by the caller.
- *
- * Notes: For best results, the selected base address should
- * have enough LSB 0's to guarantee single address bit
- * changes. For example, to test a 64-Kbyte region,
- * select a base address on a 64-Kbyte boundary. Also,
- * select the region size as a power-of-two--if at all
- * possible.
- *
- * Returns: NULL if the test succeeds.
- * A non-zero result is the first address at which an
- * aliasing problem was uncovered. By examining the
- * contents of memory, it may be possible to gather
- * additional information about the problem.
- *
- **********************************************************************/
- static u32 *addressbus(u32 *address, u32 nb_bytes)
- {
- u32 mask = (nb_bytes / sizeof(u32) - 1);
- u32 offset;
- u32 test_offset;
- u32 read_value;
- u32 pattern = 0xAAAAAAAA;
- u32 antipattern = 0x55555555;
- /* Write the default pattern at each of the power-of-two offsets. */
- for (offset = 1; (offset & mask) != 0; offset <<= 1)
- writel(pattern, &address[offset]);
- /* Check for address bits stuck high. */
- test_offset = 0;
- writel(antipattern, &address[test_offset]);
- for (offset = 1; (offset & mask) != 0; offset <<= 1) {
- read_value = readl(&address[offset]);
- log_debug("%x: %x <=> %x\n",
- (u32)&address[offset], read_value, pattern);
- if (read_value != pattern)
- return &address[offset];
- }
- writel(pattern, &address[test_offset]);
- /* Check for address bits stuck low or shorted. */
- for (test_offset = 1; (test_offset & mask) != 0; test_offset <<= 1) {
- writel(antipattern, &address[test_offset]);
- if (readl(&address[0]) != pattern)
- return &address[test_offset];
- for (offset = 1; (offset & mask) != 0; offset <<= 1) {
- if (readl(&address[offset]) != pattern &&
- offset != test_offset)
- return &address[test_offset];
- }
- writel(pattern, &address[test_offset]);
- }
- return NULL;
- }
- /**********************************************************************
- *
- * Function: memTestDevice()
- *
- * Description: Test the integrity of a physical memory device by
- * performing an increment/decrement test over the
- * entire region. In the process every storage bit
- * in the device is tested as a zero and a one. The
- * base address and the size of the region are
- * selected by the caller.
- *
- * Notes:
- *
- * Returns: NULL if the test succeeds.
- *
- * A non-zero result is the first address at which an
- * incorrect value was read back. By examining the
- * contents of memory, it may be possible to gather
- * additional information about the problem.
- *
- **********************************************************************/
- static u32 *memdevice(u32 *address, u32 nb_bytes)
- {
- u32 offset;
- u32 nb_words = nb_bytes / sizeof(u32);
- u32 pattern;
- u32 antipattern;
- puts("Fill with pattern");
- /* Fill memory with a known pattern. */
- for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) {
- writel(pattern, &address[offset]);
- if (progress(offset))
- return NULL;
- }
- puts("\nCheck and invert pattern");
- /* Check each location and invert it for the second pass. */
- for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) {
- if (readl(&address[offset]) != pattern)
- return &address[offset];
- antipattern = ~pattern;
- writel(antipattern, &address[offset]);
- if (progress(offset))
- return NULL;
- }
- puts("\nCheck inverted pattern");
- /* Check each location for the inverted pattern and zero it. */
- for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) {
- antipattern = ~pattern;
- if (readl(&address[offset]) != antipattern)
- return &address[offset];
- if (progress(offset))
- return NULL;
- }
- printf("\n");
- return NULL;
- }
- static enum test_result databuswalk0(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- int i;
- u32 loop = 0, nb_loop;
- u32 addr;
- u32 error = 0;
- u32 data;
- if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100))
- return TEST_ERROR;
- if (get_addr(string, argc, argv, 1, &addr))
- return TEST_ERROR;
- printf("running %d loops at 0x%x\n", nb_loop, addr);
- while (!error) {
- for (i = 0; i < 32; i++)
- writel(~(1 << i), addr + 4 * i);
- for (i = 0; i < 32; i++) {
- data = readl(addr + 4 * i);
- if (~(1 << i) != data) {
- error |= 1 << i;
- log_debug("%x: error %x expected %x => error:%x\n",
- addr + 4 * i, data, ~(1 << i), error);
- }
- }
- if (test_loop_end(&loop, nb_loop, 1000))
- break;
- for (i = 0; i < 32; i++)
- writel(0, addr + 4 * i);
- }
- if (error) {
- sprintf(string, "loop %d: error for bits 0x%x",
- loop, error);
- return TEST_FAILED;
- }
- sprintf(string, "no error for %d loops", loop);
- return TEST_PASSED;
- }
- static enum test_result databuswalk1(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- int i;
- u32 loop = 0, nb_loop;
- u32 addr;
- u32 error = 0;
- u32 data;
- if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100))
- return TEST_ERROR;
- if (get_addr(string, argc, argv, 1, &addr))
- return TEST_ERROR;
- printf("running %d loops at 0x%x\n", nb_loop, addr);
- while (!error) {
- for (i = 0; i < 32; i++)
- writel(1 << i, addr + 4 * i);
- for (i = 0; i < 32; i++) {
- data = readl(addr + 4 * i);
- if ((1 << i) != data) {
- error |= 1 << i;
- log_debug("%x: error %x expected %x => error:%x\n",
- addr + 4 * i, data, (1 << i), error);
- }
- }
- if (test_loop_end(&loop, nb_loop, 1000))
- break;
- for (i = 0; i < 32; i++)
- writel(0, addr + 4 * i);
- }
- if (error) {
- sprintf(string, "loop %d: error for bits 0x%x",
- loop, error);
- return TEST_FAILED;
- }
- sprintf(string, "no error for %d loops", loop);
- return TEST_PASSED;
- }
- static enum test_result test_databus(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- u32 addr;
- u32 error;
- if (get_addr(string, argc, argv, 0, &addr))
- return TEST_ERROR;
- error = databus((u32 *)addr);
- if (error) {
- sprintf(string, "0x%x: error for bits 0x%x",
- addr, error);
- return TEST_FAILED;
- }
- sprintf(string, "address 0x%x", addr);
- return TEST_PASSED;
- }
- static enum test_result test_addressbus(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- u32 addr;
- u32 bufsize;
- u32 error;
- if (get_bufsize(string, argc, argv, 0, &bufsize, STM32_DDR_SIZE, 4))
- return TEST_ERROR;
- if (!is_power_of_2(bufsize)) {
- sprintf(string, "size 0x%x is not a power of 2",
- (u32)bufsize);
- return TEST_ERROR;
- }
- if (get_addr(string, argc, argv, 1, &addr))
- return TEST_ERROR;
- printf("running at 0x%08x length 0x%x\n", addr, bufsize);
- error = (u32)addressbus((u32 *)addr, bufsize);
- if (error) {
- sprintf(string, "0x%x: error for address 0x%x",
- addr, error);
- return TEST_FAILED;
- }
- sprintf(string, "address 0x%x, size 0x%x",
- addr, bufsize);
- return TEST_PASSED;
- }
- static enum test_result test_memdevice(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- u32 addr;
- size_t bufsize;
- u32 error;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
- return TEST_ERROR;
- if (get_addr(string, argc, argv, 1, &addr))
- return TEST_ERROR;
- error = (u32)memdevice((u32 *)addr, (unsigned long)bufsize);
- if (error) {
- sprintf(string, "0x%x: error for address 0x%x",
- addr, error);
- return TEST_FAILED;
- }
- sprintf(string, "address 0x%x, size 0x%x",
- addr, bufsize);
- return TEST_PASSED;
- }
- /**********************************************************************
- *
- * Function: sso
- *
- * Description: Test the Simultaneous Switching Output.
- * Verifies succes sive reads and writes to the same memory word,
- * holding one bit constant while toggling all other data bits
- * simultaneously
- * => stress the data bus over an address range
- *
- * The CPU writes to each address in the given range.
- * For each bit, first the CPU holds the bit at 1 while
- * toggling the other bits, and then the CPU holds the bit at 0
- * while toggling the other bits.
- * After each write, the CPU reads the address that was written
- * to verify that it contains the correct data
- *
- **********************************************************************/
- static enum test_result test_sso(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- int i, j;
- u32 addr, bufsize, remaining, offset;
- u32 error = 0;
- u32 data;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
- return TEST_ERROR;
- if (get_addr(string, argc, argv, 1, &addr))
- return TEST_ERROR;
- printf("running sso at 0x%x length 0x%x", addr, bufsize);
- offset = addr;
- remaining = bufsize;
- while (remaining) {
- for (i = 0; i < 32; i++) {
- /* write pattern. */
- for (j = 0; j < 6; j++) {
- switch (j) {
- case 0:
- case 2:
- data = 1 << i;
- break;
- case 3:
- case 5:
- data = ~(1 << i);
- break;
- case 1:
- data = ~0x0;
- break;
- case 4:
- data = 0x0;
- break;
- }
- writel(data, offset);
- error = check_addr(offset, data);
- if (error)
- goto end;
- }
- }
- offset += 4;
- remaining -= 4;
- if (progress(offset << 7))
- goto end;
- }
- puts("\n");
- end:
- if (error) {
- sprintf(string, "error for pattern 0x%x @0x%x",
- data, offset);
- return TEST_FAILED;
- }
- sprintf(string, "no error for sso at 0x%x length 0x%x", addr, bufsize);
- return TEST_PASSED;
- }
- /**********************************************************************
- *
- * Function: Random
- *
- * Description: Verifies r/w with pseudo-ramdom value on one region
- * + write the region (individual access)
- * + memcopy to the 2nd region (try to use burst)
- * + verify the 2 regions
- *
- **********************************************************************/
- static enum test_result test_random(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- u32 addr, offset, value = 0;
- size_t bufsize;
- u32 loop = 0, nb_loop;
- u32 error = 0;
- unsigned int seed;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 8))
- return TEST_ERROR;
- if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
- return TEST_ERROR;
- if (get_addr(string, argc, argv, 2, &addr))
- return TEST_ERROR;
- bufsize /= 2;
- printf("running %d loops copy from 0x%x to 0x%x (buffer size=0x%x)\n",
- nb_loop, addr, addr + bufsize, bufsize);
- while (!error) {
- seed = rand();
- for (offset = 0; offset < bufsize; offset += 4)
- writel(rand(), addr + offset);
- memcpy((void *)addr + bufsize, (void *)addr, bufsize);
- srand(seed);
- for (offset = 0; offset < 2 * bufsize; offset += 4) {
- if (offset == bufsize)
- srand(seed);
- value = rand();
- error = check_addr(addr + offset, value);
- if (error)
- break;
- if (progress(offset))
- return TEST_FAILED;
- }
- if (test_loop_end(&loop, nb_loop, 100))
- break;
- }
- putc('\n');
- if (error) {
- sprintf(string,
- "loop %d: error for address 0x%x: 0x%x expected 0x%x",
- loop, offset, readl(offset), value);
- return TEST_FAILED;
- }
- sprintf(string, "no error for %d loops, size 0x%x",
- loop, bufsize);
- return TEST_PASSED;
- }
- /**********************************************************************
- *
- * Function: noise
- *
- * Description: Verifies r/w while forcing switching of all data bus lines.
- * optimised 4 iteration write/read/write/read cycles...
- * for pattern and inversed pattern
- *
- **********************************************************************/
- void do_noise(u32 addr, u32 pattern, u32 *result)
- {
- __asm__("push {R0-R11}");
- __asm__("mov r0, %0" : : "r" (addr));
- __asm__("mov r1, %0" : : "r" (pattern));
- __asm__("mov r11, %0" : : "r" (result));
- __asm__("mvn r2, r1");
- __asm__("str r1, [r0]");
- __asm__("ldr r3, [r0]");
- __asm__("str r2, [r0]");
- __asm__("ldr r4, [r0]");
- __asm__("str r1, [r0]");
- __asm__("ldr r5, [r0]");
- __asm__("str r2, [r0]");
- __asm__("ldr r6, [r0]");
- __asm__("str r1, [r0]");
- __asm__("ldr r7, [r0]");
- __asm__("str r2, [r0]");
- __asm__("ldr r8, [r0]");
- __asm__("str r1, [r0]");
- __asm__("ldr r9, [r0]");
- __asm__("str r2, [r0]");
- __asm__("ldr r10, [r0]");
- __asm__("stmia R11!, {R3-R10}");
- __asm__("pop {R0-R11}");
- }
- static enum test_result test_noise(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- u32 addr, pattern;
- u32 result[8];
- int i;
- enum test_result res = TEST_PASSED;
- if (get_pattern(string, argc, argv, 0, &pattern, 0xFFFFFFFF))
- return TEST_ERROR;
- if (get_addr(string, argc, argv, 1, &addr))
- return TEST_ERROR;
- printf("running noise for 0x%x at 0x%x\n", pattern, addr);
- do_noise(addr, pattern, result);
- for (i = 0; i < 0x8;) {
- if (check_addr((u32)&result[i++], pattern))
- res = TEST_FAILED;
- if (check_addr((u32)&result[i++], ~pattern))
- res = TEST_FAILED;
- }
- return res;
- }
- /**********************************************************************
- *
- * Function: noise_burst
- *
- * Description: Verifies r/w while forcing switching of all data bus lines.
- * optimised write loop witrh store multiple to use burst
- * for pattern and inversed pattern
- *
- **********************************************************************/
- void do_noise_burst(u32 addr, u32 pattern, size_t bufsize)
- {
- __asm__("push {R0-R9}");
- __asm__("mov r0, %0" : : "r" (addr));
- __asm__("mov r1, %0" : : "r" (pattern));
- __asm__("mov r9, %0" : : "r" (bufsize));
- __asm__("mvn r2, r1");
- __asm__("mov r3, r1");
- __asm__("mov r4, r2");
- __asm__("mov r5, r1");
- __asm__("mov r6, r2");
- __asm__("mov r7, r1");
- __asm__("mov r8, r2");
- __asm__("loop1:");
- __asm__("stmia R0!, {R1-R8}");
- __asm__("stmia R0!, {R1-R8}");
- __asm__("stmia R0!, {R1-R8}");
- __asm__("stmia R0!, {R1-R8}");
- __asm__("subs r9, r9, #128");
- __asm__("bge loop1");
- __asm__("pop {R0-R9}");
- }
- /* chunk size enough to allow interruption with Ctrl-C*/
- #define CHUNK_SIZE 0x8000000
- static enum test_result test_noise_burst(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- u32 addr, offset, pattern;
- size_t bufsize, remaining, size;
- int i;
- enum test_result res = TEST_PASSED;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 128))
- return TEST_ERROR;
- if (get_pattern(string, argc, argv, 1, &pattern, 0xFFFFFFFF))
- return TEST_ERROR;
- if (get_addr(string, argc, argv, 2, &addr))
- return TEST_ERROR;
- printf("running noise burst for 0x%x at 0x%x + 0x%x",
- pattern, addr, bufsize);
- offset = addr;
- remaining = bufsize;
- size = CHUNK_SIZE;
- while (remaining) {
- if (remaining < size)
- size = remaining;
- do_noise_burst(offset, pattern, size);
- remaining -= size;
- offset += size;
- if (progress(offset)) {
- res = TEST_FAILED;
- goto end;
- }
- }
- puts("\ncheck buffer");
- for (i = 0; i < bufsize;) {
- if (check_addr(addr + i, pattern))
- res = TEST_FAILED;
- i += 4;
- if (check_addr(addr + i, ~pattern))
- res = TEST_FAILED;
- i += 4;
- if (progress(i)) {
- res = TEST_FAILED;
- goto end;
- }
- }
- end:
- puts("\n");
- return res;
- }
- /**********************************************************************
- *
- * Function: pattern test
- *
- * Description: optimized loop for read/write pattern (array of 8 u32)
- *
- **********************************************************************/
- #define PATTERN_SIZE 8
- static enum test_result test_loop(const u32 *pattern, u32 *address,
- const u32 bufsize)
- {
- int i;
- int j;
- enum test_result res = TEST_PASSED;
- u32 offset, testsize, remaining;
- offset = (u32)address;
- remaining = bufsize;
- while (remaining) {
- testsize = bufsize > 0x1000000 ? 0x1000000 : bufsize;
- __asm__("push {R0-R10}");
- __asm__("mov r0, %0" : : "r" (pattern));
- __asm__("mov r1, %0" : : "r" (offset));
- __asm__("mov r2, %0" : : "r" (testsize));
- __asm__("ldmia r0!, {R3-R10}");
- __asm__("loop2:");
- __asm__("stmia r1!, {R3-R10}");
- __asm__("stmia r1!, {R3-R10}");
- __asm__("stmia r1!, {R3-R10}");
- __asm__("stmia r1!, {R3-R10}");
- __asm__("subs r2, r2, #128");
- __asm__("bge loop2");
- __asm__("pop {R0-R10}");
- offset += testsize;
- remaining -= testsize;
- if (progress((u32)offset)) {
- res = TEST_FAILED;
- goto end;
- }
- }
- puts("\ncheck buffer");
- for (i = 0; i < bufsize; i += PATTERN_SIZE * 4) {
- for (j = 0; j < PATTERN_SIZE; j++, address++)
- if (check_addr((u32)address, pattern[j])) {
- res = TEST_FAILED;
- goto end;
- }
- if (progress(i)) {
- res = TEST_FAILED;
- goto end;
- }
- }
- end:
- puts("\n");
- return res;
- }
- const u32 pattern_div1_x16[PATTERN_SIZE] = {
- 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF,
- 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF
- };
- const u32 pattern_div2_x16[PATTERN_SIZE] = {
- 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
- 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000
- };
- const u32 pattern_div4_x16[PATTERN_SIZE] = {
- 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
- 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000
- };
- const u32 pattern_div4_x32[PATTERN_SIZE] = {
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000
- };
- const u32 pattern_mostly_zero_x16[PATTERN_SIZE] = {
- 0x00000000, 0x00000000, 0x00000000, 0x0000FFFF,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000
- };
- const u32 pattern_mostly_zero_x32[PATTERN_SIZE] = {
- 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000
- };
- const u32 pattern_mostly_one_x16[PATTERN_SIZE] = {
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
- };
- const u32 pattern_mostly_one_x32[PATTERN_SIZE] = {
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
- };
- #define NB_PATTERN 5
- static enum test_result test_freq_pattern(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- const u32 * const patterns_x16[NB_PATTERN] = {
- pattern_div1_x16,
- pattern_div2_x16,
- pattern_div4_x16,
- pattern_mostly_zero_x16,
- pattern_mostly_one_x16,
- };
- const u32 * const patterns_x32[NB_PATTERN] = {
- pattern_div2_x16,
- pattern_div4_x16,
- pattern_div4_x32,
- pattern_mostly_zero_x32,
- pattern_mostly_one_x32
- };
- const char *patterns_comments[NB_PATTERN] = {
- "switching at frequency F/1",
- "switching at frequency F/2",
- "switching at frequency F/4",
- "mostly zero",
- "mostly one"
- };
- enum test_result res = TEST_PASSED, pattern_res;
- int i, bus_width;
- const u32 **patterns;
- u32 bufsize, addr;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 128))
- return TEST_ERROR;
- if (get_addr(string, argc, argv, 1, &addr))
- return TEST_ERROR;
- switch (readl(&ctl->mstr) & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK) {
- case DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF:
- case DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER:
- bus_width = 16;
- break;
- default:
- bus_width = 32;
- break;
- }
- printf("running test pattern at 0x%08x length 0x%x width = %d\n",
- addr, bufsize, bus_width);
- patterns =
- (const u32 **)(bus_width == 16 ? patterns_x16 : patterns_x32);
- for (i = 0; i < NB_PATTERN; i++) {
- printf("test data pattern %s:", patterns_comments[i]);
- pattern_res = test_loop(patterns[i], (u32 *)addr, bufsize);
- if (pattern_res != TEST_PASSED) {
- printf("Failed\n");
- return pattern_res;
- }
- printf("Passed\n");
- }
- return res;
- }
- /**********************************************************************
- *
- * Function: pattern test with size
- *
- * Description: loop for write pattern
- *
- **********************************************************************/
- static enum test_result test_loop_size(const u32 *pattern, u32 size,
- u32 *address,
- const u32 bufsize)
- {
- int i, j;
- enum test_result res = TEST_PASSED;
- u32 *p = address;
- for (i = 0; i < bufsize; i += size * 4) {
- for (j = 0; j < size ; j++, p++)
- *p = pattern[j];
- if (progress(i)) {
- res = TEST_FAILED;
- goto end;
- }
- }
- puts("\ncheck buffer");
- p = address;
- for (i = 0; i < bufsize; i += size * 4) {
- for (j = 0; j < size; j++, p++)
- if (check_addr((u32)p, pattern[j])) {
- res = TEST_FAILED;
- goto end;
- }
- if (progress(i)) {
- res = TEST_FAILED;
- goto end;
- }
- }
- end:
- puts("\n");
- return res;
- }
- static enum test_result test_checkboard(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- enum test_result res = TEST_PASSED;
- u32 bufsize, nb_loop, loop = 0, addr;
- int i;
- u32 checkboard[2] = {0x55555555, 0xAAAAAAAA};
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 8))
- return TEST_ERROR;
- if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
- return TEST_ERROR;
- if (get_addr(string, argc, argv, 2, &addr))
- return TEST_ERROR;
- printf("running %d loops at 0x%08x length 0x%x\n",
- nb_loop, addr, bufsize);
- while (1) {
- for (i = 0; i < 2; i++) {
- res = test_loop_size(checkboard, 2, (u32 *)addr,
- bufsize);
- if (res)
- return res;
- checkboard[0] = ~checkboard[0];
- checkboard[1] = ~checkboard[1];
- }
- if (test_loop_end(&loop, nb_loop, 1))
- break;
- }
- sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
- loop, addr, bufsize);
- return res;
- }
- static enum test_result test_blockseq(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- enum test_result res = TEST_PASSED;
- u32 bufsize, nb_loop, loop = 0, addr, value;
- int i;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
- return TEST_ERROR;
- if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
- return TEST_ERROR;
- if (get_addr(string, argc, argv, 2, &addr))
- return TEST_ERROR;
- printf("running %d loops at 0x%08x length 0x%x\n",
- nb_loop, addr, bufsize);
- while (1) {
- for (i = 0; i < 256; i++) {
- value = i | i << 8 | i << 16 | i << 24;
- printf("pattern = %08x", value);
- res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
- if (res != TEST_PASSED)
- return res;
- }
- if (test_loop_end(&loop, nb_loop, 1))
- break;
- }
- sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
- loop, addr, bufsize);
- return res;
- }
- static enum test_result test_walkbit0(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- enum test_result res = TEST_PASSED;
- u32 bufsize, nb_loop, loop = 0, addr, value;
- int i;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
- return TEST_ERROR;
- if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
- return TEST_ERROR;
- if (get_addr(string, argc, argv, 2, &addr))
- return TEST_ERROR;
- printf("running %d loops at 0x%08x length 0x%x\n",
- nb_loop, addr, bufsize);
- while (1) {
- for (i = 0; i < 64; i++) {
- if (i < 32)
- value = 1 << i;
- else
- value = 1 << (63 - i);
- printf("pattern = %08x", value);
- res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
- if (res != TEST_PASSED)
- return res;
- }
- if (test_loop_end(&loop, nb_loop, 1))
- break;
- }
- sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
- loop, addr, bufsize);
- return res;
- }
- static enum test_result test_walkbit1(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- enum test_result res = TEST_PASSED;
- u32 bufsize, nb_loop, loop = 0, addr, value;
- int i;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4))
- return TEST_ERROR;
- if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
- return TEST_ERROR;
- if (get_addr(string, argc, argv, 2, &addr))
- return TEST_ERROR;
- printf("running %d loops at 0x%08x length 0x%x\n",
- nb_loop, addr, bufsize);
- while (1) {
- for (i = 0; i < 64; i++) {
- if (i < 32)
- value = ~(1 << i);
- else
- value = ~(1 << (63 - i));
- printf("pattern = %08x", value);
- res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
- if (res != TEST_PASSED)
- return res;
- }
- if (test_loop_end(&loop, nb_loop, 1))
- break;
- }
- sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
- loop, addr, bufsize);
- return res;
- }
- /*
- * try to catch bad bits which are dependent on the current values of
- * surrounding bits in either the same word32
- */
- static enum test_result test_bitspread(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- enum test_result res = TEST_PASSED;
- u32 bufsize, nb_loop, loop = 0, addr, bitspread[4];
- int i, j;
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 32))
- return TEST_ERROR;
- if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
- return TEST_ERROR;
- if (get_addr(string, argc, argv, 2, &addr))
- return TEST_ERROR;
- printf("running %d loops at 0x%08x length 0x%x\n",
- nb_loop, addr, bufsize);
- while (1) {
- for (i = 1; i < 32; i++) {
- for (j = 0; j < i; j++) {
- if (i < 32)
- bitspread[0] = (1 << i) | (1 << j);
- else
- bitspread[0] = (1 << (63 - i)) |
- (1 << (63 - j));
- bitspread[1] = bitspread[0];
- bitspread[2] = ~bitspread[0];
- bitspread[3] = ~bitspread[0];
- printf("pattern = %08x", bitspread[0]);
- res = test_loop_size(bitspread, 4, (u32 *)addr,
- bufsize);
- if (res != TEST_PASSED)
- return res;
- }
- }
- if (test_loop_end(&loop, nb_loop, 1))
- break;
- }
- sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
- loop, addr, bufsize);
- return res;
- }
- static enum test_result test_bitflip(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- enum test_result res = TEST_PASSED;
- u32 bufsize, nb_loop, loop = 0, addr;
- int i;
- u32 bitflip[4];
- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 32))
- return TEST_ERROR;
- if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
- return TEST_ERROR;
- if (get_addr(string, argc, argv, 2, &addr))
- return TEST_ERROR;
- printf("running %d loops at 0x%08x length 0x%x\n",
- nb_loop, addr, bufsize);
- while (1) {
- for (i = 0; i < 32; i++) {
- bitflip[0] = 1 << i;
- bitflip[1] = bitflip[0];
- bitflip[2] = ~bitflip[0];
- bitflip[3] = bitflip[2];
- printf("pattern = %08x", bitflip[0]);
- res = test_loop_size(bitflip, 4, (u32 *)addr, bufsize);
- if (res != TEST_PASSED)
- return res;
- }
- if (test_loop_end(&loop, nb_loop, 1))
- break;
- }
- sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
- loop, addr, bufsize);
- return res;
- }
- /**********************************************************************
- *
- * Function: infinite read access to DDR
- *
- * Description: continuous read the same pattern at the same address
- *
- **********************************************************************/
- static enum test_result test_read(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- u32 *addr;
- u32 data;
- u32 loop = 0;
- int i, size = 1024 * 1024;
- bool random = false;
- if (get_addr(string, argc, argv, 0, (u32 *)&addr))
- return TEST_ERROR;
- if (get_pattern(string, argc, argv, 1, &data, 0xA5A5AA55))
- return TEST_ERROR;
- if ((u32)addr == ADDR_INVALID) {
- printf("running random\n");
- random = true;
- } else {
- printf("running at 0x%08x with pattern=0x%08x\n",
- (u32)addr, data);
- writel(data, addr);
- }
- while (1) {
- for (i = 0; i < size; i++) {
- if (random)
- addr = (u32 *)(STM32_DDR_BASE +
- (rand() & (STM32_DDR_SIZE - 1) & ~0x3));
- data = readl(addr);
- }
- if (test_loop_end(&loop, 0, 1))
- break;
- }
- if (random)
- sprintf(string, "%d loops random", loop);
- else
- sprintf(string, "%d loops at 0x%x: %x", loop, (u32)addr, data);
- return TEST_PASSED;
- }
- /**********************************************************************
- *
- * Function: infinite write access to DDR
- *
- * Description: continuous write the same pattern at the same address
- *
- **********************************************************************/
- static enum test_result test_write(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- u32 *addr;
- u32 data;
- u32 loop = 0;
- int i, size = 1024 * 1024;
- bool random = false;
- if (get_addr(string, argc, argv, 0, (u32 *)&addr))
- return TEST_ERROR;
- if (get_pattern(string, argc, argv, 1, &data, 0xA5A5AA55))
- return TEST_ERROR;
- if ((u32)addr == ADDR_INVALID) {
- printf("running random\n");
- random = true;
- } else {
- printf("running at 0x%08x with pattern 0x%08x\n",
- (u32)addr, data);
- }
- while (1) {
- for (i = 0; i < size; i++) {
- if (random) {
- addr = (u32 *)(STM32_DDR_BASE +
- (rand() & (STM32_DDR_SIZE - 1) & ~0x3));
- data = rand();
- }
- writel(data, addr);
- }
- if (test_loop_end(&loop, 0, 1))
- break;
- }
- if (random)
- sprintf(string, "%d loops random", loop);
- else
- sprintf(string, "%d loops at 0x%x: %x", loop, (u32)addr, data);
- return TEST_PASSED;
- }
- #define NB_TEST_INFINITE 2
- static enum test_result test_all(struct stm32mp1_ddrctl *ctl,
- struct stm32mp1_ddrphy *phy,
- char *string, int argc, char *argv[])
- {
- enum test_result res = TEST_PASSED, result;
- int i, j, nb_error = 0, len;
- u32 loop = 0, nb_loop;
- int argc_test;
- char *argv_test[4];
- char loop_string[] = "1";
- char pattern_string[] = PATTERN_DEFAULT;
- u32 *addr;
- if (get_nb_loop(string, argc, argv, 0, &nb_loop, 1))
- return TEST_ERROR;
- if (get_addr(string, argc, argv, 2, (u32 *)&addr))
- return TEST_ERROR;
- while (!nb_error) {
- /* execute all the test except the lasts which are infinite */
- for (i = 1; i < test_nb - NB_TEST_INFINITE; i++) {
- argc_test = 0;
- j = 0;
- len = strlen(test[i].usage);
- if (argc > 1 && j < len &&
- !strncmp("[size]", &test[i].usage[j], 6)) {
- argv_test[argc_test++] = argv[1];
- j += 7;
- }
- if (argc > 2) {
- if (j < len &&
- !strncmp("[loop]", &test[i].usage[j], 6)) {
- argv_test[argc_test++] = loop_string;
- j += 7;
- }
- if (j < len &&
- !strncmp("[pattern]", &test[i].usage[j],
- 9)) {
- argv_test[argc_test++] = pattern_string;
- j += 10;
- }
- if (j < len &&
- !strncmp("[addr]", &test[i].usage[j], 6)) {
- argv_test[argc_test++] = argv[2];
- j += 7;
- }
- }
- printf("execute %d:%s\n", (int)i, test[i].name);
- result = test[i].fct(ctl, phy, string,
- argc_test, argv_test);
- printf("result %d:%s = ", (int)i, test[i].name);
- if (result != TEST_PASSED) {
- nb_error++;
- res = TEST_FAILED;
- puts("Failed");
- } else {
- puts("Passed");
- }
- puts("\n\n");
- }
- printf("loop %d: %d/%d test failed\n\n\n",
- loop + 1, nb_error, test_nb - NB_TEST_INFINITE);
- if (test_loop_end(&loop, nb_loop, 1))
- break;
- }
- if (res != TEST_PASSED) {
- sprintf(string, "loop %d: %d/%d test failed", loop, nb_error,
- test_nb - NB_TEST_INFINITE);
- } else {
- sprintf(string, "loop %d: %d tests passed", loop,
- test_nb - NB_TEST_INFINITE);
- }
- return res;
- }
- /****************************************************************
- * TEST Description
- ****************************************************************/
- const struct test_desc test[] = {
- {test_all, "All", "[loop] [size] [addr]", "Execute all tests", 3 },
- {test_databus, "Simple DataBus", "[addr]",
- "Verifies each data line by walking 1 on fixed address",
- 1
- },
- {databuswalk0, "DataBusWalking0", "[loop] [addr]",
- "Verifies each data bus signal can be driven low (32 word burst)",
- 2
- },
- {databuswalk1, "DataBusWalking1", "[loop] [addr]",
- "Verifies each data bus signal can be driven high (32 word burst)",
- 2
- },
- {test_addressbus, "AddressBus", "[size] [addr]",
- "Verifies each relevant bits of the address and checking for aliasing",
- 2
- },
- {test_memdevice, "MemDevice", "[size] [addr]",
- "Test the integrity of a physical memory (test every storage bit in the region)",
- 2
- },
- {test_sso, "SimultaneousSwitchingOutput", "[size] [addr] ",
- "Stress the data bus over an address range",
- 2
- },
- {test_noise, "Noise", "[pattern] [addr]",
- "Verifies r/w while forcing switching of all data bus lines.",
- 3
- },
- {test_noise_burst, "NoiseBurst", "[size] [pattern] [addr]",
- "burst transfers while forcing switching of the data bus lines",
- 3
- },
- {test_random, "Random", "[size] [loop] [addr]",
- "Verifies r/w and memcopy(burst for pseudo random value.",
- 3
- },
- {test_freq_pattern, "FrequencySelectivePattern", "[size] [addr]",
- "write & test patterns: Mostly Zero, Mostly One and F/n",
- 2
- },
- {test_blockseq, "BlockSequential", "[size] [loop] [addr]",
- "test incremental pattern",
- 3
- },
- {test_checkboard, "Checkerboard", "[size] [loop] [addr]",
- "test checker pattern",
- 3
- },
- {test_bitspread, "BitSpread", "[size] [loop] [addr]",
- "test Bit Spread pattern",
- 3
- },
- {test_bitflip, "BitFlip", "[size] [loop] [addr]",
- "test Bit Flip pattern",
- 3
- },
- {test_walkbit0, "WalkingOnes", "[size] [loop] [addr]",
- "test Walking Ones pattern",
- 3
- },
- {test_walkbit1, "WalkingZeroes", "[size] [loop] [addr]",
- "test Walking Zeroes pattern",
- 3
- },
- /* need to the the 2 last one (infinite) : skipped for test all */
- {test_read, "infinite read", "[addr] [pattern]",
- "basic test : infinite read access (random: addr=0xFFFFFFFF)", 2},
- {test_write, "infinite write", "[addr] [pattern]",
- "basic test : infinite write access (random: addr=0xFFFFFFFF)", 2},
- };
- const int test_nb = ARRAY_SIZE(test);
|