mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH] memory commands
@ 2013-04-17 11:39 Sascha Hauer
  2013-04-17 11:39 ` [PATCH 1/7] memory commands: export common functions Sascha Hauer
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Sascha Hauer @ 2013-04-17 11:39 UTC (permalink / raw)
  To: barebox

This series contains some cleanups for the memory commands and a new
memory command: mm. 'mm' allows to manipulate registers bitwise.

Sascha

----------------------------------------------------------------
Sascha Hauer (7):
      memory commands: export common functions
      memory commands: move memory_display to separate file
      Use a common define for RW_BUF_SIZE
      memory commands: cleanup initialization
      memory commands: make rw_buf global
      memory commands: separate into one file per command
      Add memory modify command (mm)

 commands/Kconfig        |  50 ++++-
 commands/Makefile       |   6 +
 commands/md.c           | 116 +++++++++++
 commands/mem.c          | 524 +-----------------------------------------------
 commands/memcmp.c       | 148 ++++++++++++++
 commands/memcpy.c       | 145 ++++++++++++++
 commands/memset.c       | 101 ++++++++++
 commands/mm.c           | 117 +++++++++++
 commands/mw.c           | 104 ++++++++++
 common/Makefile         |   1 +
 common/memory_display.c |  64 ++++++
 include/common.h        |   7 +-
 lib/copy_file.c         |   2 -
 13 files changed, 868 insertions(+), 517 deletions(-)
 create mode 100644 commands/md.c
 create mode 100644 commands/memcmp.c
 create mode 100644 commands/memcpy.c
 create mode 100644 commands/memset.c
 create mode 100644 commands/mm.c
 create mode 100644 commands/mw.c
 create mode 100644 common/memory_display.c

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/7] memory commands: export common functions
  2013-04-17 11:39 [PATCH] memory commands Sascha Hauer
@ 2013-04-17 11:39 ` Sascha Hauer
  2013-04-17 11:39 ` [PATCH 2/7] memory commands: move memory_display to separate file Sascha Hauer
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Sascha Hauer @ 2013-04-17 11:39 UTC (permalink / raw)
  To: barebox

The memory commands all use open_and_lseek and mem_parse_options. Export
them to be able to split the memory commands into separate files.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/mem.c   | 8 ++++++--
 include/common.h | 4 ++++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/commands/mem.c b/commands/mem.c
index 51aa04d..f25c6b6 100644
--- a/commands/mem.c
+++ b/commands/mem.c
@@ -112,7 +112,7 @@ int memory_display(char *addr, loff_t offs, ulong nbytes, int size, int swab)
 	return 0;
 }
 
-static int open_and_lseek(const char *filename, int mode, loff_t pos)
+int open_and_lseek(const char *filename, int mode, loff_t pos)
 {
 	int fd, ret;
 
@@ -135,7 +135,11 @@ static int open_and_lseek(const char *filename, int mode, loff_t pos)
 	return fd;
 }
 
-static int mem_parse_options(int argc, char *argv[], char *optstr, int *mode,
+/*
+ * Common function for parsing options for the 'md', 'mw', 'memcpy', 'memcmp'
+ * commands.
+ */
+int mem_parse_options(int argc, char *argv[], char *optstr, int *mode,
 		char **sourcefile, char **destfile, int *swab)
 {
 	int opt;
diff --git a/include/common.h b/include/common.h
index e559b94..2263c00 100644
--- a/include/common.h
+++ b/include/common.h
@@ -221,6 +221,10 @@ int run_shell(void);
 
 int memory_display(char *addr, loff_t offs, ulong nbytes, int size, int swab);
 
+int mem_parse_options(int argc, char *argv[], char *optstr, int *mode,
+		char **sourcefile, char **destfile, int *swab);
+int open_and_lseek(const char *filename, int mode, loff_t pos);
+
 extern const char version_string[];
 #ifdef CONFIG_BANNER
 void barebox_banner(void);
-- 
1.8.2.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 2/7] memory commands: move memory_display to separate file
  2013-04-17 11:39 [PATCH] memory commands Sascha Hauer
  2013-04-17 11:39 ` [PATCH 1/7] memory commands: export common functions Sascha Hauer
@ 2013-04-17 11:39 ` Sascha Hauer
  2013-04-17 11:39 ` [PATCH 3/7] Use a common define for RW_BUF_SIZE Sascha Hauer
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Sascha Hauer @ 2013-04-17 11:39 UTC (permalink / raw)
  To: barebox

memory_display is a function which should generally be available.
Currently it depends on memory command support being compiled in,
so move the function to a separate file.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/mem.c          | 68 -------------------------------------------------
 common/Makefile         |  1 +
 common/memory_display.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++
 include/common.h        |  2 +-
 4 files changed, 66 insertions(+), 69 deletions(-)
 create mode 100644 common/memory_display.c

diff --git a/commands/mem.c b/commands/mem.c
index f25c6b6..a4a1658 100644
--- a/commands/mem.c
+++ b/commands/mem.c
@@ -44,74 +44,6 @@ static char *rw_buf;
 
 static char *DEVMEM = "/dev/mem";
 
-/* Memory Display
- *
- * Syntax:
- *	md{.b, .w, .l} {addr} {len}
- */
-#define DISP_LINE_LEN	16
-
-int memory_display(char *addr, loff_t offs, ulong nbytes, int size, int swab)
-{
-	ulong linebytes, i;
-	u_char	*cp;
-
-	/* Print the lines.
-	 *
-	 * We buffer all read data, so we can make sure data is read only
-	 * once, and all accesses are with the specified bus width.
-	 */
-	do {
-		char	linebuf[DISP_LINE_LEN];
-		uint	*uip = (uint   *)linebuf;
-		ushort	*usp = (ushort *)linebuf;
-		u_char	*ucp = (u_char *)linebuf;
-		uint	count = 52;
-
-		printf("%08llx:", offs);
-		linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
-
-		for (i = 0; i < linebytes; i += size) {
-			if (size == 4) {
-				u32 res;
-				res = (*uip++ = *((uint *)addr));
-				if (swab)
-					res = __swab32(res);
-				count -= printf(" %08x", res);
-			} else if (size == 2) {
-				u16 res;
-				res = (*usp++ = *((ushort *)addr));
-				if (swab)
-					res = __swab16(res);
-				count -= printf(" %04x", res);
-			} else {
-				count -= printf(" %02x", (*ucp++ = *((u_char *)addr)));
-			}
-			addr += size;
-			offs += size;
-		}
-
-		while(count--)
-			putchar(' ');
-
-		cp = (u_char *)linebuf;
-		for (i=0; i<linebytes; i++) {
-			if ((*cp < 0x20) || (*cp > 0x7e))
-				putchar('.');
-			else
-				printf("%c", *cp);
-			cp++;
-		}
-		putchar('\n');
-		nbytes -= linebytes;
-		if (ctrlc()) {
-			return -EINTR;
-		}
-	} while (nbytes > 0);
-
-	return 0;
-}
-
 int open_and_lseek(const char *filename, int mode, loff_t pos)
 {
 	int fd, ret;
diff --git a/common/Makefile b/common/Makefile
index dcb07c2..9460172 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_CMD_LOADS)		+= s_record.o
 obj-$(CONFIG_OFTREE)		+= oftree.o
 
 obj-y += memory.o
+obj-y += memory_display.o
 obj-$(CONFIG_MALLOC_DLMALLOC) += dlmalloc.o
 obj-$(CONFIG_MALLOC_TLSF) += tlsf_malloc.o
 obj-$(CONFIG_MALLOC_TLSF) += tlsf.o
diff --git a/common/memory_display.c b/common/memory_display.c
new file mode 100644
index 0000000..eb188e1
--- /dev/null
+++ b/common/memory_display.c
@@ -0,0 +1,64 @@
+#include <common.h>
+
+#define DISP_LINE_LEN	16
+
+int memory_display(char *addr, loff_t offs, unsigned nbytes, int size, int swab)
+{
+	ulong linebytes, i;
+	u_char	*cp;
+
+	/* Print the lines.
+	 *
+	 * We buffer all read data, so we can make sure data is read only
+	 * once, and all accesses are with the specified bus width.
+	 */
+	do {
+		char linebuf[DISP_LINE_LEN];
+		uint32_t *uip = (uint   *)linebuf;
+		uint16_t *usp = (ushort *)linebuf;
+		uint8_t *ucp = (u_char *)linebuf;
+		unsigned count = 52;
+
+		printf("%08llx:", offs);
+		linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
+
+		for (i = 0; i < linebytes; i += size) {
+			if (size == 4) {
+				u32 res;
+				res = (*uip++ = *((uint *)addr));
+				if (swab)
+					res = __swab32(res);
+				count -= printf(" %08x", res);
+			} else if (size == 2) {
+				u16 res;
+				res = (*usp++ = *((ushort *)addr));
+				if (swab)
+					res = __swab16(res);
+				count -= printf(" %04x", res);
+			} else {
+				count -= printf(" %02x", (*ucp++ = *((u_char *)addr)));
+			}
+			addr += size;
+			offs += size;
+		}
+
+		while (count--)
+			putchar(' ');
+
+		cp = (uint8_t *)linebuf;
+		for (i = 0; i < linebytes; i++) {
+			if ((*cp < 0x20) || (*cp > 0x7e))
+				putchar('.');
+			else
+				printf("%c", *cp);
+			cp++;
+		}
+
+		putchar('\n');
+		nbytes -= linebytes;
+		if (ctrlc())
+			return -EINTR;
+	} while (nbytes > 0);
+
+	return 0;
+}
diff --git a/include/common.h b/include/common.h
index 2263c00..11904ab 100644
--- a/include/common.h
+++ b/include/common.h
@@ -219,7 +219,7 @@ int run_shell(void);
 #define PAGE_ALIGN(s) (((s) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
 #define PAGE_ALIGN_DOWN(x) ((x) & ~(PAGE_SIZE - 1))
 
-int memory_display(char *addr, loff_t offs, ulong nbytes, int size, int swab);
+int memory_display(char *addr, loff_t offs, unsigned nbytes, int size, int swab);
 
 int mem_parse_options(int argc, char *argv[], char *optstr, int *mode,
 		char **sourcefile, char **destfile, int *swab);
-- 
1.8.2.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 3/7] Use a common define for RW_BUF_SIZE
  2013-04-17 11:39 [PATCH] memory commands Sascha Hauer
  2013-04-17 11:39 ` [PATCH 1/7] memory commands: export common functions Sascha Hauer
  2013-04-17 11:39 ` [PATCH 2/7] memory commands: move memory_display to separate file Sascha Hauer
@ 2013-04-17 11:39 ` Sascha Hauer
  2013-04-17 11:39 ` [PATCH 4/7] memory commands: cleanup initialization Sascha Hauer
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Sascha Hauer @ 2013-04-17 11:39 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/mem.c   | 1 -
 include/common.h | 1 +
 lib/copy_file.c  | 2 --
 3 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/commands/mem.c b/commands/mem.c
index a4a1658..d48f92e 100644
--- a/commands/mem.c
+++ b/commands/mem.c
@@ -39,7 +39,6 @@
 #define PRINTF(fmt,args...)
 #endif
 
-#define RW_BUF_SIZE	4096
 static char *rw_buf;
 
 static char *DEVMEM = "/dev/mem";
diff --git a/include/common.h b/include/common.h
index 11904ab..59fcd35 100644
--- a/include/common.h
+++ b/include/common.h
@@ -224,6 +224,7 @@ int memory_display(char *addr, loff_t offs, unsigned nbytes, int size, int swab)
 int mem_parse_options(int argc, char *argv[], char *optstr, int *mode,
 		char **sourcefile, char **destfile, int *swab);
 int open_and_lseek(const char *filename, int mode, loff_t pos);
+#define RW_BUF_SIZE	(unsigned)4096
 
 extern const char version_string[];
 #ifdef CONFIG_BANNER
diff --git a/lib/copy_file.c b/lib/copy_file.c
index 484b2ca..ab3d845 100644
--- a/lib/copy_file.c
+++ b/lib/copy_file.c
@@ -6,8 +6,6 @@
 #include <libbb.h>
 #include <progress.h>
 
-#define RW_BUF_SIZE	(ulong)4096
-
 /**
  * @param[in] src FIXME
  * @param[out] dst FIXME
-- 
1.8.2.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 4/7] memory commands: cleanup initialization
  2013-04-17 11:39 [PATCH] memory commands Sascha Hauer
                   ` (2 preceding siblings ...)
  2013-04-17 11:39 ` [PATCH 3/7] Use a common define for RW_BUF_SIZE Sascha Hauer
@ 2013-04-17 11:39 ` Sascha Hauer
  2013-04-17 11:39 ` [PATCH 5/7] memory commands: make rw_buf global Sascha Hauer
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Sascha Hauer @ 2013-04-17 11:39 UTC (permalink / raw)
  To: barebox

- return -ENOMEM instead of -1
- return the result of platform_driver_register

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/mem.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/commands/mem.c b/commands/mem.c
index d48f92e..5bef3f7 100644
--- a/commands/mem.c
+++ b/commands/mem.c
@@ -567,15 +567,10 @@ static struct driver_d mem_drv = {
 static int mem_init(void)
 {
 	rw_buf = malloc(RW_BUF_SIZE);
-	if(!rw_buf) {
-		printf("%s: Out of memory\n", __FUNCTION__);
-		return -1;
-	}
+	if(!rw_buf)
+		return -ENOMEM;
 
 	add_mem_device("mem", 0, ~0, IORESOURCE_MEM_WRITEABLE);
-	platform_driver_register(&mem_drv);
-
-	return 0;
+	return platform_driver_register(&mem_drv);
 }
-
 device_initcall(mem_init);
-- 
1.8.2.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 5/7] memory commands: make rw_buf global
  2013-04-17 11:39 [PATCH] memory commands Sascha Hauer
                   ` (3 preceding siblings ...)
  2013-04-17 11:39 ` [PATCH 4/7] memory commands: cleanup initialization Sascha Hauer
@ 2013-04-17 11:39 ` Sascha Hauer
  2013-04-17 11:39 ` [PATCH 6/7] memory commands: separate into one file per command Sascha Hauer
  2013-04-17 11:39 ` [PATCH 7/7] Add memory modify command (mm) Sascha Hauer
  6 siblings, 0 replies; 8+ messages in thread
From: Sascha Hauer @ 2013-04-17 11:39 UTC (permalink / raw)
  To: barebox

The rw_buf is used by several memory commands. Make it global since
we want to split the memory commands into separate files. Also rename
it to mem_rw_buf.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/mem.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/commands/mem.c b/commands/mem.c
index 5bef3f7..a531bd5 100644
--- a/commands/mem.c
+++ b/commands/mem.c
@@ -39,7 +39,7 @@
 #define PRINTF(fmt,args...)
 #endif
 
-static char *rw_buf;
+char *mem_rw_buf;
 
 static char *DEVMEM = "/dev/mem";
 
@@ -135,7 +135,7 @@ static int do_mem_md(int argc, char *argv[])
 
 	do {
 		now = min(size, (loff_t)RW_BUF_SIZE);
-		r = read(fd, rw_buf, now);
+		r = read(fd, mem_rw_buf, now);
 		if (r < 0) {
 			perror("read");
 			goto out;
@@ -143,7 +143,7 @@ static int do_mem_md(int argc, char *argv[])
 		if (!r)
 			goto out;
 
-		if ((ret = memory_display(rw_buf, start, r,
+		if ((ret = memory_display(mem_rw_buf, start, r,
 				mode >> O_RWSIZE_SHIFT, swab)))
 			goto out;
 
@@ -306,7 +306,7 @@ static int do_mem_cmp(int argc, char *argv[])
 
 		now = min((loff_t)RW_BUF_SIZE, count);
 
-		r1 = read(sourcefd, rw_buf,  now);
+		r1 = read(sourcefd, mem_rw_buf,  now);
 		if (r1 < 0) {
 			perror("read");
 			goto out;
@@ -324,7 +324,7 @@ static int do_mem_cmp(int argc, char *argv[])
 		}
 
 		for (i = 0; i < now; i++) {
-			if (rw_buf[i] != rw_buf1[i]) {
+			if (mem_rw_buf[i] != rw_buf1[i]) {
 				printf("files differ at offset %d\n", offset);
 				goto out;
 			}
@@ -412,7 +412,7 @@ static int do_mem_cp(int argc, char *argv[])
 
 		now = min((loff_t)RW_BUF_SIZE, count);
 
-		r = read(sourcefd, rw_buf, now);
+		r = read(sourcefd, mem_rw_buf, now);
 		if (r < 0) {
 			perror("read");
 			goto out;
@@ -424,7 +424,7 @@ static int do_mem_cp(int argc, char *argv[])
 		tmp = 0;
 		now = r;
 		while (now) {
-			w = write(destfd, rw_buf + tmp, now);
+			w = write(destfd, mem_rw_buf + tmp, now);
 			if (w < 0) {
 				perror("write");
 				goto out;
@@ -566,8 +566,8 @@ static struct driver_d mem_drv = {
 
 static int mem_init(void)
 {
-	rw_buf = malloc(RW_BUF_SIZE);
-	if(!rw_buf)
+	mem_rw_buf = malloc(RW_BUF_SIZE);
+	if(!mem_rw_buf)
 		return -ENOMEM;
 
 	add_mem_device("mem", 0, ~0, IORESOURCE_MEM_WRITEABLE);
-- 
1.8.2.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 6/7] memory commands: separate into one file per command
  2013-04-17 11:39 [PATCH] memory commands Sascha Hauer
                   ` (4 preceding siblings ...)
  2013-04-17 11:39 ` [PATCH 5/7] memory commands: make rw_buf global Sascha Hauer
@ 2013-04-17 11:39 ` Sascha Hauer
  2013-04-17 11:39 ` [PATCH 7/7] Add memory modify command (mm) Sascha Hauer
  6 siblings, 0 replies; 8+ messages in thread
From: Sascha Hauer @ 2013-04-17 11:39 UTC (permalink / raw)
  To: barebox

Normally in commands we have one file per command which is named like
the command itself. The memory commands are an exception to this. This
patch changes this by separating the memory commands. This also has the
effect that the memory commands can now be selected individually. Along
the way we add some Kconfig help text for the commmands.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/Kconfig  |  42 +++++-
 commands/Makefile |   5 +
 commands/md.c     | 116 +++++++++++++++
 commands/mem.c    | 432 ------------------------------------------------------
 commands/memcmp.c | 148 +++++++++++++++++++
 commands/memcpy.c | 145 ++++++++++++++++++
 commands/memset.c | 101 +++++++++++++
 commands/mw.c     | 104 +++++++++++++
 8 files changed, 660 insertions(+), 433 deletions(-)
 create mode 100644 commands/md.c
 create mode 100644 commands/memcmp.c
 create mode 100644 commands/memcpy.c
 create mode 100644 commands/memset.c
 create mode 100644 commands/mw.c

diff --git a/commands/Kconfig b/commands/Kconfig
index 0062758..fe171d8 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -303,7 +303,47 @@ config CMD_IOMEM
 config CMD_MEMORY
 	bool
 	default y
-	prompt "md and mw"
+
+config CMD_MD
+	tristate
+	default y
+	select CMD_MEMORY
+	prompt "md"
+	help
+	  the md command allows to display (hexdump) memory locations and files.
+
+config CMD_MW
+	tristate
+	default y
+	select CMD_MEMORY
+	prompt "mw"
+	help
+	  the mw command allows to write to memory locations and files.
+
+config CMD_MEMCMP
+	tristate
+	default y
+	select CMD_MEMORY
+	prompt "memcmp"
+	help
+	  the memcmp command allows to compare memory and file regions.
+
+config CMD_MEMCPY
+	tristate
+	default y
+	select CMD_MEMORY
+	prompt "memcpy"
+	help
+	  the memcpy command allows to copy memory and file regions.
+
+config CMD_MEMSET
+	tristate
+	default y
+	select CMD_MEMORY
+	prompt "memset"
+	help
+	  the memset command allows to set regions of memory and files to
+	  a specific value.
 
 config CMD_CRC
 	tristate
diff --git a/commands/Makefile b/commands/Makefile
index 0ae6b95..beec8e9 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -7,6 +7,11 @@ obj-$(CONFIG_CMD_LOADY)		+= loadxy.o
 obj-$(CONFIG_CMD_LOADS)		+= loads.o
 obj-$(CONFIG_CMD_ECHO)		+= echo.o
 obj-$(CONFIG_CMD_MEMORY)	+= mem.o
+obj-$(CONFIG_CMD_MD)		+= md.o
+obj-$(CONFIG_CMD_MW)		+= mw.o
+obj-$(CONFIG_CMD_MEMCMP)	+= memcmp.o
+obj-$(CONFIG_CMD_MEMCPY)	+= memcpy.o
+obj-$(CONFIG_CMD_MEMSET)	+= memset.o
 obj-$(CONFIG_CMD_MTEST)		+= memtest.o
 obj-$(CONFIG_CMD_EDIT)		+= edit.o
 obj-$(CONFIG_CMD_EXEC)		+= exec.o
diff --git a/commands/md.c b/commands/md.c
new file mode 100644
index 0000000..03c5905
--- /dev/null
+++ b/commands/md.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2011 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.
+ *
+ */
+
+/*
+ * Memory Functions
+ *
+ * Copied from FADS ROM, Dan Malek (dmalek@jlc.net)
+ */
+
+#include <common.h>
+#include <command.h>
+#include <init.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <linux/stat.h>
+#include <xfuncs.h>
+
+extern char *mem_rw_buf;
+
+static int do_mem_md(int argc, char *argv[])
+{
+	loff_t	start = 0, size = 0x100;
+	int	r, now;
+	int	ret = 0;
+	int fd;
+	char *filename = "/dev/mem";
+	int mode = O_RWSIZE_4;
+	int swab = 0;
+
+	if (argc < 2)
+		return COMMAND_ERROR_USAGE;
+
+	if (mem_parse_options(argc, argv, "bwls:x", &mode, &filename, NULL,
+			&swab) < 0)
+		return 1;
+
+	if (optind < argc) {
+		if (parse_area_spec(argv[optind], &start, &size)) {
+			printf("could not parse: %s\n", argv[optind]);
+			return 1;
+		}
+		if (size == ~0)
+			size = 0x100;
+	}
+
+	fd = open_and_lseek(filename, mode | O_RDONLY, start);
+	if (fd < 0)
+		return 1;
+
+	do {
+		now = min(size, (loff_t)RW_BUF_SIZE);
+		r = read(fd, mem_rw_buf, now);
+		if (r < 0) {
+			perror("read");
+			goto out;
+		}
+		if (!r)
+			goto out;
+
+		if ((ret = memory_display(mem_rw_buf, start, r,
+				mode >> O_RWSIZE_SHIFT, swab)))
+			goto out;
+
+		start += r;
+		size  -= r;
+	} while (size);
+
+out:
+	close(fd);
+
+	return ret ? 1 : 0;
+}
+
+static const __maybe_unused char cmd_md_help[] =
+"Usage md [OPTIONS] <region>\n"
+"display (hexdump) a memory region.\n"
+"options:\n"
+"  -s <file>   display file (default /dev/mem)\n"
+"  -b          output in bytes\n"
+"  -w          output in halfwords (16bit)\n"
+"  -l          output in words (32bit)\n"
+"  -x          swap bytes at output\n"
+"\n"
+"Memory regions:\n"
+"Memory regions can be specified in two different forms: start+size\n"
+"or start-end, If <start> is omitted it defaults to 0. If end is omitted it\n"
+"defaults to the end of the device, except for interactive commands like md\n"
+"and mw for which it defaults to 0x100.\n"
+"Sizes can be specified as decimal, or if prefixed with 0x as hexadecimal.\n"
+"an optional suffix of k, M or G is for kibibytes, Megabytes or Gigabytes,\n"
+"respectively\n";
+
+
+BAREBOX_CMD_START(md)
+	.cmd		= do_mem_md,
+	.usage		= "memory display",
+	BAREBOX_CMD_HELP(cmd_md_help)
+BAREBOX_CMD_END
diff --git a/commands/mem.c b/commands/mem.c
index a531bd5..7eb60af 100644
--- a/commands/mem.c
+++ b/commands/mem.c
@@ -103,438 +103,6 @@ int mem_parse_options(int argc, char *argv[], char *optstr, int *mode,
 	return 0;
 }
 
-static int do_mem_md(int argc, char *argv[])
-{
-	loff_t	start = 0, size = 0x100;
-	int	r, now;
-	int	ret = 0;
-	int fd;
-	char *filename = DEVMEM;
-	int mode = O_RWSIZE_4;
-	int swab = 0;
-
-	if (argc < 2)
-		return COMMAND_ERROR_USAGE;
-
-	if (mem_parse_options(argc, argv, "bwls:x", &mode, &filename, NULL,
-			&swab) < 0)
-		return 1;
-
-	if (optind < argc) {
-		if (parse_area_spec(argv[optind], &start, &size)) {
-			printf("could not parse: %s\n", argv[optind]);
-			return 1;
-		}
-		if (size == ~0)
-			size = 0x100;
-	}
-
-	fd = open_and_lseek(filename, mode | O_RDONLY, start);
-	if (fd < 0)
-		return 1;
-
-	do {
-		now = min(size, (loff_t)RW_BUF_SIZE);
-		r = read(fd, mem_rw_buf, now);
-		if (r < 0) {
-			perror("read");
-			goto out;
-		}
-		if (!r)
-			goto out;
-
-		if ((ret = memory_display(mem_rw_buf, start, r,
-				mode >> O_RWSIZE_SHIFT, swab)))
-			goto out;
-
-		start += r;
-		size  -= r;
-	} while (size);
-
-out:
-	close(fd);
-
-	return ret ? 1 : 0;
-}
-
-static const __maybe_unused char cmd_md_help[] =
-"Usage md [OPTIONS] <region>\n"
-"display (hexdump) a memory region.\n"
-"options:\n"
-"  -s <file>   display file (default /dev/mem)\n"
-"  -b          output in bytes\n"
-"  -w          output in halfwords (16bit)\n"
-"  -l          output in words (32bit)\n"
-"  -x          swap bytes at output\n"
-"\n"
-"Memory regions:\n"
-"Memory regions can be specified in two different forms: start+size\n"
-"or start-end, If <start> is omitted it defaults to 0. If end is omitted it\n"
-"defaults to the end of the device, except for interactive commands like md\n"
-"and mw for which it defaults to 0x100.\n"
-"Sizes can be specified as decimal, or if prefixed with 0x as hexadecimal.\n"
-"an optional suffix of k, M or G is for kibibytes, Megabytes or Gigabytes,\n"
-"respectively\n";
-
-
-BAREBOX_CMD_START(md)
-	.cmd		= do_mem_md,
-	.usage		= "memory display",
-	BAREBOX_CMD_HELP(cmd_md_help)
-BAREBOX_CMD_END
-
-static int do_mem_mw(int argc, char *argv[])
-{
-	int ret = 0;
-	int fd;
-	char *filename = DEVMEM;
-	int mode = O_RWSIZE_4;
-	loff_t adr;
-	int swab = 0;
-
-	if (mem_parse_options(argc, argv, "bwld:x", &mode, NULL, &filename,
-			&swab) < 0)
-		return 1;
-
-	if (optind + 1 >= argc)
-		return COMMAND_ERROR_USAGE;
-
-	adr = strtoull_suffix(argv[optind++], NULL, 0);
-
-	fd = open_and_lseek(filename, mode | O_WRONLY, adr);
-	if (fd < 0)
-		return 1;
-
-	while (optind < argc) {
-		u8 val8;
-		u16 val16;
-		u32 val32;
-		switch (mode) {
-		case O_RWSIZE_1:
-			val8 = simple_strtoul(argv[optind], NULL, 0);
-			ret = write(fd, &val8, 1);
-			break;
-		case O_RWSIZE_2:
-			val16 = simple_strtoul(argv[optind], NULL, 0);
-			if (swab)
-				val16 = __swab16(val16);
-			ret = write(fd, &val16, 2);
-			break;
-		case O_RWSIZE_4:
-			val32 = simple_strtoul(argv[optind], NULL, 0);
-			if (swab)
-				val32 = __swab32(val32);
-			ret = write(fd, &val32, 4);
-			break;
-		}
-		if (ret < 0) {
-			perror("write");
-			break;
-		}
-		ret = 0;
-		optind++;
-	}
-
-	close(fd);
-
-	return ret ? 1 : 0;
-}
-
-static const __maybe_unused char cmd_mw_help[] =
-"Usage: mw [OPTIONS] <region> <value(s)>\n"
-"Write value(s) to the specifies region.\n"
-"options:\n"
-"  -b, -w, -l	use byte, halfword, or word accesses\n"
-"  -d <file>	write file (default /dev/mem)\n";
-
-BAREBOX_CMD_START(mw)
-	.cmd		= do_mem_mw,
-	.usage		= "memory write (fill)",
-	BAREBOX_CMD_HELP(cmd_mw_help)
-BAREBOX_CMD_END
-
-static int do_mem_cmp(int argc, char *argv[])
-{
-	loff_t	addr1, addr2, count = ~0;
-	int	mode  = O_RWSIZE_1;
-	char   *sourcefile = DEVMEM;
-	char   *destfile = DEVMEM;
-	int     sourcefd, destfd;
-	char   *rw_buf1;
-	int     ret = 1;
-	int     offset = 0;
-	struct  stat statbuf;
-
-	if (mem_parse_options(argc, argv, "bwls:d:", &mode, &sourcefile,
-			&destfile, NULL) < 0)
-		return 1;
-
-	if (optind + 2 > argc)
-		return COMMAND_ERROR_USAGE;
-
-	addr1 = strtoull_suffix(argv[optind], NULL, 0);
-	addr2 = strtoull_suffix(argv[optind + 1], NULL, 0);
-
-	if (optind + 2 == argc) {
-		if (sourcefile == DEVMEM) {
-			printf("source and count not given\n");
-			return 1;
-		}
-		if (stat(sourcefile, &statbuf)) {
-			perror("stat");
-			return 1;
-		}
-		count = statbuf.st_size - addr1;
-	} else {
-		count = strtoull_suffix(argv[optind + 2], NULL, 0);
-	}
-
-	sourcefd = open_and_lseek(sourcefile, mode | O_RDONLY, addr1);
-	if (sourcefd < 0)
-		return 1;
-
-	destfd = open_and_lseek(destfile, mode | O_RDONLY, addr2);
-	if (destfd < 0) {
-		close(sourcefd);
-		return 1;
-	}
-
-	rw_buf1 = xmalloc(RW_BUF_SIZE);
-
-	while (count > 0) {
-		int now, r1, r2, i;
-
-		now = min((loff_t)RW_BUF_SIZE, count);
-
-		r1 = read(sourcefd, mem_rw_buf,  now);
-		if (r1 < 0) {
-			perror("read");
-			goto out;
-		}
-
-		r2 = read(destfd, rw_buf1, now);
-		if (r2 < 0) {
-			perror("read");
-			goto out;
-		}
-
-		if (r1 != now || r2 != now) {
-			printf("regions differ in size\n");
-			goto out;
-		}
-
-		for (i = 0; i < now; i++) {
-			if (mem_rw_buf[i] != rw_buf1[i]) {
-				printf("files differ at offset %d\n", offset);
-				goto out;
-			}
-			offset++;
-		}
-
-		count -= now;
-	}
-
-	printf("OK\n");
-	ret = 0;
-out:
-	close(sourcefd);
-	close(destfd);
-	free(rw_buf1);
-
-	return ret;
-}
-
-static const __maybe_unused char cmd_memcmp_help[] =
-"Usage: memcmp [OPTIONS] <addr1> <addr2> <count>\n"
-"\n"
-"options:\n"
-"  -b, -w, -l	use byte, halfword, or word accesses\n"
-"  -s <file>    source file (default /dev/mem)\n"
-"  -d <file>    destination file (default /dev/mem)\n"
-"\n"
-"Compare memory regions specified with addr1 and addr2\n"
-"of size <count> bytes. If source is a file count can\n"
-"be left unspecified in which case the whole file is\n"
-"compared\n";
-
-BAREBOX_CMD_START(memcmp)
-	.cmd		= do_mem_cmp,
-	.usage		= "memory compare",
-	BAREBOX_CMD_HELP(cmd_memcmp_help)
-BAREBOX_CMD_END
-
-static int do_mem_cp(int argc, char *argv[])
-{
-	loff_t count, dest, src;
-	char *sourcefile = DEVMEM;
-	char *destfile = DEVMEM;
-	int sourcefd, destfd;
-	int mode = 0;
-	struct stat statbuf;
-	int ret = 0;
-
-	if (mem_parse_options(argc, argv, "bwls:d:", &mode, &sourcefile,
-			&destfile, NULL) < 0)
-		return 1;
-
-	if (optind + 2 > argc)
-		return COMMAND_ERROR_USAGE;
-
-	src = strtoull_suffix(argv[optind], NULL, 0);
-	dest = strtoull_suffix(argv[optind + 1], NULL, 0);
-
-	if (optind + 2 == argc) {
-		if (sourcefile == DEVMEM) {
-			printf("source and count not given\n");
-			return 1;
-		}
-		if (stat(sourcefile, &statbuf)) {
-			perror("stat");
-			return 1;
-		}
-		count = statbuf.st_size - src;
-	} else {
-		count = strtoull_suffix(argv[optind + 2], NULL, 0);
-	}
-
-	sourcefd = open_and_lseek(sourcefile, mode | O_RDONLY, src);
-	if (sourcefd < 0)
-		return 1;
-
-	destfd = open_and_lseek(destfile, O_WRONLY | O_CREAT | mode, dest);
-	if (destfd < 0) {
-		close(sourcefd);
-		return 1;
-	}
-
-	while (count > 0) {
-		int now, r, w, tmp;
-
-		now = min((loff_t)RW_BUF_SIZE, count);
-
-		r = read(sourcefd, mem_rw_buf, now);
-		if (r < 0) {
-			perror("read");
-			goto out;
-		}
-
-		if (!r)
-			break;
-
-		tmp = 0;
-		now = r;
-		while (now) {
-			w = write(destfd, mem_rw_buf + tmp, now);
-			if (w < 0) {
-				perror("write");
-				goto out;
-			}
-	                if (!w)
-			        break;
-
-			now -= w;
-			tmp += w;
-		}
-
-		count -= r;
-
-		if (ctrlc())
-			goto out;
-	}
-
-	if (count) {
-		printf("ran out of data\n");
-		ret = 1;
-	}
-
-out:
-	close(sourcefd);
-	close(destfd);
-
-	return ret;
-}
-
-static const __maybe_unused char cmd_memcpy_help[] =
-"Usage: memcpy [OPTIONS] <src> <dst> <count>\n"
-"\n"
-"options:\n"
-"  -b, -w, -l   use byte, halfword, or word accesses\n"
-"  -s <file>    source file (default /dev/mem)\n"
-"  -d <file>    destination file (default /dev/mem)\n"
-"\n"
-"Copy memory at <src> of <count> bytes to <dst>\n";
-
-BAREBOX_CMD_START(memcpy)
-	.cmd		= do_mem_cp,
-	.usage		= "memory copy",
-	BAREBOX_CMD_HELP(cmd_memcpy_help)
-BAREBOX_CMD_END
-
-static int do_memset(int argc, char *argv[])
-{
-	loff_t	s, c, n;
-	int     fd;
-	char   *buf;
-	int	mode  = O_RWSIZE_1;
-	int     ret = 1;
-	char	*file = DEVMEM;
-
-	if (mem_parse_options(argc, argv, "bwld:", &mode, NULL, &file,
-			NULL) < 0)
-		return 1;
-
-	if (optind + 3 > argc)
-		return COMMAND_ERROR_USAGE;
-
-	s = strtoull_suffix(argv[optind], NULL, 0);
-	c = strtoull_suffix(argv[optind + 1], NULL, 0);
-	n = strtoull_suffix(argv[optind + 2], NULL, 0);
-
-	fd = open_and_lseek(file, mode | O_WRONLY, s);
-	if (fd < 0)
-		return 1;
-
-	buf = xmalloc(RW_BUF_SIZE);
-	memset(buf, c, RW_BUF_SIZE);
-
-	while (n > 0) {
-		int now;
-
-		now = min((loff_t)RW_BUF_SIZE, n);
-
-		ret = write(fd, buf, now);
-		if (ret < 0) {
-			perror("write");
-			ret = 1;
-			goto out;
-		}
-
-		n -= now;
-	}
-
-	ret = 0;
-out:
-	close(fd);
-	free(buf);
-
-	return ret;
-}
-
-static const __maybe_unused char cmd_memset_help[] =
-"Usage: memset [OPTIONS] <addr> <c> <n>\n"
-"\n"
-"options:\n"
-"  -b, -w, -l   use byte, halfword, or word accesses\n"
-"  -d <file>    destination file (default /dev/mem)\n"
-"\n"
-"Fill the first <n> bytes at offset <addr> with byte <c>\n";
-
-BAREBOX_CMD_START(memset)
-	.cmd		= do_memset,
-	.usage		= "memory fill",
-	BAREBOX_CMD_HELP(cmd_memset_help)
-BAREBOX_CMD_END
-
 static struct file_operations memops = {
 	.read  = mem_read,
 	.write = mem_write,
diff --git a/commands/memcmp.c b/commands/memcmp.c
new file mode 100644
index 0000000..4a03862
--- /dev/null
+++ b/commands/memcmp.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2011 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.
+ *
+ */
+
+/*
+ * Memory Functions
+ *
+ * Copied from FADS ROM, Dan Malek (dmalek@jlc.net)
+ */
+
+#include <common.h>
+#include <command.h>
+#include <init.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <linux/stat.h>
+#include <xfuncs.h>
+
+extern char *mem_rw_buf;
+
+static char *devmem = "/dev/mem";
+
+static int do_memcmp(int argc, char *argv[])
+{
+	loff_t	addr1, addr2, count = ~0;
+	int	mode  = O_RWSIZE_1;
+	char   *sourcefile = devmem;
+	char   *destfile = devmem;
+	int     sourcefd, destfd;
+	char   *rw_buf1;
+	int     ret = 1;
+	int     offset = 0;
+	struct  stat statbuf;
+
+	if (mem_parse_options(argc, argv, "bwls:d:", &mode, &sourcefile,
+			&destfile, NULL) < 0)
+		return 1;
+
+	if (optind + 2 > argc)
+		return COMMAND_ERROR_USAGE;
+
+	addr1 = strtoull_suffix(argv[optind], NULL, 0);
+	addr2 = strtoull_suffix(argv[optind + 1], NULL, 0);
+
+	if (optind + 2 == argc) {
+		if (sourcefile == devmem) {
+			printf("source and count not given\n");
+			return 1;
+		}
+		if (stat(sourcefile, &statbuf)) {
+			perror("stat");
+			return 1;
+		}
+		count = statbuf.st_size - addr1;
+	} else {
+		count = strtoull_suffix(argv[optind + 2], NULL, 0);
+	}
+
+	sourcefd = open_and_lseek(sourcefile, mode | O_RDONLY, addr1);
+	if (sourcefd < 0)
+		return 1;
+
+	destfd = open_and_lseek(destfile, mode | O_RDONLY, addr2);
+	if (destfd < 0) {
+		close(sourcefd);
+		return 1;
+	}
+
+	rw_buf1 = xmalloc(RW_BUF_SIZE);
+
+	while (count > 0) {
+		int now, r1, r2, i;
+
+		now = min((loff_t)RW_BUF_SIZE, count);
+
+		r1 = read(sourcefd, mem_rw_buf,  now);
+		if (r1 < 0) {
+			perror("read");
+			goto out;
+		}
+
+		r2 = read(destfd, rw_buf1, now);
+		if (r2 < 0) {
+			perror("read");
+			goto out;
+		}
+
+		if (r1 != now || r2 != now) {
+			printf("regions differ in size\n");
+			goto out;
+		}
+
+		for (i = 0; i < now; i++) {
+			if (mem_rw_buf[i] != rw_buf1[i]) {
+				printf("files differ at offset %d\n", offset);
+				goto out;
+			}
+			offset++;
+		}
+
+		count -= now;
+	}
+
+	printf("OK\n");
+	ret = 0;
+out:
+	close(sourcefd);
+	close(destfd);
+	free(rw_buf1);
+
+	return ret;
+}
+
+static const __maybe_unused char cmd_memcmp_help[] =
+"Usage: memcmp [OPTIONS] <addr1> <addr2> <count>\n"
+"\n"
+"options:\n"
+"  -b, -w, -l	use byte, halfword, or word accesses\n"
+"  -s <file>    source file (default /dev/mem)\n"
+"  -d <file>    destination file (default /dev/mem)\n"
+"\n"
+"Compare memory regions specified with addr1 and addr2\n"
+"of size <count> bytes. If source is a file count can\n"
+"be left unspecified in which case the whole file is\n"
+"compared\n";
+
+BAREBOX_CMD_START(memcmp)
+	.cmd		= do_memcmp,
+	.usage		= "memory compare",
+	BAREBOX_CMD_HELP(cmd_memcmp_help)
+BAREBOX_CMD_END
diff --git a/commands/memcpy.c b/commands/memcpy.c
new file mode 100644
index 0000000..98f099f
--- /dev/null
+++ b/commands/memcpy.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2011 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.
+ *
+ */
+
+/*
+ * Memory Functions
+ *
+ * Copied from FADS ROM, Dan Malek (dmalek@jlc.net)
+ */
+
+#include <common.h>
+#include <command.h>
+#include <init.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <linux/stat.h>
+#include <xfuncs.h>
+
+extern char *mem_rw_buf;
+
+static char *devmem = "/dev/mem";
+
+static int do_memcpy(int argc, char *argv[])
+{
+	loff_t count, dest, src;
+	char *sourcefile = devmem;
+	char *destfile = devmem;
+	int sourcefd, destfd;
+	int mode = 0;
+	struct stat statbuf;
+	int ret = 0;
+
+	if (mem_parse_options(argc, argv, "bwls:d:", &mode, &sourcefile,
+			&destfile, NULL) < 0)
+		return 1;
+
+	if (optind + 2 > argc)
+		return COMMAND_ERROR_USAGE;
+
+	src = strtoull_suffix(argv[optind], NULL, 0);
+	dest = strtoull_suffix(argv[optind + 1], NULL, 0);
+
+	if (optind + 2 == argc) {
+		if (sourcefile == devmem) {
+			printf("source and count not given\n");
+			return 1;
+		}
+		if (stat(sourcefile, &statbuf)) {
+			perror("stat");
+			return 1;
+		}
+		count = statbuf.st_size - src;
+	} else {
+		count = strtoull_suffix(argv[optind + 2], NULL, 0);
+	}
+
+	sourcefd = open_and_lseek(sourcefile, mode | O_RDONLY, src);
+	if (sourcefd < 0)
+		return 1;
+
+	destfd = open_and_lseek(destfile, O_WRONLY | O_CREAT | mode, dest);
+	if (destfd < 0) {
+		close(sourcefd);
+		return 1;
+	}
+
+	while (count > 0) {
+		int now, r, w, tmp;
+
+		now = min((loff_t)RW_BUF_SIZE, count);
+
+		r = read(sourcefd, mem_rw_buf, now);
+		if (r < 0) {
+			perror("read");
+			goto out;
+		}
+
+		if (!r)
+			break;
+
+		tmp = 0;
+		now = r;
+		while (now) {
+			w = write(destfd, mem_rw_buf + tmp, now);
+			if (w < 0) {
+				perror("write");
+				goto out;
+			}
+	                if (!w)
+			        break;
+
+			now -= w;
+			tmp += w;
+		}
+
+		count -= r;
+
+		if (ctrlc())
+			goto out;
+	}
+
+	if (count) {
+		printf("ran out of data\n");
+		ret = 1;
+	}
+
+out:
+	close(sourcefd);
+	close(destfd);
+
+	return ret;
+}
+
+static const __maybe_unused char cmd_memcpy_help[] =
+"Usage: memcpy [OPTIONS] <src> <dst> <count>\n"
+"\n"
+"options:\n"
+"  -b, -w, -l   use byte, halfword, or word accesses\n"
+"  -s <file>    source file (default /dev/mem)\n"
+"  -d <file>    destination file (default /dev/mem)\n"
+"\n"
+"Copy memory at <src> of <count> bytes to <dst>\n";
+
+BAREBOX_CMD_START(memcpy)
+	.cmd		= do_memcpy,
+	.usage		= "memory copy",
+	BAREBOX_CMD_HELP(cmd_memcpy_help)
+BAREBOX_CMD_END
diff --git a/commands/memset.c b/commands/memset.c
new file mode 100644
index 0000000..48e55bc
--- /dev/null
+++ b/commands/memset.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2011 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.
+ *
+ */
+
+/*
+ * Memory Functions
+ *
+ * Copied from FADS ROM, Dan Malek (dmalek@jlc.net)
+ */
+
+#include <common.h>
+#include <command.h>
+#include <init.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <linux/stat.h>
+#include <xfuncs.h>
+
+extern char *mem_rw_buf;
+
+static int do_memset(int argc, char *argv[])
+{
+	loff_t	s, c, n;
+	int     fd;
+	char   *buf;
+	int	mode  = O_RWSIZE_1;
+	int     ret = 1;
+	char	*file = "/dev/mem";
+
+	if (mem_parse_options(argc, argv, "bwld:", &mode, NULL, &file,
+			NULL) < 0)
+		return 1;
+
+	if (optind + 3 > argc)
+		return COMMAND_ERROR_USAGE;
+
+	s = strtoull_suffix(argv[optind], NULL, 0);
+	c = strtoull_suffix(argv[optind + 1], NULL, 0);
+	n = strtoull_suffix(argv[optind + 2], NULL, 0);
+
+	fd = open_and_lseek(file, mode | O_WRONLY, s);
+	if (fd < 0)
+		return 1;
+
+	buf = xmalloc(RW_BUF_SIZE);
+	memset(buf, c, RW_BUF_SIZE);
+
+	while (n > 0) {
+		int now;
+
+		now = min((loff_t)RW_BUF_SIZE, n);
+
+		ret = write(fd, buf, now);
+		if (ret < 0) {
+			perror("write");
+			ret = 1;
+			goto out;
+		}
+
+		n -= now;
+	}
+
+	ret = 0;
+out:
+	close(fd);
+	free(buf);
+
+	return ret;
+}
+
+static const __maybe_unused char cmd_memset_help[] =
+"Usage: memset [OPTIONS] <addr> <c> <n>\n"
+"\n"
+"options:\n"
+"  -b, -w, -l   use byte, halfword, or word accesses\n"
+"  -d <file>    destination file (default /dev/mem)\n"
+"\n"
+"Fill the first <n> bytes at offset <addr> with byte <c>\n";
+
+BAREBOX_CMD_START(memset)
+	.cmd		= do_memset,
+	.usage		= "memory fill",
+	BAREBOX_CMD_HELP(cmd_memset_help)
+BAREBOX_CMD_END
diff --git a/commands/mw.c b/commands/mw.c
new file mode 100644
index 0000000..d7d73a8
--- /dev/null
+++ b/commands/mw.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2011 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.
+ *
+ */
+
+/*
+ * Memory Functions
+ *
+ * Copied from FADS ROM, Dan Malek (dmalek@jlc.net)
+ */
+
+#include <common.h>
+#include <command.h>
+#include <init.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <linux/stat.h>
+#include <xfuncs.h>
+
+static int do_mem_mw(int argc, char *argv[])
+{
+	int ret = 0;
+	int fd;
+	char *filename = "/dev/mem";
+	int mode = O_RWSIZE_4;
+	loff_t adr;
+	int swab = 0;
+
+	if (mem_parse_options(argc, argv, "bwld:x", &mode, NULL, &filename,
+			&swab) < 0)
+		return 1;
+
+	if (optind + 1 >= argc)
+		return COMMAND_ERROR_USAGE;
+
+	adr = strtoull_suffix(argv[optind++], NULL, 0);
+
+	fd = open_and_lseek(filename, mode | O_WRONLY, adr);
+	if (fd < 0)
+		return 1;
+
+	while (optind < argc) {
+		u8 val8;
+		u16 val16;
+		u32 val32;
+		switch (mode) {
+		case O_RWSIZE_1:
+			val8 = simple_strtoul(argv[optind], NULL, 0);
+			ret = write(fd, &val8, 1);
+			break;
+		case O_RWSIZE_2:
+			val16 = simple_strtoul(argv[optind], NULL, 0);
+			if (swab)
+				val16 = __swab16(val16);
+			ret = write(fd, &val16, 2);
+			break;
+		case O_RWSIZE_4:
+			val32 = simple_strtoul(argv[optind], NULL, 0);
+			if (swab)
+				val32 = __swab32(val32);
+			ret = write(fd, &val32, 4);
+			break;
+		}
+		if (ret < 0) {
+			perror("write");
+			break;
+		}
+		ret = 0;
+		optind++;
+	}
+
+	close(fd);
+
+	return ret ? 1 : 0;
+}
+
+static const __maybe_unused char cmd_mw_help[] =
+"Usage: mw [OPTIONS] <region> <value(s)>\n"
+"Write value(s) to the specifies region.\n"
+"options:\n"
+"  -b, -w, -l	use byte, halfword, or word accesses\n"
+"  -d <file>	write file (default /dev/mem)\n";
+
+BAREBOX_CMD_START(mw)
+	.cmd		= do_mem_mw,
+	.usage		= "memory write (fill)",
+	BAREBOX_CMD_HELP(cmd_mw_help)
+BAREBOX_CMD_END
-- 
1.8.2.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 7/7] Add memory modify command (mm)
  2013-04-17 11:39 [PATCH] memory commands Sascha Hauer
                   ` (5 preceding siblings ...)
  2013-04-17 11:39 ` [PATCH 6/7] memory commands: separate into one file per command Sascha Hauer
@ 2013-04-17 11:39 ` Sascha Hauer
  6 siblings, 0 replies; 8+ messages in thread
From: Sascha Hauer @ 2013-04-17 11:39 UTC (permalink / raw)
  To: barebox

As of now we have no way to manipulate individual bits of registers on the
command line. This introduces a memory modify command which allows this. It
has the syntax:

mm [OPTIONS] <adr> <val> <mask>

With [OPTIONS] being the usual memory command options (-b, -w, -l, -d <file>).

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/Kconfig  |   8 ++++
 commands/Makefile |   1 +
 commands/mm.c     | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 126 insertions(+)
 create mode 100644 commands/mm.c

diff --git a/commands/Kconfig b/commands/Kconfig
index fe171d8..e6168ce 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -320,6 +320,14 @@ config CMD_MW
 	help
 	  the mw command allows to write to memory locations and files.
 
+config CMD_MM
+	tristate
+	select CMD_MEMORY
+	prompt "memory modify (mm)"
+	help
+	  the mm command allows to read-modify-write registers by doing:
+	  reg = (reg & ~mask) | (val & mask)
+
 config CMD_MEMCMP
 	tristate
 	default y
diff --git a/commands/Makefile b/commands/Makefile
index beec8e9..953ecc2 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_CMD_LOADS)		+= loads.o
 obj-$(CONFIG_CMD_ECHO)		+= echo.o
 obj-$(CONFIG_CMD_MEMORY)	+= mem.o
 obj-$(CONFIG_CMD_MD)		+= md.o
+obj-$(CONFIG_CMD_MM)		+= mm.o
 obj-$(CONFIG_CMD_MW)		+= mw.o
 obj-$(CONFIG_CMD_MEMCMP)	+= memcmp.o
 obj-$(CONFIG_CMD_MEMCPY)	+= memcpy.o
diff --git a/commands/mm.c b/commands/mm.c
new file mode 100644
index 0000000..f51fd27
--- /dev/null
+++ b/commands/mm.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2013 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 <init.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <linux/stat.h>
+#include <xfuncs.h>
+
+static int do_mem_mm(int argc, char *argv[])
+{
+	int ret = 0;
+	int fd;
+	char *filename = "/dev/mem";
+	int mode = O_RWSIZE_4;
+	loff_t adr;
+	int swab = 0;
+	u8 val8;
+	u16 val16;
+	u32 val32;
+	u32 value, mask;
+
+	if (mem_parse_options(argc, argv, "bwld:", &mode, NULL, &filename,
+			&swab) < 0)
+		return 1;
+
+	if (optind + 2 >= argc)
+		return COMMAND_ERROR_USAGE;
+
+	adr = strtoull_suffix(argv[optind++], NULL, 0);
+	value = simple_strtoul(argv[optind++], NULL, 0);
+	mask = simple_strtoul(argv[optind++], NULL, 0);
+
+	fd = open_and_lseek(filename, mode | O_RDWR, adr);
+	if (fd < 0)
+		return 1;
+
+	switch (mode) {
+	case O_RWSIZE_1:
+		ret = pread(fd, &val8, 1, adr);
+		if (ret < 0)
+			goto out_read;
+		val8 &= ~mask;
+		val8 |= (value & mask);
+		ret = pwrite(fd, &val8, 1, adr);
+		if (ret < 0)
+			goto out_write;
+		break;
+	case O_RWSIZE_2:
+		ret = pread(fd, &val16, 2, adr);
+		if (ret < 0)
+			goto out_read;
+		val16 &= ~mask;
+		val16 |= (value & mask);
+		ret = pwrite(fd, &val16, 2, adr);
+		if (ret < 0)
+			goto out_write;
+		break;
+	case O_RWSIZE_4:
+		if (ret < 0)
+			goto out_read;
+		ret = pread(fd, &val32, 4, adr);
+		val32 &= ~mask;
+		val32 |= (value & mask);
+		ret = pwrite(fd, &val32, 4, adr);
+		if (ret < 0)
+			goto out_write;
+		break;
+	}
+
+	close(fd);
+
+	return 0;
+
+out_read:
+	perror("read");
+	close(fd);
+	return 1;
+
+out_write:
+	perror("write");
+	close(fd);
+	return 1;
+}
+
+static const __maybe_unused char cmd_mm_help[] =
+"Usage: mm [OPTIONS] <adr> <val> <mask>\n"
+"set/clear bits specified with <mask> in <adr> to <value>\n"
+"options:\n"
+"  -b, -w, -l	use byte, halfword, or word accesses\n"
+"  -d <file>	write file (default /dev/mem)\n";
+
+BAREBOX_CMD_START(mm)
+	.cmd		= do_mem_mm,
+	.usage		= "memory modify write with mask",
+	BAREBOX_CMD_HELP(cmd_mm_help)
+BAREBOX_CMD_END
-- 
1.8.2.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-04-17 11:39 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-04-17 11:39 [PATCH] memory commands Sascha Hauer
2013-04-17 11:39 ` [PATCH 1/7] memory commands: export common functions Sascha Hauer
2013-04-17 11:39 ` [PATCH 2/7] memory commands: move memory_display to separate file Sascha Hauer
2013-04-17 11:39 ` [PATCH 3/7] Use a common define for RW_BUF_SIZE Sascha Hauer
2013-04-17 11:39 ` [PATCH 4/7] memory commands: cleanup initialization Sascha Hauer
2013-04-17 11:39 ` [PATCH 5/7] memory commands: make rw_buf global Sascha Hauer
2013-04-17 11:39 ` [PATCH 6/7] memory commands: separate into one file per command Sascha Hauer
2013-04-17 11:39 ` [PATCH 7/7] Add memory modify command (mm) Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox