All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1
@ 2019-07-19 12:57 Patrick Delaunay
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 01/14] dfu: cosmetic: cleanup sf to avoid checkpatch error Patrick Delaunay
                   ` (14 more replies)
  0 siblings, 15 replies; 25+ messages in thread
From: Patrick Delaunay @ 2019-07-19 12:57 UTC (permalink / raw)
  To: u-boot


This serie based on v2019.07 propose some update on the DFU stack:
- add capability to have several DFU backend running in parallel
- add MTD backend for NAND, NOR or SPI-NAND
- add VIRTUAL backend for board/command specific behavior
- add some weak callback

To test the feature and as example, I update the stm32mp1
to use the new features (tested with command "dfu 0")

This serie prepares the DFU backend for communication with
STM32CubeProgrammer on stm32mp1 platform (stm32prog command).
This STMicroelectronics tool is based on DFU protocol and
update the boot devices and the OTPs on the ST boards.



Patrick Delaunay (14):
  dfu: cosmetic: cleanup sf to avoid checkpatch error
  dfu: sf: add partition support for nor backend
  dfu: prepare the support of multiple interface
  dfu: allow to manage DFU on several devices
  dfu: allow read with 0 data for EOF indication
  dfu: add backend for MTD device
  dfu: add partition support for MTD backend
  dfu: add DFU virtual backend
  dfu: add callback for flush and initiated operation
  stm32mp1: activate DFU support and command MTD
  stm32mp1: activate SET_DFU_ALT_INFO
  stp32mp1: configs: activate CONFIG_MTD_SPI_NAND
  stm32mp1: board: add spi nand support
  stm32mp1: add support for virtual partition read

 board/st/stm32mp1/README            | 111 +++++++++++++
 board/st/stm32mp1/stm32mp1.c        | 165 ++++++++++++++++++-
 cmd/dfu.c                           |  21 ++-
 configs/stm32mp15_basic_defconfig   |   6 +
 configs/stm32mp15_trusted_defconfig |   6 +
 drivers/dfu/Kconfig                 |  13 ++
 drivers/dfu/Makefile                |   2 +
 drivers/dfu/dfu.c                   | 145 +++++++++++++++--
 drivers/dfu/dfu_mtd.c               | 306 ++++++++++++++++++++++++++++++++++++
 drivers/dfu/dfu_sf.c                |  55 ++++++-
 drivers/dfu/dfu_virt.c              |  49 ++++++
 include/configs/stm32mp1.h          |  38 ++++-
 include/dfu.h                       |  51 ++++++
 13 files changed, 939 insertions(+), 29 deletions(-)
 create mode 100644 drivers/dfu/dfu_mtd.c
 create mode 100644 drivers/dfu/dfu_virt.c

-- 
2.7.4

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

* [U-Boot] [RFC PATCH 01/14] dfu: cosmetic: cleanup sf to avoid checkpatch error
  2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
@ 2019-07-19 12:57 ` Patrick Delaunay
  2019-07-22  7:51   ` Lukasz Majewski
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 02/14] dfu: sf: add partition support for nor backend Patrick Delaunay
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Patrick Delaunay @ 2019-07-19 12:57 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 drivers/dfu/dfu.c    | 7 ++++---
 drivers/dfu/dfu_sf.c | 4 ++--
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index 3189495..eb3a3c6 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -477,14 +477,15 @@ int dfu_config_entities(char *env, char *interface, char *devstr)
 
 const char *dfu_get_dev_type(enum dfu_device_type t)
 {
-	const char *dev_t[] = {NULL, "eMMC", "OneNAND", "NAND", "RAM", "SF" };
+	const char *const dev_t[] = {NULL, "eMMC", "OneNAND", "NAND", "RAM",
+				     "SF"};
 	return dev_t[t];
 }
 
 const char *dfu_get_layout(enum dfu_layout l)
 {
-	const char *dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT2",
-					   "EXT3", "EXT4", "RAM_ADDR" };
+	const char *const dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT2",
+					  "EXT3", "EXT4", "RAM_ADDR" };
 	return dfu_layout[l];
 }
 
diff --git a/drivers/dfu/dfu_sf.c b/drivers/dfu/dfu_sf.c
index 066e767..b78fcfd 100644
--- a/drivers/dfu/dfu_sf.c
+++ b/drivers/dfu/dfu_sf.c
@@ -19,7 +19,7 @@ static int dfu_get_medium_size_sf(struct dfu_entity *dfu, u64 *size)
 }
 
 static int dfu_read_medium_sf(struct dfu_entity *dfu, u64 offset, void *buf,
-		long *len)
+			      long *len)
 {
 	return spi_flash_read(dfu->data.sf.dev, dfu->data.sf.start + offset,
 		*len, buf);
@@ -32,7 +32,7 @@ static u64 find_sector(struct dfu_entity *dfu, u64 start, u64 offset)
 }
 
 static int dfu_write_medium_sf(struct dfu_entity *dfu,
-		u64 offset, void *buf, long *len)
+			       u64 offset, void *buf, long *len)
 {
 	int ret;
 
-- 
2.7.4

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

* [U-Boot] [RFC PATCH 02/14] dfu: sf: add partition support for nor backend
  2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 01/14] dfu: cosmetic: cleanup sf to avoid checkpatch error Patrick Delaunay
@ 2019-07-19 12:57 ` Patrick Delaunay
  2019-07-22  7:54   ` Lukasz Majewski
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 03/14] dfu: prepare the support of multiple interface Patrick Delaunay
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Patrick Delaunay @ 2019-07-19 12:57 UTC (permalink / raw)
  To: u-boot

Copy the partition support from NAND backend to SF,
support part and partubi option.
In case of ubi partition, erase the rest of the
partition as it is mandatory for UBI.

for example:

U-Boot> env set dfu_alt_info "spl part 0 1;\
u-boot part 0 2;u-boot-env part 0 3;UBI partubi 0 4"
U-Boot> dfu 0 sf 0:0:10000000:0

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 drivers/dfu/dfu_sf.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/dfu.h        |  2 ++
 2 files changed, 53 insertions(+)

diff --git a/drivers/dfu/dfu_sf.c b/drivers/dfu/dfu_sf.c
index b78fcfd..d401b76 100644
--- a/drivers/dfu/dfu_sf.c
+++ b/drivers/dfu/dfu_sf.c
@@ -10,6 +10,8 @@
 #include <dfu.h>
 #include <spi.h>
 #include <spi_flash.h>
+#include <jffs2/load_kernel.h>
+#include <linux/mtd/mtd.h>
 
 static int dfu_get_medium_size_sf(struct dfu_entity *dfu, u64 *size)
 {
@@ -52,11 +54,33 @@ static int dfu_write_medium_sf(struct dfu_entity *dfu,
 
 static int dfu_flush_medium_sf(struct dfu_entity *dfu)
 {
+	u64 off, length;
+
+	if (!dfu->data.sf.ubi)
+		return 0;
+
+	/* in case of ubi partition, erase rest of the partition */
+	off = find_sector(dfu, dfu->data.sf.start, dfu->offset);
+	/* last write ended with unaligned length jump to next */
+	if (off != dfu->data.sf.start + dfu->offset)
+		off += dfu->data.sf.dev->sector_size;
+	length = dfu->data.sf.start + dfu->data.sf.size - off;
+	if (length)
+		return spi_flash_erase(dfu->data.sf.dev, off, length);
+
 	return 0;
 }
 
 static unsigned int dfu_polltimeout_sf(struct dfu_entity *dfu)
 {
+	/*
+	 * Currently, Poll Timeout != 0 is only needed on nand
+	 * ubi partition, as sectors which are not used need
+	 * to be erased
+	 */
+	if (dfu->data.sf.ubi)
+		return DFU_MANIFEST_POLL_TIMEOUT;
+
 	return DFU_DEFAULT_POLL_TIMEOUT;
 }
 
@@ -133,6 +157,33 @@ int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr, char *s)
 		dfu->data.sf.start = simple_strtoul(s, &s, 16);
 		s++;
 		dfu->data.sf.size = simple_strtoul(s, &s, 16);
+	} else if ((!strcmp(st, "part")) || (!strcmp(st, "partubi"))) {
+		char mtd_id[32];
+		struct mtd_device *mtd_dev;
+		u8 part_num;
+		struct part_info *pi;
+		int ret, dev, part;
+
+		dfu->layout = DFU_RAW_ADDR;
+
+		dev = simple_strtoul(s, &s, 10);
+		s++;
+		part = simple_strtoul(s, &s, 10);
+
+		sprintf(mtd_id, "%s%d,%d", "nor", dev, part - 1);
+		printf("using id '%s'\n", mtd_id);
+
+		mtdparts_init();
+
+		ret = find_dev_and_part(mtd_id, &mtd_dev, &part_num, &pi);
+		if (ret != 0) {
+			printf("Could not locate '%s'\n", mtd_id);
+			return -1;
+		}
+		dfu->data.sf.start = pi->offset;
+		dfu->data.sf.size = pi->size;
+		if (!strcmp(st, "partubi"))
+			dfu->data.sf.ubi = 1;
 	} else {
 		printf("%s: Memory layout (%s) not supported!\n", __func__, st);
 		spi_flash_free(dfu->data.sf.dev);
diff --git a/include/dfu.h b/include/dfu.h
index 145a157..bf51ab7 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -77,6 +77,8 @@ struct sf_internal_data {
 	/* RAW programming */
 	u64 start;
 	u64 size;
+	/* for sf/ubi use */
+	unsigned int ubi;
 };
 
 #define DFU_NAME_SIZE			32
-- 
2.7.4

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

* [U-Boot] [RFC PATCH 03/14] dfu: prepare the support of multiple interface
  2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 01/14] dfu: cosmetic: cleanup sf to avoid checkpatch error Patrick Delaunay
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 02/14] dfu: sf: add partition support for nor backend Patrick Delaunay
@ 2019-07-19 12:57 ` Patrick Delaunay
  2019-07-22  7:57   ` Lukasz Majewski
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 04/14] dfu: allow to manage DFU on several devices Patrick Delaunay
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Patrick Delaunay @ 2019-07-19 12:57 UTC (permalink / raw)
  To: u-boot

Split the function dfu_config_entities with 2 new functions
- dfu_alt_init
- dfu_alt_add

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 drivers/dfu/dfu.c | 51 +++++++++++++++++++++++++++++++++++++++------------
 include/dfu.h     |  2 ++
 2 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index eb3a3c6..79a652e 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -438,13 +438,12 @@ void dfu_free_entities(void)
 	alt_num_cnt = 0;
 }
 
-int dfu_config_entities(char *env, char *interface, char *devstr)
+int dfu_alt_init(int num, struct dfu_entity **dfu)
 {
-	struct dfu_entity *dfu;
-	int i, ret;
 	char *s;
+	int ret;
 
-	dfu_alt_num = dfu_find_alt_num(env);
+	dfu_alt_num = num;
 	debug("%s: dfu_alt_num=%d\n", __func__, dfu_alt_num);
 
 	dfu_hash_algo = NULL;
@@ -455,21 +454,49 @@ int dfu_config_entities(char *env, char *interface, char *devstr)
 			pr_err("Hash algorithm %s not supported\n", s);
 	}
 
-	dfu = calloc(sizeof(*dfu), dfu_alt_num);
-	if (!dfu)
+	*dfu = calloc(sizeof(struct dfu_entity), dfu_alt_num);
+	if (!*dfu)
+		return -1;
+
+	return 0;
+}
+
+int dfu_alt_add(struct dfu_entity *dfu, char *interface, char *devstr, char *s)
+{
+	struct dfu_entity *p_dfu;
+	int ret;
+
+	if (alt_num_cnt >= dfu_alt_num)
+		return -1;
+
+	p_dfu = &dfu[alt_num_cnt];
+	ret = dfu_fill_entity(p_dfu, s, alt_num_cnt, interface, devstr);
+	if (ret)
 		return -1;
-	for (i = 0; i < dfu_alt_num; i++) {
 
+	list_add_tail(&p_dfu->list, &dfu_list);
+	alt_num_cnt++;
+
+	return 0;
+}
+
+int dfu_config_entities(char *env, char *interface, char *devstr)
+{
+	struct dfu_entity *dfu;
+	int i, ret;
+	char *s;
+
+	ret = dfu_alt_init(dfu_find_alt_num(env), &dfu);
+	if (ret)
+		return -1;
+
+	for (i = 0; i < dfu_alt_num; i++) {
 		s = strsep(&env, ";");
-		ret = dfu_fill_entity(&dfu[i], s, alt_num_cnt, interface,
-				      devstr);
+		ret = dfu_alt_add(dfu, interface, devstr, s);
 		if (ret) {
 			/* We will free "dfu" in dfu_free_entities() */
 			return -1;
 		}
-
-		list_add_tail(&dfu[i].list, &dfu_list);
-		alt_num_cnt++;
 	}
 
 	return 0;
diff --git a/include/dfu.h b/include/dfu.h
index bf51ab7..7d60ffc 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -143,6 +143,8 @@ struct dfu_entity {
 #ifdef CONFIG_SET_DFU_ALT_INFO
 void set_dfu_alt_info(char *interface, char *devstr);
 #endif
+int dfu_alt_init(int num, struct dfu_entity **dfu);
+int dfu_alt_add(struct dfu_entity *dfu, char *interface, char *devstr, char *s);
 int dfu_config_entities(char *s, char *interface, char *devstr);
 void dfu_free_entities(void);
 void dfu_show_entities(void);
-- 
2.7.4

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

* [U-Boot] [RFC PATCH 04/14] dfu: allow to manage DFU on several devices
  2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
                   ` (2 preceding siblings ...)
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 03/14] dfu: prepare the support of multiple interface Patrick Delaunay
@ 2019-07-19 12:57 ` Patrick Delaunay
  2019-07-22  8:04   ` Lukasz Majewski
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 05/14] dfu: allow read with 0 data for EOF indication Patrick Delaunay
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Patrick Delaunay @ 2019-07-19 12:57 UTC (permalink / raw)
  To: u-boot

Add support of DFU for several interface/device
with one command.

The format for "dfu_alt_info" in this case is :
  interface with devstring'='alternate list (';' separated)
  and each interface is separated by '&'

The previous behavior is always supported.

One example for NOR (bootloaders) + NAND (rootfs in UBI):

U-Boot> env set dfu_alt_info \
"sf 0:0:10000000:0=spl part 0 1;u-boot part 0 2; \
u-boot-env part 0 3&nand 0=UBI partubi 0,3"

U-Boot> dfu 0 list

DFU alt settings list:
dev: SF alt: 0 name: spl layout: RAW_ADDR
dev: SF alt: 1 name: ssbl layout: RAW_ADDR
dev: SF alt: 2 name: u-boot-env layout: RAW_ADDR
dev: NAND alt: 3 name: UBI layout: RAW_ADDR

U-Boot> dfu 0

$> dfu-util -l

Found DFU: [0483:5720] ver=9999, devnum=96, cfg=1, intf=0, alt=3, name="UBI", serial="002700333338511934383330"
Found DFU: [0483:5720] ver=9999, devnum=96, cfg=1, intf=0, alt=2, name="u-boot-env", serial="002700333338511934383330"
Found DFU: [0483:5720] ver=9999, devnum=96, cfg=1, intf=0, alt=1, name="u-boot", serial="002700333338511934383330"
Found DFU: [0483:5720] ver=9999, devnum=96, cfg=1, intf=0, alt=0, name="spl", serial="002700333338511934383330"

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 cmd/dfu.c         | 21 +++++++++++--------
 drivers/dfu/dfu.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 72 insertions(+), 9 deletions(-)

diff --git a/cmd/dfu.c b/cmd/dfu.c
index 91a750a..33491d0 100644
--- a/cmd/dfu.c
+++ b/cmd/dfu.c
@@ -21,23 +21,28 @@
 static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 
-	if (argc < 4)
+	if (argc < 2)
 		return CMD_RET_USAGE;
 
 #ifdef CONFIG_DFU_OVER_USB
 	char *usb_controller = argv[1];
 #endif
 #if defined(CONFIG_DFU_OVER_USB) || defined(CONFIG_DFU_OVER_TFTP)
-	char *interface = argv[2];
-	char *devstring = argv[3];
+	char *interface = NULL;
+	char *devstring = NULL;
+
+	if (argc >= 4) {
+		interface = argv[2];
+		devstring = argv[3];
+	}
 #endif
 
 	int ret = 0;
 #ifdef CONFIG_DFU_OVER_TFTP
 	unsigned long addr = 0;
 	if (!strcmp(argv[1], "tftp")) {
-		if (argc == 5)
-			addr = simple_strtoul(argv[4], NULL, 0);
+		if (argc == 5 || argc == 3)
+			addr = simple_strtoul(argv[argc - 1], NULL, 0);
 
 		return update_tftp(addr, interface, devstring);
 	}
@@ -48,7 +53,7 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		goto done;
 
 	ret = CMD_RET_SUCCESS;
-	if (argc > 4 && strcmp(argv[4], "list") == 0) {
+	if (strcmp(argv[argc - 1], "list") == 0) {
 		dfu_show_entities();
 		goto done;
 	}
@@ -67,7 +72,7 @@ U_BOOT_CMD(dfu, CONFIG_SYS_MAXARGS, 1, do_dfu,
 	"Device Firmware Upgrade",
 	""
 #ifdef CONFIG_DFU_OVER_USB
-	"<USB_controller> <interface> <dev> [list]\n"
+	"<USB_controller> [<interface> <dev>] [list]\n"
 	"  - device firmware upgrade via <USB_controller>\n"
 	"    on device <dev>, attached to interface\n"
 	"    <interface>\n"
@@ -77,7 +82,7 @@ U_BOOT_CMD(dfu, CONFIG_SYS_MAXARGS, 1, do_dfu,
 #ifdef CONFIG_DFU_OVER_USB
 	"dfu "
 #endif
-	"tftp <interface> <dev> [<addr>]\n"
+	"tftp [<interface> <dev>] [<addr>]\n"
 	"  - device firmware upgrade via TFTP\n"
 	"    on device <dev>, attached to interface\n"
 	"    <interface>\n"
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index 79a652e..01ec690 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -52,6 +52,54 @@ static int dfu_find_alt_num(const char *s)
 	return ++i;
 }
 
+/*
+ * treat dfu_alt_info with several interface information
+ * to allow DFU on several device with one command,
+ * the string format is
+ * interface devstring'='alternate list (';' separated)
+ * and each interface separated by '&'
+ */
+int dfu_config_interfaces(char *env)
+{
+	struct dfu_entity *dfu;
+	char *s, *i, *d, *a, *part;
+	int ret = -EINVAL;
+	int n = 1;
+
+	s = env;
+	for (; *s; s++) {
+		if (*s == ';')
+			n++;
+		if (*s == '&')
+			n++;
+	}
+	ret = dfu_alt_init(n, &dfu);
+	if (ret)
+		return ret;
+
+	s = env;
+	while (s) {
+		ret = -EINVAL;
+		i = strsep(&s, " ");
+		if (!i)
+			break;
+		d = strsep(&s, "=");
+		if (!d)
+			break;
+		a = strsep(&s, "&");
+		if (!a)
+			a = s;
+		do {
+			part = strsep(&a, ";");
+			ret = dfu_alt_add(dfu, i, d, part);
+			if (ret)
+				return ret;
+		} while (a);
+	}
+
+	return ret;
+}
+
 int dfu_init_env_entities(char *interface, char *devstr)
 {
 	const char *str_env;
@@ -68,7 +116,11 @@ int dfu_init_env_entities(char *interface, char *devstr)
 	}
 
 	env_bkp = strdup(str_env);
-	ret = dfu_config_entities(env_bkp, interface, devstr);
+	if (!interface && !devstr)
+		ret = dfu_config_interfaces(env_bkp);
+	else
+		ret = dfu_config_entities(env_bkp, interface, devstr);
+
 	if (ret) {
 		pr_err("DFU entities configuration failed!\n");
 		pr_err("(partition table does not match dfu_alt_info?)\n");
@@ -82,6 +134,7 @@ done:
 
 static unsigned char *dfu_buf;
 static unsigned long dfu_buf_size;
+static enum dfu_device_type dfu_buf_device_type;
 
 unsigned char *dfu_free_buf(void)
 {
@@ -99,6 +152,10 @@ unsigned char *dfu_get_buf(struct dfu_entity *dfu)
 {
 	char *s;
 
+	/* manage several entity with several contraint */
+	if (dfu_buf && dfu->dev_type != dfu_buf_device_type)
+		dfu_free_buf();
+
 	if (dfu_buf != NULL)
 		return dfu_buf;
 
@@ -117,6 +174,7 @@ unsigned char *dfu_get_buf(struct dfu_entity *dfu)
 		printf("%s: Could not memalign 0x%lx bytes\n",
 		       __func__, dfu_buf_size);
 
+	dfu_buf_device_type = dfu->dev_type;
 	return dfu_buf;
 }
 
-- 
2.7.4

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

* [U-Boot] [RFC PATCH 05/14] dfu: allow read with 0 data for EOF indication
  2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
                   ` (3 preceding siblings ...)
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 04/14] dfu: allow to manage DFU on several devices Patrick Delaunay
@ 2019-07-19 12:57 ` Patrick Delaunay
  2019-07-22  8:05   ` Lukasz Majewski
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 06/14] dfu: add backend for MTD device Patrick Delaunay
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Patrick Delaunay @ 2019-07-19 12:57 UTC (permalink / raw)
  To: u-boot

This patch allows into the DFU backend to indicate that there is no
remaining data (for EOF for example). That allows users to read a
buffer greater than the device size; the dfu stack stops the read
request when the backend return a length=0 without error.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 drivers/dfu/dfu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index 01ec690..bcfa170 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -395,6 +395,8 @@ static int dfu_read_buffer_fill(struct dfu_entity *dfu, void *buf, int size)
 				debug("%s: Read error!\n", __func__);
 				return ret;
 			}
+			if (dfu->b_left == 0)
+				break;
 			dfu->offset += dfu->b_left;
 			dfu->r_left -= dfu->b_left;
 
-- 
2.7.4

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

* [U-Boot] [RFC PATCH 06/14] dfu: add backend for MTD device
  2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
                   ` (4 preceding siblings ...)
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 05/14] dfu: allow read with 0 data for EOF indication Patrick Delaunay
@ 2019-07-19 12:57 ` Patrick Delaunay
  2019-07-22  8:11   ` Lukasz Majewski
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 07/14] dfu: add partition support for MTD backend Patrick Delaunay
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Patrick Delaunay @ 2019-07-19 12:57 UTC (permalink / raw)
  To: u-boot

Add DFU backend for MTD device: allow to read
and write on any MTD device (RAW or SPI)

For example :
> set dfu_alt_info "nand_raw raw 0x0 0x100000"
> dfu 0 mtd nand0

This MTD backend provides the same level than dfu nand
backend for NAND in RAW mode and sf backend for NOR;
So it can replace booth of them but it can also
add support of spi-nand.

> set dfu_alt_info "nand_raw raw 0x0 0x100000"
> dfu 0 mtd spi-nand0

The backend code is based on the MTD command
introduced by commit 5db66b3aee6f ("cmd: mtd:
add 'mtd' command")

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 drivers/dfu/Kconfig   |   6 ++
 drivers/dfu/Makefile  |   1 +
 drivers/dfu/dfu.c     |   5 +-
 drivers/dfu/dfu_mtd.c | 230 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/dfu.h         |  21 +++++
 5 files changed, 262 insertions(+), 1 deletion(-)
 create mode 100644 drivers/dfu/dfu_mtd.c

diff --git a/drivers/dfu/Kconfig b/drivers/dfu/Kconfig
index 4692736..ee664a3 100644
--- a/drivers/dfu/Kconfig
+++ b/drivers/dfu/Kconfig
@@ -46,5 +46,11 @@ config DFU_SF
 	  This option enables using DFU to read and write to SPI flash based
 	  storage.
 
+config DFU_MTD
+	bool "MTD back end for DFU"
+	depends on MTD
+	help
+	  This option enables using DFU to read and write to on any MTD device.
+
 endif
 endmenu
diff --git a/drivers/dfu/Makefile b/drivers/dfu/Makefile
index 4164f34..ebb119f 100644
--- a/drivers/dfu/Makefile
+++ b/drivers/dfu/Makefile
@@ -5,6 +5,7 @@
 
 obj-$(CONFIG_$(SPL_)DFU) += dfu.o
 obj-$(CONFIG_$(SPL_)DFU_MMC) += dfu_mmc.o
+obj-$(CONFIG_$(SPL_)DFU_MTD) += dfu_mtd.o
 obj-$(CONFIG_$(SPL_)DFU_NAND) += dfu_nand.o
 obj-$(CONFIG_$(SPL_)DFU_RAM) += dfu_ram.o
 obj-$(CONFIG_$(SPL_)DFU_SF) += dfu_sf.o
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index bcfa170..ab7fdc0 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -461,6 +461,9 @@ static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt,
 	if (strcmp(interface, "mmc") == 0) {
 		if (dfu_fill_entity_mmc(dfu, devstr, s))
 			return -1;
+	} else if (strcmp(interface, "mtd") == 0) {
+		if (dfu_fill_entity_mtd(dfu, devstr, s))
+			return -1;
 	} else if (strcmp(interface, "nand") == 0) {
 		if (dfu_fill_entity_nand(dfu, devstr, s))
 			return -1;
@@ -565,7 +568,7 @@ int dfu_config_entities(char *env, char *interface, char *devstr)
 const char *dfu_get_dev_type(enum dfu_device_type t)
 {
 	const char *const dev_t[] = {NULL, "eMMC", "OneNAND", "NAND", "RAM",
-				     "SF"};
+				     "SF", "MTD"};
 	return dev_t[t];
 }
 
diff --git a/drivers/dfu/dfu_mtd.c b/drivers/dfu/dfu_mtd.c
new file mode 100644
index 0000000..1168a6e
--- /dev/null
+++ b/drivers/dfu/dfu_mtd.c
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dfu_mtd.c -- DFU for MTD device.
+ *
+ * Copyright (C) 2019,STMicroelectronics - All Rights Reserved
+ *
+ * Based on dfu_nand.c
+ */
+
+#include <common.h>
+#include <dfu.h>
+#include <mtd.h>
+
+static bool mtd_is_aligned_with_block_size(struct mtd_info *mtd, u64 size)
+{
+	return !do_div(size, mtd->erasesize);
+}
+
+static int mtd_block_op(enum dfu_op op, struct dfu_entity *dfu,
+			u64 offset, void *buf, long *len)
+{
+	u64 off, lim, remaining;
+	struct mtd_info *mtd = dfu->data.mtd.info;
+	struct mtd_oob_ops io_op = {};
+	int ret = 0;
+	bool has_pages = mtd->type == MTD_NANDFLASH ||
+			 mtd->type == MTD_MLCNANDFLASH;
+
+	/* if buf == NULL return total size of the area */
+	if (!buf) {
+		*len = dfu->data.mtd.size;
+		return 0;
+	}
+
+	off = dfu->data.mtd.start + offset + dfu->bad_skip;
+	lim = dfu->data.mtd.start + dfu->data.mtd.size;
+
+	if (off >= lim) {
+		printf("Limit reached 0x%llx\n", lim);
+		*len = 0;
+		return op == DFU_OP_READ ? 0 : -EIO;
+	}
+	/* limit request with the available size */
+	if (off + *len >= lim)
+		*len = lim - off;
+
+	if (!mtd_is_aligned_with_block_size(mtd, off)) {
+		printf("Offset not aligned with a block (0x%x)\n",
+		       mtd->erasesize);
+		return 0;
+	}
+
+	/* first erase */
+	if (op == DFU_OP_WRITE) {
+		struct erase_info erase_op = {};
+
+		erase_op.mtd = mtd;
+		erase_op.addr = off;
+		erase_op.len = round_up(*len, mtd->erasesize);
+		erase_op.scrub = 0;
+
+		while (erase_op.len) {
+			if (erase_op.addr + erase_op.len > lim) {
+				printf("Limit reached 0x%llx while erasing at offset 0x%llx\n",
+				       lim, off);
+				return -EIO;
+			}
+
+			ret = mtd_erase(mtd, &erase_op);
+			/* Abort if its not a bad block error */
+			if (ret != -EIO)
+				break;
+
+			printf("Skipping bad block at 0x%08llx\n",
+			       erase_op.fail_addr);
+
+			/* Continue erase behind bad block */
+			erase_op.len -= erase_op.fail_addr - erase_op.addr;
+			erase_op.addr = erase_op.fail_addr + mtd->erasesize;
+		}
+		if (ret && ret != -EIO) {
+			printf("Failure while erasing at offset 0x%llx\n",
+			       erase_op.fail_addr);
+			return 0;
+		}
+	}
+
+	io_op.mode = MTD_OPS_AUTO_OOB;
+	io_op.len = *len;
+	if (has_pages && io_op.len > mtd->writesize)
+		io_op.len = mtd->writesize;
+	io_op.ooblen = 0;
+	io_op.datbuf = buf;
+	io_op.oobbuf = NULL;
+
+	/* Loop over to do the actual read/write */
+	remaining = *len;
+	while (remaining) {
+		if (off + remaining > lim) {
+			printf("Limit reached 0x%llx while %s at offset 0x%llx\n",
+			       lim, op == DFU_OP_READ ? "reading" : "writing",
+			       off);
+			if (op == DFU_OP_READ) {
+				*len -= remaining;
+				return 0;
+			} else {
+				return -EIO;
+			}
+		}
+
+		/* Skip the block if it is bad */
+		if (mtd_is_aligned_with_block_size(mtd, off) &&
+		    mtd_block_isbad(mtd, off)) {
+			off += mtd->erasesize;
+			dfu->bad_skip += mtd->erasesize;
+			continue;
+		}
+
+		if (op == DFU_OP_READ)
+			ret = mtd_read_oob(mtd, off, &io_op);
+		else
+			ret = mtd_write_oob(mtd, off, &io_op);
+
+		if (ret) {
+			printf("Failure while %s at offset 0x%llx\n",
+			       op == DFU_OP_READ ? "reading" : "writing", off);
+			return -EIO;
+		}
+
+		off += io_op.retlen;
+		remaining -= io_op.retlen;
+		io_op.datbuf += io_op.retlen;
+		io_op.len = remaining;
+		if (has_pages && io_op.len > mtd->writesize)
+			io_op.len = mtd->writesize;
+	}
+
+	return ret;
+}
+
+static int dfu_get_medium_size_mtd(struct dfu_entity *dfu, u64 *size)
+{
+	*size = dfu->data.mtd.info->size;
+
+	return 0;
+}
+
+static int dfu_read_medium_mtd(struct dfu_entity *dfu, u64 offset, void *buf,
+			       long *len)
+{
+	int ret = -1;
+
+	switch (dfu->layout) {
+	case DFU_RAW_ADDR:
+		ret = mtd_block_op(DFU_OP_READ, dfu, offset, buf, len);
+		break;
+	default:
+		printf("%s: Layout (%s) not (yet) supported!\n", __func__,
+		       dfu_get_layout(dfu->layout));
+	}
+
+	return ret;
+}
+
+static int dfu_write_medium_mtd(struct dfu_entity *dfu,
+				u64 offset, void *buf, long *len)
+{
+	int ret = -1;
+
+	switch (dfu->layout) {
+	case DFU_RAW_ADDR:
+		ret = mtd_block_op(DFU_OP_WRITE, dfu, offset, buf, len);
+		break;
+	default:
+		printf("%s: Layout (%s) not (yet) supported!\n", __func__,
+		       dfu_get_layout(dfu->layout));
+	}
+
+	return ret;
+}
+
+static int dfu_flush_medium_mtd(struct dfu_entity *dfu)
+{
+	return 0;
+}
+
+static unsigned int dfu_polltimeout_mtd(struct dfu_entity *dfu)
+{
+	return DFU_DEFAULT_POLL_TIMEOUT;
+}
+
+int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr, char *s)
+{
+	char *st;
+	struct mtd_info *mtd;
+	bool has_pages;
+
+	mtd = get_mtd_device_nm(devstr);
+	if (IS_ERR_OR_NULL(mtd))
+		return -ENODEV;
+	put_mtd_device(mtd);
+
+	dfu->dev_type = DFU_DEV_MTD;
+	dfu->data.mtd.info = mtd;
+
+	has_pages = mtd->type == MTD_NANDFLASH || mtd->type == MTD_MLCNANDFLASH;
+	dfu->max_buf_size = has_pages ? mtd->erasesize : 0;
+
+	st = strsep(&s, " ");
+	if (!strcmp(st, "raw")) {
+		dfu->layout = DFU_RAW_ADDR;
+		dfu->data.mtd.start = simple_strtoul(s, &s, 16);
+		s++;
+		dfu->data.mtd.size = simple_strtoul(s, &s, 16);
+	} else {
+		printf("%s: (%s) not supported!\n", __func__, st);
+		return -1;
+	}
+
+	dfu->get_medium_size = dfu_get_medium_size_mtd;
+	dfu->read_medium = dfu_read_medium_mtd;
+	dfu->write_medium = dfu_write_medium_mtd;
+	dfu->flush_medium = dfu_flush_medium_mtd;
+	dfu->poll_timeout = dfu_polltimeout_mtd;
+
+	/* initial state */
+	dfu->inited = 0;
+
+	return 0;
+}
diff --git a/include/dfu.h b/include/dfu.h
index 7d60ffc..924952f 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -22,6 +22,7 @@ enum dfu_device_type {
 	DFU_DEV_NAND,
 	DFU_DEV_RAM,
 	DFU_DEV_SF,
+	DFU_DEV_MTD,
 };
 
 enum dfu_layout {
@@ -55,6 +56,14 @@ struct mmc_internal_data {
 	unsigned int part;
 };
 
+struct mtd_internal_data {
+	struct mtd_info *info;
+
+	/* RAW programming */
+	u64 start;
+	u64 size;
+};
+
 struct nand_internal_data {
 	/* RAW programming */
 	u64 start;
@@ -105,6 +114,7 @@ struct dfu_entity {
 
 	union {
 		struct mmc_internal_data mmc;
+		struct mtd_internal_data mtd;
 		struct nand_internal_data nand;
 		struct ram_internal_data ram;
 		struct sf_internal_data sf;
@@ -249,6 +259,17 @@ static inline int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr,
 }
 #endif
 
+#if CONFIG_IS_ENABLED(DFU_MTD)
+int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr, char *s);
+#else
+static inline int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr,
+				      char *s)
+{
+	puts("MTD support not available!\n");
+	return -1;
+}
+#endif
+
 /**
  * dfu_tftp_write - Write TFTP data to DFU medium
  *
-- 
2.7.4

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

* [U-Boot] [RFC PATCH 07/14] dfu: add partition support for MTD backend
  2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
                   ` (5 preceding siblings ...)
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 06/14] dfu: add backend for MTD device Patrick Delaunay
@ 2019-07-19 12:57 ` Patrick Delaunay
  2019-07-22  8:16   ` Lukasz Majewski
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 08/14] dfu: add DFU virtual backend Patrick Delaunay
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Patrick Delaunay @ 2019-07-19 12:57 UTC (permalink / raw)
  To: u-boot

Add the support of MTD partition for the MTD backend.

The expected dfu_alt_info for one alternate on the mtd device :
	<name> part <part_id>
        <name> partubi <part_id>

"partubi" also erase up to the end of the partition after write operation.

For example: dfu_alt_info = "spl part 1;u-boot part 2; UBI partubi 3"

U-Boot> dfu 0 mtd nand0

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 drivers/dfu/dfu_mtd.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 include/dfu.h         |  2 ++
 2 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/drivers/dfu/dfu_mtd.c b/drivers/dfu/dfu_mtd.c
index 1168a6e..223b0fe 100644
--- a/drivers/dfu/dfu_mtd.c
+++ b/drivers/dfu/dfu_mtd.c
@@ -10,6 +10,7 @@
 #include <common.h>
 #include <dfu.h>
 #include <mtd.h>
+#include <jffs2/load_kernel.h>
 
 static bool mtd_is_aligned_with_block_size(struct mtd_info *mtd, u64 size)
 {
@@ -181,11 +182,49 @@ static int dfu_write_medium_mtd(struct dfu_entity *dfu,
 
 static int dfu_flush_medium_mtd(struct dfu_entity *dfu)
 {
+	struct mtd_info *mtd = dfu->data.mtd.info;
+	int ret;
+
+	/* in case of ubi partition, erase rest of the partition */
+	if (dfu->data.nand.ubi) {
+		struct erase_info erase_op = {};
+
+		erase_op.mtd = dfu->data.mtd.info;
+		erase_op.addr = round_up(dfu->data.mtd.start + dfu->offset +
+					 dfu->bad_skip, mtd->erasesize);
+		erase_op.len = dfu->data.mtd.start + dfu->data.mtd.size -
+			       erase_op.addr;
+		erase_op.scrub = 0;
+
+		while (erase_op.len) {
+			ret = mtd_erase(mtd, &erase_op);
+			/* Abort if its not a bad block error */
+			if (ret != -EIO)
+				break;
+
+			printf("Skipping bad block at 0x%08llx\n",
+			       erase_op.fail_addr);
+
+			/* Skip bad block and continue behind it */
+			erase_op.addr = erase_op.fail_addr + mtd->erasesize;
+			erase_op.len = dfu->data.mtd.start +
+				       dfu->data.mtd.size -
+				       erase_op.addr;
+		}
+	}
 	return 0;
 }
 
 static unsigned int dfu_polltimeout_mtd(struct dfu_entity *dfu)
 {
+	/*
+	 * Currently, Poll Timeout != 0 is only needed on nand
+	 * ubi partition, as sectors which are not used need
+	 * to be erased
+	 */
+	if (dfu->data.nand.ubi)
+		return DFU_MANIFEST_POLL_TIMEOUT;
+
 	return DFU_DEFAULT_POLL_TIMEOUT;
 }
 
@@ -194,6 +233,7 @@ int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr, char *s)
 	char *st;
 	struct mtd_info *mtd;
 	bool has_pages;
+	int ret, part;
 
 	mtd = get_mtd_device_nm(devstr);
 	if (IS_ERR_OR_NULL(mtd))
@@ -212,11 +252,47 @@ int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr, char *s)
 		dfu->data.mtd.start = simple_strtoul(s, &s, 16);
 		s++;
 		dfu->data.mtd.size = simple_strtoul(s, &s, 16);
+	} else if ((!strcmp(st, "part")) || (!strcmp(st, "partubi"))) {
+		char mtd_id[32];
+		struct mtd_device *mtd_dev;
+		u8 part_num;
+		struct part_info *pi;
+
+		dfu->layout = DFU_RAW_ADDR;
+
+		part = simple_strtoul(s, &s, 10);
+
+		sprintf(mtd_id, "%s,%d", devstr, part - 1);
+		printf("using id '%s'\n", mtd_id);
+
+		mtdparts_init();
+
+		ret = find_dev_and_part(mtd_id, &mtd_dev, &part_num, &pi);
+		if (ret != 0) {
+			printf("Could not locate '%s'\n", mtd_id);
+			return -1;
+		}
+
+		dfu->data.mtd.start = pi->offset;
+		dfu->data.mtd.size = pi->size;
+		if (!strcmp(st, "partubi"))
+			dfu->data.mtd.ubi = 1;
 	} else {
-		printf("%s: (%s) not supported!\n", __func__, st);
+		printf("%s: Memory layout (%s) not supported!\n", __func__, st);
 		return -1;
 	}
 
+	if (!mtd_is_aligned_with_block_size(mtd, dfu->data.mtd.start)) {
+		printf("Offset not aligned with a block (0x%x)\n",
+		       mtd->erasesize);
+		return -EINVAL;
+	}
+	if (!mtd_is_aligned_with_block_size(mtd, dfu->data.mtd.size)) {
+		printf("Size not aligned with a block (0x%x)\n",
+		       mtd->erasesize);
+		return -EINVAL;
+	}
+
 	dfu->get_medium_size = dfu_get_medium_size_mtd;
 	dfu->read_medium = dfu_read_medium_mtd;
 	dfu->write_medium = dfu_write_medium_mtd;
diff --git a/include/dfu.h b/include/dfu.h
index 924952f..a90732c 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -62,6 +62,8 @@ struct mtd_internal_data {
 	/* RAW programming */
 	u64 start;
 	u64 size;
+	/* for ubi partition */
+	unsigned int ubi;
 };
 
 struct nand_internal_data {
-- 
2.7.4

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

* [U-Boot] [RFC PATCH 08/14] dfu: add DFU virtual backend
  2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
                   ` (6 preceding siblings ...)
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 07/14] dfu: add partition support for MTD backend Patrick Delaunay
@ 2019-07-19 12:57 ` Patrick Delaunay
  2019-07-22  8:20   ` Lukasz Majewski
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 09/14] dfu: add callback for flush and initiated operation Patrick Delaunay
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Patrick Delaunay @ 2019-07-19 12:57 UTC (permalink / raw)
  To: u-boot

Add a virtual DFU backend to allow board specific read and write
(for OTP update for example).

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 drivers/dfu/Kconfig    |  7 +++++++
 drivers/dfu/Makefile   |  1 +
 drivers/dfu/dfu.c      |  5 ++++-
 drivers/dfu/dfu_virt.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/dfu.h          | 22 ++++++++++++++++++++++
 5 files changed, 83 insertions(+), 1 deletion(-)
 create mode 100644 drivers/dfu/dfu_virt.c

diff --git a/drivers/dfu/Kconfig b/drivers/dfu/Kconfig
index ee664a3..c0e6e5d 100644
--- a/drivers/dfu/Kconfig
+++ b/drivers/dfu/Kconfig
@@ -52,5 +52,12 @@ config DFU_MTD
 	help
 	  This option enables using DFU to read and write to on any MTD device.
 
+config DFU_VIRT
+	bool "VIRTUAL flash back end for DFU"
+	help
+	  This option enables using DFU to read and write to VIRTUAL device
+	  used at board level to manage specific behavior
+	  (OTP update for example).
+
 endif
 endmenu
diff --git a/drivers/dfu/Makefile b/drivers/dfu/Makefile
index ebb119f..0d7925c 100644
--- a/drivers/dfu/Makefile
+++ b/drivers/dfu/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_$(SPL_)DFU_NAND) += dfu_nand.o
 obj-$(CONFIG_$(SPL_)DFU_RAM) += dfu_ram.o
 obj-$(CONFIG_$(SPL_)DFU_SF) += dfu_sf.o
 obj-$(CONFIG_$(SPL_)DFU_TFTP) += dfu_tftp.o
+obj-$(CONFIG_$(SPL_)DFU_VIRT) += dfu_virt.o
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index ab7fdc0..a960b6e 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -473,6 +473,9 @@ static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt,
 	} else if (strcmp(interface, "sf") == 0) {
 		if (dfu_fill_entity_sf(dfu, devstr, s))
 			return -1;
+	} else if (strcmp(interface, "virt") == 0) {
+		if (dfu_fill_entity_virt(dfu, devstr, s))
+			return -1;
 	} else {
 		printf("%s: Device %s not (yet) supported!\n",
 		       __func__,  interface);
@@ -568,7 +571,7 @@ int dfu_config_entities(char *env, char *interface, char *devstr)
 const char *dfu_get_dev_type(enum dfu_device_type t)
 {
 	const char *const dev_t[] = {NULL, "eMMC", "OneNAND", "NAND", "RAM",
-				     "SF", "MTD"};
+				     "SF", "MTD", "VIRT"};
 	return dev_t[t];
 }
 
diff --git a/drivers/dfu/dfu_virt.c b/drivers/dfu/dfu_virt.c
new file mode 100644
index 0000000..ea8c71f
--- /dev/null
+++ b/drivers/dfu/dfu_virt.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
+ */
+#include <common.h>
+#include <dfu.h>
+#include <errno.h>
+#include <malloc.h>
+
+int __weak dfu_write_medium_virt(struct dfu_entity *dfu, u64 offset,
+				 void *buf, long *len)
+{
+	debug("%s: off=0x%llx, len=0x%x\n", __func__, offset, (u32)*len);
+
+	return 0;
+}
+
+int __weak dfu_get_medium_size_virt(struct dfu_entity *dfu, u64 *size)
+{
+	*size = 0;
+
+	return 0;
+}
+
+int __weak dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset,
+				void *buf, long *len)
+{
+	debug("%s: off=0x%llx, len=0x%x\n", __func__, offset, (u32)*len);
+	*len = 0;
+
+	return 0;
+}
+
+int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr, char *s)
+{
+	debug("%s: devstr = %s\n", __func__, devstr);
+
+	dfu->dev_type = DFU_DEV_VIRT;
+	dfu->layout = DFU_RAW_ADDR;
+	dfu->data.virt.dev_num = simple_strtoul(devstr, NULL, 10);
+
+	dfu->write_medium = dfu_write_medium_virt;
+	dfu->get_medium_size = dfu_get_medium_size_virt;
+	dfu->read_medium = dfu_read_medium_virt;
+
+	dfu->inited = 0;
+
+	return 0;
+}
diff --git a/include/dfu.h b/include/dfu.h
index a90732c..4de7d35 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -23,6 +23,7 @@ enum dfu_device_type {
 	DFU_DEV_RAM,
 	DFU_DEV_SF,
 	DFU_DEV_MTD,
+	DFU_DEV_VIRT,
 };
 
 enum dfu_layout {
@@ -92,6 +93,10 @@ struct sf_internal_data {
 	unsigned int ubi;
 };
 
+struct virt_internal_data {
+	int dev_num;
+};
+
 #define DFU_NAME_SIZE			32
 #ifndef CONFIG_SYS_DFU_DATA_BUF_SIZE
 #define CONFIG_SYS_DFU_DATA_BUF_SIZE		(1024*1024*8)	/* 8 MiB */
@@ -120,6 +125,7 @@ struct dfu_entity {
 		struct nand_internal_data nand;
 		struct ram_internal_data ram;
 		struct sf_internal_data sf;
+		struct virt_internal_data virt;
 	} data;
 
 	int (*get_medium_size)(struct dfu_entity *dfu, u64 *size);
@@ -272,6 +278,22 @@ static inline int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr,
 }
 #endif
 
+#ifdef CONFIG_DFU_VIRT
+int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr, char *s);
+int dfu_write_medium_virt(struct dfu_entity *dfu, u64 offset,
+			  void *buf, long *len);
+int dfu_get_medium_size_virt(struct dfu_entity *dfu, u64 *size);
+int dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset,
+			 void *buf, long *len);
+#else
+static inline int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr,
+				       char *s)
+{
+	puts("VIRT support not available!\n");
+	return -1;
+}
+#endif
+
 /**
  * dfu_tftp_write - Write TFTP data to DFU medium
  *
-- 
2.7.4

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

* [U-Boot] [RFC PATCH 09/14] dfu: add callback for flush and initiated operation
  2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
                   ` (7 preceding siblings ...)
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 08/14] dfu: add DFU virtual backend Patrick Delaunay
@ 2019-07-19 12:57 ` Patrick Delaunay
  2019-07-22  8:22   ` Lukasz Majewski
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 10/14] stm32mp1: activate DFU support and command MTD Patrick Delaunay
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Patrick Delaunay @ 2019-07-19 12:57 UTC (permalink / raw)
  To: u-boot

Add weak callback to allow board specific behavior
- flush
- initiated

This patch prepare usage of DFU back end for communication with
STM32CubeProgrammer on stm32mp1 platform with stm32prog command.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 drivers/dfu/dfu.c | 19 +++++++++++++++++++
 include/dfu.h     |  2 ++
 2 files changed, 21 insertions(+)

diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index a960b6e..e642b09 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -22,6 +22,22 @@ static int alt_num_cnt;
 static struct hash_algo *dfu_hash_algo;
 
 /*
+ * The purpose of the dfu_flush_callback() function is to
+ * provide callback for dfu user
+ */
+__weak void dfu_flush_callback(struct dfu_entity *dfu)
+{
+}
+
+/*
+ * The purpose of the dfu_flush_callback() function is to
+ * provide callback for dfu user
+ */
+__weak void dfu_initiated_callback(struct dfu_entity *dfu)
+{
+}
+
+/*
  * The purpose of the dfu_usb_get_reset() function is to
  * provide information if after USB_DETACH request
  * being sent the dfu-util performed reset of USB
@@ -262,6 +278,7 @@ int dfu_transaction_initiate(struct dfu_entity *dfu, bool read)
 	}
 
 	dfu->inited = 1;
+	dfu_initiated_callback(dfu);
 
 	return 0;
 }
@@ -281,6 +298,8 @@ int dfu_flush(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
 		printf("\nDFU complete %s: 0x%08x\n", dfu_hash_algo->name,
 		       dfu->crc);
 
+	dfu_flush_callback(dfu);
+
 	dfu_transaction_cleanup(dfu);
 
 	return ret;
diff --git a/include/dfu.h b/include/dfu.h
index 4de7d35..5d85cc3 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -182,6 +182,8 @@ bool dfu_usb_get_reset(void);
 int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
 int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
 int dfu_flush(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
+void dfu_flush_callback(struct dfu_entity *dfu);
+void dfu_initiated_callback(struct dfu_entity *dfu);
 
 /*
  * dfu_defer_flush - pointer to store dfu_entity for deferred flashing.
-- 
2.7.4

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

* [U-Boot] [RFC PATCH 10/14] stm32mp1: activate DFU support and command MTD
  2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
                   ` (8 preceding siblings ...)
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 09/14] dfu: add callback for flush and initiated operation Patrick Delaunay
@ 2019-07-19 12:57 ` Patrick Delaunay
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 11/14] stm32mp1: activate SET_DFU_ALT_INFO Patrick Delaunay
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Patrick Delaunay @ 2019-07-19 12:57 UTC (permalink / raw)
  To: u-boot

Add support of DFU for MMC, MTD, RAM and MTD command.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 configs/stm32mp15_basic_defconfig   | 4 ++++
 configs/stm32mp15_trusted_defconfig | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig
index 4aa184f..3f1cc49 100644
--- a/configs/stm32mp15_basic_defconfig
+++ b/configs/stm32mp15_basic_defconfig
@@ -29,6 +29,7 @@ CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_MTD=y
 CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_USB=y
@@ -53,6 +54,9 @@ CONFIG_ENV_EXT4_FILE="/uboot.env"
 CONFIG_ENV_UBI_PART="UBI"
 CONFIG_ENV_UBI_VOLUME="uboot_config"
 CONFIG_STM32_ADC=y
+CONFIG_DFU_MMC=y
+CONFIG_DFU_RAM=y
+CONFIG_DFU_MTD=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0xC0000000
 CONFIG_FASTBOOT_BUF_SIZE=0x02000000
diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig
index 5fe9477..5eb9a8c 100644
--- a/configs/stm32mp15_trusted_defconfig
+++ b/configs/stm32mp15_trusted_defconfig
@@ -22,6 +22,7 @@ CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_MTD=y
 CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_USB=y
@@ -45,6 +46,9 @@ CONFIG_ENV_EXT4_FILE="/uboot.env"
 CONFIG_ENV_UBI_PART="UBI"
 CONFIG_ENV_UBI_VOLUME="uboot_config"
 CONFIG_STM32_ADC=y
+CONFIG_DFU_MMC=y
+CONFIG_DFU_RAM=y
+CONFIG_DFU_MTD=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0xC0000000
 CONFIG_FASTBOOT_BUF_SIZE=0x02000000
-- 
2.7.4

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

* [U-Boot] [RFC PATCH 11/14] stm32mp1: activate SET_DFU_ALT_INFO
  2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
                   ` (9 preceding siblings ...)
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 10/14] stm32mp1: activate DFU support and command MTD Patrick Delaunay
@ 2019-07-19 12:57 ` Patrick Delaunay
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 12/14] stp32mp1: configs: activate CONFIG_MTD_SPI_NAND Patrick Delaunay
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Patrick Delaunay @ 2019-07-19 12:57 UTC (permalink / raw)
  To: u-boot

Generate automatically dfu_alt_info for the supported device.
The simple command "dfu 0" allows to start the dfu stack on usb 0
for the supported devices:
- dfu mtd for nand0
- dfu mtd for nor0
- dfu mmc for SDCard
- dfu mmc for eMMC
- dfu ram for images in DDR

The DUF alternate use the "part", "partubi" and "mmcpart" options
to select the correct MTD or GPT partition or the eMMC hw boot partition.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 board/st/stm32mp1/README     | 111 +++++++++++++++++++++++++++++++++++++++++++
 board/st/stm32mp1/stm32mp1.c |  51 ++++++++++++++++++++
 include/configs/stm32mp1.h   |  32 +++++++++++++
 3 files changed, 194 insertions(+)

diff --git a/board/st/stm32mp1/README b/board/st/stm32mp1/README
index b0c8325..eed3f95 100644
--- a/board/st/stm32mp1/README
+++ b/board/st/stm32mp1/README
@@ -334,3 +334,114 @@ on bank 0 to access to internal OTP:
     4 check env update
        STM32MP> print ethaddr
        ethaddr=12:34:56:78:9a:bc
+
+10. DFU support
+===============
+
+The DFU is supported on ST board.
+The env variable dfu_alt_info is automatically build, and all
+the memory present on the ST boards are exported.
+
+The mode is started by
+
+STM32MP> dfu 0
+
+On EV1 board:
+
+STM32MP> dfu 0 list
+
+DFU alt settings list:
+dev: RAM alt: 0 name: uImage layout: RAM_ADDR
+dev: RAM alt: 1 name: devicetree.dtb layout: RAM_ADDR
+dev: RAM alt: 2 name: uramdisk.image.gz layout: RAM_ADDR
+dev: eMMC alt: 3 name: sdcard_fsbl1 layout: RAW_ADDR
+dev: eMMC alt: 4 name: sdcard_fsbl2 layout: RAW_ADDR
+dev: eMMC alt: 5 name: sdcard_ssbl layout: RAW_ADDR
+dev: eMMC alt: 6 name: sdcard_bootfs layout: RAW_ADDR
+dev: eMMC alt: 7 name: sdcard_vendorfs layout: RAW_ADDR
+dev: eMMC alt: 8 name: sdcard_rootfs layout: RAW_ADDR
+dev: eMMC alt: 9 name: sdcard_userfs layout: RAW_ADDR
+dev: eMMC alt: 10 name: emmc_fsbl1 layout: RAW_ADDR
+dev: eMMC alt: 11 name: emmc_fsbl2 layout: RAW_ADDR
+dev: eMMC alt: 12 name: emmc_ssbl layout: RAW_ADDR
+dev: eMMC alt: 13 name: emmc_bootfs layout: RAW_ADDR
+dev: eMMC alt: 14 name: emmc_vendorfs layout: RAW_ADDR
+dev: eMMC alt: 15 name: emmc_rootfs layout: RAW_ADDR
+dev: eMMC alt: 16 name: emmc_userfs layout: RAW_ADDR
+dev: MTD alt: 17 name: nor_fsbl1 layout: RAW_ADDR
+dev: MTD alt: 18 name: nor_fsbl2 layout: RAW_ADDR
+dev: MTD alt: 19 name: nor_ssbl layout: RAW_ADDR
+dev: MTD alt: 20 name: nor_env layout: RAW_ADDR
+dev: MTD alt: 21 name: nand_fsbl layout: RAW_ADDR
+dev: MTD alt: 22 name: nand_ssbl1 layout: RAW_ADDR
+dev: MTD alt: 23 name: nand_ssbl2 layout: RAW_ADDR
+dev: MTD alt: 24 name: nand_UBI layout: RAW_ADDR
+dev: VIRT alt: 25 name: OTP layout: RAW_ADDR
+dev: VIRT alt: 26 name: PMIC layout: RAW_ADDR
+
+All the supported device are exported for dfu-util tool:
+
+$> dfu-util -l
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=26, name="PMIC", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=25, name="OTP", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=24, name="nand_UBI", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=23, name="nand_ssbl2", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=22, name="nand_ssbl1", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=21, name="nand_fsbl", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=20, name="nor_env", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=19, name="nor_ssbl", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=18, name="nor_fsbl2", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=17, name="nor_fsbl1", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=16, name="emmc_userfs", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=15, name="emmc_rootfs", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=14, name="emmc_vendorfs", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=13, name="emmc_bootfs", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=12, name="emmc_ssbl", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=11, name="emmc_fsbl2", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=10, name="emmc_fsbl1", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=9, name="sdcard_userfs", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=8, name="sdcard_rootfs", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=7, name="sdcard_vendorfs", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=6, name="sdcard_bootfs", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=5, name="sdcard_ssbl", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=4, name="sdcard_fsbl2", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=3, name="sdcard_fsbl1", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=2, name="uramdisk.image.gz", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=1, name="devicetree.dtb", serial="002700333338511934383330"
+Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=0, name="uImage", serial="002700333338511934383330"
+
+You can update the boot device:
+
+#SDCARD
+$> dfu-util -d 0483:5720 -a 3 -D tf-a-stm32mp157c-ev1-trusted.stm32
+$> dfu-util -d 0483:5720 -a 4 -D tf-a-stm32mp157c-ev1-trusted.stm32
+$> dfu-util -d 0483:5720 -a 5 -D u-boot-stm32mp157c-ev1-trusted.img
+$> dfu-util -d 0483:5720 -a 6 -D st-image-bootfs-openstlinux-weston-stm32mp1.ext4
+$> dfu-util -d 0483:5720 -a 7 -D st-image-vendorfs-openstlinux-weston-stm32mp1.ext4
+$> dfu-util -d 0483:5720 -a 8 -D st-image-weston-openstlinux-weston-stm32mp1.ext4
+$> dfu-util -d 0483:5720 -a 9 -D st-image-userfs-openstlinux-weston-stm32mp1.ext4
+
+#EMMC
+$> dfu-util -d 0483:5720 -a 10 -D tf-a-stm32mp157c-ev1-trusted.stm32
+$> dfu-util -d 0483:5720 -a 11 -D tf-a-stm32mp157c-ev1-trusted.stm32
+$> dfu-util -d 0483:5720 -a 12 -D u-boot-stm32mp157c-ev1-trusted.img
+$> dfu-util -d 0483:5720 -a 13 -D st-image-bootfs-openstlinux-weston-stm32mp1.ext4
+$> dfu-util -d 0483:5720 -a 14 -D st-image-vendorfs-openstlinux-weston-stm32mp1.ext4
+$> dfu-util -d 0483:5720 -a 15 -D st-image-weston-openstlinux-weston-stm32mp1.ext4
+$> dfu-util -d 0483:5720 -a 16 -D st-image-userfs-openstlinux-weston-stm32mp1.ext4
+
+#NOR
+$> dfu-util -d 0483:5720 -a 17 -D tf-a-stm32mp157c-ev1-trusted.stm32
+$> dfu-util -d 0483:5720 -a 18 -D tf-a-stm32mp157c-ev1-trusted.stm32
+$> dfu-util -d 0483:5720 -a 19 -D u-boot-stm32mp157c-ev1-trusted.img
+
+#NAND (UBI partition used for NAND only boot or NOR + NAND boot)
+$> dfu-util -d 0483:5720 -a 21 -D tf-a-stm32mp157c-ev1-trusted.stm32
+$> dfu-util -d 0483:5720 -a 22 -D u-boot-stm32mp157c-ev1-trusted.img
+$> dfu-util -d 0483:5720 -a 23 -D u-boot-stm32mp157c-ev1-trusted.img
+$> dfu-util -d 0483:5720 -a 24 -D st-image-weston-openstlinux-weston-stm32mp1_nand_4_256_multivolume.ubi
+
+And you can also dump the OTP and the PMIC NVM with:
+
+$> dfu-util -d 0483:5720 -a 25 -U otp.bin
+$> dfu-util -d 0483:5720 -a 26 -U pmic.bin
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index b1e592c..7656c66 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -12,6 +12,7 @@
 #include <generic-phy.h>
 #include <i2c.h>
 #include <led.h>
+#include <memalign.h>
 #include <misc.h>
 #include <phy.h>
 #include <reset.h>
@@ -745,3 +746,53 @@ void board_mtdparts_default(const char **mtdids, const char **mtdparts)
 	debug("%s:mtdids=%s & mtdparts=%s\n", __func__, ids, parts);
 }
 #endif
+
+#ifdef CONFIG_SET_DFU_ALT_INFO
+#define DFU_ALT_BUF_LEN SZ_1K
+
+static void board_get_alt_info(const char *dev, char *buff)
+{
+	char var_name[32] = "dfu_alt_info_";
+	int ret;
+
+	ALLOC_CACHE_ALIGN_BUFFER(char, tmp_alt, DFU_ALT_BUF_LEN);
+
+	/* name of env variable to read = dfu_alt_info_<dev> */
+	strcat(var_name, dev);
+	ret = env_get_f(var_name, tmp_alt, DFU_ALT_BUF_LEN);
+	if (ret) {
+		if (buff[0] != '\0')
+			strcat(buff, "&");
+		strncat(buff, tmp_alt, DFU_ALT_BUF_LEN);
+	}
+}
+
+void set_dfu_alt_info(char *interface, char *devstr)
+{
+	struct udevice *dev;
+
+	ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
+
+	if (env_get("dfu_alt_info"))
+		return;
+
+	memset(buf, 0, sizeof(buf));
+
+	board_get_alt_info("ram", buf);
+
+	if (!uclass_get_device(UCLASS_MMC, 0, &dev))
+		board_get_alt_info("mmc0", buf);
+
+	if (!uclass_get_device(UCLASS_MMC, 1, &dev))
+		board_get_alt_info("mmc1", buf);
+
+	if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev))
+		board_get_alt_info("nor0", buf);
+
+	if (!uclass_get_device(UCLASS_MTD, 0, &dev))
+		board_get_alt_info("nand0", buf);
+
+	env_set("dfu_alt_info", buf);
+	puts("DFU alt info setting: done\n");
+}
+#endif
diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h
index 1d385e0..27b2bdb 100644
--- a/include/configs/stm32mp1.h
+++ b/include/configs/stm32mp1.h
@@ -85,6 +85,8 @@
 #define CONFIG_SYS_AUTOLOAD		"no"
 #endif
 
+#define CONFIG_SET_DFU_ALT_INFO
+
 /*****************************************************************************/
 #ifdef CONFIG_DISTRO_DEFAULTS
 /*****************************************************************************/
@@ -129,6 +131,34 @@
 	"mtdparts_nor0=256k(fsbl1),256k(fsbl2),2m(ssbl),256k(u-boot-env),-(nor_user)\0" \
 	"mtdparts_nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),-(UBI)\0"
 
+#define STM32MP_DFU_ALT_RAM \
+	"dfu_alt_info_ram=ram 0=" \
+		"uImage ram ${kernel_addr_r} 0x2000000;" \
+		"devicetree.dtb ram ${fdt_addr_r} 0x100000;" \
+		"uramdisk.image.gz ram ${ramdisk_addr_r} 0x10000000\0"
+
+#ifdef CONFIG_SET_DFU_ALT_INFO
+#define STM32MP_DFU_ALT_INFO \
+	"dfu_alt_info_nor0=mtd nor0=" \
+		"nor_fsbl1 part 1;nor_fsbl2 part 2;" \
+		"nor_ssbl part 3;nor_env part 4\0" \
+	"dfu_alt_info_nand0=mtd nand0="\
+		"nand_fsbl part 1;nand_ssbl1 part 2;" \
+		"nand_ssbl2 part 3;nand_UBI partubi 4\0" \
+	"dfu_alt_info_mmc0=mmc 0=" \
+		"sdcard_fsbl1 part 0 1;sdcard_fsbl2 part 0 2;" \
+		"sdcard_ssbl part 0 3;sdcard_bootfs part 0 4;" \
+		"sdcard_vendorfs part 0 5;sdcard_rootfs part 0 6;" \
+		"sdcard_userfs part 0 7\0" \
+	"dfu_alt_info_mmc1=mmc 1=" \
+		"emmc_fsbl1 raw 0x0 0x200 mmcpart 1;" \
+		"emmc_fsbl2 raw 0x0 0x200 mmcpart 2;emmc_ssbl part 1 1;" \
+		"emmc_bootfs part 1 2;emmc_vendorfs part 1 3;" \
+		"emmc_rootfs part 1 4;emmc_userfs part 1 5\0"
+#else
+#define STM32MP_DFU_ALT_INFO
+#endif
+
 /*
  * memory layout for 32M uncompressed/compressed kernel,
  * 1M fdt, 1M script, 1M pxe and 1M for splashimage
@@ -145,6 +175,8 @@
 	"initrd_high=0xffffffff\0" \
 	STM32MP_BOOTCMD \
 	STM32MP_MTDPARTS \
+	STM32MP_DFU_ALT_RAM \
+	STM32MP_DFU_ALT_INFO \
 	BOOTENV
 
 #endif /* ifndef CONFIG_SPL_BUILD */
-- 
2.7.4

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

* [U-Boot] [RFC PATCH 12/14] stp32mp1: configs: activate CONFIG_MTD_SPI_NAND
  2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
                   ` (10 preceding siblings ...)
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 11/14] stm32mp1: activate SET_DFU_ALT_INFO Patrick Delaunay
@ 2019-07-19 12:57 ` Patrick Delaunay
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 13/14] stm32mp1: board: add spi nand support Patrick Delaunay
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Patrick Delaunay @ 2019-07-19 12:57 UTC (permalink / raw)
  To: u-boot

Activate the support of SPI NAND in stm32mp1 U-Boot.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 configs/stm32mp15_basic_defconfig   | 1 +
 configs/stm32mp15_trusted_defconfig | 1 +
 2 files changed, 2 insertions(+)

diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig
index 3f1cc49..4728376 100644
--- a/configs/stm32mp15_basic_defconfig
+++ b/configs/stm32mp15_basic_defconfig
@@ -75,6 +75,7 @@ CONFIG_STM32_SDMMC2=y
 CONFIG_MTD=y
 CONFIG_NAND=y
 CONFIG_NAND_STM32_FMC2=y
+CONFIG_MTD_SPI_NAND=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig
index 5eb9a8c..0d9e13e 100644
--- a/configs/stm32mp15_trusted_defconfig
+++ b/configs/stm32mp15_trusted_defconfig
@@ -67,6 +67,7 @@ CONFIG_STM32_SDMMC2=y
 CONFIG_MTD=y
 CONFIG_NAND=y
 CONFIG_NAND_STM32_FMC2=y
+CONFIG_MTD_SPI_NAND=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
-- 
2.7.4

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

* [U-Boot] [RFC PATCH 13/14] stm32mp1: board: add spi nand support
  2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
                   ` (11 preceding siblings ...)
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 12/14] stp32mp1: configs: activate CONFIG_MTD_SPI_NAND Patrick Delaunay
@ 2019-07-19 12:57 ` Patrick Delaunay
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 14/14] stm32mp1: add support for virtual partition read Patrick Delaunay
  2019-07-22  8:27 ` [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Lukasz Majewski
  14 siblings, 0 replies; 25+ messages in thread
From: Patrick Delaunay @ 2019-07-19 12:57 UTC (permalink / raw)
  To: u-boot

This patch adds the support of the spi nand device in mtdparts command
and in dfu_alt_info.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 board/st/stm32mp1/stm32mp1.c | 33 ++++++++++++++++++++++++++++++---
 include/configs/stm32mp1.h   |  6 +++++-
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 7656c66..68bd06c 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -14,6 +14,7 @@
 #include <led.h>
 #include <memalign.h>
 #include <misc.h>
+#include <mtd.h>
 #include <phy.h>
 #include <reset.h>
 #include <syscon.h>
@@ -720,8 +721,9 @@ static void board_get_mtdparts(const char *dev,
 
 void board_mtdparts_default(const char **mtdids, const char **mtdparts)
 {
+	struct mtd_info *mtd;
 	struct udevice *dev;
-	static char parts[2 * MTDPARTS_LEN + 1];
+	static char parts[3 * MTDPARTS_LEN + 1];
 	static char ids[MTDIDS_LEN + 1];
 	static bool mtd_initialized;
 
@@ -734,8 +736,24 @@ void board_mtdparts_default(const char **mtdids, const char **mtdparts)
 	memset(parts, 0, sizeof(parts));
 	memset(ids, 0, sizeof(ids));
 
-	if (!uclass_get_device(UCLASS_MTD, 0, &dev))
+	/* probe all MTD devices */
+	for (uclass_first_device(UCLASS_MTD, &dev);
+	     dev;
+	     uclass_next_device(&dev)) {
+		pr_debug("mtd device = %s\n", dev->name);
+	}
+
+	mtd = get_mtd_device_nm("nand0");
+	if (!IS_ERR_OR_NULL(mtd)) {
 		board_get_mtdparts("nand0", ids, parts);
+		put_mtd_device(mtd);
+	}
+
+	mtd = get_mtd_device_nm("spi-nand0");
+	if (!IS_ERR_OR_NULL(mtd)) {
+		board_get_mtdparts("spi-nand0", ids, parts);
+		put_mtd_device(mtd);
+	}
 
 	if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev))
 		board_get_mtdparts("nor0", ids, parts);
@@ -770,6 +788,7 @@ static void board_get_alt_info(const char *dev, char *buff)
 void set_dfu_alt_info(char *interface, char *devstr)
 {
 	struct udevice *dev;
+	struct mtd_info *mtd;
 
 	ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
 
@@ -778,6 +797,9 @@ void set_dfu_alt_info(char *interface, char *devstr)
 
 	memset(buf, 0, sizeof(buf));
 
+	/* probe all MTD devices */
+	mtd_probe_devices();
+
 	board_get_alt_info("ram", buf);
 
 	if (!uclass_get_device(UCLASS_MMC, 0, &dev))
@@ -789,9 +811,14 @@ void set_dfu_alt_info(char *interface, char *devstr)
 	if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev))
 		board_get_alt_info("nor0", buf);
 
-	if (!uclass_get_device(UCLASS_MTD, 0, &dev))
+	mtd = get_mtd_device_nm("nand0");
+	if (!IS_ERR_OR_NULL(mtd))
 		board_get_alt_info("nand0", buf);
 
+	mtd = get_mtd_device_nm("spi-nand0");
+	if (!IS_ERR_OR_NULL(mtd))
+		board_get_alt_info("spi-nand0", buf);
+
 	env_set("dfu_alt_info", buf);
 	puts("DFU alt info setting: done\n");
 }
diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h
index 27b2bdb..6dcf0e2 100644
--- a/include/configs/stm32mp1.h
+++ b/include/configs/stm32mp1.h
@@ -129,7 +129,8 @@
 
 #define STM32MP_MTDPARTS \
 	"mtdparts_nor0=256k(fsbl1),256k(fsbl2),2m(ssbl),256k(u-boot-env),-(nor_user)\0" \
-	"mtdparts_nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),-(UBI)\0"
+	"mtdparts_nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),-(UBI)\0" \
+	"mtdparts_spi-nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),-(UBI)\0"
 
 #define STM32MP_DFU_ALT_RAM \
 	"dfu_alt_info_ram=ram 0=" \
@@ -145,6 +146,9 @@
 	"dfu_alt_info_nand0=mtd nand0="\
 		"nand_fsbl part 1;nand_ssbl1 part 2;" \
 		"nand_ssbl2 part 3;nand_UBI partubi 4\0" \
+	"dfu_alt_info_spi-nand0=mtd spi-nand0="\
+		"spi-nand_fsbl part 1;spi-nand_ssbl1 part 2;" \
+		"spi-nand_ssbl2 part 3;spi-nand_UBI partubi 4\0" \
 	"dfu_alt_info_mmc0=mmc 0=" \
 		"sdcard_fsbl1 part 0 1;sdcard_fsbl2 part 0 2;" \
 		"sdcard_ssbl part 0 3;sdcard_bootfs part 0 4;" \
-- 
2.7.4

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

* [U-Boot] [RFC PATCH 14/14] stm32mp1: add support for virtual partition read
  2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
                   ` (12 preceding siblings ...)
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 13/14] stm32mp1: board: add spi nand support Patrick Delaunay
@ 2019-07-19 12:57 ` Patrick Delaunay
  2019-07-22  8:27 ` [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Lukasz Majewski
  14 siblings, 0 replies; 25+ messages in thread
From: Patrick Delaunay @ 2019-07-19 12:57 UTC (permalink / raw)
  To: u-boot

Add read for OTP and PMIC NVM with alternates
on virtual DFU device.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
# Conflicts:
#	board/st/stm32mp1/stm32mp1.c

---

 board/st/stm32mp1/stm32mp1.c        | 83 +++++++++++++++++++++++++++++++++++++
 configs/stm32mp15_basic_defconfig   |  1 +
 configs/stm32mp15_trusted_defconfig |  1 +
 3 files changed, 85 insertions(+)

diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 68bd06c..4d5cd70 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -819,7 +819,90 @@ void set_dfu_alt_info(char *interface, char *devstr)
 	if (!IS_ERR_OR_NULL(mtd))
 		board_get_alt_info("spi-nand0", buf);
 
+#ifdef CONFIG_DFU_VIRT
+	strncat(buf, "&virt 0=OTP", DFU_ALT_BUF_LEN);
+
+	if (IS_ENABLED(CONFIG_PMIC_STPMIC1))
+		strncat(buf, "&virt 1=PMIC", DFU_ALT_BUF_LEN);
+#endif
+
 	env_set("dfu_alt_info", buf);
 	puts("DFU alt info setting: done\n");
 }
+
+#if CONFIG_IS_ENABLED(DFU_VIRT)
+#include <dfu.h>
+#include <power/stpmic1.h>
+
+int dfu_otp_read(u64 offset, u8 *buffer, long *size)
+{
+	struct udevice *dev;
+	int ret;
+
+	ret = uclass_get_device_by_driver(UCLASS_MISC,
+					  DM_GET_DRIVER(stm32mp_bsec),
+					  &dev);
+	if (ret)
+		return ret;
+
+	ret = misc_read(dev, offset + STM32_BSEC_OTP_OFFSET, buffer, *size);
+	if (ret >= 0) {
+		*size = ret;
+		ret = 0;
+	}
+
+	return 0;
+}
+
+int dfu_pmic_read(u64 offset, u8 *buffer, long *size)
+{
+	int ret;
+#ifdef CONFIG_PMIC_STPMIC1
+	struct udevice *dev;
+
+	ret = uclass_get_device_by_driver(UCLASS_MISC,
+					  DM_GET_DRIVER(stpmic1_nvm),
+					  &dev);
+	if (ret)
+		return ret;
+
+	ret = misc_read(dev, 0xF8 + offset, buffer, *size);
+	if (ret >= 0) {
+		*size = ret;
+		ret = 0;
+	}
+	if (ret == -EACCES) {
+		*size = 0;
+		ret = 0;
+	}
+#else
+	pr_err("PMIC update not supported");
+	ret = -EOPNOTSUPP;
+#endif
+
+	return ret;
+}
+
+int dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset,
+			 void *buf, long *len)
+{
+	switch (dfu->data.virt.dev_num) {
+	case 0x0:
+		return dfu_otp_read(offset, buf, len);
+	case 0x1:
+		return dfu_pmic_read(offset, buf, len);
+	}
+	*len = 0;
+	return 0;
+}
+
+int __weak dfu_get_medium_size_virt(struct dfu_entity *dfu, u64 *size)
+{
+	*size = SZ_1K;
+
+	return 0;
+}
+
+#endif
+
 #endif
diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig
index 4728376..ba7b2f6 100644
--- a/configs/stm32mp15_basic_defconfig
+++ b/configs/stm32mp15_basic_defconfig
@@ -57,6 +57,7 @@ CONFIG_STM32_ADC=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_MTD=y
+CONFIG_DFU_VIRT=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0xC0000000
 CONFIG_FASTBOOT_BUF_SIZE=0x02000000
diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig
index 0d9e13e..25d9e4f 100644
--- a/configs/stm32mp15_trusted_defconfig
+++ b/configs/stm32mp15_trusted_defconfig
@@ -49,6 +49,7 @@ CONFIG_STM32_ADC=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_MTD=y
+CONFIG_DFU_VIRT=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0xC0000000
 CONFIG_FASTBOOT_BUF_SIZE=0x02000000
-- 
2.7.4

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

* [U-Boot] [RFC PATCH 01/14] dfu: cosmetic: cleanup sf to avoid checkpatch error
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 01/14] dfu: cosmetic: cleanup sf to avoid checkpatch error Patrick Delaunay
@ 2019-07-22  7:51   ` Lukasz Majewski
  0 siblings, 0 replies; 25+ messages in thread
From: Lukasz Majewski @ 2019-07-22  7:51 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
> 
>  drivers/dfu/dfu.c    | 7 ++++---
>  drivers/dfu/dfu_sf.c | 4 ++--
>  2 files changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
> index 3189495..eb3a3c6 100644
> --- a/drivers/dfu/dfu.c
> +++ b/drivers/dfu/dfu.c
> @@ -477,14 +477,15 @@ int dfu_config_entities(char *env, char
> *interface, char *devstr) 
>  const char *dfu_get_dev_type(enum dfu_device_type t)
>  {
> -	const char *dev_t[] = {NULL, "eMMC", "OneNAND", "NAND",
> "RAM", "SF" };
> +	const char *const dev_t[] = {NULL, "eMMC", "OneNAND",
> "NAND", "RAM",
> +				     "SF"};
>  	return dev_t[t];
>  }
>  
>  const char *dfu_get_layout(enum dfu_layout l)
>  {
> -	const char *dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT2",
> -					   "EXT3", "EXT4",
> "RAM_ADDR" };
> +	const char *const dfu_layout[] = {NULL, "RAW_ADDR", "FAT",
> "EXT2",
> +					  "EXT3", "EXT4",
> "RAM_ADDR" }; return dfu_layout[l];
>  }
>  
> diff --git a/drivers/dfu/dfu_sf.c b/drivers/dfu/dfu_sf.c
> index 066e767..b78fcfd 100644
> --- a/drivers/dfu/dfu_sf.c
> +++ b/drivers/dfu/dfu_sf.c
> @@ -19,7 +19,7 @@ static int dfu_get_medium_size_sf(struct dfu_entity
> *dfu, u64 *size) }
>  
>  static int dfu_read_medium_sf(struct dfu_entity *dfu, u64 offset,
> void *buf,
> -		long *len)
> +			      long *len)
>  {
>  	return spi_flash_read(dfu->data.sf.dev, dfu->data.sf.start +
> offset, *len, buf);
> @@ -32,7 +32,7 @@ static u64 find_sector(struct dfu_entity *dfu, u64
> start, u64 offset) }
>  
>  static int dfu_write_medium_sf(struct dfu_entity *dfu,
> -		u64 offset, void *buf, long *len)
> +			       u64 offset, void *buf, long *len)
>  {
>  	int ret;
>  

Thanks for fixing this.

Acked-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190722/70d707cf/attachment.sig>

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

* [U-Boot] [RFC PATCH 02/14] dfu: sf: add partition support for nor backend
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 02/14] dfu: sf: add partition support for nor backend Patrick Delaunay
@ 2019-07-22  7:54   ` Lukasz Majewski
  0 siblings, 0 replies; 25+ messages in thread
From: Lukasz Majewski @ 2019-07-22  7:54 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

> Copy the partition support from NAND backend to SF,
> support part and partubi option.
> In case of ubi partition, erase the rest of the
> partition as it is mandatory for UBI.
> 
> for example:
> 
> U-Boot> env set dfu_alt_info "spl part 0 1;\
> u-boot part 0 2;u-boot-env part 0 3;UBI partubi 0 4"
> U-Boot> dfu 0 sf 0:0:10000000:0
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
> 
>  drivers/dfu/dfu_sf.c | 51
> +++++++++++++++++++++++++++++++++++++++++++++++++++
> include/dfu.h        |  2 ++ 2 files changed, 53 insertions(+)
> 
> diff --git a/drivers/dfu/dfu_sf.c b/drivers/dfu/dfu_sf.c
> index b78fcfd..d401b76 100644
> --- a/drivers/dfu/dfu_sf.c
> +++ b/drivers/dfu/dfu_sf.c
> @@ -10,6 +10,8 @@
>  #include <dfu.h>
>  #include <spi.h>
>  #include <spi_flash.h>
> +#include <jffs2/load_kernel.h>
> +#include <linux/mtd/mtd.h>
>  
>  static int dfu_get_medium_size_sf(struct dfu_entity *dfu, u64 *size)
>  {
> @@ -52,11 +54,33 @@ static int dfu_write_medium_sf(struct dfu_entity
> *dfu, 
>  static int dfu_flush_medium_sf(struct dfu_entity *dfu)
>  {
> +	u64 off, length;
> +
> +	if (!dfu->data.sf.ubi)
> +		return 0;
> +
> +	/* in case of ubi partition, erase rest of the partition */
> +	off = find_sector(dfu, dfu->data.sf.start, dfu->offset);
> +	/* last write ended with unaligned length jump to next */
> +	if (off != dfu->data.sf.start + dfu->offset)
> +		off += dfu->data.sf.dev->sector_size;
> +	length = dfu->data.sf.start + dfu->data.sf.size - off;
> +	if (length)
> +		return spi_flash_erase(dfu->data.sf.dev, off,
> length); +
>  	return 0;
>  }
>  
>  static unsigned int dfu_polltimeout_sf(struct dfu_entity *dfu)
>  {
> +	/*
> +	 * Currently, Poll Timeout != 0 is only needed on nand
							  ^^^^^ -
							  please update
							  the comment 

> +	 * ubi partition, as sectors which are not used need
> +	 * to be erased
> +	 */
> +	if (dfu->data.sf.ubi)
> +		return DFU_MANIFEST_POLL_TIMEOUT;
> +
>  	return DFU_DEFAULT_POLL_TIMEOUT;
>  }
>  
> @@ -133,6 +157,33 @@ int dfu_fill_entity_sf(struct dfu_entity *dfu,
> char *devstr, char *s) dfu->data.sf.start = simple_strtoul(s, &s, 16);
>  		s++;
>  		dfu->data.sf.size = simple_strtoul(s, &s, 16);
> +	} else if ((!strcmp(st, "part")) || (!strcmp(st,
> "partubi"))) {
> +		char mtd_id[32];
> +		struct mtd_device *mtd_dev;
> +		u8 part_num;
> +		struct part_info *pi;
> +		int ret, dev, part;
> +
> +		dfu->layout = DFU_RAW_ADDR;
> +
> +		dev = simple_strtoul(s, &s, 10);
> +		s++;
> +		part = simple_strtoul(s, &s, 10);
> +
> +		sprintf(mtd_id, "%s%d,%d", "nor", dev, part - 1);
> +		printf("using id '%s'\n", mtd_id);
> +
> +		mtdparts_init();
> +
> +		ret = find_dev_and_part(mtd_id, &mtd_dev, &part_num,
> &pi);
> +		if (ret != 0) {
> +			printf("Could not locate '%s'\n", mtd_id);
> +			return -1;
> +		}
> +		dfu->data.sf.start = pi->offset;
> +		dfu->data.sf.size = pi->size;
> +		if (!strcmp(st, "partubi"))
> +			dfu->data.sf.ubi = 1;
>  	} else {
>  		printf("%s: Memory layout (%s) not supported!\n",
> __func__, st); spi_flash_free(dfu->data.sf.dev);
> diff --git a/include/dfu.h b/include/dfu.h
> index 145a157..bf51ab7 100644
> --- a/include/dfu.h
> +++ b/include/dfu.h
> @@ -77,6 +77,8 @@ struct sf_internal_data {
>  	/* RAW programming */
>  	u64 start;
>  	u64 size;
> +	/* for sf/ubi use */
> +	unsigned int ubi;
>  };
>  
>  #define DFU_NAME_SIZE			32




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190722/2893727c/attachment-0001.sig>

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

* [U-Boot] [RFC PATCH 03/14] dfu: prepare the support of multiple interface
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 03/14] dfu: prepare the support of multiple interface Patrick Delaunay
@ 2019-07-22  7:57   ` Lukasz Majewski
  0 siblings, 0 replies; 25+ messages in thread
From: Lukasz Majewski @ 2019-07-22  7:57 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

> Split the function dfu_config_entities with 2 new functions
> - dfu_alt_init
> - dfu_alt_add

Ok.

> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
> 
>  drivers/dfu/dfu.c | 51
> +++++++++++++++++++++++++++++++++++++++------------ include/dfu.h
> |  2 ++ 2 files changed, 41 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
> index eb3a3c6..79a652e 100644
> --- a/drivers/dfu/dfu.c
> +++ b/drivers/dfu/dfu.c
> @@ -438,13 +438,12 @@ void dfu_free_entities(void)
>  	alt_num_cnt = 0;
>  }
>  
> -int dfu_config_entities(char *env, char *interface, char *devstr)
> +int dfu_alt_init(int num, struct dfu_entity **dfu)
>  {
> -	struct dfu_entity *dfu;
> -	int i, ret;
>  	char *s;
> +	int ret;
>  
> -	dfu_alt_num = dfu_find_alt_num(env);
> +	dfu_alt_num = num;
>  	debug("%s: dfu_alt_num=%d\n", __func__, dfu_alt_num);
>  
>  	dfu_hash_algo = NULL;
> @@ -455,21 +454,49 @@ int dfu_config_entities(char *env, char
> *interface, char *devstr) pr_err("Hash algorithm %s not supported\n",
> s); }
>  
> -	dfu = calloc(sizeof(*dfu), dfu_alt_num);
> -	if (!dfu)
> +	*dfu = calloc(sizeof(struct dfu_entity), dfu_alt_num);
> +	if (!*dfu)
> +		return -1;

I'm aware that the dfu.c file in some places uses -1 or -<errno> as
return value.

I would prefer that with new code we shall add -<errno>. In this
particular case it would be -ENOMEM 

> +
> +	return 0;
> +}
> +
> +int dfu_alt_add(struct dfu_entity *dfu, char *interface, char
> *devstr, char *s) +{
> +	struct dfu_entity *p_dfu;
> +	int ret;
> +
> +	if (alt_num_cnt >= dfu_alt_num)
> +		return -1;
> +
> +	p_dfu = &dfu[alt_num_cnt];
> +	ret = dfu_fill_entity(p_dfu, s, alt_num_cnt, interface,
> devstr);
> +	if (ret)
>  		return -1;
> -	for (i = 0; i < dfu_alt_num; i++) {
>  
> +	list_add_tail(&p_dfu->list, &dfu_list);
> +	alt_num_cnt++;
> +
> +	return 0;
> +}
> +
> +int dfu_config_entities(char *env, char *interface, char *devstr)
> +{
> +	struct dfu_entity *dfu;
> +	int i, ret;
> +	char *s;
> +
> +	ret = dfu_alt_init(dfu_find_alt_num(env), &dfu);
> +	if (ret)
> +		return -1;
> +
> +	for (i = 0; i < dfu_alt_num; i++) {
>  		s = strsep(&env, ";");
> -		ret = dfu_fill_entity(&dfu[i], s, alt_num_cnt,
> interface,
> -				      devstr);
> +		ret = dfu_alt_add(dfu, interface, devstr, s);
>  		if (ret) {
>  			/* We will free "dfu" in dfu_free_entities()
> */ return -1;
>  		}
> -
> -		list_add_tail(&dfu[i].list, &dfu_list);
> -		alt_num_cnt++;
>  	}
>  
>  	return 0;
> diff --git a/include/dfu.h b/include/dfu.h
> index bf51ab7..7d60ffc 100644
> --- a/include/dfu.h
> +++ b/include/dfu.h
> @@ -143,6 +143,8 @@ struct dfu_entity {
>  #ifdef CONFIG_SET_DFU_ALT_INFO
>  void set_dfu_alt_info(char *interface, char *devstr);
>  #endif
> +int dfu_alt_init(int num, struct dfu_entity **dfu);
> +int dfu_alt_add(struct dfu_entity *dfu, char *interface, char
> *devstr, char *s); int dfu_config_entities(char *s, char *interface,
> char *devstr); void dfu_free_entities(void);
>  void dfu_show_entities(void);




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190722/ac6e6bfd/attachment.sig>

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

* [U-Boot] [RFC PATCH 04/14] dfu: allow to manage DFU on several devices
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 04/14] dfu: allow to manage DFU on several devices Patrick Delaunay
@ 2019-07-22  8:04   ` Lukasz Majewski
  0 siblings, 0 replies; 25+ messages in thread
From: Lukasz Majewski @ 2019-07-22  8:04 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

> Add support of DFU for several interface/device
> with one command.
> 
> The format for "dfu_alt_info" in this case is :
>   interface with devstring'='alternate list (';' separated)
>   and each interface is separated by '&'
> 
> The previous behavior is always supported.

Good.

> 
> One example for NOR (bootloaders) + NAND (rootfs in UBI):
> 
> U-Boot> env set dfu_alt_info \
> "sf 0:0:10000000:0=spl part 0 1;u-boot part 0 2; \
> u-boot-env part 0 3&nand 0=UBI partubi 0,3"
> 
> U-Boot> dfu 0 list
> 
> DFU alt settings list:
> dev: SF alt: 0 name: spl layout: RAW_ADDR
> dev: SF alt: 1 name: ssbl layout: RAW_ADDR
> dev: SF alt: 2 name: u-boot-env layout: RAW_ADDR
> dev: NAND alt: 3 name: UBI layout: RAW_ADDR
> 
> U-Boot> dfu 0
> 
> $> dfu-util -l  
> 
> Found DFU: [0483:5720] ver=9999, devnum=96, cfg=1, intf=0, alt=3,
> name="UBI", serial="002700333338511934383330" Found DFU: [0483:5720]
> ver=9999, devnum=96, cfg=1, intf=0, alt=2, name="u-boot-env",
> serial="002700333338511934383330" Found DFU: [0483:5720] ver=9999,
> devnum=96, cfg=1, intf=0, alt=1, name="u-boot",
> serial="002700333338511934383330" Found DFU: [0483:5720] ver=9999,
> devnum=96, cfg=1, intf=0, alt=0, name="spl",
> serial="002700333338511934383330"
> 

Please add this info (with above example usage) to ./doc/README.dfu (in
a similar way as I did it some time ago for ./doc/README.dfutftp).

I also think that it would be beneficial for the community to add a
separate entry (in this file) for the description of ST's way to
program their platform with this code.

(I mean simple howto for people who would like to start playing around
with ST & U-Boot & DFU).

> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
> 
>  cmd/dfu.c         | 21 +++++++++++--------
>  drivers/dfu/dfu.c | 60
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files
> changed, 72 insertions(+), 9 deletions(-)
> 
> diff --git a/cmd/dfu.c b/cmd/dfu.c
> index 91a750a..33491d0 100644
> --- a/cmd/dfu.c
> +++ b/cmd/dfu.c
> @@ -21,23 +21,28 @@
>  static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const
> argv[]) {
>  
> -	if (argc < 4)
> +	if (argc < 2)
>  		return CMD_RET_USAGE;
>  
>  #ifdef CONFIG_DFU_OVER_USB
>  	char *usb_controller = argv[1];
>  #endif
>  #if defined(CONFIG_DFU_OVER_USB) || defined(CONFIG_DFU_OVER_TFTP)
> -	char *interface = argv[2];
> -	char *devstring = argv[3];
> +	char *interface = NULL;
> +	char *devstring = NULL;
> +
> +	if (argc >= 4) {
> +		interface = argv[2];
> +		devstring = argv[3];
> +	}
>  #endif
>  
>  	int ret = 0;
>  #ifdef CONFIG_DFU_OVER_TFTP
>  	unsigned long addr = 0;
>  	if (!strcmp(argv[1], "tftp")) {
> -		if (argc == 5)
> -			addr = simple_strtoul(argv[4], NULL, 0);
> +		if (argc == 5 || argc == 3)
> +			addr = simple_strtoul(argv[argc - 1], NULL,
> 0); 
>  		return update_tftp(addr, interface, devstring);
>  	}
> @@ -48,7 +53,7 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int
> argc, char * const argv[]) goto done;
>  
>  	ret = CMD_RET_SUCCESS;
> -	if (argc > 4 && strcmp(argv[4], "list") == 0) {
> +	if (strcmp(argv[argc - 1], "list") == 0) {
>  		dfu_show_entities();
>  		goto done;
>  	}
> @@ -67,7 +72,7 @@ U_BOOT_CMD(dfu, CONFIG_SYS_MAXARGS, 1, do_dfu,
>  	"Device Firmware Upgrade",
>  	""
>  #ifdef CONFIG_DFU_OVER_USB
> -	"<USB_controller> <interface> <dev> [list]\n"
> +	"<USB_controller> [<interface> <dev>] [list]\n"
>  	"  - device firmware upgrade via <USB_controller>\n"
>  	"    on device <dev>, attached to interface\n"
>  	"    <interface>\n"
> @@ -77,7 +82,7 @@ U_BOOT_CMD(dfu, CONFIG_SYS_MAXARGS, 1, do_dfu,
>  #ifdef CONFIG_DFU_OVER_USB
>  	"dfu "
>  #endif
> -	"tftp <interface> <dev> [<addr>]\n"
> +	"tftp [<interface> <dev>] [<addr>]\n"
>  	"  - device firmware upgrade via TFTP\n"
>  	"    on device <dev>, attached to interface\n"
>  	"    <interface>\n"
> diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
> index 79a652e..01ec690 100644
> --- a/drivers/dfu/dfu.c
> +++ b/drivers/dfu/dfu.c
> @@ -52,6 +52,54 @@ static int dfu_find_alt_num(const char *s)
>  	return ++i;
>  }
>  
> +/*
> + * treat dfu_alt_info with several interface information
> + * to allow DFU on several device with one command,
> + * the string format is
> + * interface devstring'='alternate list (';' separated)
> + * and each interface separated by '&'
> + */
> +int dfu_config_interfaces(char *env)
> +{
> +	struct dfu_entity *dfu;
> +	char *s, *i, *d, *a, *part;
> +	int ret = -EINVAL;
> +	int n = 1;
> +
> +	s = env;
> +	for (; *s; s++) {
> +		if (*s == ';')
> +			n++;
> +		if (*s == '&')
> +			n++;
> +	}
> +	ret = dfu_alt_init(n, &dfu);
> +	if (ret)
> +		return ret;
> +
> +	s = env;
> +	while (s) {
> +		ret = -EINVAL;
> +		i = strsep(&s, " ");
> +		if (!i)
> +			break;
> +		d = strsep(&s, "=");
> +		if (!d)
> +			break;
> +		a = strsep(&s, "&");
> +		if (!a)
> +			a = s;
> +		do {
> +			part = strsep(&a, ";");
> +			ret = dfu_alt_add(dfu, i, d, part);
> +			if (ret)
> +				return ret;
> +		} while (a);
> +	}
> +
> +	return ret;
> +}
> +
>  int dfu_init_env_entities(char *interface, char *devstr)
>  {
>  	const char *str_env;
> @@ -68,7 +116,11 @@ int dfu_init_env_entities(char *interface, char
> *devstr) }
>  
>  	env_bkp = strdup(str_env);
> -	ret = dfu_config_entities(env_bkp, interface, devstr);
> +	if (!interface && !devstr)
> +		ret = dfu_config_interfaces(env_bkp);
> +	else
> +		ret = dfu_config_entities(env_bkp, interface,
> devstr); +
>  	if (ret) {
>  		pr_err("DFU entities configuration failed!\n");
>  		pr_err("(partition table does not match
> dfu_alt_info?)\n"); @@ -82,6 +134,7 @@ done:
>  
>  static unsigned char *dfu_buf;
>  static unsigned long dfu_buf_size;
> +static enum dfu_device_type dfu_buf_device_type;
>  
>  unsigned char *dfu_free_buf(void)
>  {
> @@ -99,6 +152,10 @@ unsigned char *dfu_get_buf(struct dfu_entity *dfu)
>  {
>  	char *s;
>  
> +	/* manage several entity with several contraint */
> +	if (dfu_buf && dfu->dev_type != dfu_buf_device_type)
> +		dfu_free_buf();
> +
>  	if (dfu_buf != NULL)
>  		return dfu_buf;
>  
> @@ -117,6 +174,7 @@ unsigned char *dfu_get_buf(struct dfu_entity *dfu)
>  		printf("%s: Could not memalign 0x%lx bytes\n",
>  		       __func__, dfu_buf_size);
>  
> +	dfu_buf_device_type = dfu->dev_type;
>  	return dfu_buf;
>  }
>  




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190722/1796a3f1/attachment.sig>

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

* [U-Boot] [RFC PATCH 05/14] dfu: allow read with 0 data for EOF indication
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 05/14] dfu: allow read with 0 data for EOF indication Patrick Delaunay
@ 2019-07-22  8:05   ` Lukasz Majewski
  0 siblings, 0 replies; 25+ messages in thread
From: Lukasz Majewski @ 2019-07-22  8:05 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

> This patch allows into the DFU backend to indicate that there is no
> remaining data (for EOF for example). That allows users to read a
> buffer greater than the device size; the dfu stack stops the read
> request when the backend return a length=0 without error.
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
> 
>  drivers/dfu/dfu.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
> index 01ec690..bcfa170 100644
> --- a/drivers/dfu/dfu.c
> +++ b/drivers/dfu/dfu.c
> @@ -395,6 +395,8 @@ static int dfu_read_buffer_fill(struct dfu_entity
> *dfu, void *buf, int size) debug("%s: Read error!\n", __func__);
>  				return ret;
>  			}
> +			if (dfu->b_left == 0)
> +				break;
>  			dfu->offset += dfu->b_left;
>  			dfu->r_left -= dfu->b_left;
>  

Reviewed-by: Lukasz Majewski <lukma@denx.de>


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190722/e266954a/attachment.sig>

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

* [U-Boot] [RFC PATCH 06/14] dfu: add backend for MTD device
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 06/14] dfu: add backend for MTD device Patrick Delaunay
@ 2019-07-22  8:11   ` Lukasz Majewski
  0 siblings, 0 replies; 25+ messages in thread
From: Lukasz Majewski @ 2019-07-22  8:11 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

> Add DFU backend for MTD device: allow to read
> and write on any MTD device (RAW or SPI)
> 
> For example :
> > set dfu_alt_info "nand_raw raw 0x0 0x100000"
> > dfu 0 mtd nand0  
> 
> This MTD backend provides the same level than dfu nand
> backend for NAND in RAW mode and sf backend for NOR;
> So it can replace booth of them but it can also
> add support of spi-nand.
> 
> > set dfu_alt_info "nand_raw raw 0x0 0x100000"
> > dfu 0 mtd spi-nand0  
> 
> The backend code is based on the MTD command
> introduced by commit 5db66b3aee6f ("cmd: mtd:
> add 'mtd' command")

Please also add documentation entry for this feature/extension.

> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
> 
>  drivers/dfu/Kconfig   |   6 ++
>  drivers/dfu/Makefile  |   1 +
>  drivers/dfu/dfu.c     |   5 +-
>  drivers/dfu/dfu_mtd.c | 230
> ++++++++++++++++++++++++++++++++++++++++++++++++++
> include/dfu.h         |  21 +++++ 5 files changed, 262 insertions(+),
> 1 deletion(-) create mode 100644 drivers/dfu/dfu_mtd.c
> 
> diff --git a/drivers/dfu/Kconfig b/drivers/dfu/Kconfig
> index 4692736..ee664a3 100644
> --- a/drivers/dfu/Kconfig
> +++ b/drivers/dfu/Kconfig
> @@ -46,5 +46,11 @@ config DFU_SF
>  	  This option enables using DFU to read and write to SPI
> flash based storage.
>  
> +config DFU_MTD
> +	bool "MTD back end for DFU"
> +	depends on MTD
> +	help
> +	  This option enables using DFU to read and write to on any
> MTD device. +
>  endif
>  endmenu
> diff --git a/drivers/dfu/Makefile b/drivers/dfu/Makefile
> index 4164f34..ebb119f 100644
> --- a/drivers/dfu/Makefile
> +++ b/drivers/dfu/Makefile
> @@ -5,6 +5,7 @@
>  
>  obj-$(CONFIG_$(SPL_)DFU) += dfu.o
>  obj-$(CONFIG_$(SPL_)DFU_MMC) += dfu_mmc.o
> +obj-$(CONFIG_$(SPL_)DFU_MTD) += dfu_mtd.o
>  obj-$(CONFIG_$(SPL_)DFU_NAND) += dfu_nand.o
>  obj-$(CONFIG_$(SPL_)DFU_RAM) += dfu_ram.o
>  obj-$(CONFIG_$(SPL_)DFU_SF) += dfu_sf.o
> diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
> index bcfa170..ab7fdc0 100644
> --- a/drivers/dfu/dfu.c
> +++ b/drivers/dfu/dfu.c
> @@ -461,6 +461,9 @@ static int dfu_fill_entity(struct dfu_entity
> *dfu, char *s, int alt, if (strcmp(interface, "mmc") == 0) {
>  		if (dfu_fill_entity_mmc(dfu, devstr, s))
>  			return -1;
> +	} else if (strcmp(interface, "mtd") == 0) {
> +		if (dfu_fill_entity_mtd(dfu, devstr, s))
> +			return -1;
>  	} else if (strcmp(interface, "nand") == 0) {
>  		if (dfu_fill_entity_nand(dfu, devstr, s))
>  			return -1;
> @@ -565,7 +568,7 @@ int dfu_config_entities(char *env, char
> *interface, char *devstr) const char *dfu_get_dev_type(enum
> dfu_device_type t) {
>  	const char *const dev_t[] = {NULL, "eMMC", "OneNAND",
> "NAND", "RAM",
> -				     "SF"};
> +				     "SF", "MTD"};
>  	return dev_t[t];
>  }
>  
> diff --git a/drivers/dfu/dfu_mtd.c b/drivers/dfu/dfu_mtd.c
> new file mode 100644
> index 0000000..1168a6e
> --- /dev/null
> +++ b/drivers/dfu/dfu_mtd.c
> @@ -0,0 +1,230 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * dfu_mtd.c -- DFU for MTD device.
> + *
> + * Copyright (C) 2019,STMicroelectronics - All Rights Reserved
> + *
> + * Based on dfu_nand.c
> + */
> +
> +#include <common.h>
> +#include <dfu.h>
> +#include <mtd.h>
> +
> +static bool mtd_is_aligned_with_block_size(struct mtd_info *mtd, u64
> size) +{
> +	return !do_div(size, mtd->erasesize);
> +}
> +
> +static int mtd_block_op(enum dfu_op op, struct dfu_entity *dfu,
> +			u64 offset, void *buf, long *len)
> +{
> +	u64 off, lim, remaining;
> +	struct mtd_info *mtd = dfu->data.mtd.info;
> +	struct mtd_oob_ops io_op = {};
> +	int ret = 0;
> +	bool has_pages = mtd->type == MTD_NANDFLASH ||
> +			 mtd->type == MTD_MLCNANDFLASH;
> +
> +	/* if buf == NULL return total size of the area */
> +	if (!buf) {
> +		*len = dfu->data.mtd.size;
> +		return 0;
> +	}
> +
> +	off = dfu->data.mtd.start + offset + dfu->bad_skip;
> +	lim = dfu->data.mtd.start + dfu->data.mtd.size;
> +
> +	if (off >= lim) {
> +		printf("Limit reached 0x%llx\n", lim);
> +		*len = 0;
> +		return op == DFU_OP_READ ? 0 : -EIO;
> +	}
> +	/* limit request with the available size */
> +	if (off + *len >= lim)
> +		*len = lim - off;
> +
> +	if (!mtd_is_aligned_with_block_size(mtd, off)) {
> +		printf("Offset not aligned with a block (0x%x)\n",
> +		       mtd->erasesize);
> +		return 0;
> +	}
> +
> +	/* first erase */
> +	if (op == DFU_OP_WRITE) {
> +		struct erase_info erase_op = {};
> +
> +		erase_op.mtd = mtd;
> +		erase_op.addr = off;
> +		erase_op.len = round_up(*len, mtd->erasesize);
> +		erase_op.scrub = 0;
> +
> +		while (erase_op.len) {
> +			if (erase_op.addr + erase_op.len > lim) {
> +				printf("Limit reached 0x%llx while
> erasing at offset 0x%llx\n",
> +				       lim, off);
> +				return -EIO;
> +			}
> +
> +			ret = mtd_erase(mtd, &erase_op);
> +			/* Abort if its not a bad block error */
> +			if (ret != -EIO)
> +				break;
> +
> +			printf("Skipping bad block at 0x%08llx\n",
> +			       erase_op.fail_addr);
> +
> +			/* Continue erase behind bad block */
> +			erase_op.len -= erase_op.fail_addr -
> erase_op.addr;
> +			erase_op.addr = erase_op.fail_addr +
> mtd->erasesize;
> +		}
> +		if (ret && ret != -EIO) {
> +			printf("Failure while erasing at offset
> 0x%llx\n",
> +			       erase_op.fail_addr);
> +			return 0;
> +		}
> +	}
> +
> +	io_op.mode = MTD_OPS_AUTO_OOB;
> +	io_op.len = *len;
> +	if (has_pages && io_op.len > mtd->writesize)
> +		io_op.len = mtd->writesize;
> +	io_op.ooblen = 0;
> +	io_op.datbuf = buf;
> +	io_op.oobbuf = NULL;
> +
> +	/* Loop over to do the actual read/write */
> +	remaining = *len;
> +	while (remaining) {
> +		if (off + remaining > lim) {
> +			printf("Limit reached 0x%llx while %s at
> offset 0x%llx\n",
> +			       lim, op == DFU_OP_READ ? "reading" :
> "writing",
> +			       off);
> +			if (op == DFU_OP_READ) {
> +				*len -= remaining;
> +				return 0;
> +			} else {
> +				return -EIO;
> +			}
> +		}
> +
> +		/* Skip the block if it is bad */
> +		if (mtd_is_aligned_with_block_size(mtd, off) &&
> +		    mtd_block_isbad(mtd, off)) {
> +			off += mtd->erasesize;
> +			dfu->bad_skip += mtd->erasesize;
> +			continue;
> +		}
> +
> +		if (op == DFU_OP_READ)
> +			ret = mtd_read_oob(mtd, off, &io_op);
> +		else
> +			ret = mtd_write_oob(mtd, off, &io_op);
> +
> +		if (ret) {
> +			printf("Failure while %s at offset 0x%llx\n",
> +			       op == DFU_OP_READ ? "reading" :
> "writing", off);
> +			return -EIO;
> +		}
> +
> +		off += io_op.retlen;
> +		remaining -= io_op.retlen;
> +		io_op.datbuf += io_op.retlen;
> +		io_op.len = remaining;
> +		if (has_pages && io_op.len > mtd->writesize)
> +			io_op.len = mtd->writesize;
> +	}
> +
> +	return ret;
> +}
> +
> +static int dfu_get_medium_size_mtd(struct dfu_entity *dfu, u64 *size)
> +{
> +	*size = dfu->data.mtd.info->size;
> +
> +	return 0;
> +}
> +
> +static int dfu_read_medium_mtd(struct dfu_entity *dfu, u64 offset,
> void *buf,
> +			       long *len)
> +{
> +	int ret = -1;
> +
> +	switch (dfu->layout) {
> +	case DFU_RAW_ADDR:
> +		ret = mtd_block_op(DFU_OP_READ, dfu, offset, buf,
> len);
> +		break;
> +	default:
> +		printf("%s: Layout (%s) not (yet) supported!\n",
> __func__,
> +		       dfu_get_layout(dfu->layout));
> +	}
> +
> +	return ret;
> +}
> +
> +static int dfu_write_medium_mtd(struct dfu_entity *dfu,
> +				u64 offset, void *buf, long *len)
> +{
> +	int ret = -1;
> +
> +	switch (dfu->layout) {
> +	case DFU_RAW_ADDR:
> +		ret = mtd_block_op(DFU_OP_WRITE, dfu, offset, buf,
> len);
> +		break;
> +	default:
> +		printf("%s: Layout (%s) not (yet) supported!\n",
> __func__,
> +		       dfu_get_layout(dfu->layout));
> +	}
> +
> +	return ret;
> +}
> +
> +static int dfu_flush_medium_mtd(struct dfu_entity *dfu)
> +{
> +	return 0;
> +}
> +
> +static unsigned int dfu_polltimeout_mtd(struct dfu_entity *dfu)
> +{
> +	return DFU_DEFAULT_POLL_TIMEOUT;
> +}
> +
> +int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr, char
> *s) +{
> +	char *st;
> +	struct mtd_info *mtd;
> +	bool has_pages;
> +
> +	mtd = get_mtd_device_nm(devstr);
> +	if (IS_ERR_OR_NULL(mtd))
> +		return -ENODEV;
> +	put_mtd_device(mtd);
> +
> +	dfu->dev_type = DFU_DEV_MTD;
> +	dfu->data.mtd.info = mtd;
> +
> +	has_pages = mtd->type == MTD_NANDFLASH || mtd->type ==
> MTD_MLCNANDFLASH;
> +	dfu->max_buf_size = has_pages ? mtd->erasesize : 0;
> +
> +	st = strsep(&s, " ");
> +	if (!strcmp(st, "raw")) {
> +		dfu->layout = DFU_RAW_ADDR;
> +		dfu->data.mtd.start = simple_strtoul(s, &s, 16);
> +		s++;
> +		dfu->data.mtd.size = simple_strtoul(s, &s, 16);
> +	} else {
> +		printf("%s: (%s) not supported!\n", __func__, st);
> +		return -1;
> +	}
> +
> +	dfu->get_medium_size = dfu_get_medium_size_mtd;
> +	dfu->read_medium = dfu_read_medium_mtd;
> +	dfu->write_medium = dfu_write_medium_mtd;
> +	dfu->flush_medium = dfu_flush_medium_mtd;
> +	dfu->poll_timeout = dfu_polltimeout_mtd;
> +
> +	/* initial state */
> +	dfu->inited = 0;
> +
> +	return 0;
> +}
> diff --git a/include/dfu.h b/include/dfu.h
> index 7d60ffc..924952f 100644
> --- a/include/dfu.h
> +++ b/include/dfu.h
> @@ -22,6 +22,7 @@ enum dfu_device_type {
>  	DFU_DEV_NAND,
>  	DFU_DEV_RAM,
>  	DFU_DEV_SF,
> +	DFU_DEV_MTD,
>  };
>  
>  enum dfu_layout {
> @@ -55,6 +56,14 @@ struct mmc_internal_data {
>  	unsigned int part;
>  };
>  
> +struct mtd_internal_data {
> +	struct mtd_info *info;
> +
> +	/* RAW programming */
> +	u64 start;
> +	u64 size;
> +};
> +
>  struct nand_internal_data {
>  	/* RAW programming */
>  	u64 start;
> @@ -105,6 +114,7 @@ struct dfu_entity {
>  
>  	union {
>  		struct mmc_internal_data mmc;
> +		struct mtd_internal_data mtd;
>  		struct nand_internal_data nand;
>  		struct ram_internal_data ram;
>  		struct sf_internal_data sf;
> @@ -249,6 +259,17 @@ static inline int dfu_fill_entity_sf(struct
> dfu_entity *dfu, char *devstr, }
>  #endif
>  
> +#if CONFIG_IS_ENABLED(DFU_MTD)
> +int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr, char
> *s); +#else
> +static inline int dfu_fill_entity_mtd(struct dfu_entity *dfu, char
> *devstr,
> +				      char *s)
> +{
> +	puts("MTD support not available!\n");
> +	return -1;
> +}
> +#endif
> +
>  /**
>   * dfu_tftp_write - Write TFTP data to DFU medium
>   *




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190722/ca414145/attachment.sig>

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

* [U-Boot] [RFC PATCH 07/14] dfu: add partition support for MTD backend
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 07/14] dfu: add partition support for MTD backend Patrick Delaunay
@ 2019-07-22  8:16   ` Lukasz Majewski
  0 siblings, 0 replies; 25+ messages in thread
From: Lukasz Majewski @ 2019-07-22  8:16 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

> Add the support of MTD partition for the MTD backend.
> 
> The expected dfu_alt_info for one alternate on the mtd device :
> 	<name> part <part_id>
>         <name> partubi <part_id>
> 
> "partubi" also erase up to the end of the partition after write
> operation.
> 
> For example: dfu_alt_info = "spl part 1;u-boot part 2; UBI partubi 3"

As in the previous comments - please add this info to dedicated doc
entry.

> 
> U-Boot> dfu 0 mtd nand0
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
> 
>  drivers/dfu/dfu_mtd.c | 78
> ++++++++++++++++++++++++++++++++++++++++++++++++++-
> include/dfu.h         |  2 ++ 2 files changed, 79 insertions(+), 1
> deletion(-)
> 
> diff --git a/drivers/dfu/dfu_mtd.c b/drivers/dfu/dfu_mtd.c
> index 1168a6e..223b0fe 100644
> --- a/drivers/dfu/dfu_mtd.c
> +++ b/drivers/dfu/dfu_mtd.c
> @@ -10,6 +10,7 @@
>  #include <common.h>
>  #include <dfu.h>
>  #include <mtd.h>
> +#include <jffs2/load_kernel.h>
>  
>  static bool mtd_is_aligned_with_block_size(struct mtd_info *mtd, u64
> size) {
> @@ -181,11 +182,49 @@ static int dfu_write_medium_mtd(struct
> dfu_entity *dfu, 
>  static int dfu_flush_medium_mtd(struct dfu_entity *dfu)
>  {
> +	struct mtd_info *mtd = dfu->data.mtd.info;
> +	int ret;
> +
> +	/* in case of ubi partition, erase rest of the partition */
> +	if (dfu->data.nand.ubi) {
> +		struct erase_info erase_op = {};
> +
> +		erase_op.mtd = dfu->data.mtd.info;
> +		erase_op.addr = round_up(dfu->data.mtd.start +
> dfu->offset +
> +					 dfu->bad_skip,
> mtd->erasesize);
> +		erase_op.len = dfu->data.mtd.start +
> dfu->data.mtd.size -
> +			       erase_op.addr;
> +		erase_op.scrub = 0;
> +
> +		while (erase_op.len) {
> +			ret = mtd_erase(mtd, &erase_op);
> +			/* Abort if its not a bad block error */
> +			if (ret != -EIO)
> +				break;
> +
> +			printf("Skipping bad block at 0x%08llx\n",
> +			       erase_op.fail_addr);
> +
> +			/* Skip bad block and continue behind it */
> +			erase_op.addr = erase_op.fail_addr +
> mtd->erasesize;
> +			erase_op.len = dfu->data.mtd.start +
> +				       dfu->data.mtd.size -
> +				       erase_op.addr;
> +		}
> +	}
>  	return 0;
>  }
>  
>  static unsigned int dfu_polltimeout_mtd(struct dfu_entity *dfu)
>  {
> +	/*
> +	 * Currently, Poll Timeout != 0 is only needed on nand
> +	 * ubi partition, as sectors which are not used need
> +	 * to be erased
> +	 */
> +	if (dfu->data.nand.ubi)
> +		return DFU_MANIFEST_POLL_TIMEOUT;
> +
>  	return DFU_DEFAULT_POLL_TIMEOUT;
>  }
>  
> @@ -194,6 +233,7 @@ int dfu_fill_entity_mtd(struct dfu_entity *dfu,
> char *devstr, char *s) char *st;
>  	struct mtd_info *mtd;
>  	bool has_pages;
> +	int ret, part;
>  
>  	mtd = get_mtd_device_nm(devstr);
>  	if (IS_ERR_OR_NULL(mtd))
> @@ -212,11 +252,47 @@ int dfu_fill_entity_mtd(struct dfu_entity *dfu,
> char *devstr, char *s) dfu->data.mtd.start = simple_strtoul(s, &s,
> 16); s++;
>  		dfu->data.mtd.size = simple_strtoul(s, &s, 16);
> +	} else if ((!strcmp(st, "part")) || (!strcmp(st,
> "partubi"))) {
> +		char mtd_id[32];
> +		struct mtd_device *mtd_dev;
> +		u8 part_num;
> +		struct part_info *pi;
> +
> +		dfu->layout = DFU_RAW_ADDR;
> +
> +		part = simple_strtoul(s, &s, 10);
> +
> +		sprintf(mtd_id, "%s,%d", devstr, part - 1);
> +		printf("using id '%s'\n", mtd_id);
> +
> +		mtdparts_init();
> +
> +		ret = find_dev_and_part(mtd_id, &mtd_dev, &part_num,
> &pi);
> +		if (ret != 0) {
> +			printf("Could not locate '%s'\n", mtd_id);
> +			return -1;

			-ENODEV maybe would be more appropriate ?

> +		}
> +
> +		dfu->data.mtd.start = pi->offset;
> +		dfu->data.mtd.size = pi->size;
> +		if (!strcmp(st, "partubi"))
> +			dfu->data.mtd.ubi = 1;
>  	} else {
> -		printf("%s: (%s) not supported!\n", __func__, st);
> +		printf("%s: Memory layout (%s) not supported!\n",
> __func__, st); return -1;
>  	}
>  
> +	if (!mtd_is_aligned_with_block_size(mtd,
> dfu->data.mtd.start)) {
> +		printf("Offset not aligned with a block (0x%x)\n",
> +		       mtd->erasesize);
> +		return -EINVAL;
> +	}
> +	if (!mtd_is_aligned_with_block_size(mtd,
> dfu->data.mtd.size)) {
> +		printf("Size not aligned with a block (0x%x)\n",
> +		       mtd->erasesize);
> +		return -EINVAL;
> +	}
> +
>  	dfu->get_medium_size = dfu_get_medium_size_mtd;
>  	dfu->read_medium = dfu_read_medium_mtd;
>  	dfu->write_medium = dfu_write_medium_mtd;
> diff --git a/include/dfu.h b/include/dfu.h
> index 924952f..a90732c 100644
> --- a/include/dfu.h
> +++ b/include/dfu.h
> @@ -62,6 +62,8 @@ struct mtd_internal_data {
>  	/* RAW programming */
>  	u64 start;
>  	u64 size;
> +	/* for ubi partition */
> +	unsigned int ubi;
>  };
>  
>  struct nand_internal_data {




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190722/c113d98e/attachment.sig>

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

* [U-Boot] [RFC PATCH 08/14] dfu: add DFU virtual backend
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 08/14] dfu: add DFU virtual backend Patrick Delaunay
@ 2019-07-22  8:20   ` Lukasz Majewski
  0 siblings, 0 replies; 25+ messages in thread
From: Lukasz Majewski @ 2019-07-22  8:20 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

> Add a virtual DFU backend to allow board specific read and write
> (for OTP update for example).

This looks like a great enhancement. Please add detailed documentation
entry of its intended usage.

> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
> 
>  drivers/dfu/Kconfig    |  7 +++++++
>  drivers/dfu/Makefile   |  1 +
>  drivers/dfu/dfu.c      |  5 ++++-
>  drivers/dfu/dfu_virt.c | 49
> +++++++++++++++++++++++++++++++++++++++++++++++++
> include/dfu.h          | 22 ++++++++++++++++++++++ 5 files changed,
> 83 insertions(+), 1 deletion(-) create mode 100644
> drivers/dfu/dfu_virt.c
> 
> diff --git a/drivers/dfu/Kconfig b/drivers/dfu/Kconfig
> index ee664a3..c0e6e5d 100644
> --- a/drivers/dfu/Kconfig
> +++ b/drivers/dfu/Kconfig
> @@ -52,5 +52,12 @@ config DFU_MTD
>  	help
>  	  This option enables using DFU to read and write to on any
> MTD device. 
> +config DFU_VIRT
> +	bool "VIRTUAL flash back end for DFU"
> +	help
> +	  This option enables using DFU to read and write to VIRTUAL
> device
> +	  used at board level to manage specific behavior
> +	  (OTP update for example).
> +
>  endif
>  endmenu
> diff --git a/drivers/dfu/Makefile b/drivers/dfu/Makefile
> index ebb119f..0d7925c 100644
> --- a/drivers/dfu/Makefile
> +++ b/drivers/dfu/Makefile
> @@ -10,3 +10,4 @@ obj-$(CONFIG_$(SPL_)DFU_NAND) += dfu_nand.o
>  obj-$(CONFIG_$(SPL_)DFU_RAM) += dfu_ram.o
>  obj-$(CONFIG_$(SPL_)DFU_SF) += dfu_sf.o
>  obj-$(CONFIG_$(SPL_)DFU_TFTP) += dfu_tftp.o
> +obj-$(CONFIG_$(SPL_)DFU_VIRT) += dfu_virt.o
> diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
> index ab7fdc0..a960b6e 100644
> --- a/drivers/dfu/dfu.c
> +++ b/drivers/dfu/dfu.c
> @@ -473,6 +473,9 @@ static int dfu_fill_entity(struct dfu_entity
> *dfu, char *s, int alt, } else if (strcmp(interface, "sf") == 0) {
>  		if (dfu_fill_entity_sf(dfu, devstr, s))
>  			return -1;
> +	} else if (strcmp(interface, "virt") == 0) {
> +		if (dfu_fill_entity_virt(dfu, devstr, s))
> +			return -1;
>  	} else {
>  		printf("%s: Device %s not (yet) supported!\n",
>  		       __func__,  interface);
> @@ -568,7 +571,7 @@ int dfu_config_entities(char *env, char
> *interface, char *devstr) const char *dfu_get_dev_type(enum
> dfu_device_type t) {
>  	const char *const dev_t[] = {NULL, "eMMC", "OneNAND",
> "NAND", "RAM",
> -				     "SF", "MTD"};
> +				     "SF", "MTD", "VIRT"};
>  	return dev_t[t];
>  }
>  
> diff --git a/drivers/dfu/dfu_virt.c b/drivers/dfu/dfu_virt.c
> new file mode 100644
> index 0000000..ea8c71f
> --- /dev/null
> +++ b/drivers/dfu/dfu_virt.c
> @@ -0,0 +1,49 @@
> +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
> +/*
> + * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
> + */
> +#include <common.h>
> +#include <dfu.h>
> +#include <errno.h>
> +#include <malloc.h>
> +
> +int __weak dfu_write_medium_virt(struct dfu_entity *dfu, u64 offset,
> +				 void *buf, long *len)
> +{
> +	debug("%s: off=0x%llx, len=0x%x\n", __func__, offset,
> (u32)*len); +
> +	return 0;
> +}
> +
> +int __weak dfu_get_medium_size_virt(struct dfu_entity *dfu, u64
> *size) +{
> +	*size = 0;
> +
> +	return 0;
> +}
> +
> +int __weak dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset,
> +				void *buf, long *len)
> +{
> +	debug("%s: off=0x%llx, len=0x%x\n", __func__, offset,
> (u32)*len);
> +	*len = 0;
> +
> +	return 0;
> +}
> +
> +int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr, char
> *s) +{
> +	debug("%s: devstr = %s\n", __func__, devstr);
> +
> +	dfu->dev_type = DFU_DEV_VIRT;
> +	dfu->layout = DFU_RAW_ADDR;
> +	dfu->data.virt.dev_num = simple_strtoul(devstr, NULL, 10);
> +
> +	dfu->write_medium = dfu_write_medium_virt;
> +	dfu->get_medium_size = dfu_get_medium_size_virt;
> +	dfu->read_medium = dfu_read_medium_virt;
> +
> +	dfu->inited = 0;
> +
> +	return 0;
> +}
> diff --git a/include/dfu.h b/include/dfu.h
> index a90732c..4de7d35 100644
> --- a/include/dfu.h
> +++ b/include/dfu.h
> @@ -23,6 +23,7 @@ enum dfu_device_type {
>  	DFU_DEV_RAM,
>  	DFU_DEV_SF,
>  	DFU_DEV_MTD,
> +	DFU_DEV_VIRT,
>  };
>  
>  enum dfu_layout {
> @@ -92,6 +93,10 @@ struct sf_internal_data {
>  	unsigned int ubi;
>  };
>  
> +struct virt_internal_data {
> +	int dev_num;
> +};
> +
>  #define DFU_NAME_SIZE			32
>  #ifndef CONFIG_SYS_DFU_DATA_BUF_SIZE
>  #define CONFIG_SYS_DFU_DATA_BUF_SIZE
> (1024*1024*8)	/* 8 MiB */ @@ -120,6 +125,7 @@ struct
> dfu_entity { struct nand_internal_data nand;
>  		struct ram_internal_data ram;
>  		struct sf_internal_data sf;
> +		struct virt_internal_data virt;
>  	} data;
>  
>  	int (*get_medium_size)(struct dfu_entity *dfu, u64 *size);
> @@ -272,6 +278,22 @@ static inline int dfu_fill_entity_mtd(struct
> dfu_entity *dfu, char *devstr, }
>  #endif
>  
> +#ifdef CONFIG_DFU_VIRT
> +int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr, char
> *s); +int dfu_write_medium_virt(struct dfu_entity *dfu, u64 offset,
> +			  void *buf, long *len);
> +int dfu_get_medium_size_virt(struct dfu_entity *dfu, u64 *size);
> +int dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset,
> +			 void *buf, long *len);
> +#else
> +static inline int dfu_fill_entity_virt(struct dfu_entity *dfu, char
> *devstr,
> +				       char *s)
> +{
> +	puts("VIRT support not available!\n");
> +	return -1;
> +}
> +#endif
> +
>  /**
>   * dfu_tftp_write - Write TFTP data to DFU medium
>   *




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190722/ca95f199/attachment.sig>

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

* [U-Boot] [RFC PATCH 09/14] dfu: add callback for flush and initiated operation
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 09/14] dfu: add callback for flush and initiated operation Patrick Delaunay
@ 2019-07-22  8:22   ` Lukasz Majewski
  0 siblings, 0 replies; 25+ messages in thread
From: Lukasz Majewski @ 2019-07-22  8:22 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

> Add weak callback to allow board specific behavior
> - flush
> - initiated
> 
> This patch prepare usage of DFU back end for communication with
> STM32CubeProgrammer on stm32mp1 platform with stm32prog command.

Would the stm32prog need to modify the environment variables ?
For example to update the "VERSION" or any other one?


> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
> 
>  drivers/dfu/dfu.c | 19 +++++++++++++++++++
>  include/dfu.h     |  2 ++
>  2 files changed, 21 insertions(+)
> 
> diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
> index a960b6e..e642b09 100644
> --- a/drivers/dfu/dfu.c
> +++ b/drivers/dfu/dfu.c
> @@ -22,6 +22,22 @@ static int alt_num_cnt;
>  static struct hash_algo *dfu_hash_algo;
>  
>  /*
> + * The purpose of the dfu_flush_callback() function is to
> + * provide callback for dfu user
> + */
> +__weak void dfu_flush_callback(struct dfu_entity *dfu)
> +{
> +}
> +
> +/*
> + * The purpose of the dfu_flush_callback() function is to
> + * provide callback for dfu user
> + */
> +__weak void dfu_initiated_callback(struct dfu_entity *dfu)
> +{
> +}
> +
> +/*
>   * The purpose of the dfu_usb_get_reset() function is to
>   * provide information if after USB_DETACH request
>   * being sent the dfu-util performed reset of USB
> @@ -262,6 +278,7 @@ int dfu_transaction_initiate(struct dfu_entity
> *dfu, bool read) }
>  
>  	dfu->inited = 1;
> +	dfu_initiated_callback(dfu);
>  
>  	return 0;
>  }
> @@ -281,6 +298,8 @@ int dfu_flush(struct dfu_entity *dfu, void *buf,
> int size, int blk_seq_num) printf("\nDFU complete %s: 0x%08x\n",
> dfu_hash_algo->name, dfu->crc);
>  
> +	dfu_flush_callback(dfu);
> +
>  	dfu_transaction_cleanup(dfu);
>  
>  	return ret;
> diff --git a/include/dfu.h b/include/dfu.h
> index 4de7d35..5d85cc3 100644
> --- a/include/dfu.h
> +++ b/include/dfu.h
> @@ -182,6 +182,8 @@ bool dfu_usb_get_reset(void);
>  int dfu_read(struct dfu_entity *de, void *buf, int size, int
> blk_seq_num); int dfu_write(struct dfu_entity *de, void *buf, int
> size, int blk_seq_num); int dfu_flush(struct dfu_entity *de, void
> *buf, int size, int blk_seq_num); +void dfu_flush_callback(struct
> dfu_entity *dfu); +void dfu_initiated_callback(struct dfu_entity
> *dfu); 
>  /*
>   * dfu_defer_flush - pointer to store dfu_entity for deferred
> flashing.




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190722/d1280fe3/attachment.sig>

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

* [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1
  2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
                   ` (13 preceding siblings ...)
  2019-07-19 12:57 ` [U-Boot] [RFC PATCH 14/14] stm32mp1: add support for virtual partition read Patrick Delaunay
@ 2019-07-22  8:27 ` Lukasz Majewski
  14 siblings, 0 replies; 25+ messages in thread
From: Lukasz Majewski @ 2019-07-22  8:27 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

> This serie based on v2019.07 propose some update on the DFU stack:
> - add capability to have several DFU backend running in parallel
> - add MTD backend for NAND, NOR or SPI-NAND
> - add VIRTUAL backend for board/command specific behavior
> - add some weak callback
> 
> To test the feature and as example, I update the stm32mp1
> to use the new features (tested with command "dfu 0")
> 
> This serie prepares the DFU backend for communication with
> STM32CubeProgrammer on stm32mp1 platform (stm32prog command).
> This STMicroelectronics tool is based on DFU protocol and
> update the boot devices and the OTPs on the ST boards.
> 

Thanks for such great enhancement on DFU. I've added Heiko to CC, so he
also would be aware of your work (as some of his boards use DFU for
update).

Please add detailed documentation entry (as I've indicated in other
patches reviewed) for above features.

The roadmap:

- Please send v1 (without RFC). (Please run buildman on several siemens
  and trats/trats2/odroid-x* boards)

- I will test it on odroid-XU3 (and probably Heiko would test it for
  regression).





A side question - would you need in some point updating envs via DFU
(no matter if those would be a whole image created with mkimage or an
individual one) ?

> 
> 
> Patrick Delaunay (14):
>   dfu: cosmetic: cleanup sf to avoid checkpatch error
>   dfu: sf: add partition support for nor backend
>   dfu: prepare the support of multiple interface
>   dfu: allow to manage DFU on several devices
>   dfu: allow read with 0 data for EOF indication
>   dfu: add backend for MTD device
>   dfu: add partition support for MTD backend
>   dfu: add DFU virtual backend
>   dfu: add callback for flush and initiated operation
>   stm32mp1: activate DFU support and command MTD
>   stm32mp1: activate SET_DFU_ALT_INFO
>   stp32mp1: configs: activate CONFIG_MTD_SPI_NAND
>   stm32mp1: board: add spi nand support
>   stm32mp1: add support for virtual partition read
> 
>  board/st/stm32mp1/README            | 111 +++++++++++++
>  board/st/stm32mp1/stm32mp1.c        | 165 ++++++++++++++++++-
>  cmd/dfu.c                           |  21 ++-
>  configs/stm32mp15_basic_defconfig   |   6 +
>  configs/stm32mp15_trusted_defconfig |   6 +
>  drivers/dfu/Kconfig                 |  13 ++
>  drivers/dfu/Makefile                |   2 +
>  drivers/dfu/dfu.c                   | 145 +++++++++++++++--
>  drivers/dfu/dfu_mtd.c               | 306
> ++++++++++++++++++++++++++++++++++++
> drivers/dfu/dfu_sf.c                |  55 ++++++-
> drivers/dfu/dfu_virt.c              |  49 ++++++
> include/configs/stm32mp1.h          |  38 ++++-
> include/dfu.h                       |  51 ++++++ 13 files changed,
> 939 insertions(+), 29 deletions(-) create mode 100644
> drivers/dfu/dfu_mtd.c create mode 100644 drivers/dfu/dfu_virt.c
> 




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190722/f9e8ff39/attachment.sig>

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

end of thread, other threads:[~2019-07-22  8:27 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-19 12:57 [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Patrick Delaunay
2019-07-19 12:57 ` [U-Boot] [RFC PATCH 01/14] dfu: cosmetic: cleanup sf to avoid checkpatch error Patrick Delaunay
2019-07-22  7:51   ` Lukasz Majewski
2019-07-19 12:57 ` [U-Boot] [RFC PATCH 02/14] dfu: sf: add partition support for nor backend Patrick Delaunay
2019-07-22  7:54   ` Lukasz Majewski
2019-07-19 12:57 ` [U-Boot] [RFC PATCH 03/14] dfu: prepare the support of multiple interface Patrick Delaunay
2019-07-22  7:57   ` Lukasz Majewski
2019-07-19 12:57 ` [U-Boot] [RFC PATCH 04/14] dfu: allow to manage DFU on several devices Patrick Delaunay
2019-07-22  8:04   ` Lukasz Majewski
2019-07-19 12:57 ` [U-Boot] [RFC PATCH 05/14] dfu: allow read with 0 data for EOF indication Patrick Delaunay
2019-07-22  8:05   ` Lukasz Majewski
2019-07-19 12:57 ` [U-Boot] [RFC PATCH 06/14] dfu: add backend for MTD device Patrick Delaunay
2019-07-22  8:11   ` Lukasz Majewski
2019-07-19 12:57 ` [U-Boot] [RFC PATCH 07/14] dfu: add partition support for MTD backend Patrick Delaunay
2019-07-22  8:16   ` Lukasz Majewski
2019-07-19 12:57 ` [U-Boot] [RFC PATCH 08/14] dfu: add DFU virtual backend Patrick Delaunay
2019-07-22  8:20   ` Lukasz Majewski
2019-07-19 12:57 ` [U-Boot] [RFC PATCH 09/14] dfu: add callback for flush and initiated operation Patrick Delaunay
2019-07-22  8:22   ` Lukasz Majewski
2019-07-19 12:57 ` [U-Boot] [RFC PATCH 10/14] stm32mp1: activate DFU support and command MTD Patrick Delaunay
2019-07-19 12:57 ` [U-Boot] [RFC PATCH 11/14] stm32mp1: activate SET_DFU_ALT_INFO Patrick Delaunay
2019-07-19 12:57 ` [U-Boot] [RFC PATCH 12/14] stp32mp1: configs: activate CONFIG_MTD_SPI_NAND Patrick Delaunay
2019-07-19 12:57 ` [U-Boot] [RFC PATCH 13/14] stm32mp1: board: add spi nand support Patrick Delaunay
2019-07-19 12:57 ` [U-Boot] [RFC PATCH 14/14] stm32mp1: add support for virtual partition read Patrick Delaunay
2019-07-22  8:27 ` [U-Boot] [RFC PATCH 00/14] dfu: update dfu stack and use them for stm32mp1 Lukasz Majewski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.