summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2018-03-05 08:53:56 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2018-03-05 08:53:56 +0100
commit3347d0327b4e2d46e6f601d4d14054ec37b44272 (patch)
tree1bd2c198dc893e645bfe2052f402a6e8d9574711
parentcce3ed31230cf60ddbc653b3ace1fb64e05bbddb (diff)
parent0d008a21d006e9541999fe2429c2112c53cd1992 (diff)
downloadbarebox-3347d0327b4e2d46e6f601d4d14054ec37b44272.tar.gz
barebox-3347d0327b4e2d46e6f601d4d14054ec37b44272.tar.xz
Merge branch 'for-next/ratp'
-rw-r--r--Documentation/user/remote-control.rst7
-rw-r--r--arch/arm/lib32/barebox.lds.S4
-rw-r--r--arch/arm/lib64/barebox.lds.S4
-rw-r--r--arch/blackfin/boards/ipe337/barebox.lds.S5
-rw-r--r--arch/mips/lib/barebox.lds.S4
-rw-r--r--arch/nios2/cpu/barebox.lds.S5
-rw-r--r--arch/openrisc/cpu/barebox.lds.S4
-rw-r--r--arch/ppc/boards/pcm030/barebox.lds.S4
-rw-r--r--arch/ppc/mach-mpc85xx/barebox.lds.S4
-rw-r--r--arch/sandbox/board/barebox.lds.S5
-rw-r--r--arch/x86/lib/barebox.lds.S7
-rw-r--r--arch/x86/mach-efi/elf_ia32_efi.lds.S5
-rw-r--r--arch/x86/mach-efi/elf_x86_64_efi.lds.S5
-rw-r--r--common/Kconfig13
-rw-r--r--common/Makefile3
-rw-r--r--common/module.lds.S2
-rw-r--r--common/ratp/Kconfig14
-rw-r--r--common/ratp/Makefile6
-rw-r--r--common/ratp/getenv.c51
-rw-r--r--common/ratp/md.c202
-rw-r--r--common/ratp/mw.c173
-rw-r--r--common/ratp/ping.c40
-rw-r--r--common/ratp/ratp.c (renamed from common/ratp.c)156
-rw-r--r--common/ratp/reset.c55
-rw-r--r--fs/Kconfig2
-rw-r--r--include/asm-generic/barebox.lds.h2
-rw-r--r--include/ratp_bb.h52
-rw-r--r--lib/Kconfig2
-rw-r--r--lib/readline.c2
-rw-r--r--scripts/remote/controller.py27
-rw-r--r--scripts/remote/main.py51
-rw-r--r--scripts/remote/messages.py105
32 files changed, 918 insertions, 103 deletions
diff --git a/Documentation/user/remote-control.rst b/Documentation/user/remote-control.rst
index 2172514290..c8b7442f17 100644
--- a/Documentation/user/remote-control.rst
+++ b/Documentation/user/remote-control.rst
@@ -18,6 +18,13 @@ Additionally files can be transferred from/to barebox and a regular
console offers interactive access to barebox on flawy serial
connections.
+In addition to the bbremote tool provided with barebox, other third
+party tools exist that use the same RATP based protocol to communicate
+with the barebox instance, e.g. the libratp-barebox C library and the
+ratp-barebox-cli tool:
+
+ https://github.com/aleksander0m/libratp-barebox
+
Enabling remote control support
-------------------------------
diff --git a/arch/arm/lib32/barebox.lds.S b/arch/arm/lib32/barebox.lds.S
index e7b87b7cdd..6fadc2a357 100644
--- a/arch/arm/lib32/barebox.lds.S
+++ b/arch/arm/lib32/barebox.lds.S
@@ -85,6 +85,10 @@ SECTIONS
.barebox_cmd : { BAREBOX_CMDS }
__barebox_cmd_end = .;
+ __barebox_ratp_cmd_start = .;
+ .barebox_ratp_cmd : { BAREBOX_RATP_CMDS }
+ __barebox_ratp_cmd_end = .;
+
__barebox_magicvar_start = .;
.barebox_magicvar : { BAREBOX_MAGICVARS }
__barebox_magicvar_end = .;
diff --git a/arch/arm/lib64/barebox.lds.S b/arch/arm/lib64/barebox.lds.S
index 240699f1a6..a53b933bba 100644
--- a/arch/arm/lib64/barebox.lds.S
+++ b/arch/arm/lib64/barebox.lds.S
@@ -82,6 +82,10 @@ SECTIONS
.barebox_cmd : { BAREBOX_CMDS }
__barebox_cmd_end = .;
+ __barebox_ratp_cmd_start = .;
+ .barebox_ratp_cmd : { BAREBOX_RATP_CMDS }
+ __barebox_ratp_cmd_end = .;
+
__barebox_magicvar_start = .;
.barebox_magicvar : { BAREBOX_MAGICVARS }
__barebox_magicvar_end = .;
diff --git a/arch/blackfin/boards/ipe337/barebox.lds.S b/arch/blackfin/boards/ipe337/barebox.lds.S
index 51a586af27..7e82a1bd74 100644
--- a/arch/blackfin/boards/ipe337/barebox.lds.S
+++ b/arch/blackfin/boards/ipe337/barebox.lds.S
@@ -68,6 +68,10 @@ SECTIONS
.barebox_cmd : { BAREBOX_CMDS }
___barebox_cmd_end = .;
+ ___barebox_ratp_cmd_start = .;
+ .barebox_ratp_cmd : { BAREBOX_RATP_CMDS }
+ ___barebox_ratp_cmd_end = .;
+
___barebox_magicvar_start = .;
.barebox_magicvar : { BAREBOX_MAGICVARS }
___barebox_magicvar_end = .;
@@ -91,4 +95,3 @@ SECTIONS
___bss_stop = .;
_end = .;
}
-
diff --git a/arch/mips/lib/barebox.lds.S b/arch/mips/lib/barebox.lds.S
index 899f62b968..660d4be85e 100644
--- a/arch/mips/lib/barebox.lds.S
+++ b/arch/mips/lib/barebox.lds.S
@@ -55,6 +55,10 @@ SECTIONS
.barebox_cmd : { BAREBOX_CMDS }
__barebox_cmd_end = .;
+ __barebox_ratp_cmd_start = .;
+ .barebox_ratp_cmd : { BAREBOX_RATP_CMDS }
+ __barebox_ratp_cmd_end = .;
+
__barebox_magicvar_start = .;
.barebox_magicvar : { BAREBOX_MAGICVARS }
__barebox_magicvar_end = .;
diff --git a/arch/nios2/cpu/barebox.lds.S b/arch/nios2/cpu/barebox.lds.S
index a2d7fa8cdf..fbcd1cd3f7 100644
--- a/arch/nios2/cpu/barebox.lds.S
+++ b/arch/nios2/cpu/barebox.lds.S
@@ -55,6 +55,10 @@ SECTIONS
.barebox_cmd : { BAREBOX_CMDS }
__barebox_cmd_end = .;
+ __barebox_ratp_cmd_start = .;
+ .barebox_ratp_cmd : { BAREBOX_RATP_CMDS }
+ __barebox_ratp_cmd_end = .;
+
__barebox_magicvar_start = .;
.barebox_magicvar : { BAREBOX_MAGICVARS }
__barebox_magicvar_end = .;
@@ -129,4 +133,3 @@ SECTIONS
_end = .;
PROVIDE (end = .);
}
-
diff --git a/arch/openrisc/cpu/barebox.lds.S b/arch/openrisc/cpu/barebox.lds.S
index b819ca0996..c6807aec3a 100644
--- a/arch/openrisc/cpu/barebox.lds.S
+++ b/arch/openrisc/cpu/barebox.lds.S
@@ -57,6 +57,10 @@ SECTIONS
.barebox_cmd : { BAREBOX_CMDS } > ram
__barebox_cmd_end = .;
+ __barebox_ratp_cmd_start = .;
+ .barebox_ratp_cmd : { BAREBOX_RATP_CMDS } > ram
+ __barebox_ratp_cmd_end = .;
+
__barebox_magicvar_start = .;
.barebox_magicvar : { BAREBOX_MAGICVARS } > ram
__barebox_magicvar_end = .;
diff --git a/arch/ppc/boards/pcm030/barebox.lds.S b/arch/ppc/boards/pcm030/barebox.lds.S
index 0e34f0a41b..3b8bf3c0d0 100644
--- a/arch/ppc/boards/pcm030/barebox.lds.S
+++ b/arch/ppc/boards/pcm030/barebox.lds.S
@@ -104,6 +104,10 @@ SECTIONS
.barebox_cmd : { BAREBOX_CMDS }
__barebox_cmd_end = .;
+ __barebox_ratp_cmd_start = .;
+ .barebox_ratp_cmd : { BAREBOX_RATP_CMDS }
+ __barebox_ratp_cmd_end = .;
+
__barebox_magicvar_start = .;
.barebox_magicvar : { BAREBOX_MAGICVARS }
__barebox_magicvar_end = .;
diff --git a/arch/ppc/mach-mpc85xx/barebox.lds.S b/arch/ppc/mach-mpc85xx/barebox.lds.S
index beebab39d6..0001972831 100644
--- a/arch/ppc/mach-mpc85xx/barebox.lds.S
+++ b/arch/ppc/mach-mpc85xx/barebox.lds.S
@@ -105,6 +105,10 @@ SECTIONS
.barebox_cmd : { BAREBOX_CMDS }
__barebox_cmd_end = .;
+ __barebox_ratp_cmd_start = .;
+ .barebox_ratp_cmd : { BAREBOX_RATP_CMDS }
+ __barebox_ratp_cmd_end = .;
+
__barebox_initcalls_start = .;
.barebox_initcalls : { INITCALLS }
__barebox_initcalls_end = .;
diff --git a/arch/sandbox/board/barebox.lds.S b/arch/sandbox/board/barebox.lds.S
index 0d67ab6607..80e27fe87d 100644
--- a/arch/sandbox/board/barebox.lds.S
+++ b/arch/sandbox/board/barebox.lds.S
@@ -21,6 +21,11 @@ SECTIONS
__barebox_cmd_start = .;
__barebox_cmd : { BAREBOX_CMDS }
__barebox_cmd_end = .;
+
+ . = ALIGN(64);
+ __barebox_ratp_cmd_start = .;
+ __barebox_ratp_cmd : { BAREBOX_RATP_CMDS }
+ __barebox_ratp_cmd_end = .;
}
INSERT BEFORE .rodata;
diff --git a/arch/x86/lib/barebox.lds.S b/arch/x86/lib/barebox.lds.S
index 23d7546532..6ee9342f47 100644
--- a/arch/x86/lib/barebox.lds.S
+++ b/arch/x86/lib/barebox.lds.S
@@ -171,6 +171,13 @@ SECTIONS
. = ALIGN(4);
} > barebox
+ .barebox_ratp_cmd : AT ( LOADADDR(.got) + SIZEOF (.got) ) {
+ __barebox_ratp_cmd_start = .;
+ BAREBOX_RATP_CMDS
+ __barebox_ratp_cmd_end = .;
+ . = ALIGN(4);
+ } > barebox
+
.barebox_magicvars : AT ( LOADADDR(.barebox_cmd) + SIZEOF (.barebox_cmd) ) {
__barebox_magicvar_start = .;
BAREBOX_MAGICVARS
diff --git a/arch/x86/mach-efi/elf_ia32_efi.lds.S b/arch/x86/mach-efi/elf_ia32_efi.lds.S
index 69f43f5547..9477aa7d73 100644
--- a/arch/x86/mach-efi/elf_ia32_efi.lds.S
+++ b/arch/x86/mach-efi/elf_ia32_efi.lds.S
@@ -70,6 +70,11 @@ SECTIONS
__barebox_cmd : { BAREBOX_CMDS }
__barebox_cmd_end = .;
+ . = ALIGN(64);
+ __barebox_ratp_cmd_start = .;
+ __barebox_ratp_cmd : { BAREBOX_RATP_CMDS }
+ __barebox_ratp_cmd_end = .;
+
. = ALIGN(4096);
.dynamic : { *(.dynamic) }
. = ALIGN(4096);
diff --git a/arch/x86/mach-efi/elf_x86_64_efi.lds.S b/arch/x86/mach-efi/elf_x86_64_efi.lds.S
index 93d34d17ab..90b6b9f3f1 100644
--- a/arch/x86/mach-efi/elf_x86_64_efi.lds.S
+++ b/arch/x86/mach-efi/elf_x86_64_efi.lds.S
@@ -72,6 +72,11 @@ SECTIONS
__barebox_cmd : { BAREBOX_CMDS }
__barebox_cmd_end = .;
+ . = ALIGN(64);
+ __barebox_ratp_cmd_start = .;
+ __barebox_ratp_cmd : { BAREBOX_RATP_CMDS }
+ __barebox_ratp_cmd_end = .;
+
. = ALIGN(4096);
.dynamic : { *(.dynamic) }
. = ALIGN(4096);
diff --git a/common/Kconfig b/common/Kconfig
index 25de2485cd..af71d6888a 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -770,18 +770,7 @@ config PBL_CONSOLE
must be running at the address it's linked at and bss must
be cleared. On ARM that would be after setup_c().
-config CONSOLE_RATP
- bool
- select RATP
- select CRC16
- select POLLER
- depends on CONSOLE_FULL
- prompt "RATP console support"
- help
- This option adds support for remote controlling barebox via serial
- port. The regular console is designed for human interaction whereas
- this option adds a machine readable interface for controlling barebox.
- Say yes here if you want to control barebox from a remote host.
+source common/ratp/Kconfig
config PARTITION
bool
diff --git a/common/Makefile b/common/Makefile
index 5351ef0f77..a9abcd1bc6 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -46,7 +46,7 @@ obj-$(CONFIG_RESET_SOURCE) += reset_source.o
obj-$(CONFIG_SHELL_HUSH) += hush.o
obj-$(CONFIG_SHELL_SIMPLE) += parser.o
obj-$(CONFIG_STATE) += state/
-obj-$(CONFIG_RATP) += ratp.o
+obj-$(CONFIG_RATP) += ratp/
obj-$(CONFIG_BOOTCHOOSER) += bootchooser.o
obj-$(CONFIG_UIMAGE) += image.o uimage.o
obj-$(CONFIG_FITIMAGE) += image-fit.o
@@ -60,7 +60,6 @@ obj-$(CONFIG_FILE_LIST) += file-list.o
obj-$(CONFIG_FIRMWARE) += firmware.o
obj-$(CONFIG_UBIFORMAT) += ubiformat.o
obj-$(CONFIG_BAREBOX_UPDATE_IMX_NAND_FCB) += imx-bbu-nand-fcb.o
-obj-$(CONFIG_CONSOLE_RATP) += ratp.o
obj-$(CONFIG_BOOT) += boot.o
ifdef CONFIG_PASSWORD
diff --git a/common/module.lds.S b/common/module.lds.S
index a03d04f401..f3dbb12f4a 100644
--- a/common/module.lds.S
+++ b/common/module.lds.S
@@ -35,6 +35,8 @@ SECTIONS
.got : { *(.got) }
.barebox_cmd : { BAREBOX_CMDS }
+ .barebox_ratp_cmd : { BAREBOX_RATP_CMDS }
+
. = ALIGN(4);
.bss : { *(.bss) }
}
diff --git a/common/ratp/Kconfig b/common/ratp/Kconfig
new file mode 100644
index 0000000000..93ff75d64d
--- /dev/null
+++ b/common/ratp/Kconfig
@@ -0,0 +1,14 @@
+
+config CONSOLE_RATP
+ bool
+ select RATP
+ select CRC16
+ select POLLER
+ depends on CONSOLE_FULL
+ prompt "RATP console support"
+ help
+ This option adds support for remote controlling barebox via serial
+ port. The regular console is designed for human interaction whereas
+ this option adds a machine readable interface for controlling barebox.
+ Say yes here if you want to control barebox from a remote host.
+
diff --git a/common/ratp/Makefile b/common/ratp/Makefile
new file mode 100644
index 0000000000..2c6d674f61
--- /dev/null
+++ b/common/ratp/Makefile
@@ -0,0 +1,6 @@
+obj-y += ratp.o
+obj-y += ping.o
+obj-y += getenv.o
+obj-y += md.o
+obj-y += mw.o
+obj-y += reset.o
diff --git a/common/ratp/getenv.c b/common/ratp/getenv.c
new file mode 100644
index 0000000000..b409634886
--- /dev/null
+++ b/common/ratp/getenv.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2018 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*
+ * RATP getenv
+ */
+
+#include <common.h>
+#include <ratp_bb.h>
+#include <malloc.h>
+#include <environment.h>
+
+static int ratp_cmd_getenv(const struct ratp_bb *req, int req_len,
+ struct ratp_bb **rsp, int *rsp_len)
+{
+ int dlen = req_len - sizeof (struct ratp_bb);
+ char *varname;
+ const char *value;
+
+ varname = xstrndup ((const char *)req->data, dlen);
+ value = getenv (varname);
+ free (varname);
+
+ dlen = strlen (value);
+
+ *rsp_len = sizeof(struct ratp_bb) + dlen;
+ *rsp = xzalloc(*rsp_len);
+ (*rsp)->type = cpu_to_be16(BB_RATP_TYPE_GETENV_RETURN);
+ memcpy ((*rsp)->data, value, dlen);
+ return 0;
+}
+
+BAREBOX_RATP_CMD_START(GETENV)
+ .request_id = BB_RATP_TYPE_GETENV,
+ .response_id = BB_RATP_TYPE_GETENV_RETURN,
+ .cmd = ratp_cmd_getenv
+BAREBOX_RATP_CMD_END
diff --git a/common/ratp/md.c b/common/ratp/md.c
new file mode 100644
index 0000000000..9b8fc2bc50
--- /dev/null
+++ b/common/ratp/md.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2011-2018 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <ratp_bb.h>
+#include <init.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fs.h>
+#include <libfile.h>
+#include <fcntl.h>
+#include <linux/stat.h>
+#include <xfuncs.h>
+
+/* NOTE:
+ * - Fixed-size fields (e.g. integers) are given just after the header.
+ * - Variable-length fields are stored inside the buffer[] and their position
+ * within the buffer[] and their size are given as fixed-sized fields after
+ * the header.
+ * The message may be extended at any time keeping backwards compatibility,
+ * as the position of the buffer[] is given by the buffer_offset field. i.e.
+ * increasing the buffer_offset field we can extend the fixed-sized section
+ * to add more fields.
+ */
+
+struct ratp_bb_md_request {
+ struct ratp_bb header;
+ uint16_t buffer_offset;
+ uint16_t addr;
+ uint16_t size;
+ uint16_t path_size;
+ uint16_t path_offset;
+ uint8_t buffer[];
+} __attribute__((packed));
+
+struct ratp_bb_md_response {
+ struct ratp_bb header;
+ uint16_t buffer_offset;
+ uint32_t errno;
+ uint16_t data_size;
+ uint16_t data_offset;
+ uint8_t buffer[];
+} __attribute__((packed));
+
+extern char *mem_rw_buf;
+
+static int do_ratp_mem_md(const char *filename,
+ loff_t start,
+ loff_t size,
+ uint8_t *output)
+{
+ int r, now, t;
+ int ret = 0;
+ int fd;
+ void *map;
+
+ fd = open_and_lseek(filename, O_RWSIZE_1 | O_RDONLY, start);
+ if (fd < 0)
+ return -errno;
+
+ map = memmap(fd, PROT_READ);
+ if (map != (void *)-1) {
+ memcpy(output, (uint8_t *)(map + start), size);
+ goto out;
+ }
+
+ t = 0;
+ do {
+ now = min(size, (loff_t)RW_BUF_SIZE);
+ r = read(fd, mem_rw_buf, now);
+ if (r < 0) {
+ ret = -errno;
+ perror("read");
+ goto out;
+ }
+ if (!r)
+ goto out;
+
+ memcpy(output + t, (uint8_t *)(mem_rw_buf), r);
+
+ size -= r;
+ t += r;
+ } while (size);
+
+out:
+ close(fd);
+
+ return ret;
+}
+
+static int ratp_cmd_md(const struct ratp_bb *req, int req_len,
+ struct ratp_bb **rsp, int *rsp_len)
+{
+ struct ratp_bb_md_request *md_req = (struct ratp_bb_md_request *)req;
+ struct ratp_bb_md_response *md_rsp;
+ uint8_t *buffer;
+ uint16_t buffer_offset;
+ uint16_t buffer_size;
+ int md_rsp_len;
+ uint16_t addr;
+ uint16_t size;
+ uint16_t path_size;
+ uint16_t path_offset;
+ char *path = NULL;
+ int ret = 0;
+
+ /* At least message header should be valid */
+ if (req_len < sizeof(*md_req)) {
+ printf("ratp md ignored: size mismatch (%d < %zu)\n",
+ req_len, sizeof (*md_req));
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Validate buffer position and size */
+ buffer_offset = be16_to_cpu(md_req->buffer_offset);
+ if (req_len < buffer_offset) {
+ printf("ratp md ignored: invalid buffer offset (%d < %hu)\n",
+ req_len, buffer_offset);
+ ret = -EINVAL;
+ goto out;
+ }
+ buffer_size = req_len - buffer_offset;
+ buffer = ((uint8_t *)md_req) + buffer_offset;
+
+ /* Validate path position and size */
+ path_offset = be16_to_cpu(md_req->path_offset);
+ if (path_offset != 0) {
+ printf("ratp md ignored: invalid path offset\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ path_size = be16_to_cpu(md_req->path_size);
+ if (!path_size) {
+ printf("ratp md ignored: no filepath given\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Validate buffer size */
+ if (buffer_size < path_size) {
+ printf("ratp mw ignored: size mismatch (%d < %hu): path may not be fully given\n",
+ req_len, path_size);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ addr = be16_to_cpu (md_req->addr);
+ size = be16_to_cpu (md_req->size);
+ path = xstrndup((const char *)&buffer[path_offset], path_size);
+
+out:
+ /* Avoid reading anything on error */
+ if (ret != 0)
+ size = 0;
+
+ md_rsp_len = sizeof(*md_rsp) + size;
+ md_rsp = xzalloc(md_rsp_len);
+ md_rsp->header.type = cpu_to_be16(BB_RATP_TYPE_MD_RETURN);
+ md_rsp->buffer_offset = cpu_to_be16(sizeof(*md_rsp));
+ md_rsp->data_offset = 0;
+
+ /* Don't read anything on error or if 0 bytes were requested */
+ if (size > 0)
+ ret = do_ratp_mem_md(path, addr, size, md_rsp->buffer);
+
+ if (ret != 0) {
+ md_rsp->data_size = 0;
+ md_rsp->errno = cpu_to_be32(ret);
+ md_rsp_len = sizeof(*md_rsp);
+ } else {
+ md_rsp->data_size = cpu_to_be16(size);
+ md_rsp->errno = 0;
+ }
+
+ *rsp = (struct ratp_bb *)md_rsp;
+ *rsp_len = md_rsp_len;
+
+ free (path);
+ return ret;
+}
+
+BAREBOX_RATP_CMD_START(MD)
+ .request_id = BB_RATP_TYPE_MD,
+ .response_id = BB_RATP_TYPE_MD_RETURN,
+ .cmd = ratp_cmd_md
+BAREBOX_RATP_CMD_END
diff --git a/common/ratp/mw.c b/common/ratp/mw.c
new file mode 100644
index 0000000000..7d6df3d0a0
--- /dev/null
+++ b/common/ratp/mw.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2011-2018 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ * Copyright (c) 2018 Zodiac Inflight Innovations
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <ratp_bb.h>
+#include <init.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fs.h>
+#include <libfile.h>
+#include <fcntl.h>
+#include <xfuncs.h>
+
+/* NOTE:
+ * - Fixed-size fields (e.g. integers) are given just after the header.
+ * - Variable-length fields are stored inside the buffer[] and their position
+ * within the buffer[] and their size are given as fixed-sized fields after
+ * the header.
+ * The message may be extended at any time keeping backwards compatibility,
+ * as the position of the buffer[] is given by the buffer_offset field. i.e.
+ * increasing the buffer_offset field we can extend the fixed-sized section
+ * to add more fields.
+ */
+
+struct ratp_bb_mw_request {
+ struct ratp_bb header;
+ uint16_t buffer_offset;
+ uint16_t addr;
+ uint16_t path_size;
+ uint16_t path_offset;
+ uint16_t data_size;
+ uint16_t data_offset;
+ uint8_t buffer[];
+} __attribute__((packed));
+
+struct ratp_bb_mw_response {
+ struct ratp_bb header;
+ uint16_t buffer_offset;
+ uint32_t errno;
+ uint16_t written;
+ uint8_t buffer[];
+} __attribute__((packed));
+
+static int ratp_cmd_mw(const struct ratp_bb *req, int req_len,
+ struct ratp_bb **rsp, int *rsp_len)
+{
+ struct ratp_bb_mw_request *mw_req = (struct ratp_bb_mw_request *)req;
+ struct ratp_bb_mw_response *mw_rsp;
+ uint8_t *buffer;
+ uint16_t buffer_offset;
+ uint16_t buffer_size;
+ uint16_t addr;
+ uint16_t path_size;
+ uint16_t path_offset;
+ uint16_t data_size;
+ uint16_t data_offset;
+ ssize_t written = 0;
+ char *path = NULL;
+ int fd;
+ int ret = 0;
+
+ /* At least message header should be valid */
+ if (req_len < sizeof(*mw_req)) {
+ printf("ratp mw ignored: size mismatch (%d < %zu)\n",
+ req_len, sizeof (*mw_req));
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Validate buffer position and size */
+ buffer_offset = be16_to_cpu(mw_req->buffer_offset);
+ if (req_len < buffer_offset) {
+ printf("ratp mw ignored: invalid buffer offset (%d < %hu)\n",
+ req_len, buffer_offset);
+ ret = -EINVAL;
+ goto out;
+ }
+ buffer_size = req_len - buffer_offset;
+ buffer = ((uint8_t *)mw_req) + buffer_offset;
+
+ /* Validate path position and size */
+ path_offset = be16_to_cpu(mw_req->path_offset);
+ if (path_offset != 0) {
+ printf("ratp mw ignored: invalid path offset\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ path_size = be16_to_cpu(mw_req->path_size);
+ if (!path_size) {
+ printf("ratp mw ignored: no filepath given\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Validate data position and size */
+ data_offset = be16_to_cpu(mw_req->data_offset);
+ if (data_offset != (path_offset + path_size)) {
+ printf("ratp mw ignored: invalid path offset\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ data_size = be16_to_cpu(mw_req->data_size);
+ if (!data_size) {
+ /* Success */
+ goto out;
+ }
+
+ /* Validate buffer size */
+ if (buffer_size < (path_size + data_size)) {
+ printf("ratp mw ignored: size mismatch (%d < %hu): path or data not be fully given\n",
+ req_len, path_size + data_size);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ addr = be16_to_cpu (mw_req->addr);
+ path = xstrndup((const char *)&buffer[path_offset], path_size);
+
+ fd = open_and_lseek(path, O_RWSIZE_1 | O_WRONLY, addr);
+ if (fd < 0) {
+ ret = -errno;
+ goto out;
+ }
+
+ written = write(fd, &buffer[data_offset], data_size);
+ if (written < 0) {
+ ret = -errno;
+ perror("write");
+ }
+
+ close(fd);
+
+out:
+ mw_rsp = xzalloc(sizeof(*mw_rsp));
+ mw_rsp->header.type = cpu_to_be16(BB_RATP_TYPE_MW_RETURN);
+ mw_rsp->buffer_offset = cpu_to_be16(sizeof(*mw_rsp)); /* n/a */
+
+ if (ret != 0) {
+ mw_rsp->written = 0;
+ mw_rsp->errno = cpu_to_be32(ret);
+ } else {
+ mw_rsp->written = cpu_to_be16((uint16_t)written);
+ mw_rsp->errno = 0;
+ }
+
+ *rsp = (struct ratp_bb *)mw_rsp;
+ *rsp_len = sizeof(*mw_rsp);
+
+ free (path);
+ return ret;
+}
+
+BAREBOX_RATP_CMD_START(MW)
+ .request_id = BB_RATP_TYPE_MW,
+ .response_id = BB_RATP_TYPE_MW_RETURN,
+ .cmd = ratp_cmd_mw
+BAREBOX_RATP_CMD_END
diff --git a/common/ratp/ping.c b/common/ratp/ping.c
new file mode 100644
index 0000000000..cc29ea36c6
--- /dev/null
+++ b/common/ratp/ping.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*
+ * RATP ping
+ */
+
+#include <common.h>
+#include <ratp_bb.h>
+#include <malloc.h>
+
+static int ratp_cmd_ping(const struct ratp_bb *req, int req_len,
+ struct ratp_bb **rsp, int *rsp_len)
+{
+ /* Just build response */
+ *rsp_len = sizeof(struct ratp_bb);
+ *rsp = xzalloc(*rsp_len);
+ (*rsp)->type = cpu_to_be16(BB_RATP_TYPE_PONG);
+ return 0;
+}
+
+BAREBOX_RATP_CMD_START(PING)
+ .request_id = BB_RATP_TYPE_PING,
+ .response_id = BB_RATP_TYPE_PONG,
+ .cmd = ratp_cmd_ping
+BAREBOX_RATP_CMD_END
diff --git a/common/ratp.c b/common/ratp/ratp.c
index 80863f81fb..fae9cec5b9 100644
--- a/common/ratp.c
+++ b/common/ratp/ratp.c
@@ -31,21 +31,10 @@
#include <ratp_bb.h>
#include <fs.h>
-#define BB_RATP_TYPE_COMMAND 1
-#define BB_RATP_TYPE_COMMAND_RETURN 2
-#define BB_RATP_TYPE_CONSOLEMSG 3
-#define BB_RATP_TYPE_PING 4
-#define BB_RATP_TYPE_PONG 5
-#define BB_RATP_TYPE_GETENV 6
-#define BB_RATP_TYPE_GETENV_RETURN 7
-#define BB_RATP_TYPE_FS 8
-#define BB_RATP_TYPE_FS_RETURN 9
-
-struct ratp_bb {
- uint16_t type;
- uint16_t flags;
- uint8_t data[];
-};
+LIST_HEAD(ratp_command_list);
+EXPORT_SYMBOL(ratp_command_list);
+
+#define for_each_ratp_command(cmd) list_for_each_entry(cmd, &ratp_command_list, list)
struct ratp_bb_command_return {
uint32_t errno;
@@ -66,6 +55,51 @@ struct ratp_ctx {
struct poller_struct poller;
};
+static int compare_ratp_command(struct list_head *a, struct list_head *b)
+{
+ int id_a = list_entry(a, struct ratp_command, list)->request_id;
+ int id_b = list_entry(b, struct ratp_command, list)->request_id;
+
+ return (id_a - id_b);
+}
+
+int register_ratp_command(struct ratp_command *cmd)
+{
+ debug("register ratp command: request %hu, response %hu\n",
+ cmd->request_id, cmd->response_id);
+ list_add_sort(&cmd->list, &ratp_command_list, compare_ratp_command);
+ return 0;
+}
+EXPORT_SYMBOL(register_ratp_command);
+
+struct ratp_command *find_ratp_request(uint16_t request_id)
+{
+ struct ratp_command *cmdtp;
+
+ for_each_ratp_command(cmdtp)
+ if (request_id == cmdtp->request_id)
+ return cmdtp;
+
+ return NULL; /* not found */
+}
+
+extern struct ratp_command __barebox_ratp_cmd_start;
+extern struct ratp_command __barebox_ratp_cmd_end;
+
+static int init_ratp_command_list(void)
+{
+ struct ratp_command *cmdtp;
+
+ for (cmdtp = &__barebox_ratp_cmd_start;
+ cmdtp != &__barebox_ratp_cmd_end;
+ cmdtp++)
+ register_ratp_command(cmdtp);
+
+ return 0;
+}
+
+late_initcall(init_ratp_command_list);
+
static int console_recv(struct ratp *r, uint8_t *data)
{
struct ratp_ctx *ctx = container_of(r, struct ratp_ctx, ratp);
@@ -98,17 +132,6 @@ static int console_send(struct ratp *r, void *pkt, int len)
return 0;
}
-static void *xmemdup_add_zero(const void *buf, int len)
-{
- void *ret;
-
- ret = xzalloc(len + 1);
- *(uint8_t *)(ret + len) = 0;
- memcpy(ret, buf, len);
-
- return ret;
-}
-
static void ratp_queue_console_tx(struct ratp_ctx *ctx)
{
u8 buf[255];
@@ -155,48 +178,6 @@ static int ratp_bb_send_command_return(struct ratp_ctx *ctx, uint32_t errno)
return ret;
}
-static int ratp_bb_send_pong(struct ratp_ctx *ctx)
-{
- void *buf;
- struct ratp_bb *rbb;
- int len = sizeof(*rbb);
- int ret;
-
- buf = xzalloc(len);
- rbb = buf;
-
- rbb->type = cpu_to_be16(BB_RATP_TYPE_PONG);
-
- ret = ratp_send(&ctx->ratp, buf, len);
-
- free(buf);
-
- return ret;
-}
-
-static int ratp_bb_send_getenv_return(struct ratp_ctx *ctx, const char *val)
-{
- void *buf;
- struct ratp_bb *rbb;
- int len, ret;
-
- if (!val)
- val = "";
-
- len = sizeof(*rbb) + strlen(val);
- buf = xzalloc(len);
- rbb = buf;
- strcpy(rbb->data, val);
-
- rbb->type = cpu_to_be16(BB_RATP_TYPE_GETENV_RETURN);
-
- ret = ratp_send(&ctx->ratp, buf, len);
-
- free(buf);
-
- return ret;
-}
-
static char *ratp_command;
static struct ratp_ctx *ratp_ctx;
@@ -205,39 +186,45 @@ static int ratp_bb_dispatch(struct ratp_ctx *ctx, const void *buf, int len)
const struct ratp_bb *rbb = buf;
struct ratp_bb_pkt *pkt;
int dlen = len - sizeof(struct ratp_bb);
- char *varname;
int ret = 0;
+ uint16_t type = be16_to_cpu(rbb->type);
+ struct ratp_command *cmd;
+
+ /* See if there's a command registered to this type */
+ cmd = find_ratp_request(type);
+ if (cmd) {
+ struct ratp_bb *rsp = NULL;
+ int rsp_len = 0;
+
+ ret = cmd->cmd(rbb, len, &rsp, &rsp_len);
+ if (!ret)
+ ret = ratp_send(&ctx->ratp, rsp, rsp_len);
+
+ free(rsp);
+ return ret;
+ }
- switch (be16_to_cpu(rbb->type)) {
+ switch (type) {
case BB_RATP_TYPE_COMMAND:
- if (ratp_command)
+ if (!IS_ENABLED(CONFIG_CONSOLE_RATP) || ratp_command)
return 0;
- ratp_command = xmemdup_add_zero(&rbb->data, dlen);
+ ratp_command = xstrndup((const char *)rbb->data, dlen);
ratp_ctx = ctx;
pr_debug("got command: %s\n", ratp_command);
break;
case BB_RATP_TYPE_COMMAND_RETURN:
- case BB_RATP_TYPE_PONG:
break;
case BB_RATP_TYPE_CONSOLEMSG:
+ if (!IS_ENABLED(CONFIG_CONSOLE_RATP))
+ return 0;
kfifo_put(ctx->console_recv_fifo, rbb->data, dlen);
break;
- case BB_RATP_TYPE_PING:
- ret = ratp_bb_send_pong(ctx);
- break;
-
- case BB_RATP_TYPE_GETENV:
- varname = xmemdup_add_zero(&rbb->data, dlen);
-
- ret = ratp_bb_send_getenv_return(ctx, getenv(varname));
- break;
-
case BB_RATP_TYPE_FS_RETURN:
pkt = xzalloc(sizeof(*pkt) + dlen);
pkt->len = dlen;
@@ -370,7 +357,8 @@ static void ratp_poller(struct poller_struct *poller)
size_t len;
void *buf;
- ratp_queue_console_tx(ctx);
+ if (IS_ENABLED(CONFIG_CONSOLE_RATP))
+ ratp_queue_console_tx(ctx);
ret = ratp_poll(&ctx->ratp);
if (ret == -EINTR)
diff --git a/common/ratp/reset.c b/common/ratp/reset.c
new file mode 100644
index 0000000000..ca8be4e62f
--- /dev/null
+++ b/common/ratp/reset.c
@@ -0,0 +1,55 @@
+/*
+ * reset.c - reset the cpu
+ *
+ * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <ratp_bb.h>
+#include <complete.h>
+#include <getopt.h>
+#include <restart.h>
+
+struct ratp_bb_reset {
+ struct ratp_bb header;
+ uint8_t force;
+} __attribute__((packed));
+
+static int ratp_cmd_reset(const struct ratp_bb *req, int req_len,
+ struct ratp_bb **rsp, int *rsp_len)
+{
+ struct ratp_bb_reset *reset_req = (struct ratp_bb_reset *)req;
+
+ if (req_len < sizeof (*reset_req)) {
+ printf ("ratp reset ignored: size mismatch (%d < %zu)\n", req_len, sizeof (*reset_req));
+ return 2;
+ }
+
+ debug("running reset %s\n", reset_req->force ? "(forced)" : "");
+
+ if (!reset_req->force)
+ shutdown_barebox();
+
+ restart_machine();
+ /* Not reached */
+ return 1;
+}
+
+BAREBOX_RATP_CMD_START(RESET)
+ .request_id = BB_RATP_TYPE_RESET,
+ .cmd = ratp_cmd_reset
+BAREBOX_RATP_CMD_END
diff --git a/fs/Kconfig b/fs/Kconfig
index 57f2676f43..3512000556 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -94,7 +94,7 @@ source fs/squashfs/Kconfig
config FS_RATP
bool
- depends on CONSOLE_RATP
+ depends on RATP
prompt "RATP filesystem support"
help
This enables support for transferring files over RATP. A host can
diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
index c8a919b928..74d3ca4a96 100644
--- a/include/asm-generic/barebox.lds.h
+++ b/include/asm-generic/barebox.lds.h
@@ -44,6 +44,8 @@
#define BAREBOX_CMDS KEEP(*(SORT_BY_NAME(.barebox_cmd*)))
+#define BAREBOX_RATP_CMDS KEEP(*(SORT_BY_NAME(.barebox_ratp_cmd*)))
+
#define BAREBOX_SYMS KEEP(*(__usymtab))
#define BAREBOX_MAGICVARS KEEP(*(SORT_BY_NAME(.barebox_magicvar*)))
diff --git a/include/ratp_bb.h b/include/ratp_bb.h
index f485f7d8ac..3a80cf6aed 100644
--- a/include/ratp_bb.h
+++ b/include/ratp_bb.h
@@ -1,6 +1,29 @@
#ifndef __RATP_BB_H
#define __RATP_BB_H
+#include <linux/stringify.h>
+
+#define BB_RATP_TYPE_COMMAND 1
+#define BB_RATP_TYPE_COMMAND_RETURN 2
+#define BB_RATP_TYPE_CONSOLEMSG 3
+#define BB_RATP_TYPE_PING 4
+#define BB_RATP_TYPE_PONG 5
+#define BB_RATP_TYPE_GETENV 6
+#define BB_RATP_TYPE_GETENV_RETURN 7
+#define BB_RATP_TYPE_FS 8
+#define BB_RATP_TYPE_FS_RETURN 9
+#define BB_RATP_TYPE_MD 10
+#define BB_RATP_TYPE_MD_RETURN 11
+#define BB_RATP_TYPE_MW 12
+#define BB_RATP_TYPE_MW_RETURN 13
+#define BB_RATP_TYPE_RESET 14
+
+struct ratp_bb {
+ uint16_t type;
+ uint16_t flags;
+ uint8_t data[];
+};
+
struct ratp_bb_pkt {
unsigned int len;
uint8_t data[];
@@ -11,4 +34,33 @@ void barebox_ratp_command_run(void);
int barebox_ratp_fs_call(struct ratp_bb_pkt *tx, struct ratp_bb_pkt **rx);
int barebox_ratp_fs_mount(const char *path);
+/*
+ * RATP commands definition
+ */
+
+struct ratp_command {
+ struct list_head list;
+ uint16_t request_id;
+ uint16_t response_id;
+ int (*cmd)(const struct ratp_bb *req,
+ int req_len,
+ struct ratp_bb **rsp,
+ int *rsp_len);
+}
+#ifdef __x86_64__
+/* This is required because the linker will put symbols on a 64 bit alignment */
+__attribute__((aligned(64)))
+#endif
+;
+
+#define BAREBOX_RATP_CMD_START(_name) \
+extern const struct ratp_command __barebox_ratp_cmd_##_name; \
+const struct ratp_command __barebox_ratp_cmd_##_name \
+ __attribute__ ((unused,section (".barebox_ratp_cmd_" __stringify(_name)))) = {
+
+#define BAREBOX_RATP_CMD_END \
+};
+
+int register_ratp_command(struct ratp_command *cmd);
+
#endif /* __RATP_BB_H */
diff --git a/lib/Kconfig b/lib/Kconfig
index dca93b80d0..4e9213f3e5 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -95,7 +95,7 @@ config STMP_DEVICE
config RATP
select CRC16
- bool
+ bool "RATP protocol support"
help
Reliable Asynchronous Transfer Protocol (RATP) is a protocol for reliably
transferring packets over serial links described in RFC916. This implementation
diff --git a/lib/readline.c b/lib/readline.c
index 1e380abeca..904a776394 100644
--- a/lib/readline.c
+++ b/lib/readline.c
@@ -202,7 +202,7 @@ int readline(const char *prompt, char *buf, int len)
while (1) {
while (!tstc()) {
poller_call();
- if (IS_ENABLED(CONFIG_RATP))
+ if (IS_ENABLED(CONFIG_CONSOLE_RATP))
barebox_ratp_command_run();
}
diff --git a/scripts/remote/controller.py b/scripts/remote/controller.py
index a7257ecc97..2ed834613e 100644
--- a/scripts/remote/controller.py
+++ b/scripts/remote/controller.py
@@ -46,6 +46,18 @@ def unpack(data):
elif p_type == BBType.fs_return:
logging.debug("received: fs_return")
return BBPacketFSReturn(raw=data)
+ elif p_type == BBType.md_return:
+ logging.debug("received: md_return")
+ return BBPacketMdReturn(raw=data)
+ elif p_type == BBType.mw:
+ logging.debug("received: mw")
+ return BBPacketMw(raw=data)
+ elif p_type == BBType.mw_return:
+ logging.debug("received: mw_return")
+ return BBPacketMwReturn(raw=data)
+ elif p_type == BBType.reset:
+ logging.debug("received: reset")
+ return BBPacketReset(raw=data)
else:
logging.debug("received: UNKNOWN")
return BBPacket(raw=data)
@@ -112,6 +124,21 @@ class Controller(Thread):
r = self._expect(BBPacketGetenvReturn)
return r.text
+ def md(self, path, addr, size):
+ self._send(BBPacketMd(path=path, addr=addr, size=size))
+ r = self._expect(BBPacketMdReturn)
+ logging.info("Md return: %r", r)
+ return (r.exit_code,r.data)
+
+ def mw(self, path, addr, data):
+ self._send(BBPacketMw(path=path, addr=addr, data=data))
+ r = self._expect(BBPacketMwReturn)
+ logging.info("Mw return: %r", r)
+ return (r.exit_code,r.written)
+
+ def reset(self, force):
+ self._send(BBPacketReset(force=force))
+
def close(self):
self.conn.close()
diff --git a/scripts/remote/main.py b/scripts/remote/main.py
index 79203df05a..38d280bfee 100644
--- a/scripts/remote/main.py
+++ b/scripts/remote/main.py
@@ -5,6 +5,7 @@ from __future__ import absolute_import, division, print_function
import sys
import os
import argparse
+import binascii
import logging
from Queue import Queue
from .ratp import RatpError
@@ -76,6 +77,34 @@ def handle_getenv(args):
return res
+def handle_md(args):
+ ctrl = get_controller(args)
+ (res,data) = ctrl.md(args.path, args.address, args.size)
+ if res == 0:
+ print(binascii.hexlify(data))
+ ctrl.close()
+ return res
+
+
+def handle_mw(args):
+ ctrl = get_controller(args)
+ data=args.data
+ if ((len(data) % 2) != 0):
+ data="0"+data
+ (res,written) = ctrl.mw(args.path, args.address, binascii.unhexlify(data))
+ if res == 0:
+ print("%i bytes written" % written)
+ ctrl.close()
+ return res
+
+
+def handle_reset(args):
+ ctrl = get_controller(args)
+ ctrl.reset(args.force)
+ ctrl.close()
+ return 0
+
+
def handle_listen(args):
port = serial.serial_for_url(args.port, args.baudrate)
conn = SerialRatpConnection(port)
@@ -118,6 +147,10 @@ def handle_console(args):
ctrl.conn.total_retransmits,
ctrl.conn.total_crc_errors))
+# Support base 10 or base 16 numbers automatically
+def auto_int(x):
+ return int(x, 0)
+
VERBOSITY = {
0: logging.WARN,
1: logging.INFO,
@@ -143,6 +176,24 @@ parser_getenv = subparsers.add_parser('getenv', help="get a barebox environment
parser_getenv.add_argument('arg', nargs='+', help="variable name")
parser_getenv.set_defaults(func=handle_getenv)
+parser_md = subparsers.add_parser('md', help="run md command")
+parser_md.add_argument('path', help="path")
+parser_md.add_argument('address', type=auto_int, help="address")
+parser_md.add_argument('size', type=auto_int, help="size")
+parser_md.set_defaults(func=handle_md)
+
+parser_mw = subparsers.add_parser('mw', help="run mw command")
+parser_mw.add_argument('path', help="path")
+parser_mw.add_argument('address', type=auto_int, help="address")
+parser_mw.add_argument('data', help="data")
+parser_mw.set_defaults(func=handle_mw)
+
+parser_reset = subparsers.add_parser('reset', help="run reset command")
+parser_reset_force = parser_reset.add_mutually_exclusive_group(required=False)
+parser_reset_force.add_argument('--force', dest='force', action='store_true')
+parser_reset_force.add_argument('--no-force', dest='force', action='store_false')
+parser_reset.set_defaults(func=handle_reset,force=False)
+
parser_listen = subparsers.add_parser('listen', help="listen for an incoming connection")
parser_listen.set_defaults(func=handle_listen)
diff --git a/scripts/remote/messages.py b/scripts/remote/messages.py
index 8e8495b12e..729f2e6177 100644
--- a/scripts/remote/messages.py
+++ b/scripts/remote/messages.py
@@ -4,6 +4,7 @@
from __future__ import absolute_import, division, print_function
import struct
+import binascii
class BBType(object):
@@ -16,6 +17,11 @@ class BBType(object):
getenv_return = 7
fs = 8
fs_return = 9
+ md = 10
+ md_return = 11
+ mw = 12
+ mw_return = 13
+ reset = 14
class BBPacket(object):
@@ -152,3 +158,102 @@ class BBPacketFSReturn(BBPacket):
def __repr__(self):
return "BBPacketFSReturn(payload=%r)" % self.payload
+
+
+class BBPacketMd(BBPacket):
+ def __init__(self, raw=None, path=None, addr=None, size=None):
+ self.path = path
+ self.addr = addr
+ self.size = size
+ super(BBPacketMd, self).__init__(BBType.md, raw=raw)
+
+ def __repr__(self):
+ return "BBPacketMd(path=%r,addr=0x%x,size=%u)" % (self.path, self.addr, self.size)
+
+ def _unpack_payload(self, payload):
+ buffer_offset, self.addr, self.size, path_size, path_offset = struct.unpack("!HHHHH", payload[:10])
+ # header size is always 4 bytes (HH), so adjust the absolute data offset without the header size
+ absolute_path_offset = buffer_offset + path_offset - 4
+ self.path = payload[absolute_path_offset:absolute_path_offset+path_size]
+
+ def _pack_payload(self):
+ # header size is always 4 bytes (HH) and we have 10 bytes of fixed data (HHHHH), so buffer offset is 14
+ return struct.pack("!HHHHH%ds" % len(self.path), 14, self.addr, self.size, len(self.path), 0, self.path)
+
+
+class BBPacketMdReturn(BBPacket):
+ def __init__(self, raw=None, exit_code=None, data=None):
+ self.exit_code = exit_code
+ self.data = data
+ super(BBPacketMdReturn, self).__init__(BBType.md_return, raw=raw)
+
+ def __repr__(self):
+ return "BBPacketMdReturn(exit_code=%i, data=%s)" % (self.exit_code, binascii.hexlify(self.data))
+
+ def _unpack_payload(self, payload):
+ buffer_offset, self.exit_code, data_size, data_offset = struct.unpack("!HLHH", payload[:10])
+ # header size is always 4 bytes (HH), so adjust the absolute data offset without the header size
+ absolute_data_offset = buffer_offset + data_offset - 4
+ self.data = payload[absolute_data_offset:absolute_data_offset + data_size]
+
+ def _pack_payload(self):
+ # header size is always 4 bytes (HH) and we have 10 bytes of fixed data (HLHH), so buffer offset is 14
+ return struct.pack("!HLHH%ds" % len(self.data), 14, self.exit_code, len(self.data), 0, self.data)
+ return self.text
+
+
+class BBPacketMw(BBPacket):
+ def __init__(self, raw=None, path=None, addr=None, data=None):
+ self.path = path
+ self.addr = addr
+ self.data = data
+ super(BBPacketMw, self).__init__(BBType.mw, raw=raw)
+
+ def __repr__(self):
+ return "BBPacketMw(path=%r,addr=0x%x,data=%r)" % (self.path, self.addr, self.data)
+
+ def _unpack_payload(self, payload):
+ buffer_offset, self.addr, path_size, path_offset, data_size, data_offset = struct.unpack("!HHHHHH", payload[:12])
+ # header size is always 4 bytes (HH), so adjust the absolute data offset without the header size
+ absolute_path_offset = buffer_offset + path_offset - 4
+ self.path = payload[absolute_path_offset:absolute_path_offset+path_size]
+ absolute_data_offset = buffer_offset + data_offset - 4
+ self.data = payload[absolute_data_offset:absolute_data_offset+data_size]
+
+ def _pack_payload(self):
+ # header size is always 4 bytes (HH) and we have 12 bytes of fixed data (HHHHHH), so buffer offset is 16
+ path_size = len(self.path)
+ data_size = len(self.data)
+ return struct.pack("!HHHHHH%ds%ds" % (path_size, path_size), 16, self.addr, path_size, 0, data_size, path_size, self.path, self.data)
+
+
+class BBPacketMwReturn(BBPacket):
+ def __init__(self, raw=None, exit_code=None, written=None):
+ self.exit_code = exit_code
+ self.written = written
+ super(BBPacketMwReturn, self).__init__(BBType.mw_return, raw=raw)
+
+ def __repr__(self):
+ return "BBPacketMwReturn(exit_code=%i, written=%i)" % (self.exit_code, self.written)
+
+ def _unpack_payload(self, payload):
+ buffer_offset, self.exit_code, self.written = struct.unpack("!HLH", payload[:8])
+
+ def _pack_payload(self):
+ # header size is always 4 bytes (HH) and we have 8 bytes of fixed data (HLH), so buffer offset is 14
+ return struct.pack("!HLH", 12, self.exit_code, self.written)
+
+
+class BBPacketReset(BBPacket):
+ def __init__(self, raw=None, force=None):
+ self.force = force
+ super(BBPacketReset, self).__init__(BBType.reset, raw=raw)
+
+ def __repr__(self):
+ return "BBPacketReset(force=%c)" % (self.force)
+
+ def _unpack_payload(self, payload):
+ self.force = struct.unpack("?", payload[:1])
+
+ def _pack_payload(self):
+ return struct.pack("?", self.force)