@@ -18,6 +18,7 @@ sources = [
'node-dispatcher.c',
'efw-commands.c',
'subcmd-device.c',
+ 'op-device-read.c',
]
headers = [
new file mode 100644
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+// Copyright (c) 2020 Takashi Sakamoto
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "efw-commands.h"
+
+static void print_help()
+{
+ printf("Usage\n"
+ " efw-downloader device CDEV read OFFSET LENGTH [OPTIONS]\n"
+ "\n"
+ "where:\n"
+ " CDEV: The firewire character device corresponding to the node for proto\n"
+ " OFFSET: The hexadecimal offset address in on-board flash memory\n"
+ " LENGTH: The hexadecimal number to read. The value is finally aligned to quadlet.\n"
+ " OPTIONS:\n"
+ " --help, -h: Print this help message and exit.\n"
+ " --debug: Output debug message to stderr\n");
+}
+
+static int parse_args(int argc, char **argv, size_t *offset, size_t *quads, gboolean *help)
+{
+ unsigned long val;
+ char *end;
+ int i;
+
+ if (argc < 4)
+ return -EINVAL;
+ assert(strncmp(argv[3], "read", sizeof("read")) == 0);
+
+ if (argc < 5)
+ return -EINVAL;
+ val = strtol(argv[4], &end, 16);
+ if (*end != '\0') {
+ printf("Invalid argument for offset address.\n");
+ return -EINVAL;
+ }
+ *offset = (size_t)val;
+
+ if (argc < 6)
+ return -EINVAL;
+ val = strtol(argv[5], &end, 16);
+ if (*end != '\0') {
+ printf("Invalid argument for quadlet count.\n");
+ return -EINVAL;
+ }
+ *quads = (size_t)(val + 3) / 4;
+
+ *help = FALSE;
+ for (i = 0; i < argc; ++i) {
+ if (strncmp(argv[i], "--help", sizeof("--help")) == 0 ||
+ strncmp(argv[i], "-h", sizeof("-h")) == 0) {
+ *help = TRUE;
+ }
+ }
+
+ return 0;
+}
+
+void op_device_read(int argc, char **argv, EfwProto *proto, GError **error)
+{
+ size_t offset;
+ size_t quads;
+ guint32 *buf;
+ gboolean help;
+ int err;
+ int i;
+
+ err = parse_args(argc, argv, &offset, &quads, &help);
+ if (err < 0) {
+ print_help();
+ g_set_error_literal(error, G_FILE_ERROR, G_FILE_ERROR_INVAL, "Invalid arguments");
+ return;
+ }
+
+ if (help) {
+ print_help();
+ return;
+ }
+
+ buf = g_try_malloc0_n(quads, sizeof(*buf));
+ if (buf == NULL) {
+ fprintf(stderr, "Memory allocation fails.\n");
+ g_set_error_literal(error, G_FILE_ERROR, G_FILE_ERROR_NOSPC, "Memory allocation error");
+ return;
+ }
+
+ efw_flash_recursive_read(proto, offset, buf, quads, error);
+ if (*error != NULL) {
+ fprintf(stderr,
+ "Fail to read contents of flash memory: %s %d %s\n",
+ g_quark_to_string((*error)->domain), (*error)->code, (*error)->message);
+ goto end;
+ }
+
+ for (i = 0; i < quads; ++i)
+ printf(" %08lx: %08x\n", offset + 4 * i, buf[i]);
+end:
+ g_free(buf);
+}
@@ -9,6 +9,8 @@
#include "config-rom.h"
#include "node-dispatcher.h"
+#include "subcmds.h"
+
#define report_error(error, msg) \
fprintf(stderr, "Fail to %s: %s %d %s\n", \
msg, g_quark_to_string(error->domain), error->code, error->message)
@@ -21,6 +23,7 @@ static int print_help()
"where:\n"
" CDEV: The firewire character device corresponding to the node for transaction\n"
" OPERATION:\n"
+ " read: read from on-board flash memory\n"
" help: print this help message\n"
" ARGUMENTS:\n"
" depending on OPERATION\n"
@@ -84,6 +87,7 @@ int subcmd_device(int argc, char **argv)
size_t size;
void (*op)(int argc, char **argv, EfwProto *proto, GError **error);
} *entry, entries[] = {
+ { "read", sizeof("read"), op_device_read },
};
GError *error = NULL;
gboolean debug;
@@ -3,6 +3,10 @@
#ifndef __SUBCMDS_H__
#define __SUBCMDS_H__
+#include "efw-proto.h"
+
int subcmd_device(int argc, char **argv);
+void op_device_read(int argc, char **argv, EfwProto *proto, GError **error);
+
#endif
This commit add read operation in device sub command. The arbitrary range of address in on-board flash memory is read and the content is dump in stdout. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> --- efw-downloader/src/meson.build | 1 + efw-downloader/src/op-device-read.c | 104 ++++++++++++++++++++++++++++ efw-downloader/src/subcmd-device.c | 4 ++ efw-downloader/src/subcmds.h | 4 ++ 4 files changed, 113 insertions(+) create mode 100644 efw-downloader/src/op-device-read.c