Commit 18a8bc29 authored by Tristan Gingold's avatar Tristan Gingold

vmecore_test: increase size of pattern area.

parent c829896c
......@@ -59,10 +59,11 @@ architecture rtl of vmecore_test is
-- 0x1005: generates bus error.
-- 0x2000: counter (4B). Generate an interrupt when 0 is reached.
-- 0x3000: pattern ram (0x1000 * 4B)
-- 0x4000 - 0x3ff000: pattern ram
signal counter : unsigned(31 downto 0);
signal leds : std_logic_vector(15 downto 0);
signal last_trans : std_logic_vector (20 downto 0);
signal last_trans : std_logic_vector (28 downto 0);
signal nbr_read : unsigned (15 downto 0);
signal nbr_write: unsigned (15 downto 0);
......@@ -79,8 +80,25 @@ begin
pattern (15 downto 0) <= slave_i.adr(15 downto 0);
process (clk_sys_i)
procedure pattern_write
is
variable err : boolean;
begin
err := false;
for i in 3 downto 0 loop
if slave_i.sel (i) = '1'
and (slave_i.dat(8*i + 7 downto 8*i) /=
pattern (8*i + 7 downto 8*i))
then
err := true;
end if;
end loop;
if err then
nbr_write_errors <= nbr_write_errors + 1;
end if;
end pattern_write;
variable idx : natural;
variable err : boolean;
begin
if rising_edge(clk_sys_i) then
slave_o.ack <= '0';
......@@ -102,103 +120,100 @@ begin
if slave_i.stb = '1' then
if slave_i.adr (13 downto 12) = "00" then
-- Save transaction (very cheap scope).
last_trans (15 downto 0) <= slave_i.adr (15 downto 0);
last_trans (19 downto 16) <= slave_i.sel;
last_trans (20) <= slave_i.we;
last_trans (23 downto 0) <= slave_i.adr (23 downto 0);
last_trans (27 downto 24) <= slave_i.sel;
last_trans (28) <= slave_i.we;
end if;
if slave_i.we = '1' then
-- Write
nbr_write <= nbr_write + 1;
case slave_i.adr (13 downto 12) is
when "00" =>
idx := to_integer(unsigned(slave_i.adr(8 downto 0)));
for i in 3 downto 0 loop
if slave_i.sel (i) = '1' then
sram(idx)(8*i + 7 downto 8*i) <=
slave_i.dat(8*i + 7 downto 8*i);
end if;
end loop;
when "01" =>
case slave_i.adr (2 downto 0) is
when "000" =>
for i in 1 downto 0 loop
if slave_i.sel (i) = '1' then
leds(8*i + 7 downto 8*i) <=
slave_i.dat(8*i + 7 downto 8*i);
end if;
end loop;
when "001" =>
null;
when "010" =>
nbr_read <= (others => '0');
when "011" =>
nbr_write <= (others => '0');
when "100" =>
nbr_write_errors <= (others => '0');
when "101" =>
slave_o.err <= '1';
when others =>
null;
end case;
when "10" =>
for i in 3 downto 0 loop
if slave_i.sel (i) = '1' then
counter(8*i + 7 downto 8*i) <=
unsigned(slave_i.dat(8*i + 7 downto 8*i));
end if;
end loop;
when "11" =>
err := false;
for i in 3 downto 0 loop
if slave_i.sel (i) = '1'
and (slave_i.dat(8*i + 7 downto 8*i) /=
pattern (8*i + 7 downto 8*i))
then
err := true;
end if;
end loop;
if err then
nbr_write_errors <= nbr_write_errors + 1;
end if;
when others =>
null;
end case;
if slave_i.adr(25 downto 14) = x"000" then
case slave_i.adr (13 downto 12) is
when "00" =>
idx := to_integer(unsigned(slave_i.adr(8 downto 0)));
for i in 3 downto 0 loop
if slave_i.sel (i) = '1' then
sram(idx)(8*i + 7 downto 8*i) <=
slave_i.dat(8*i + 7 downto 8*i);
end if;
end loop;
when "01" =>
case slave_i.adr (2 downto 0) is
when "000" =>
for i in 1 downto 0 loop
if slave_i.sel (i) = '1' then
leds(8*i + 7 downto 8*i) <=
slave_i.dat(8*i + 7 downto 8*i);
end if;
end loop;
when "001" =>
null;
when "010" =>
nbr_read <= (others => '0');
when "011" =>
nbr_write <= (others => '0');
when "100" =>
nbr_write_errors <= (others => '0');
when "101" =>
slave_o.err <= '1';
when others =>
null;
end case;
when "10" =>
for i in 3 downto 0 loop
if slave_i.sel (i) = '1' then
counter(8*i + 7 downto 8*i) <=
unsigned(slave_i.dat(8*i + 7 downto 8*i));
end if;
end loop;
when "11" =>
pattern_write;
when others =>
null;
end case;
else
pattern_write;
end if;
slave_o.ack <= '1';
else
-- Read
nbr_read <= nbr_read + 1;
case slave_i.adr (13 downto 12) is
when "00" =>
idx := to_integer(unsigned(slave_i.adr(8 downto 0)));
slave_o.dat <= sram(idx);
when "01" =>
case slave_i.adr (2 downto 0) is
when "000" =>
slave_o.dat(31 downto 16) <= (others => '0');
slave_o.dat(15 downto 0) <= leds;
when "001" =>
slave_o.dat <= (31 downto 21 => '0') & last_trans;
when "010" =>
slave_o.dat (31 downto 16) <= (others => '0');
slave_o.dat (15 downto 0) <= std_logic_vector (nbr_read);
when "011" =>
slave_o.dat (31 downto 16) <= (others => '0');
slave_o.dat (15 downto 0) <= std_logic_vector (nbr_write);
when "100" =>
slave_o.dat <= std_logic_vector (nbr_write_errors);
when "101" =>
slave_o.err <= '1';
when others =>
null;
end case;
when "10" =>
slave_o.dat <= std_logic_vector(counter);
when "11" =>
slave_o.dat <= pattern;
when others =>
null;
end case;
if slave_i.adr(25 downto 14) = x"000" then
case slave_i.adr (13 downto 12) is
when "00" =>
idx := to_integer(unsigned(slave_i.adr(8 downto 0)));
slave_o.dat <= sram(idx);
when "01" =>
case slave_i.adr (2 downto 0) is
when "000" =>
slave_o.dat(31 downto 16) <= (others => '0');
slave_o.dat(15 downto 0) <= leds;
when "001" =>
slave_o.dat <= (31 downto 29 => '0') & last_trans;
when "010" =>
slave_o.dat (31 downto 16) <= (others => '0');
slave_o.dat (15 downto 0) <= std_logic_vector (nbr_read);
when "011" =>
slave_o.dat (31 downto 16) <= (others => '0');
slave_o.dat (15 downto 0) <= std_logic_vector (nbr_write);
when "100" =>
slave_o.dat <= std_logic_vector (nbr_write_errors);
when "101" =>
slave_o.err <= '1';
when others =>
null;
end case;
when "10" =>
slave_o.dat <= std_logic_vector(counter);
when "11" =>
slave_o.dat <= pattern;
when others =>
null;
end case;
else
slave_o.dat <= pattern;
end if;
slave_o.ack <= '1';
end if;
end if;
......
......@@ -76,8 +76,37 @@ static volatile unsigned char *ptr8;
static volatile unsigned short *ptr16;
static volatile unsigned int *ptr32;
/* Setup the board for access mode AM. Return the base + mask. */
static void
map_for_function (struct vme_function *fn)
setup_am (uint8_t am, uint32_t *base, uint32_t *mask)
{
for (int i = 0; i < 8; i++)
{
struct vme_function fn;
read_vme_function (&fn, i);
if (!((fn.amcap >> am) & 1))
continue;
*mask = fn.adem & 0xffffff00;
*base = (slot << 19) & *mask;
fn.ader = *base | (am << 2);
fn.am = am;
conf[0x7ff63 + i * 0x10 + 0] = (fn.ader >> 24) & 0xff;
conf[0x7ff63 + i * 0x10 + 4] = (fn.ader >> 16) & 0xff;
conf[0x7ff63 + i * 0x10 + 8] = (fn.ader >> 8) & 0xff;
conf[0x7ff63 + i * 0x10 + 12] = (fn.ader >> 0) & 0xff;
return;
}
fprintf (stderr, "am 0x%02x is not supported\n", am);
exit (3);
}
/* Map vme space defined by AM, BASE, MASK to user memory. */
static void
setup_map (uint8_t am, uint32_t base, uint32_t mask)
{
if (ptr != NULL)
{
......@@ -85,12 +114,10 @@ map_for_function (struct vme_function *fn)
ptr = NULL;
}
uint32_t mask = fn->adem & 0xffffff00;
data_map.am = fn->am;
data_map.am = am;
data_map.data_width = 32;
data_map.sizel = MAX (0x10000, ~mask + 1);
data_map.vme_addrl = fn->ader & mask;
data_map.sizel = MAX (0x80000, ~mask + 1);
data_map.vme_addrl = base & mask;
printf ("INFO: Map VME 0x%08x AM 0x%02x\n", data_map.vme_addrl, data_map.am);
......@@ -107,32 +134,20 @@ map_for_function (struct vme_function *fn)
ptr32 = (volatile unsigned int *)ptr;
}
/* Setup the board for AM and map the address space. */
static uint32_t
map_for_am (uint8_t am)
{
for (int i = 0; i < 8; i++)
{
uint32_t base;
struct vme_function fn;
read_vme_function (&fn, i);
if (!((fn.amcap >> am) & 1))
continue;
uint32_t base;
uint32_t mask;
base = (slot << 19) & fn.adem & 0xffffff00;
fn.ader = base | (am << 2);
fn.am = am;
conf[0x7ff63 + i * 0x10 + 0] = (fn.ader >> 24) & 0xff;
conf[0x7ff63 + i * 0x10 + 4] = (fn.ader >> 16) & 0xff;
conf[0x7ff63 + i * 0x10 + 8] = (fn.ader >> 8) & 0xff;
conf[0x7ff63 + i * 0x10 + 12] = (fn.ader >> 0) & 0xff;
map_for_function (&fn);
return base;
}
fprintf (stderr, "am 0x%02x is not supported\n", am);
exit (3);
setup_am (am, &base, &mask);
setup_map (am, base, mask);
return base;
}
static unsigned int
read_nbr_interrupts (unsigned int level)
{
......@@ -254,7 +269,7 @@ rate_done (struct timespec *start_ts, unsigned int nbr_bytes)
{
struct timespec end_ts;
unsigned long nano;
if (clock_gettime (CLOCK_MONOTONIC, &end_ts) != 0)
{
fprintf (stderr, "clock_gettime error: %m\n");
......@@ -283,14 +298,16 @@ do_test_error_counter (void)
}
static void
do_test_dma (uint8_t am)
do_test_dma_with_len (uint8_t am, uint32_t off, uint32_t len)
{
struct vme_dma dma;
uint32_t base;
uint32_t mask;
void *buf;
int s;
struct timespec start_ts;
enum vme_dma_block_size bsize;
int nbr_err;
// Clear pattern write error counter
map_for_am (0x39);
......@@ -301,17 +318,18 @@ do_test_dma (uint8_t am)
exit (3);
}
printf ("INFO: test DMA for am 0x%02x\n", am);
base = map_for_am (am);
printf ("INFO: test DMA for am 0x%02x (off: 0x%08x, len: 0x%0x)\n",
am, off, len);
setup_am (am, &base, &mask);
if (posix_memalign (&buf, 4096, 0x4000) != 0)
if (posix_memalign (&buf, 4096, len) != 0)
{
fprintf (stderr, "cannot allocate memory\n");
exit (4);
}
memset (&dma, 0, sizeof (dma));
dma.status = 0; // ??
dma.length = 0x4000;
dma.length = len;
dma.novmeinc = 0;
dma.dir = VME_DMA_FROM_DEVICE;
......@@ -320,7 +338,7 @@ do_test_dma (uint8_t am)
dma.src.v2esst_mode = VME_SST160;
dma.src.bcast_select = 0;
dma.src.addru = 0;
dma.src.addrl = base + 0xc000;
dma.src.addrl = base + off;
dma.dst.addru = ((uintptr_t)buf) >> 32;
dma.dst.addrl = (uintptr_t)buf;
......@@ -340,32 +358,35 @@ do_test_dma (uint8_t am)
rate_start (&start_ts);
s = vme_dma_read (&dma);
rate_done (&start_ts, 0x4000);
rate_done (&start_ts, len);
report (s == 0, "DMA read");
for (int j = 0; j < 0x1000; j++)
nbr_err = 0;
for (int j = 0; j < len / 4; j++)
{
uint32_t r = ((uint32_t *)buf)[j];
uint32_t v;
v = (j + 0x3000);
v = (j + (off >> 2)) & 0xffff;
v = v | (~v << 16);
r = swapbe32 (r);
if (r != v)
{
report (false,
"dma read error at 0x%04x (got 0x%08x, expect 0x%08x)",
j << 2, r, v);
break;
"dma read error at 0x%08x (got 0x%08x, expect 0x%08x)",
off + (j << 2), r, v);
nbr_err++;
if (nbr_err >= 10)
break;
}
}
// DMA write
memset (&dma, 0, sizeof (dma));
dma.status = 0; // ??
dma.length = 0x4000;
dma.length = len;
dma.novmeinc = 0;
dma.dir = VME_DMA_TO_DEVICE;
......@@ -377,7 +398,7 @@ do_test_dma (uint8_t am)
dma.dst.v2esst_mode = VME_SST160;
dma.dst.bcast_select = 0;
dma.dst.addru = 0;
dma.dst.addrl = base + 0xc000;
dma.dst.addrl = base + off;
dma.ctrl.vme_block_size = bsize;
dma.ctrl.vme_backoff_time = VME_DMA_BACKOFF_1;
......@@ -386,7 +407,7 @@ do_test_dma (uint8_t am)
rate_start (&start_ts);
s = vme_dma_write (&dma);
rate_done (&start_ts, 0x4000);
rate_done (&start_ts, len);
report (s == 0, "DMA write");
free (buf);
......@@ -396,6 +417,12 @@ do_test_dma (uint8_t am)
swapbe32 (ptr32[0x1004]));
}
static void
do_test_dma (uint8_t am)
{
do_test_dma_with_len (am, 0xc000, 0x4000);
}
static void
do_irq_test (void)
{
......@@ -526,7 +553,7 @@ do_leds (void)
int
main (int argc, char **argv)
{
int am = VME_A24_USER_DATA_SCT;
int am = -1;
int c;
struct vme_mapping conf_map;
char *action = NULL;
......@@ -544,7 +571,7 @@ main (int argc, char **argv)
action = optarg;
break;
case 'h':
printf ("usage: %s [-h] [-a ACTION] -s SLOT\n", argv[0]);
printf ("usage: %s [-h] [-m AM] [-a ACTION] -s SLOT\n", argv[0]);
return 0;
case '?':
fprintf (stderr, "incorrect option, try %s -h\n", argv[0]);
......@@ -557,6 +584,7 @@ main (int argc, char **argv)
return 2;
}
/* Map the CR/CSR space of the board. */
memset (&conf_map, 0, sizeof (conf_map));
conf_map.am = VME_CR_CSR;
conf_map.data_width = 32;
......@@ -571,33 +599,44 @@ main (int argc, char **argv)
}
if (action == NULL)
return do_vme_test();
/* Find a map. */
memset (&data_map, 0, sizeof (data_map));
{
printf ("No action, testing vme...\n");
return do_vme_test();
}
else
printf ("action: %s\n", action);
for (int i = 0; i < 8; i++)
/* Set an am if needed. */
if (am != -1)
map_for_am (am);
else
{
struct vme_function fn;
/* Find a map. */
memset (&data_map, 0, sizeof (data_map));
read_vme_function (&fn, i);
for (int i = 0; i < 8; i++)
{
struct vme_function fn;
if (!is_vme_function_enabled (&fn))
continue;
read_vme_function (&fn, i);
uint32_t mask = fn.adem & 0xffffff00;
if (!is_vme_function_enabled (&fn))
continue;
printf ("Func %d: 0x%08x-0x%08x, am=0x%02x\n",
i, fn.ader & mask, (fn.ader & mask) | ~mask, fn.am);
uint32_t mask = fn.adem & 0xffffff00;
uint32_t base = fn.ader & mask;
map_for_function (&fn);
break;
}
printf ("Func %d: 0x%08x-0x%08x, am=0x%02x\n",
i, base, (base & mask) | ~mask, fn.am);
setup_map (fn.am, base, mask);
break;
}
if (data_map.data_width == 0)
{
printf ("No map found\n");
return 3;
if (data_map.data_width == 0)
{
printf ("No map found\n");
return 3;
}
}
if (action == NULL || strcmp (action, "simple") == 0)
......@@ -736,7 +775,7 @@ main (int argc, char **argv)
unsigned int i, j;
unsigned int cnt = 4 * 16;
struct timespec start_ts;
rate_start (&start_ts);
for (j = 0; j < cnt; j++)
for (i = 0xc000; i <= 0xffff; i += 4)
......@@ -750,6 +789,18 @@ main (int argc, char **argv)
printf ("irq vector: %d\n", conf[0x7ff5f]);
printf ("nbr ints: %u\n", read_nbr_interrupts (level));
}
else if (strcmp (action, "blt") == 0)
{
if (am == -1)
am = 0x39;
do_test_dma_with_len (am, 0x10000, 0x40000);
}
else if (strcmp (action, "mblt") == 0)
{
if (am == -1)
am = 0x38;
do_test_dma_with_len (am, 0x10000, 0x40000);
}
else
printf ("unknown action\n");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment