All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space
@ 2013-02-21 17:15 sjur.brandeland
  2013-02-21 17:15 ` [PATCHv2 01/10] remoteproc: Bugfix: Deallocate firmware image on shutdown sjur.brandeland
                   ` (10 more replies)
  0 siblings, 11 replies; 16+ messages in thread
From: sjur.brandeland @ 2013-02-21 17:15 UTC (permalink / raw)
  To: Ido Yariv, Ohad Ben-Cohen
  Cc: linux-kernel, Dmitry Tarnyagin, Linus Walleij, Erwan Yvin, sjur,
	Sjur Brændeland

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

This patch-set adds support for shared resource table between
Linux kernel and remote devices. 
- dynamically-allocated address of the vrings can be communicated
- vdev statuses can be communicated
- virtio config space becomes bi-directional
- virtio feature negotiation is two-way 

Changes since v1:
- Address all of Ido's review comments on the previous patch-set.

Thanks,
Sjur

Dmitry Tarnyagin (1):
  remoteproc: Bugfix: Deallocate firmware image on shutdown

Sjur Brændeland (9):
  remoteproc: Bugfix remove entry from list before freeing it
  remoteproc: Refactor function rproc_elf_find_rsc_table
  remoteproc: Parse ELF file to find resource table address
  remoteproc: Parse STE-firmware and find resource table address
  remoteproc: Code cleanup of resource parsing
  remoteproc: Calculate max_notifyid by counting vrings
  remoteproc: Always perserve resource table data
  remoteproc: Support virtio config space.
  remoteproc: Set vring addresses in resource table

 drivers/remoteproc/Kconfig                 |    1 +
 drivers/remoteproc/remoteproc_core.c       |  185 +++++++++++++++++----------
 drivers/remoteproc/remoteproc_elf_loader.c |   92 +++++++++-----
 drivers/remoteproc/remoteproc_internal.h   |   13 ++
 drivers/remoteproc/remoteproc_virtio.c     |   61 +++++++---
 drivers/remoteproc/ste_modem_rproc.c       |   52 ++++++---
 include/linux/remoteproc.h                 |   13 ++-
 7 files changed, 283 insertions(+), 134 deletions(-)

-- 
1.7.5.4


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

* [PATCHv2 01/10] remoteproc: Bugfix: Deallocate firmware image on shutdown
  2013-02-21 17:15 [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space sjur.brandeland
@ 2013-02-21 17:15 ` sjur.brandeland
  2013-02-21 17:15 ` [PATCHv2 02/10] remoteproc: Bugfix remove entry from list before freeing it sjur.brandeland
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: sjur.brandeland @ 2013-02-21 17:15 UTC (permalink / raw)
  To: Ido Yariv, Ohad Ben-Cohen
  Cc: linux-kernel, Dmitry Tarnyagin, Linus Walleij, Erwan Yvin, sjur

From: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>

Fixes coherent memory leakage, caused by non-deallocated
firmware image chunk.

Signed-off-by: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
---
 drivers/remoteproc/ste_modem_rproc.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/remoteproc/ste_modem_rproc.c b/drivers/remoteproc/ste_modem_rproc.c
index a7743c0..fb95c42 100644
--- a/drivers/remoteproc/ste_modem_rproc.c
+++ b/drivers/remoteproc/ste_modem_rproc.c
@@ -240,6 +240,8 @@ static int sproc_drv_remove(struct platform_device *pdev)
 
 	/* Unregister as remoteproc device */
 	rproc_del(sproc->rproc);
+	dma_free_coherent(sproc->rproc->dev.parent, SPROC_FW_SIZE,
+			  sproc->fw_addr, sproc->fw_dma_addr);
 	rproc_put(sproc->rproc);
 
 	mdev->drv_data = NULL;
@@ -297,10 +299,13 @@ static int sproc_probe(struct platform_device *pdev)
 	/* Register as a remoteproc device */
 	err = rproc_add(rproc);
 	if (err)
-		goto free_rproc;
+		goto free_mem;
 
 	return 0;
 
+free_mem:
+	dma_free_coherent(rproc->dev.parent, SPROC_FW_SIZE,
+			  sproc->fw_addr, sproc->fw_dma_addr);
 free_rproc:
 	/* Reset device data upon error */
 	mdev->drv_data = NULL;
-- 
1.7.5.4


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

* [PATCHv2 02/10] remoteproc: Bugfix remove entry from list before freeing it
  2013-02-21 17:15 [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space sjur.brandeland
  2013-02-21 17:15 ` [PATCHv2 01/10] remoteproc: Bugfix: Deallocate firmware image on shutdown sjur.brandeland
@ 2013-02-21 17:15 ` sjur.brandeland
  2013-03-19 13:31   ` Ohad Ben-Cohen
  2013-02-21 17:15 ` [PATCHv2 03/10] remoteproc: Refactor function rproc_elf_find_rsc_table sjur.brandeland
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 16+ messages in thread
From: sjur.brandeland @ 2013-02-21 17:15 UTC (permalink / raw)
  To: Ido Yariv, Ohad Ben-Cohen
  Cc: linux-kernel, Dmitry Tarnyagin, Linus Walleij, Erwan Yvin, sjur,
	Sjur Brændeland

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

Remove the vdev entry from the list before freeing it,
otherwise the rproc->vdevs list get corrupted.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
---
 drivers/remoteproc/remoteproc_core.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index dd3bfaf..752b507 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -370,10 +370,12 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
 	/* it is now safe to add the virtio device */
 	ret = rproc_add_virtio_dev(rvdev, rsc->id);
 	if (ret)
-		goto free_rvdev;
+		goto remove_rvdev;
 
 	return 0;
 
+remove_rvdev:
+	list_del(&rvdev->node);
 free_rvdev:
 	kfree(rvdev);
 	return ret;
-- 
1.7.5.4


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

* [PATCHv2 03/10] remoteproc: Refactor function rproc_elf_find_rsc_table
  2013-02-21 17:15 [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space sjur.brandeland
  2013-02-21 17:15 ` [PATCHv2 01/10] remoteproc: Bugfix: Deallocate firmware image on shutdown sjur.brandeland
  2013-02-21 17:15 ` [PATCHv2 02/10] remoteproc: Bugfix remove entry from list before freeing it sjur.brandeland
@ 2013-02-21 17:15 ` sjur.brandeland
  2013-03-19 15:04   ` Ohad Ben-Cohen
  2013-02-21 17:15 ` [PATCHv2 04/10] remoteproc: Parse ELF file to find resource table address sjur.brandeland
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 16+ messages in thread
From: sjur.brandeland @ 2013-02-21 17:15 UTC (permalink / raw)
  To: Ido Yariv, Ohad Ben-Cohen
  Cc: linux-kernel, Dmitry Tarnyagin, Linus Walleij, Erwan Yvin, sjur,
	Sjur Brændeland

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

Refactor rproc_elf_find_rsc_table and split out the scanning
for the section header named resource table. This is done to
prepare for loading firmware once.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
---
 drivers/remoteproc/remoteproc_elf_loader.c |   75 +++++++++++++++++-----------
 1 files changed, 46 insertions(+), 29 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index 0d36f94..ed12c16 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -208,41 +208,22 @@ rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
 	return ret;
 }
 
-/**
- * rproc_elf_find_rsc_table() - find the resource table
- * @rproc: the rproc handle
- * @fw: the ELF firmware image
- * @tablesz: place holder for providing back the table size
- *
- * This function finds the resource table inside the remote processor's
- * firmware. It is used both upon the registration of @rproc (in order
- * to look for and register the supported virito devices), and when the
- * @rproc is booted.
- *
- * Returns the pointer to the resource table if it is found, and write its
- * size into @tablesz. If a valid table isn't found, NULL is returned
- * (and @tablesz isn't set).
- */
-static struct resource_table *
-rproc_elf_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
-							int *tablesz)
+static struct elf32_shdr *
+find_rsc_shdr(struct device *dev, struct elf32_hdr *ehdr, size_t fw_size)
 {
-	struct elf32_hdr *ehdr;
 	struct elf32_shdr *shdr;
+	int i;
 	const char *name_table;
-	struct device *dev = &rproc->dev;
 	struct resource_table *table = NULL;
-	int i;
-	const u8 *elf_data = fw->data;
+	const u8 *elf_data = (void *)ehdr;
 
-	ehdr = (struct elf32_hdr *)elf_data;
+	/* look for the resource table and handle it */
 	shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff);
 	name_table = elf_data + shdr[ehdr->e_shstrndx].sh_offset;
 
-	/* look for the resource table and handle it */
 	for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
-		int size = shdr->sh_size;
-		int offset = shdr->sh_offset;
+		u32 size = shdr->sh_size;
+		u32 offset = shdr->sh_offset;
 
 		if (strcmp(name_table + shdr->sh_name, ".resource_table"))
 			continue;
@@ -250,7 +231,7 @@ rproc_elf_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
 		table = (struct resource_table *)(elf_data + offset);
 
 		/* make sure we have the entire table */
-		if (offset + size > fw->size) {
+		if (offset + size > fw_size || offset + size < size) {
 			dev_err(dev, "resource table truncated\n");
 			return NULL;
 		}
@@ -280,10 +261,46 @@ rproc_elf_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
 			return NULL;
 		}
 
-		*tablesz = shdr->sh_size;
-		break;
+		return shdr;
 	}
 
+	return NULL;
+}
+
+/**
+ * rproc_elf_find_rsc_table() - find the resource table
+ * @rproc: the rproc handle
+ * @fw: the ELF firmware image
+ * @tablesz: place holder for providing back the table size
+ *
+ * This function finds the resource table inside the remote processor's
+ * firmware. It is used both upon the registration of @rproc (in order
+ * to look for and register the supported virito devices), and when the
+ * @rproc is booted.
+ *
+ * Returns the pointer to the resource table if it is found, and write its
+ * size into @tablesz. If a valid table isn't found, NULL is returned
+ * (and @tablesz isn't set).
+ */
+static struct resource_table *
+rproc_elf_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
+							int *tablesz)
+{
+	struct elf32_hdr *ehdr;
+	struct elf32_shdr *shdr;
+	struct device *dev = &rproc->dev;
+	struct resource_table *table = NULL;
+	const u8 *elf_data = fw->data;
+
+	ehdr = (struct elf32_hdr *)elf_data;
+
+	shdr = find_rsc_shdr(dev, ehdr, fw->size);
+	if (!shdr)
+		return NULL;
+
+	table = (struct resource_table *)(elf_data + shdr->sh_offset);
+	*tablesz = shdr->sh_size;
+
 	return table;
 }
 
-- 
1.7.5.4


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

* [PATCHv2 04/10] remoteproc: Parse ELF file to find resource table address
  2013-02-21 17:15 [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space sjur.brandeland
                   ` (2 preceding siblings ...)
  2013-02-21 17:15 ` [PATCHv2 03/10] remoteproc: Refactor function rproc_elf_find_rsc_table sjur.brandeland
@ 2013-02-21 17:15 ` sjur.brandeland
  2013-02-24 16:21   ` Ido Yariv
  2013-02-21 17:15 ` [PATCHv2 05/10] remoteproc: Parse STE-firmware and " sjur.brandeland
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 16+ messages in thread
From: sjur.brandeland @ 2013-02-21 17:15 UTC (permalink / raw)
  To: Ido Yariv, Ohad Ben-Cohen
  Cc: linux-kernel, Dmitry Tarnyagin, Linus Walleij, Erwan Yvin, sjur,
	Sjur Brændeland

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

Add function find_rsc_table_va to firmware ops. This function
returns the location of the resource table in shared memory
after loading.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
---
 drivers/remoteproc/remoteproc_elf_loader.c |   17 ++++++++++++++++-
 drivers/remoteproc/remoteproc_internal.h   |   13 +++++++++++++
 2 files changed, 29 insertions(+), 1 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index ed12c16..3d6ec76 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -304,9 +304,24 @@ rproc_elf_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
 	return table;
 }
 
+static struct resource_table *rproc_elf_get_rsctab_va(struct rproc *rproc,
+						 const struct firmware *fw)
+{
+	struct elf32_shdr *shdr;
+
+	shdr = find_rsc_shdr(&rproc->dev, (struct elf32_hdr *)fw->data,
+				fw->size);
+	if (!shdr)
+		return NULL;
+
+	/* Find resource table in loaded segments */
+	return rproc_da_to_va(rproc, shdr->sh_addr, shdr->sh_size);
+}
+
 const struct rproc_fw_ops rproc_elf_fw_ops = {
 	.load = rproc_elf_load_segments,
 	.find_rsc_table = rproc_elf_find_rsc_table,
 	.sanity_check = rproc_elf_sanity_check,
-	.get_boot_addr = rproc_elf_get_boot_addr
+	.get_boot_addr = rproc_elf_get_boot_addr,
+	.get_rsctab_va = rproc_elf_get_rsctab_addr
 };
diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
index 7bb6648..b7372b1 100644
--- a/drivers/remoteproc/remoteproc_internal.h
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -32,6 +32,7 @@ struct rproc;
  *			expects to find it
  * @sanity_check:	sanity check the fw image
  * @get_boot_addr:	get boot address to entry point specified in firmware
+ * @get_rsctab_va:	get resouce table address as specified in firmware
  */
 struct rproc_fw_ops {
 	struct resource_table *(*find_rsc_table) (struct rproc *rproc,
@@ -40,6 +41,8 @@ struct rproc_fw_ops {
 	int (*load)(struct rproc *rproc, const struct firmware *fw);
 	int (*sanity_check)(struct rproc *rproc, const struct firmware *fw);
 	u32 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw);
+	struct resource_table *(*get_rsctab_va)(struct rproc *rproc,
+						const struct firmware *fw);
 };
 
 /* from remoteproc_core.c */
@@ -102,6 +105,16 @@ struct resource_table *rproc_find_rsc_table(struct rproc *rproc,
 	return NULL;
 }
 
+static inline
+struct resource_table *rproc_get_rsctab_addr(struct rproc *rproc,
+				const struct firmware *fw)
+{
+	if (rproc->fw_ops->get_rsctab_addr)
+		return rproc->fw_ops->get_rsctab_addr(rproc, fw);
+
+	return NULL;
+}
+
 extern const struct rproc_fw_ops rproc_elf_fw_ops;
 
 #endif /* REMOTEPROC_INTERNAL_H */
-- 
1.7.5.4


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

* [PATCHv2 05/10] remoteproc: Parse STE-firmware and find resource table address
  2013-02-21 17:15 [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space sjur.brandeland
                   ` (3 preceding siblings ...)
  2013-02-21 17:15 ` [PATCHv2 04/10] remoteproc: Parse ELF file to find resource table address sjur.brandeland
@ 2013-02-21 17:15 ` sjur.brandeland
  2013-02-21 17:15 ` [PATCHv2 06/10] remoteproc: Code cleanup of resource parsing sjur.brandeland
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: sjur.brandeland @ 2013-02-21 17:15 UTC (permalink / raw)
  To: Ido Yariv, Ohad Ben-Cohen
  Cc: linux-kernel, Dmitry Tarnyagin, Linus Walleij, Erwan Yvin, sjur,
	Sjur Brændeland

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

Parse the STE firmware and scan the TOC-table to find the address
of the resource table.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
---
 drivers/remoteproc/remoteproc_elf_loader.c |    2 +-
 drivers/remoteproc/remoteproc_internal.h   |    6 ++--
 drivers/remoteproc/ste_modem_rproc.c       |   43 +++++++++++++++++++---------
 3 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index 3d6ec76..b93551f 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -323,5 +323,5 @@ const struct rproc_fw_ops rproc_elf_fw_ops = {
 	.find_rsc_table = rproc_elf_find_rsc_table,
 	.sanity_check = rproc_elf_sanity_check,
 	.get_boot_addr = rproc_elf_get_boot_addr,
-	.get_rsctab_va = rproc_elf_get_rsctab_addr
+	.get_rsctab_va = rproc_elf_get_rsctab_va
 };
diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
index b7372b1..91aa7ca 100644
--- a/drivers/remoteproc/remoteproc_internal.h
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -106,11 +106,11 @@ struct resource_table *rproc_find_rsc_table(struct rproc *rproc,
 }
 
 static inline
-struct resource_table *rproc_get_rsctab_addr(struct rproc *rproc,
+struct resource_table *rproc_get_rsctab_va(struct rproc *rproc,
 				const struct firmware *fw)
 {
-	if (rproc->fw_ops->get_rsctab_addr)
-		return rproc->fw_ops->get_rsctab_addr(rproc, fw);
+	if (rproc->fw_ops->get_rsctab_va)
+		return rproc->fw_ops->get_rsctab_va(rproc, fw);
 
 	return NULL;
 }
diff --git a/drivers/remoteproc/ste_modem_rproc.c b/drivers/remoteproc/ste_modem_rproc.c
index fb95c42..09f1b4e 100644
--- a/drivers/remoteproc/ste_modem_rproc.c
+++ b/drivers/remoteproc/ste_modem_rproc.c
@@ -64,26 +64,18 @@ static int sproc_load_segments(struct rproc *rproc, const struct firmware *fw)
 }
 
 /* Find the entry for resource table in the Table of Content */
-static struct ste_toc_entry *sproc_find_rsc_entry(const struct firmware *fw)
+static const struct ste_toc_entry *sproc_find_rsc_entry(const void *data)
 {
 	int i;
-	struct ste_toc *toc;
-
-	if (!fw)
-		return NULL;
-
-	toc = (void *)fw->data;
+	const struct ste_toc *toc;
+	toc = data;
 
 	/* Search the table for the resource table */
 	for (i = 0; i < SPROC_MAX_TOC_ENTRIES &&
 		    toc->table[i].start != 0xffffffff; i++) {
-
 		if (!strncmp(toc->table[i].name, SPROC_RESOURCE_NAME,
-			     sizeof(toc->table[i].name))) {
-			if (toc->table[i].start > fw->size)
-				return NULL;
+			     sizeof(toc->table[i].name)))
 			return &toc->table[i];
-		}
 	}
 
 	return NULL;
@@ -96,9 +88,12 @@ sproc_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
 {
 	struct sproc *sproc = rproc->priv;
 	struct resource_table *table;
-	struct ste_toc_entry *entry;
+	const struct ste_toc_entry *entry;
 
-	entry = sproc_find_rsc_entry(fw);
+	if (!fw)
+		return NULL;
+
+	entry = sproc_find_rsc_entry(fw->data);
 	if (!entry) {
 		sproc_err(sproc, "resource table not found in fw\n");
 		return NULL;
@@ -149,10 +144,30 @@ sproc_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
 	return table;
 }
 
+/* Find the resource table inside the remote processor's firmware. */
+static struct resource_table *
+sproc_get_rsctab_va(struct rproc *rproc, const struct firmware *fw)
+{
+	struct sproc *sproc = rproc->priv;
+	const struct ste_toc_entry *entry;
+
+	if (!fw || !sproc->fw_addr)
+		return NULL;
+
+	entry = sproc_find_rsc_entry(sproc->fw_addr);
+	if (!entry) {
+		sproc_err(sproc, "resource table not found in fw\n");
+		return NULL;
+	}
+
+	return sproc->fw_addr + entry->start;
+}
+
 /* STE modem firmware handler operations */
 const struct rproc_fw_ops sproc_fw_ops = {
 	.load = sproc_load_segments,
 	.find_rsc_table = sproc_find_rsc_table,
+	.get_rsctab_va = sproc_get_rsctab_va,
 };
 
 /* Kick the modem with specified notification id */
-- 
1.7.5.4


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

* [PATCHv2 06/10] remoteproc: Code cleanup of resource parsing
  2013-02-21 17:15 [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space sjur.brandeland
                   ` (4 preceding siblings ...)
  2013-02-21 17:15 ` [PATCHv2 05/10] remoteproc: Parse STE-firmware and " sjur.brandeland
@ 2013-02-21 17:15 ` sjur.brandeland
  2013-03-21 13:16   ` Ohad Ben-Cohen
  2013-02-21 17:15 ` [PATCHv2 07/10] remoteproc: Calculate max_notifyid by counting vrings sjur.brandeland
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 16+ messages in thread
From: sjur.brandeland @ 2013-02-21 17:15 UTC (permalink / raw)
  To: Ido Yariv, Ohad Ben-Cohen
  Cc: linux-kernel, Dmitry Tarnyagin, Linus Walleij, Erwan Yvin, sjur,
	Sjur Brændeland

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

Combine the almost identical functions rproc_handle_virtio_rsc
and rproc_handle_boot_rsc.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
---
 drivers/remoteproc/remoteproc_core.c |   51 ++++++++--------------------------
 1 files changed, 12 insertions(+), 39 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 752b507..6e515d7 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -679,16 +679,22 @@ free_carv:
  * A lookup table for resource handlers. The indices are defined in
  * enum fw_resource_type.
  */
-static rproc_handle_resource_t rproc_handle_rsc[] = {
+static rproc_handle_resource_t rproc_handle_rsc[RSC_LAST] = {
 	[RSC_CARVEOUT] = (rproc_handle_resource_t)rproc_handle_carveout,
 	[RSC_DEVMEM] = (rproc_handle_resource_t)rproc_handle_devmem,
 	[RSC_TRACE] = (rproc_handle_resource_t)rproc_handle_trace,
 	[RSC_VDEV] = NULL, /* VDEVs were handled upon registrarion */
 };
 
+static rproc_handle_resource_t rproc_handle_vdev_rsc[RSC_LAST] = {
+	[RSC_VDEV] = (rproc_handle_resource_t)rproc_handle_vdev,
+};
+
 /* handle firmware resource entries before booting the remote processor */
 static int
-rproc_handle_boot_rsc(struct rproc *rproc, struct resource_table *table, int len)
+rproc_handle_resource(struct rproc *rproc, struct resource_table *table,
+				int len,
+				rproc_handle_resource_t handlers[RSC_LAST])
 {
 	struct device *dev = &rproc->dev;
 	rproc_handle_resource_t handler;
@@ -713,7 +719,7 @@ rproc_handle_boot_rsc(struct rproc *rproc, struct resource_table *table, int len
 			continue;
 		}
 
-		handler = rproc_handle_rsc[hdr->type];
+		handler = handlers[hdr->type];
 		if (!handler)
 			continue;
 
@@ -725,40 +731,6 @@ rproc_handle_boot_rsc(struct rproc *rproc, struct resource_table *table, int len
 	return ret;
 }
 
-/* handle firmware resource entries while registering the remote processor */
-static int
-rproc_handle_virtio_rsc(struct rproc *rproc, struct resource_table *table, int len)
-{
-	struct device *dev = &rproc->dev;
-	int ret = 0, i;
-
-	for (i = 0; i < table->num; i++) {
-		int offset = table->offset[i];
-		struct fw_rsc_hdr *hdr = (void *)table + offset;
-		int avail = len - offset - sizeof(*hdr);
-		struct fw_rsc_vdev *vrsc;
-
-		/* make sure table isn't truncated */
-		if (avail < 0) {
-			dev_err(dev, "rsc table is truncated\n");
-			return -EINVAL;
-		}
-
-		dev_dbg(dev, "%s: rsc type %d\n", __func__, hdr->type);
-
-		if (hdr->type != RSC_VDEV)
-			continue;
-
-		vrsc = (struct fw_rsc_vdev *)hdr->data;
-
-		ret = rproc_handle_vdev(rproc, vrsc, avail);
-		if (ret)
-			break;
-	}
-
-	return ret;
-}
-
 /**
  * rproc_resource_cleanup() - clean up and free all acquired resources
  * @rproc: rproc handle
@@ -838,7 +810,7 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
 	}
 
 	/* handle fw resources which are required to boot rproc */
-	ret = rproc_handle_boot_rsc(rproc, table, tablesz);
+	ret = rproc_handle_resource(rproc, table, tablesz, rproc_handle_rsc);
 	if (ret) {
 		dev_err(dev, "Failed to process resources: %d\n", ret);
 		goto clean_up;
@@ -893,7 +865,8 @@ static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
 		goto out;
 
 	/* look for virtio devices and register them */
-	ret = rproc_handle_virtio_rsc(rproc, table, tablesz);
+	ret = rproc_handle_resource(rproc, table, tablesz,
+						rproc_handle_vdev_rsc);
 	if (ret)
 		goto out;
 
-- 
1.7.5.4


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

* [PATCHv2 07/10] remoteproc: Calculate max_notifyid by counting vrings
  2013-02-21 17:15 [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space sjur.brandeland
                   ` (5 preceding siblings ...)
  2013-02-21 17:15 ` [PATCHv2 06/10] remoteproc: Code cleanup of resource parsing sjur.brandeland
@ 2013-02-21 17:15 ` sjur.brandeland
  2013-02-21 17:15 ` [PATCHv2 08/10] remoteproc: Always perserve resource table data sjur.brandeland
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: sjur.brandeland @ 2013-02-21 17:15 UTC (permalink / raw)
  To: Ido Yariv, Ohad Ben-Cohen
  Cc: linux-kernel, Dmitry Tarnyagin, Linus Walleij, Erwan Yvin, sjur,
	Sjur Brændeland

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

Simplify handling of max_notifyid by simply counting the
number of vrings.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
---
 drivers/remoteproc/remoteproc_core.c |   33 ++++++++++++++++++---------------
 drivers/remoteproc/ste_modem_rproc.c |    2 +-
 2 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 6e515d7..a747d95 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -228,9 +228,6 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
 		return ret;
 	}
 
-	/* Store largest notifyid */
-	rproc->max_notifyid = max(rproc->max_notifyid, notifyid);
-
 	dev_dbg(dev, "vring%d: va %p dma %llx size %x idr %d\n", i, va,
 				(unsigned long long)dma, size, notifyid);
 
@@ -272,25 +269,13 @@ rproc_parse_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i)
 	return 0;
 }
 
-static int rproc_max_notifyid(int id, void *p, void *data)
-{
-	int *maxid = data;
-	*maxid = max(*maxid, id);
-	return 0;
-}
-
 void rproc_free_vring(struct rproc_vring *rvring)
 {
 	int size = PAGE_ALIGN(vring_size(rvring->len, rvring->align));
 	struct rproc *rproc = rvring->rvdev->rproc;
-	int maxid = 0;
 
 	dma_free_coherent(rproc->dev.parent, size, rvring->va, rvring->dma);
 	idr_remove(&rproc->notifyids, rvring->notifyid);
-
-	/* Find the largest remaining notifyid */
-	idr_for_each(&rproc->notifyids, rproc_max_notifyid, &maxid);
-	rproc->max_notifyid = maxid;
 }
 
 /**
@@ -675,6 +660,15 @@ free_carv:
 	return ret;
 }
 
+static int rproc_handle_notifyid(struct rproc *rproc, struct fw_rsc_vdev *rsc,
+								int avail)
+{
+	/* Summerize the number of notification IDs */
+	rproc->max_notifyid += rsc->num_of_vrings;
+
+	return 0;
+}
+
 /*
  * A lookup table for resource handlers. The indices are defined in
  * enum fw_resource_type.
@@ -690,6 +684,10 @@ static rproc_handle_resource_t rproc_handle_vdev_rsc[RSC_LAST] = {
 	[RSC_VDEV] = (rproc_handle_resource_t)rproc_handle_vdev,
 };
 
+static rproc_handle_resource_t rproc_handle_notifyid_rsc[RSC_LAST] = {
+	[RSC_VDEV] = (rproc_handle_resource_t)rproc_handle_notifyid,
+};
+
 /* handle firmware resource entries before booting the remote processor */
 static int
 rproc_handle_resource(struct rproc *rproc, struct resource_table *table,
@@ -864,6 +862,11 @@ static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
 	if (!table)
 		goto out;
 
+	/* count the number of notify-ids */
+	rproc->max_notifyid = -1;
+	ret = rproc_handle_resource(rproc, table, tablesz,
+						rproc_handle_notifyid_rsc);
+
 	/* look for virtio devices and register them */
 	ret = rproc_handle_resource(rproc, table, tablesz,
 						rproc_handle_vdev_rsc);
diff --git a/drivers/remoteproc/ste_modem_rproc.c b/drivers/remoteproc/ste_modem_rproc.c
index 09f1b4e..bcb2b2d 100644
--- a/drivers/remoteproc/ste_modem_rproc.c
+++ b/drivers/remoteproc/ste_modem_rproc.c
@@ -213,7 +213,7 @@ static int sproc_start(struct rproc *rproc)
 	}
 
 	/* Subscribe to notifications */
-	for (i = 0; i < rproc->max_notifyid; i++) {
+	for (i = 0; i <= rproc->max_notifyid; i++) {
 		err = sproc->mdev->ops.kick_subscribe(sproc->mdev, i);
 		if (err) {
 			sproc_err(sproc,
-- 
1.7.5.4


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

* [PATCHv2 08/10] remoteproc: Always perserve resource table data
  2013-02-21 17:15 [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space sjur.brandeland
                   ` (6 preceding siblings ...)
  2013-02-21 17:15 ` [PATCHv2 07/10] remoteproc: Calculate max_notifyid by counting vrings sjur.brandeland
@ 2013-02-21 17:15 ` sjur.brandeland
  2013-02-21 17:15 ` [PATCHv2 09/10] remoteproc: Support virtio config space sjur.brandeland
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: sjur.brandeland @ 2013-02-21 17:15 UTC (permalink / raw)
  To: Ido Yariv, Ohad Ben-Cohen
  Cc: linux-kernel, Dmitry Tarnyagin, Linus Walleij, Erwan Yvin, sjur,
	Sjur Brændeland

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

Copy resource table from first to second firmware loading.
After firmware is loaded to memory, update the vdevs resource
pointer to the resource table kept in device memory.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
---
 drivers/remoteproc/Kconfig           |    1 +
 drivers/remoteproc/remoteproc_core.c |   99 ++++++++++++++++++++++++++-------
 include/linux/remoteproc.h           |    9 +++
 3 files changed, 88 insertions(+), 21 deletions(-)

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 96ce101..ea060e9 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -5,6 +5,7 @@ config REMOTEPROC
 	tristate
 	depends on EXPERIMENTAL
 	depends on HAS_DMA
+	select CRC32
 	select FW_CONFIG
 	select VIRTIO
 
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index a747d95..6466f39 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -37,6 +37,7 @@
 #include <linux/iommu.h>
 #include <linux/idr.h>
 #include <linux/elf.h>
+#include <linux/crc32.h>
 #include <linux/virtio_ids.h>
 #include <linux/virtio_ring.h>
 #include <asm/byteorder.h>
@@ -45,7 +46,8 @@
 
 typedef int (*rproc_handle_resources_t)(struct rproc *rproc,
 				struct resource_table *table, int len);
-typedef int (*rproc_handle_resource_t)(struct rproc *rproc, void *, int avail);
+typedef int (*rproc_handle_resource_t)(struct rproc *rproc,
+				 void *, int offset, int avail);
 
 /* Unique indices for remoteproc devices */
 static DEFINE_IDA(rproc_dev_index);
@@ -306,7 +308,7 @@ void rproc_free_vring(struct rproc_vring *rvring)
  * Returns 0 on success, or an appropriate error code otherwise
  */
 static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
-								int avail)
+							int offset, int avail)
 {
 	struct device *dev = &rproc->dev;
 	struct rproc_vdev *rvdev;
@@ -350,6 +352,9 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
 	/* remember the device features */
 	rvdev->dfeatures = rsc->dfeatures;
 
+	/* remember the resource offset*/
+	rvdev->rsc_offset = offset;
+
 	list_add_tail(&rvdev->node, &rproc->rvdevs);
 
 	/* it is now safe to add the virtio device */
@@ -383,7 +388,7 @@ free_rvdev:
  * Returns 0 on success, or an appropriate error code otherwise
  */
 static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc,
-								int avail)
+							int offset, int avail)
 {
 	struct rproc_mem_entry *trace;
 	struct device *dev = &rproc->dev;
@@ -465,7 +470,7 @@ static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc,
  * are outside those ranges.
  */
 static int rproc_handle_devmem(struct rproc *rproc, struct fw_rsc_devmem *rsc,
-								int avail)
+							int offset, int avail)
 {
 	struct rproc_mem_entry *mapping;
 	struct device *dev = &rproc->dev;
@@ -538,7 +543,9 @@ out:
  * pressure is important; it may have a substantial impact on performance.
  */
 static int rproc_handle_carveout(struct rproc *rproc,
-				struct fw_rsc_carveout *rsc, int avail)
+						struct fw_rsc_carveout *rsc,
+						int offset, int avail)
+
 {
 	struct rproc_mem_entry *carveout, *mapping;
 	struct device *dev = &rproc->dev;
@@ -661,7 +668,7 @@ free_carv:
 }
 
 static int rproc_handle_notifyid(struct rproc *rproc, struct fw_rsc_vdev *rsc,
-								int avail)
+							int offset, int avail)
 {
 	/* Summerize the number of notification IDs */
 	rproc->max_notifyid += rsc->num_of_vrings;
@@ -690,17 +697,16 @@ static rproc_handle_resource_t rproc_handle_notifyid_rsc[RSC_LAST] = {
 
 /* handle firmware resource entries before booting the remote processor */
 static int
-rproc_handle_resource(struct rproc *rproc, struct resource_table *table,
-				int len,
-				rproc_handle_resource_t handlers[RSC_LAST])
+rproc_handle_resource(struct rproc *rproc, int len,
+		      rproc_handle_resource_t handlers[RSC_LAST])
 {
 	struct device *dev = &rproc->dev;
 	rproc_handle_resource_t handler;
 	int ret = 0, i;
 
-	for (i = 0; i < table->num; i++) {
-		int offset = table->offset[i];
-		struct fw_rsc_hdr *hdr = (void *)table + offset;
+	for (i = 0; i < rproc->rsc->num; i++) {
+		int offset = rproc->rsc->offset[i];
+		struct fw_rsc_hdr *hdr = (void *)rproc->rsc + offset;
 		int avail = len - offset - sizeof(*hdr);
 		void *rsc = (void *)hdr + sizeof(*hdr);
 
@@ -721,7 +727,7 @@ rproc_handle_resource(struct rproc *rproc, struct resource_table *table,
 		if (!handler)
 			continue;
 
-		ret = handler(rproc, rsc, avail);
+		ret = handler(rproc, rsc, offset + sizeof(*hdr), avail);
 		if (ret)
 			break;
 	}
@@ -779,9 +785,12 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
 {
 	struct device *dev = &rproc->dev;
 	const char *name = rproc->firmware;
-	struct resource_table *table;
+	struct resource_table *table, *devmem_rsc;
 	int ret, tablesz;
 
+	if (!rproc->rsc)
+		return -ENOMEM;
+
 	ret = rproc_fw_sanity_check(rproc, fw);
 	if (ret)
 		return ret;
@@ -807,8 +816,15 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
 		goto clean_up;
 	}
 
+	/* Verify that resource table in loaded fw is unchanged */
+	if (rproc->rsc_csum != crc32(0, table, tablesz)) {
+		dev_err(dev, "resource checksum failed, fw changed?\n");
+		ret = -EINVAL;
+		goto clean_up;
+	}
+
 	/* handle fw resources which are required to boot rproc */
-	ret = rproc_handle_resource(rproc, table, tablesz, rproc_handle_rsc);
+	ret = rproc_handle_resource(rproc, tablesz, rproc_handle_rsc);
 	if (ret) {
 		dev_err(dev, "Failed to process resources: %d\n", ret);
 		goto clean_up;
@@ -821,6 +837,19 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
 		goto clean_up;
 	}
 
+	/*
+	 * The starting device has been given the rproc->rsc_copy as the
+	 * resource table. The address of the vring along with the other
+	 * allocated resources (carveouts etc) is stored in rsc_copy.
+	 * In order to pass this information to the remote device we must
+	 * copy this information to device memory.
+	 */
+	devmem_rsc = rproc_get_rsctab_va(rproc, fw);
+	if (!devmem_rsc)
+		goto clean_up;
+
+	memcpy(devmem_rsc, rproc->rsc_copy, tablesz);
+
 	/* power up the remote processor */
 	ret = rproc->ops->start(rproc);
 	if (ret) {
@@ -828,6 +857,12 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
 		goto clean_up;
 	}
 
+	/*
+	 * Update rproc->rsc so that all subsequent allocations updates the
+	 * resource table in device memory.
+	 */
+	rproc->rsc = devmem_rsc;
+
 	rproc->state = RPROC_RUNNING;
 
 	dev_info(dev, "remote processor %s is now up\n", rproc->name);
@@ -862,17 +897,30 @@ static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
 	if (!table)
 		goto out;
 
+	rproc->rsc_csum = crc32(0, table, tablesz);
+
+	/*
+	 * Create a copy of the resource table. When a virtio device starts
+	 * and calls vring_new_virtqueue() the address of the allocated vring
+	 * will be stored in the rsc_copy. Before the device is started,
+	 * rsc_copy will be copied into devic memory.
+	 */
+	rproc->rsc_copy = kmalloc(tablesz, GFP_KERNEL);
+	if (!rproc->rsc_copy)
+		goto out;
+
+	memcpy(rproc->rsc_copy, table, tablesz);
+	rproc->rsc = rproc->rsc_copy;
+
 	/* count the number of notify-ids */
 	rproc->max_notifyid = -1;
-	ret = rproc_handle_resource(rproc, table, tablesz,
-						rproc_handle_notifyid_rsc);
-
-	/* look for virtio devices and register them */
-	ret = rproc_handle_resource(rproc, table, tablesz,
-						rproc_handle_vdev_rsc);
+	ret = rproc_handle_resource(rproc, tablesz, rproc_handle_notifyid_rsc);
 	if (ret)
 		goto out;
 
+	/* look for virtio devices and register them */
+	ret = rproc_handle_resource(rproc, tablesz, rproc_handle_vdev_rsc);
+
 out:
 	release_firmware(fw);
 	/* allow rproc_del() contexts, if any, to proceed */
@@ -930,6 +978,9 @@ int rproc_trigger_recovery(struct rproc *rproc)
 	/* wait until there is no more rproc users */
 	wait_for_completion(&rproc->crash_comp);
 
+	/* Free the copy of the resource table */
+	kfree(rproc->rsc_copy);
+
 	return rproc_add_virtio_devices(rproc);
 }
 
@@ -1085,6 +1136,9 @@ void rproc_shutdown(struct rproc *rproc)
 
 	rproc_disable_iommu(rproc);
 
+	/* Give the next start a clean resource table */
+	rproc->rsc = rproc->rsc_copy;
+
 	/* if in crash state, unlock crash handler */
 	if (rproc->state == RPROC_CRASHED)
 		complete_all(&rproc->crash_comp);
@@ -1296,6 +1350,9 @@ int rproc_del(struct rproc *rproc)
 	list_for_each_entry_safe(rvdev, tmp, &rproc->rvdevs, node)
 		rproc_remove_virtio_dev(rvdev);
 
+	/* Free the copy of the resource table */
+	kfree(rproc->rsc_copy);
+
 	device_del(&rproc->dev);
 
 	return 0;
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index faf3332..272f088 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -401,6 +401,9 @@ enum rproc_crash_type {
  * @crash_comp: completion used to sync crash handler and the rproc reload
  * @recovery_disabled: flag that state if recovery was disabled
  * @max_notifyid: largest allocated notify id.
+ * @rsc: resource table entry
+ * @rsc_copy: copy of the resource table
+ * @rsc_csum: checksum of the resource table
  */
 struct rproc {
 	struct klist_node node;
@@ -429,9 +432,13 @@ struct rproc {
 	struct completion crash_comp;
 	bool recovery_disabled;
 	int max_notifyid;
+	struct resource_table *rsc;
+	struct resource_table *rsc_copy;
+	u32 rsc_csum;
 };
 
 /* we currently support only two vrings per rvdev */
+
 #define RVDEV_NUM_VRINGS 2
 
 /**
@@ -464,6 +471,7 @@ struct rproc_vring {
  * @vring: the vrings for this vdev
  * @dfeatures: virtio device features
  * @gfeatures: virtio guest features
+ * @rsc_offset: offset of the vdev's resource entry
  */
 struct rproc_vdev {
 	struct list_head node;
@@ -472,6 +480,7 @@ struct rproc_vdev {
 	struct rproc_vring vring[RVDEV_NUM_VRINGS];
 	unsigned long dfeatures;
 	unsigned long gfeatures;
+	u32 rsc_offset;
 };
 
 struct rproc *rproc_alloc(struct device *dev, const char *name,
-- 
1.7.5.4


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

* [PATCHv2 09/10] remoteproc: Support virtio config space.
  2013-02-21 17:15 [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space sjur.brandeland
                   ` (7 preceding siblings ...)
  2013-02-21 17:15 ` [PATCHv2 08/10] remoteproc: Always perserve resource table data sjur.brandeland
@ 2013-02-21 17:15 ` sjur.brandeland
  2013-02-21 17:15 ` [PATCHv2 10/10] remoteproc: Set vring addresses in resource table sjur.brandeland
  2013-04-05  5:59 ` [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space Ohad Ben-Cohen
  10 siblings, 0 replies; 16+ messages in thread
From: sjur.brandeland @ 2013-02-21 17:15 UTC (permalink / raw)
  To: Ido Yariv, Ohad Ben-Cohen
  Cc: linux-kernel, Dmitry Tarnyagin, Linus Walleij, Erwan Yvin, sjur,
	Sjur Brændeland

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

Support virtio configuration space and device status. The virtio
device can now access the resource table in shared memory.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
---
 drivers/remoteproc/remoteproc_core.c   |    3 --
 drivers/remoteproc/remoteproc_virtio.c |   61 ++++++++++++++++++++++++--------
 include/linux/remoteproc.h             |    4 --
 3 files changed, 46 insertions(+), 22 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 6466f39..93529e3 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -349,9 +349,6 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
 			goto free_rvdev;
 	}
 
-	/* remember the device features */
-	rvdev->dfeatures = rsc->dfeatures;
-
 	/* remember the resource offset*/
 	rvdev->rsc_offset = offset;
 
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index 9e198e5..b32bf1f 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -173,25 +173,29 @@ error:
 	return ret;
 }
 
-/*
- * We don't support yet real virtio status semantics.
- *
- * The plan is to provide this via the VDEV resource entry
- * which is part of the firmware: this way the remote processor
- * will be able to access the status values as set by us.
- */
 static u8 rproc_virtio_get_status(struct virtio_device *vdev)
 {
-	return 0;
+	struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
+	struct fw_rsc_vdev *rsc = (void *)rvdev->rproc->rsc + rvdev->rsc_offset;
+
+	return rsc->status;
 }
 
 static void rproc_virtio_set_status(struct virtio_device *vdev, u8 status)
 {
+	struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
+	struct fw_rsc_vdev *rsc = (void *)rvdev->rproc->rsc + rvdev->rsc_offset;
+
+	rsc->status = status;
 	dev_dbg(&vdev->dev, "status: %d\n", status);
 }
 
 static void rproc_virtio_reset(struct virtio_device *vdev)
 {
+	struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
+	struct fw_rsc_vdev *rsc = (void *)rvdev->rproc->rsc + rvdev->rsc_offset;
+
+	rsc->status = 0;
 	dev_dbg(&vdev->dev, "reset !\n");
 }
 
@@ -199,13 +203,15 @@ static void rproc_virtio_reset(struct virtio_device *vdev)
 static u32 rproc_virtio_get_features(struct virtio_device *vdev)
 {
 	struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
+	struct fw_rsc_vdev *rsc = (void *)rvdev->rproc->rsc + rvdev->rsc_offset;
 
-	return rvdev->dfeatures;
+	return rsc->dfeatures;
 }
 
 static void rproc_virtio_finalize_features(struct virtio_device *vdev)
 {
 	struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
+	struct fw_rsc_vdev *rsc = (void *)rvdev->rproc->rsc + rvdev->rsc_offset;
 
 	/* Give virtio_ring a chance to accept features */
 	vring_transport_features(vdev);
@@ -213,13 +219,36 @@ static void rproc_virtio_finalize_features(struct virtio_device *vdev)
 	/*
 	 * Remember the finalized features of our vdev, and provide it
 	 * to the remote processor once it is powered on.
-	 *
-	 * Similarly to the status field, we don't expose yet the negotiated
-	 * features to the remote processors at this point. This will be
-	 * fixed as part of a small resource table overhaul and then an
-	 * extension of the virtio resource entries.
 	 */
-	rvdev->gfeatures = vdev->features[0];
+	rsc->gfeatures = vdev->features[0];
+}
+
+static void rproc_virtio_get(struct virtio_device *vdev, unsigned offset,
+							void *buf, unsigned len)
+{
+	struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
+	struct fw_rsc_vdev *rsc = (void *)rvdev->rproc->rsc + rvdev->rsc_offset;
+	void *cfg = &rsc->vring[rsc->num_of_vrings];
+
+	if (offset + len > rsc->config_len || offset + len < len)
+		dev_err(&vdev->dev,
+			"rproc_virtio_get: access out of bounds\n");
+	else
+		memcpy(buf, cfg + offset, len);
+}
+
+static void rproc_virtio_set(struct virtio_device *vdev, unsigned offset,
+		      const void *buf, unsigned len)
+{
+	struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
+	struct fw_rsc_vdev *rsc = (void *)rvdev->rproc->rsc + rvdev->rsc_offset;
+	void *cfg = &rsc->vring[rsc->num_of_vrings];
+
+	if (offset + len > rsc->config_len || offset + len < len)
+		dev_err(&vdev->dev,
+			"rproc_virtio_set: access out of bounds\n");
+	else
+		memcpy(cfg + offset, buf, len);
 }
 
 static struct virtio_config_ops rproc_virtio_config_ops = {
@@ -230,6 +259,8 @@ static struct virtio_config_ops rproc_virtio_config_ops = {
 	.reset		= rproc_virtio_reset,
 	.set_status	= rproc_virtio_set_status,
 	.get_status	= rproc_virtio_get_status,
+	.get		= rproc_virtio_get,
+	.set		= rproc_virtio_set,
 };
 
 /*
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 272f088..ca1c1b5 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -469,8 +469,6 @@ struct rproc_vring {
  * @rproc: the rproc handle
  * @vdev: the virio device
  * @vring: the vrings for this vdev
- * @dfeatures: virtio device features
- * @gfeatures: virtio guest features
  * @rsc_offset: offset of the vdev's resource entry
  */
 struct rproc_vdev {
@@ -478,8 +476,6 @@ struct rproc_vdev {
 	struct rproc *rproc;
 	struct virtio_device vdev;
 	struct rproc_vring vring[RVDEV_NUM_VRINGS];
-	unsigned long dfeatures;
-	unsigned long gfeatures;
 	u32 rsc_offset;
 };
 
-- 
1.7.5.4


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

* [PATCHv2 10/10] remoteproc: Set vring addresses in resource table
  2013-02-21 17:15 [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space sjur.brandeland
                   ` (8 preceding siblings ...)
  2013-02-21 17:15 ` [PATCHv2 09/10] remoteproc: Support virtio config space sjur.brandeland
@ 2013-02-21 17:15 ` sjur.brandeland
  2013-04-05  5:59 ` [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space Ohad Ben-Cohen
  10 siblings, 0 replies; 16+ messages in thread
From: sjur.brandeland @ 2013-02-21 17:15 UTC (permalink / raw)
  To: Ido Yariv, Ohad Ben-Cohen
  Cc: linux-kernel, Dmitry Tarnyagin, Linus Walleij, Erwan Yvin, sjur,
	Sjur Brændeland

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

Set the vring addresses in the resource table so that
the remote device can read the actual addresses used.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
---
 drivers/remoteproc/remoteproc_core.c |   19 +++++++++++++++++--
 1 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 93529e3..63f3d07 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -194,6 +194,7 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
 	struct rproc *rproc = rvdev->rproc;
 	struct device *dev = &rproc->dev;
 	struct rproc_vring *rvring = &rvdev->vring[i];
+	struct fw_rsc_vdev *rsc;
 	dma_addr_t dma;
 	void *va;
 	int ret, size, notifyid;
@@ -209,7 +210,6 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
 	/*
 	 * Allocate non-cacheable memory for the vring. In the future
 	 * this call will also configure the IOMMU for us
-	 * TODO: let the rproc know the da of this vring
 	 */
 	va = dma_alloc_coherent(dev->parent, size, &dma, GFP_KERNEL);
 	if (!va) {
@@ -220,7 +220,6 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
 	/*
 	 * Assign an rproc-wide unique index for this vring
 	 * TODO: assign a notifyid for rvdev updates as well
-	 * TODO: let the rproc know the notifyid of this vring
 	 * TODO: support predefined notifyids (via resource table)
 	 */
 	ret = idr_get_new(&rproc->notifyids, rvring, &notifyid);
@@ -237,6 +236,15 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
 	rvring->dma = dma;
 	rvring->notifyid = notifyid;
 
+	/*
+	 * Let the rproc know the notifyid and da of this vring.
+	 * Not all platforms use dma_alloc_coherent to automatically
+	 * set up the iommu. In this case the device address (da) will
+	 * hold the physical address and not the device address.
+	 */
+	rsc = (void *)rproc->rsc + rvdev->rsc_offset;
+	rsc->vring[i].da = dma;
+	rsc->vring[i].notifyid = notifyid;
 	return 0;
 }
 
@@ -275,9 +283,16 @@ void rproc_free_vring(struct rproc_vring *rvring)
 {
 	int size = PAGE_ALIGN(vring_size(rvring->len, rvring->align));
 	struct rproc *rproc = rvring->rvdev->rproc;
+	int idx = rvring->rvdev->vring - rvring;
+	struct fw_rsc_vdev *rsc;
 
 	dma_free_coherent(rproc->dev.parent, size, rvring->va, rvring->dma);
 	idr_remove(&rproc->notifyids, rvring->notifyid);
+
+	/* reset resource entry info */
+	rsc = (void *)rproc->rsc + rvring->rvdev->rsc_offset;
+	rsc->vring[idx].da = 0;
+	rsc->vring[idx].notifyid = -1;
 }
 
 /**
-- 
1.7.5.4


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

* Re: [PATCHv2 04/10] remoteproc: Parse ELF file to find resource table address
  2013-02-21 17:15 ` [PATCHv2 04/10] remoteproc: Parse ELF file to find resource table address sjur.brandeland
@ 2013-02-24 16:21   ` Ido Yariv
  0 siblings, 0 replies; 16+ messages in thread
From: Ido Yariv @ 2013-02-24 16:21 UTC (permalink / raw)
  To: sjur.brandeland
  Cc: Ohad Ben-Cohen, linux-kernel, Dmitry Tarnyagin, Linus Walleij,
	Erwan Yvin, sjur

Hi Sjur,

On Thu, Feb 21, 2013 at 06:15:34PM +0100, sjur.brandeland@stericsson.com wrote:
> From: Sjur Brændeland <sjur.brandeland@stericsson.com>
> 
> Add function find_rsc_table_va to firmware ops. This function
> returns the location of the resource table in shared memory
> after loading.
> 
> Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
> ---
>  drivers/remoteproc/remoteproc_elf_loader.c |   17 ++++++++++++++++-
>  drivers/remoteproc/remoteproc_internal.h   |   13 +++++++++++++
>  2 files changed, 29 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
> index ed12c16..3d6ec76 100644
> --- a/drivers/remoteproc/remoteproc_elf_loader.c
> +++ b/drivers/remoteproc/remoteproc_elf_loader.c
> @@ -304,9 +304,24 @@ rproc_elf_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
>  	return table;
>  }
>  
> +static struct resource_table *rproc_elf_get_rsctab_va(struct rproc *rproc,
> +						 const struct firmware *fw)
> +{
> +	struct elf32_shdr *shdr;
> +
> +	shdr = find_rsc_shdr(&rproc->dev, (struct elf32_hdr *)fw->data,
> +				fw->size);
> +	if (!shdr)
> +		return NULL;
> +
> +	/* Find resource table in loaded segments */
> +	return rproc_da_to_va(rproc, shdr->sh_addr, shdr->sh_size);
> +}
> +
>  const struct rproc_fw_ops rproc_elf_fw_ops = {
>  	.load = rproc_elf_load_segments,
>  	.find_rsc_table = rproc_elf_find_rsc_table,
>  	.sanity_check = rproc_elf_sanity_check,
> -	.get_boot_addr = rproc_elf_get_boot_addr
> +	.get_boot_addr = rproc_elf_get_boot_addr,
> +	.get_rsctab_va = rproc_elf_get_rsctab_addr

There's a typo here, fixed in the next patch instead of this one, which
will break bisect.

Other than that this patch set looks good. This issue can be fixed when
the patches are merged, so I don't think there's a need to resend
another revision.

Thanks,
Ido.

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

* Re: [PATCHv2 02/10] remoteproc: Bugfix remove entry from list before freeing it
  2013-02-21 17:15 ` [PATCHv2 02/10] remoteproc: Bugfix remove entry from list before freeing it sjur.brandeland
@ 2013-03-19 13:31   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 16+ messages in thread
From: Ohad Ben-Cohen @ 2013-03-19 13:31 UTC (permalink / raw)
  To: Sjur Brændeland
  Cc: Ido Yariv, linux-kernel, Dmitry Tarnyagin, Linus Walleij,
	Erwan Yvin, Sjur Brændeland

On Thu, Feb 21, 2013 at 7:15 PM,  <sjur.brandeland@stericsson.com> wrote:
> From: Sjur Brændeland <sjur.brandeland@stericsson.com>
>
> Remove the vdev entry from the list before freeing it,
> otherwise the rproc->vdevs list get corrupted.
>
> Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>

Cc'ing stable here too and slightly modifying subject+commit log.

Thanks!

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

* Re: [PATCHv2 03/10] remoteproc: Refactor function rproc_elf_find_rsc_table
  2013-02-21 17:15 ` [PATCHv2 03/10] remoteproc: Refactor function rproc_elf_find_rsc_table sjur.brandeland
@ 2013-03-19 15:04   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 16+ messages in thread
From: Ohad Ben-Cohen @ 2013-03-19 15:04 UTC (permalink / raw)
  To: Sjur Brændeland
  Cc: Ido Yariv, linux-kernel, Dmitry Tarnyagin, Linus Walleij,
	Erwan Yvin, Sjur Brændeland

On Thu, Feb 21, 2013 at 7:15 PM,  <sjur.brandeland@stericsson.com> wrote:
> +static struct resource_table *
> +rproc_elf_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
> +                                                       int *tablesz)

Applying with a minor style change, thanks!

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

* Re: [PATCHv2 06/10] remoteproc: Code cleanup of resource parsing
  2013-02-21 17:15 ` [PATCHv2 06/10] remoteproc: Code cleanup of resource parsing sjur.brandeland
@ 2013-03-21 13:16   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 16+ messages in thread
From: Ohad Ben-Cohen @ 2013-03-21 13:16 UTC (permalink / raw)
  To: Sjur Brændeland
  Cc: Ido Yariv, linux-kernel, Dmitry Tarnyagin, Linus Walleij,
	Erwan Yvin, Sjur Brændeland

On Thu, Feb 21, 2013 at 7:15 PM,  <sjur.brandeland@stericsson.com> wrote:
> From: Sjur Brændeland <sjur.brandeland@stericsson.com>
>
> Combine the almost identical functions rproc_handle_virtio_rsc
> and rproc_handle_boot_rsc.
>
> Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>

Cool patch :)

BTW I'm almost done. Doing very small changes here and there and
briefly testing the code. Will let you test a private branch before I
push out.

Thanks,
Ohad.

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

* Re: [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space
  2013-02-21 17:15 [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space sjur.brandeland
                   ` (9 preceding siblings ...)
  2013-02-21 17:15 ` [PATCHv2 10/10] remoteproc: Set vring addresses in resource table sjur.brandeland
@ 2013-04-05  5:59 ` Ohad Ben-Cohen
  10 siblings, 0 replies; 16+ messages in thread
From: Ohad Ben-Cohen @ 2013-04-05  5:59 UTC (permalink / raw)
  To: Sjur Brændeland
  Cc: Ido Yariv, linux-kernel, Dmitry Tarnyagin, Linus Walleij,
	Erwan Yvin, Sjur Brændeland

On Thu, Feb 21, 2013 at 7:15 PM, <sjur.brandeland@stericsson.com> wrote:
>
> From: Sjur Brændeland <sjur.brandeland@stericsson.com>
>
> This patch-set adds support for shared resource table between
> Linux kernel and remote devices.
> - dynamically-allocated address of the vrings can be communicated
> - vdev statuses can be communicated
> - virtio config space becomes bi-directional
> - virtio feature negotiation is two-way
>
> Changes since v1:
> - Address all of Ido's review comments on the previous patch-set.

At long last I've applied and pushed out the patches, after some
changes to make it easier to read the code. These are mostly
style/terminology changes, as well as some cleanups and sporadic
addition of function documentation. Patches have also been rebased -
thanks Sjur for helping that feat privately.

The fixes were pushed to the fixes branch of remoteproc, and will be
pushed to Linus ASAP. The patches that add new functionality were
pushed to the for-next branch, and will subsequently show up in
linux-next. These will be pushed to Linus as soon as the next merge
window opens.

Sjur thanks for your effort and cooperation all along - the patches are great!

And sorry again for the delay - it was a hectic time and hopefully
we're back on track now.

Thanks,
Ohad.

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

end of thread, other threads:[~2013-04-05  5:59 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-21 17:15 [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space sjur.brandeland
2013-02-21 17:15 ` [PATCHv2 01/10] remoteproc: Bugfix: Deallocate firmware image on shutdown sjur.brandeland
2013-02-21 17:15 ` [PATCHv2 02/10] remoteproc: Bugfix remove entry from list before freeing it sjur.brandeland
2013-03-19 13:31   ` Ohad Ben-Cohen
2013-02-21 17:15 ` [PATCHv2 03/10] remoteproc: Refactor function rproc_elf_find_rsc_table sjur.brandeland
2013-03-19 15:04   ` Ohad Ben-Cohen
2013-02-21 17:15 ` [PATCHv2 04/10] remoteproc: Parse ELF file to find resource table address sjur.brandeland
2013-02-24 16:21   ` Ido Yariv
2013-02-21 17:15 ` [PATCHv2 05/10] remoteproc: Parse STE-firmware and " sjur.brandeland
2013-02-21 17:15 ` [PATCHv2 06/10] remoteproc: Code cleanup of resource parsing sjur.brandeland
2013-03-21 13:16   ` Ohad Ben-Cohen
2013-02-21 17:15 ` [PATCHv2 07/10] remoteproc: Calculate max_notifyid by counting vrings sjur.brandeland
2013-02-21 17:15 ` [PATCHv2 08/10] remoteproc: Always perserve resource table data sjur.brandeland
2013-02-21 17:15 ` [PATCHv2 09/10] remoteproc: Support virtio config space sjur.brandeland
2013-02-21 17:15 ` [PATCHv2 10/10] remoteproc: Set vring addresses in resource table sjur.brandeland
2013-04-05  5:59 ` [PATCHv2 00/10] remoteproc: Support bi-directional vdev config space Ohad Ben-Cohen

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.