diff mbox

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

Message ID 1390840102-23455-1-git-send-email-paul.chavent@onera.fr
State RFC
Delegated to: Tom Rini
Headers show

Commit Message

Paul Chavent Jan. 27, 2014, 4:28 p.m. UTC
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@onera.fr>
Cc: Tom Rini <trini@ti.com>
---
 board/davinci/da8xxevm/da850evm.c | 43 ++++++++++++++++++++++++++
 common/cmd_elf.c                  | 65 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+)

Comments

Tom Rini Jan. 29, 2014, 10:37 p.m. UTC | #1
On Mon, Jan 27, 2014 at 05:28:22PM +0100, Paul Chavent wrote:

> 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.
> 

This seems like the right direction to take for things.  The question I
have first is, are we talking about loading something into the DSP and
then letting it go, or are we talking about getting a result back from
the DSP in Linux?  I assume the first case.
Paul Chavent Jan. 30, 2014, 7:55 a.m. UTC | #2
On 01/29/2014 11:37 PM, Tom Rini wrote:
> On Mon, Jan 27, 2014 at 05:28:22PM +0100, Paul Chavent wrote:
>
>> 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.
>>
>
> This seems like the right direction to take for things.  The question I
> have first is, are we talking about loading something into the DSP and
> then letting it go, or are we talking about getting a result back from
> the DSP in Linux?  I assume the first case.
>

Thank you for having considered the patch.

Indeed, this is about loading something into the DSP and then letting it 
go without worrying about the result.

In our use case however, later, the ARM run some programs (under Linux) 
that will use services provided by the DSP through its L2 cache used as 
shared memory. Ideally, we would like to be able to soft reset the ARM 
without killing the DSP that will run the critical code that should 
survive to hight level apps failures...

I wait for your advices to improve the patch integration (I'm not sure 
that the "extern" declarations on top of cmd_elf.c will be integrated 
like that).
Moreover, i wonder if we should begin to think about a more generic 
"boot_companion" function that would introduce a framework in order to 
boot companion cpu... but perhaps it's a bit premature.

Regards.

Paul Chavent.
diff mbox

Patch

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) */