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