[U-Boot] [PATCH] arm/da850 : [RFC] add bootdsp to cmd_elf

Paul Chavent Paul.Chavent at onera.fr
Mon Jan 27 17:28:22 CET 2014


On platform with a DSP co-processor, add a command to boot an elf on
it.

* Test *

This patch has been tested on an OMAP-L138 EVM with DSP code generated
with TI's code generation tools 7.4.6 with the --abi=eabi option.

* Bugs *

Some elf generated with older TI's cgt have mis-aligned header
sections that lead to u-boot freeze. This point can be checked with
readelf (see "Start of program headers" and/or "Start of section
headers") if you experience such problem.

* Discussion *

Our first question is about the interest of the u-boot community for
this feature ?

For the implementation, we tried to separate platform specific code
(dsp's reset and entry point) from the elf generic code (check and
load elf in memory). We would like to have your opinion on this
design.

Signed-off-by: Paul Chavent <paul.chavent at onera.fr>
Cc: Tom Rini <trini at ti.com>
---
 board/davinci/da8xxevm/da850evm.c | 43 ++++++++++++++++++++++++++
 common/cmd_elf.c                  | 65 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+)

diff --git a/board/davinci/da8xxevm/da850evm.c b/board/davinci/da8xxevm/da850evm.c
index 85b4830..3d361b6 100644
--- a/board/davinci/da8xxevm/da850evm.c
+++ b/board/davinci/da8xxevm/da850evm.c
@@ -121,6 +121,49 @@ static void dspwake(void)
 	writel(val, (PSC0_MDCTL + (15 * 4)));
 }
 
+void dsp_reset_assert(void)
+{
+	unsigned int id = DAVINCI_LPSC_GEM;
+	dv_reg_p mdstat, mdctl;
+	struct davinci_psc_regs *psc_regs;
+
+	psc_regs = davinci_psc0_regs;
+	mdstat = &psc_regs->psc0.mdstat[id];
+	mdctl = &psc_regs->psc0.mdctl[id];
+
+	if ((*mdstat & 0x100) == 0x000)
+		return;
+
+	*mdctl &= ~0x100;
+
+	while ((*mdstat & 0x100) != 0x000)
+		;
+}
+
+void dsp_entry_point(unsigned long addr)
+{
+	writel(addr, HOST1CFG);
+}
+
+void dsp_reset_deassert(void)
+{
+	unsigned int id = DAVINCI_LPSC_GEM;
+	dv_reg_p mdstat, mdctl;
+	struct davinci_psc_regs *psc_regs;
+
+	psc_regs = davinci_psc0_regs;
+	mdstat = &psc_regs->psc0.mdstat[id];
+	mdctl = &psc_regs->psc0.mdctl[id];
+
+	if ((*mdstat & 0x100) == 0x100)
+		return;
+
+	*mdctl |= 0x100;
+
+	while ((*mdstat & 0x100) != 0x100)
+		;
+}
+
 int misc_init_r(void)
 {
 	dspwake();
diff --git a/common/cmd_elf.c b/common/cmd_elf.c
index ab9c7e3..ae7b6e1 100644
--- a/common/cmd_elf.c
+++ b/common/cmd_elf.c
@@ -24,6 +24,12 @@
 DECLARE_GLOBAL_DATA_PTR;
 #endif
 
+#if defined(CONFIG_MACH_DAVINCI_DA850_EVM)
+extern void dsp_reset_assert(void);
+extern void dsp_entry_point(unsigned long addr);
+extern void dsp_reset_deassert(void);
+#endif
+
 static unsigned long load_elf_image_phdr(unsigned long addr);
 static unsigned long load_elf_image_shdr(unsigned long addr);
 
@@ -269,6 +275,55 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	return 1;
 }
 
+#if defined(CONFIG_MACH_DAVINCI_DA850_EVM)
+/* ======================================================================
+ * Interpreter command to boot the companion dsp with an arbitrary ELF
+ * image from memory. Can be improved to bring bootargs
+ * ====================================================================== */
+int do_bootdsp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	unsigned long addr;		/* Address of the ELF image     */
+	char *sload, *saddr;
+
+	sload = saddr = NULL;
+	if (argc == 3) {
+		sload = argv[1];
+		saddr = argv[2];
+	} else if (argc == 2) {
+		if (argv[1][0] == '-')
+			sload = argv[1];
+		else
+			saddr = argv[1];
+	}
+
+	if (saddr)
+		addr = simple_strtoul(saddr, NULL, 16);
+	else
+		addr = load_addr;
+
+	if (!valid_elf_image(addr))
+		return 1;
+
+	/* hold the reset */
+	dsp_reset_assert();
+
+	if (sload && sload[1] == 'p')
+		addr = load_elf_image_phdr(addr);
+	else
+		addr = load_elf_image_shdr(addr);
+
+	printf("## Starting dsp's application at 0x%08lx ...\n", addr);
+
+	/* setup the DSP reset vector */
+	dsp_entry_point(addr);
+
+	/* release the reset */
+	dsp_reset_deassert();
+
+	return 0;
+}
+#endif /* defined(CONFIG_MACH_DAVINCI_DA850_EVM) */
+
 /* ======================================================================
  * A very simple elf loader, assumes the image is valid, returns the
  * entry point address.
@@ -367,3 +422,13 @@ U_BOOT_CMD(
 	"Boot vxWorks from an ELF image",
 	" [address] - load address of vxWorks ELF image."
 );
+
+#if defined(CONFIG_MACH_DAVINCI_DA850_EVM)
+U_BOOT_CMD(
+	bootdsp,      3,      0,      do_bootdsp,
+	"Boot dsp from an ELF image in memory",
+	"[-p|-s] [address]\n"
+	"\t- load ELF image at [address] via program headers (-p)\n"
+	"\t  or via section headers (-s)"
+);
+#endif /* defined(CONFIG_MACH_DAVINCI_DA850_EVM) */
-- 
1.7.12.1



More information about the U-Boot mailing list