|
@@ -50,6 +50,7 @@ typedef struct {
|
|
|
COPY_UINT64 = 0,
|
|
|
COPY_MEMCPY,
|
|
|
} copy;
|
|
|
+ int number;
|
|
|
} Options;
|
|
|
|
|
|
|
|
@@ -64,6 +65,7 @@ usage (void)
|
|
|
" -o, --output Output filename\n"
|
|
|
" -i, --input Input filename\n"
|
|
|
" -s, --size Size of data (leave if reading supplied input)\n"
|
|
|
+ " -n, --number Number of times data should be read\n"
|
|
|
" -c, --copy Copy method, either `memcpy' or `64'\n");
|
|
|
}
|
|
|
|
|
@@ -78,6 +80,7 @@ parse_options (int argc, char *const *argv, Options *opts)
|
|
|
OPT_OUTPUT = 'o',
|
|
|
OPT_SIZE = 's',
|
|
|
OPT_COPY = 'c',
|
|
|
+ OPT_NUMBER = 'n',
|
|
|
};
|
|
|
|
|
|
static struct option long_options[] = {
|
|
@@ -88,6 +91,7 @@ parse_options (int argc, char *const *argv, Options *opts)
|
|
|
{ "output", required_argument, 0, OPT_OUTPUT },
|
|
|
{ "size", required_argument, 0, OPT_SIZE },
|
|
|
{ "copy", required_argument, 0, OPT_COPY },
|
|
|
+ { "number", 0, 0, OPT_NUMBER },
|
|
|
{ 0, 0, 0, 0 },
|
|
|
};
|
|
|
|
|
@@ -100,8 +104,9 @@ parse_options (int argc, char *const *argv, Options *opts)
|
|
|
}
|
|
|
|
|
|
memset (opts, 0, sizeof (Options));
|
|
|
+ opts->number = 1;
|
|
|
|
|
|
- while ((ret = getopt_long (argc, argv, "i:o:s:c:khv", long_options, &index)) != -1) {
|
|
|
+ while ((ret = getopt_long (argc, argv, "i:o:s:c:n:khv", long_options, &index)) != -1) {
|
|
|
switch (ret) {
|
|
|
case OPT_HELP:
|
|
|
usage ();
|
|
@@ -126,6 +131,10 @@ parse_options (int argc, char *const *argv, Options *opts)
|
|
|
opts->copy = COPY_MEMCPY;
|
|
|
else if (!strcmp (optarg, "64"))
|
|
|
opts->copy = COPY_UINT64;
|
|
|
+ break;
|
|
|
+ case OPT_NUMBER:
|
|
|
+ opts->number = atoi (optarg);
|
|
|
+ break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
@@ -249,7 +258,6 @@ read_from_ddr (pcilib_t *pci, volatile void *bar, Options *opts)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- size = opts->size;
|
|
|
kmem_data = pcilib_alloc_kernel_memory (pci, PCILIB_KMEM_TYPE_CONSISTENT, 1, mem_size, mem_size, PCILIB_KMEM_USE_DMA_PAGES, KMEM_DEFAULT_FLAGS);
|
|
|
kmem_desc = pcilib_alloc_kernel_memory (pci, PCILIB_KMEM_TYPE_CONSISTENT, 1, 128, 4096, KMEM_USE_RING, KMEM_DEFAULT_FLAGS);
|
|
|
data = (uint32_t *) pcilib_kmem_get_block_ua (pci, kmem_data, 0);
|
|
@@ -257,19 +265,6 @@ read_from_ddr (pcilib_t *pci, volatile void *bar, Options *opts)
|
|
|
bus_addr_data = pcilib_kmem_get_block_ba (pci, kmem_data, 0);
|
|
|
bus_addr_desc = pcilib_kmem_get_block_ba (pci, kmem_desc, 0);
|
|
|
|
|
|
- memset (data, 0xf0, mem_size);
|
|
|
- hardware_ptr = 0;
|
|
|
-
|
|
|
- /* enable multi-read from DDR */
|
|
|
- WR32_sleep (HF_REG_CONTROL,
|
|
|
- HF_CONTROL_ENABLE_READ |
|
|
|
- HF_CONTROL_ENABLE_MULTI_READ |
|
|
|
- HF_CONTROL_SOURCE_RX_FIFO);
|
|
|
-
|
|
|
- WR32_sleep (HF_REG_CONTROL,
|
|
|
- HF_CONTROL_ENABLE_READ |
|
|
|
- HF_CONTROL_SOURCE_RX_FIFO);
|
|
|
-
|
|
|
/* DMA config */
|
|
|
WR32_sleep (HF_REG_NUM_PACKETS, 0x20);
|
|
|
WR32_sleep (HF_REG_PACKET_LENGTH, 0x20);
|
|
@@ -277,51 +272,69 @@ read_from_ddr (pcilib_t *pci, volatile void *bar, Options *opts)
|
|
|
WR64_sleep (HF_REG_UPDATE_ADDRESS, bus_addr_desc);
|
|
|
WR32_sleep (HF_REG_TIMER_THRESHOLD, 0x20000);
|
|
|
|
|
|
- desc[flag_index] = 0;
|
|
|
+ if (opts->verbose)
|
|
|
+ printf ("Reading %i times %zu B\n", opts->number, opts->size);
|
|
|
+
|
|
|
+ for (int i = 0; i < opts->number; i++) {
|
|
|
+ size = opts->size;
|
|
|
+ hardware_ptr = 0;
|
|
|
+
|
|
|
+ /* enable multi-read from DDR */
|
|
|
+ WR32_sleep (HF_REG_CONTROL,
|
|
|
+ HF_CONTROL_ENABLE_READ |
|
|
|
+ HF_CONTROL_ENABLE_MULTI_READ |
|
|
|
+ HF_CONTROL_SOURCE_RX_FIFO);
|
|
|
+
|
|
|
+ WR32_sleep (HF_REG_CONTROL,
|
|
|
+ HF_CONTROL_ENABLE_READ |
|
|
|
+ HF_CONTROL_SOURCE_RX_FIFO);
|
|
|
|
|
|
- while (size >= mem_size) {
|
|
|
desc[flag_index] = 0;
|
|
|
|
|
|
- /* set write addr */
|
|
|
- WR64 (HF_REG_DESCRIPTOR_ADDRESS, bus_addr_data);
|
|
|
+ while (size >= mem_size) {
|
|
|
+ desc[flag_index] = 0;
|
|
|
|
|
|
- /* start DMA */
|
|
|
- if (!started) {
|
|
|
- WR32_sleep (HF_REG_DMA, HF_DMA_START);
|
|
|
- started = 1;
|
|
|
- }
|
|
|
+ /* set write addr */
|
|
|
+ WR64 (HF_REG_DESCRIPTOR_ADDRESS, bus_addr_data);
|
|
|
|
|
|
- do {
|
|
|
- hardware_ptr = desc[flag_index];
|
|
|
- }
|
|
|
- while (hardware_ptr != (bus_addr_data & 0xFFFFFFFF));
|
|
|
+ /* start DMA */
|
|
|
+ if (!started) {
|
|
|
+ WR32_sleep (HF_REG_DMA, HF_DMA_START);
|
|
|
+ started = 1;
|
|
|
+ }
|
|
|
|
|
|
- fwrite (data, 1, mem_size, fp);
|
|
|
+ do {
|
|
|
+ hardware_ptr = desc[flag_index];
|
|
|
+ }
|
|
|
+ while (hardware_ptr != (bus_addr_data & 0xFFFFFFFF));
|
|
|
|
|
|
- size -= mem_size;
|
|
|
- }
|
|
|
+ fwrite (data, 1, mem_size, fp);
|
|
|
|
|
|
- memset (data, 0xf0, mem_size);
|
|
|
+ size -= mem_size;
|
|
|
+ }
|
|
|
|
|
|
- if (size > 0) {
|
|
|
- desc[flag_index] = 0;
|
|
|
+ memset (data, 0xf0, mem_size);
|
|
|
|
|
|
- if (opts->verbose)
|
|
|
- printf ("Read remaining %zu bytes\n", size);
|
|
|
+ if (size > 0) {
|
|
|
+ desc[flag_index] = 0;
|
|
|
+
|
|
|
+ if (opts->verbose)
|
|
|
+ printf ("Read remaining %zu bytes\n", size);
|
|
|
|
|
|
- WR64_sleep (HF_REG_DESCRIPTOR_ADDRESS, bus_addr_data);
|
|
|
+ WR64_sleep (HF_REG_DESCRIPTOR_ADDRESS, bus_addr_data);
|
|
|
+
|
|
|
+ do {
|
|
|
+ hardware_ptr = desc[flag_index];
|
|
|
+ }
|
|
|
+ while (hardware_ptr != (bus_addr_data & 0xFFFFFFFF));
|
|
|
|
|
|
- do {
|
|
|
- hardware_ptr = desc[flag_index];
|
|
|
+ fwrite (data, 1, size, fp);
|
|
|
}
|
|
|
- while (hardware_ptr != (bus_addr_data & 0xFFFFFFFF));
|
|
|
|
|
|
- fwrite (data, 1, size, fp);
|
|
|
+ if (opts->verbose)
|
|
|
+ printf ("Descriptor: update_pattern=%x empty=%x last_address=%lx\n", desc[0], 1 & desc[1], desc[2] | (((uint64_t) desc[3]) << 32));
|
|
|
}
|
|
|
|
|
|
- if (opts->verbose)
|
|
|
- printf ("Descriptor: update_pattern=%x empty=%x last_address=%lx\n", desc[0], 1 & desc[1], desc[2] | (((uint64_t) desc[3]) << 32));
|
|
|
-
|
|
|
WR32_sleep (HF_REG_DMA, HF_DMA_STOP);
|
|
|
fclose (fp);
|
|
|
|