|
@@ -2,6 +2,7 @@
|
|
|
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
|
+#include <stdbool.h>
|
|
|
#include <string.h>
|
|
|
#include <unistd.h>
|
|
|
#include <getopt.h>
|
|
@@ -30,6 +31,7 @@
|
|
|
typedef struct {
|
|
|
const char *input;
|
|
|
const char *output;
|
|
|
+ bool keep;
|
|
|
size_t size;
|
|
|
enum {
|
|
|
COPY_UINT64 = 0,
|
|
@@ -44,10 +46,11 @@ usage (void)
|
|
|
printf ("Usage: ddr [OPTION] [FILE]\n"
|
|
|
"Options:\n"
|
|
|
" -h, --help Show this help message and exit\n"
|
|
|
+ " -k, --keep-data Keep data and don't reset DMA\n"
|
|
|
" -o, --output Output filename\n"
|
|
|
" -i, --input Input filename\n"
|
|
|
" -s, --size Size of data (leave if reading supplied input)\n"
|
|
|
- " -c, --copy Copy method, either `memcpy', `8', `16', `32' or `64'\n");
|
|
|
+ " -c, --copy Copy method, either `memcpy' or `64'\n");
|
|
|
}
|
|
|
|
|
|
static void
|
|
@@ -55,6 +58,7 @@ parse_options (int argc, char *const *argv, Options *opts)
|
|
|
{
|
|
|
enum {
|
|
|
OPT_HELP = 'h',
|
|
|
+ OPT_KEEP = 'k',
|
|
|
OPT_INPUT = 'i',
|
|
|
OPT_OUTPUT = 'o',
|
|
|
OPT_SIZE = 's',
|
|
@@ -63,6 +67,7 @@ parse_options (int argc, char *const *argv, Options *opts)
|
|
|
|
|
|
static struct option long_options[] = {
|
|
|
{ "help", no_argument, 0, OPT_HELP },
|
|
|
+ { "keep", no_argument, 0, OPT_KEEP },
|
|
|
{ "input", required_argument, 0, OPT_INPUT },
|
|
|
{ "output", required_argument, 0, OPT_OUTPUT },
|
|
|
{ "size", required_argument, 0, OPT_SIZE },
|
|
@@ -80,11 +85,14 @@ parse_options (int argc, char *const *argv, Options *opts)
|
|
|
|
|
|
memset (opts, 0, sizeof (Options));
|
|
|
|
|
|
- while ((ret = getopt_long (argc, argv, "i:o:s:c:h", long_options, &index)) != -1) {
|
|
|
+ while ((ret = getopt_long (argc, argv, "i:o:s:c:kh", long_options, &index)) != -1) {
|
|
|
switch (ret) {
|
|
|
case OPT_HELP:
|
|
|
usage ();
|
|
|
exit (0);
|
|
|
+ case OPT_KEEP:
|
|
|
+ opts->keep = true;
|
|
|
+ break;
|
|
|
case OPT_INPUT:
|
|
|
opts->input = optarg;
|
|
|
break;
|
|
@@ -105,6 +113,25 @@ parse_options (int argc, char *const *argv, Options *opts)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+reset_ddr_data (pcilib_t *pci, volatile void *bar, Options *opts)
|
|
|
+{
|
|
|
+ /* reset DMA */
|
|
|
+ WR32_sleep (HF_REG_BASE, HF_BASE_RESET);
|
|
|
+ WR32_sleep (HF_REG_BASE, 0);
|
|
|
+
|
|
|
+ /* reset DDR and FIFOs */
|
|
|
+ WR32_sleep (HF_REG_CONTROL,
|
|
|
+ HF_CONTROL_RESET |
|
|
|
+ HF_CONTROL_SOFT_RESET |
|
|
|
+ HF_CONTROL_SOURCE_RX_FIFO);
|
|
|
+
|
|
|
+ /* write only in DDR mode, disable read */
|
|
|
+ WR32_sleep (HF_REG_CONTROL,
|
|
|
+ HF_CONTROL_SOURCE_RX_FIFO);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
write_to_ddr (pcilib_t *pci, volatile void *bar, Options *opts)
|
|
|
{
|
|
@@ -135,20 +162,6 @@ write_to_ddr (pcilib_t *pci, volatile void *bar, Options *opts)
|
|
|
read_size, size);
|
|
|
}
|
|
|
|
|
|
- /* reset DMA */
|
|
|
- WR32_sleep (HF_REG_BASE, HF_BASE_RESET);
|
|
|
- WR32_sleep (HF_REG_BASE, 0);
|
|
|
-
|
|
|
- /* reset DDR and FIFOs */
|
|
|
- WR32_sleep (HF_REG_CONTROL,
|
|
|
- HF_CONTROL_RESET |
|
|
|
- HF_CONTROL_SOFT_RESET |
|
|
|
- HF_CONTROL_SOURCE_RX_FIFO);
|
|
|
-
|
|
|
- /* write only in DDR mode, disable read */
|
|
|
- WR32_sleep (HF_REG_CONTROL,
|
|
|
- HF_CONTROL_SOURCE_RX_FIFO);
|
|
|
-
|
|
|
switch (opts->copy) {
|
|
|
case COPY_MEMCPY:
|
|
|
memcpy (bar + 0x9400, data, size);
|
|
@@ -274,6 +287,9 @@ main (int argc, char const* argv[])
|
|
|
WR32_sleep (HF_REG_DEBUG_COMPLETER_RESET, 1);
|
|
|
WR32_sleep (HF_REG_DEBUG_COMPLETER_RESET, 0);
|
|
|
|
|
|
+ if (!opts.keep)
|
|
|
+ reset_ddr_data (pci, bar, &opts);
|
|
|
+
|
|
|
if (opts.input != NULL)
|
|
|
write_to_ddr (pci, bar, &opts);
|
|
|
|