[Sound-open-firmware] [PATCH] arch: xtensa: Add bootloader support

Liam Girdwood liam.r.girdwood at linux.intel.com
Tue Jan 23 17:40:15 CET 2018


From: Rander Wang <rander.wang at linux.intel.com>

Add a support for a secondary boot loader than cant be used to bootstrap
multiple firmware modules.

Signed-off-by: Rander Wang <rander.wang at linux.intel.com>
---
 src/arch/xtensa/boot_entry.S   |  98 ++++++++++++++++++++
 src/arch/xtensa/boot_loader.c  | 206 +++++++++++++++++++++++++++++++++++++++++
 src/arch/xtensa/crt1-boards.S  |  16 ++++
 src/arch/xtensa/main-entry.S   |  57 ++++++++++++
 src/arch/xtensa/reset-vector.S |  16 +++-
 5 files changed, 391 insertions(+), 2 deletions(-)
 create mode 100644 src/arch/xtensa/boot_entry.S
 create mode 100644 src/arch/xtensa/boot_loader.c
 create mode 100644 src/arch/xtensa/main-entry.S

diff --git a/src/arch/xtensa/boot_entry.S b/src/arch/xtensa/boot_entry.S
new file mode 100644
index 0000000..cf793f5
--- /dev/null
+++ b/src/arch/xtensa/boot_entry.S
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2016, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of the Intel Corporation nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Liam Girdwood <liam.r.girdwood at linux.intel.com>
+ */
+
+/*
+ * Entry point from ROM - assumes :-
+ *
+ * 1) C runtime environment is initalised by ROM.
+ * 2) Stack is in first HPSRAM bank.
+ */
+
+#include <config.h>
+#include <platform/shim.h>
+#include <xtensa/corebits.h>
+#include <xtensa/config/core-isa-boot.h>
+
+	.type   boot_pri_core, @function
+	.type   boot_sec_core, @function
+
+	.begin	literal_prefix	.boot_entry
+	.section .boot_entry.text, "ax"
+
+	.align	4
+	.global	boot_entry
+
+boot_entry:
+	entry	a1, 48
+	j boot_init
+
+	.align 4
+	.literal_position
+l2_mecs:
+	.word SHIM_L2_MECS
+
+boot_init:
+	.align 4
+#if defined(CONFIG_CANNONLAKE)
+	/* reset memory hole */
+	l32r a3, l2_mecs
+	movi a5, 0
+	s32i a5, a3, 0
+#endif
+
+#if (XCHAL_DCACHE_IS_COHERENT || XCHAL_LOOP_BUFFER_SIZE) && \
+	XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RE_2012_0
+	/*	Enable zero-overhead loop instr buffer,
+		and snoop responses, if configured.  */
+	movi	a3, (MEMCTL_SNOOP_EN | MEMCTL_L0IBUF_EN)
+	rsr a2, MEMCTL
+	or	a2, a2, a3
+	wsr a2, MEMCTL
+#endif
+
+	/* determine core we are running on */
+	rsr a2, PRID
+	beqz a2, 1f
+
+	/* we are seconadry core, so boot it */
+	call8 boot_sec_core
+	j dead
+
+1:
+	/* we are primary core so boot it */
+	call8 boot_pri_core
+
+dead:
+	/* should never get here - we are dead */
+	j dead
+
+	.size	boot_entry, . - boot_entry
+
+	.end	literal_prefix
diff --git a/src/arch/xtensa/boot_loader.c b/src/arch/xtensa/boot_loader.c
new file mode 100644
index 0000000..5c5939c
--- /dev/null
+++ b/src/arch/xtensa/boot_loader.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2016, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of the Intel Corporation nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Liam Girdwood <liam.r.girdwood at linux.intel.com>
+ */
+
+#include <arch/cache.h>
+#include <arch/wait.h>
+#include <reef/trace.h>
+#include <reef/io.h>
+#include <uapi/manifest.h>
+#include <platform/memory.h>
+
+/* entry point to main firmware */
+extern void _ResetVector(void);
+
+void boot_pri_core(void);
+void boot_sec_core(void);
+
+#if defined(CONFIG_CANNONLAKE)
+
+/* memcopy used by boot loader */
+static inline void bmemcpy(void *dest, void *src, size_t bytes)
+{
+	uint32_t *d = dest;
+	uint32_t *s = src;
+	int i;
+
+	for (i = 0; i < (bytes >> 2); i++)
+		d[i] = s[i];
+
+	dcache_writeback_region(dest, bytes);
+}
+
+/* bzero used by bootloader */
+static inline void bbzero(void *dest, size_t bytes)
+{
+	uint32_t *d = dest;
+	int i;
+
+	for (i = 0; i < (bytes >> 2); i++)
+		d[i] = 0;
+
+	dcache_writeback_region(dest, bytes);
+}
+
+static void parse_module(struct sof_man_fw_header *hdr,
+	struct sof_man_module *mod)
+{
+	int i;
+	uint32_t bias;
+
+	/* each module has 3 segments */
+	for (i = 0; i < 3; i++) {
+
+		switch (mod->segment[i].flags.r.type) {
+		case SOF_MAN_SEGMENT_TEXT:
+		case SOF_MAN_SEGMENT_DATA:
+			bias = (mod->segment[i].file_offset -
+				SOF_MAN_ELF_TEXT_OFFSET);
+
+			/* copy from IMR to SRAM */
+			bmemcpy((void *)mod->segment[i].v_base_addr,
+				(void *)((int)hdr + bias),
+				mod->segment[i].flags.r.length * HOST_PAGE_SIZE);
+			break;
+		case SOF_MAN_SEGMENT_BSS:
+			/* copy from IMR to SRAM */
+			bbzero((void*)mod->segment[i].v_base_addr,
+				mod->segment[i].flags.r.length * HOST_PAGE_SIZE);
+			break;
+		default:
+			/* ignore */
+			break;
+		}
+	}
+}
+
+/* parse FW manifest and copy modules */
+static void parse_manifest(void)
+{
+	struct sof_man_fw_desc *desc =
+		(struct sof_man_fw_desc *)IMR_BOOT_LDR_MANIFEST_BASE;
+	struct sof_man_fw_header *hdr = &desc->header;
+	struct sof_man_module *mod;
+	int i;
+
+	/* copy module to SRAM  - skip bootloader module */
+	for (i = 1; i < hdr->num_module_entries; i++) {
+
+		mod = sof_man_get_module(desc, i);
+		parse_module(hdr, mod);
+	}
+}
+#endif
+
+/* power on HPSRAM */
+static int32_t hp_sram_init(void)
+{
+	int delay_count = 256, timeout = 256;
+	uint32_t status;
+
+	shim_write(SHIM_LDOCTL, SHIM_HPMEM_POWER_ON);
+
+	/* add some delay before touch power register */
+	idelay(delay_count);
+
+	/* now all the memory bank has been powered up */
+	io_reg_write(HSPGCTL0, 0);
+	io_reg_write(HSRMCTL0, 0);
+	io_reg_write(HSPGCTL1, 0);
+	io_reg_write(HSRMCTL1, 0);
+
+	/* query the power status of first part of HP memory */
+	/* to check whether it has been powered up. A few    */
+	/* cycles are needed for it to be powered up         */
+	status = io_reg_read(HSPGISTS0);
+	while (status) {
+		idelay(delay_count);
+
+		status = io_reg_read(HSPGISTS0);
+		if (timeout-- < 0) {
+			return -EIO;
+		}
+	}
+
+	/* query the power status of second part of HP memory */
+	/* and do as above code                               */
+	timeout = 256;
+	status = io_reg_read(HSPGISTS1);
+	while (status) {
+		idelay(delay_count);
+
+		status = io_reg_read(HSPGISTS1);
+		if (timeout-- < 0) {
+			return -EIO;
+		}
+	}
+
+	/* add some delay before touch power register */
+	idelay(delay_count);
+	shim_write(SHIM_LDOCTL, SHIM_LPMEM_POWER_BYPASS);
+
+	return 0;
+}
+
+/* boot secondary core - i.e core ID > 0 */
+void boot_sec_core(void)
+{
+	/* TODO: prepare C stack for this core */
+	while (1);
+
+	/* now call SOF entry */
+	_ResetVector();
+}
+
+/* boot primary core - i.e. core ID == 0 */
+void boot_pri_core(void)
+{
+	int32_t result;
+
+	/* TODO: platform trace should write to HW IPC regs on CNL */
+	platform_trace_point(TRACE_BOOT_LDR_ENTRY);
+
+	/* init the HPSRAM */
+	platform_trace_point(TRACE_BOOT_LDR_HPSRAM);
+	result = hp_sram_init();
+	if (result < 0) {
+		platform_panic(PANIC_MEM);
+		return;
+	}
+
+#if defined(CONFIG_CANNONLAKE)
+	/* parse manifest and copy modules */
+	platform_trace_point(TRACE_BOOT_LDR_MANIFEST);
+	parse_manifest();
+#endif
+
+	/* now call SOF entry */
+	platform_trace_point(TRACE_BOOT_LDR_JUMP);
+	_ResetVector();
+}
diff --git a/src/arch/xtensa/crt1-boards.S b/src/arch/xtensa/crt1-boards.S
index 5d9b842..ff24bfd 100644
--- a/src/arch/xtensa/crt1-boards.S
+++ b/src/arch/xtensa/crt1-boards.S
@@ -120,6 +120,22 @@ _start:
 #include "reset-unneeded.S"
 #endif
 
+#if XCHAL_HAVE_BOOTLOADER
+	.weak	_Level2FromVector
+	.weak	_Level3FromVector
+	.weak	_Level4FromVector
+	.weak	_Level5FromVector
+
+	movi	a4, _Level2FromVector
+	wsr	a4, EXCSAVE+2
+	movi	a4, _Level3FromVector
+	wsr	a4, EXCSAVE+3
+	movi	a4, _Level4FromVector
+	wsr	a4, EXCSAVE+4
+	movi	a4, _Level5FromVector
+	wsr	a4, EXCSAVE+5
+#endif
+
 	// Initialize the stack pointer.
 	// See the "ABI and Software Conventions" chapter in the
 	// Xtensa ISA Reference manual for details.
diff --git a/src/arch/xtensa/main-entry.S b/src/arch/xtensa/main-entry.S
new file mode 100644
index 0000000..27a18b4
--- /dev/null
+++ b/src/arch/xtensa/main-entry.S
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2017, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of the Intel Corporation nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Rander Wang <rander.wang at intel.com>
+ */
+
+/*
+ * Entry point from boot loader.
+ * Fix link address of this entry to REEF_TEXT_START so that
+ * it is easy for boot loader to jump to the baseFW becasue
+ * the boot loader and baseFW are in different elf file.
+ */
+
+
+// Exports
+.global _MainEntry
+
+
+/**************************************************************************/
+
+	.begin	literal_prefix	.MainEntry
+	.section .MainEntry.text, "ax"
+
+	.align	4
+	.global	_MainEntry
+
+_MainEntry:
+
+	call0	_start
+
+	.size	_MainEntry, . - _MainEntry
+
+	.end	literal_prefix
diff --git a/src/arch/xtensa/reset-vector.S b/src/arch/xtensa/reset-vector.S
index be2eb7a..f491b33 100644
--- a/src/arch/xtensa/reset-vector.S
+++ b/src/arch/xtensa/reset-vector.S
@@ -35,6 +35,10 @@
 #include "xtos-internal.h"
 #include <config.h>
 
+#if XCHAL_HAVE_BOOTLOADER
+#include <platform/memory.h>
+#endif
+
 // The following reset vector avoids initializing certain registers already
 // initialized by processor reset.  But it does initialize some of them
 // anyway, for minimal support of warm restart (restarting in software by
@@ -290,6 +294,7 @@ _ResetHandler:
 	s32i	a0, a2, 0	// clear sync variable
 .Ldonesync:
 #endif
+
 #if XCHAL_HAVE_EXTERN_REGS && XCHAL_HAVE_MP_RUNSTALL
 	/* On core 0, this releases other cores.  On other cores this has no effect, because
 	   runstall control is unconnected.  */
@@ -375,7 +380,6 @@ _ResetHandler:
 	movi	a2, _memmap_cacheattr_reset	/* note: absolute symbol, not a ptr */
 	cacheattr_set				/* set CACHEATTR from a2 (clobbers a3-a8) */
 #endif
-
 	/*  Now that caches are initialized, cache coherency can be enabled.  */
 #if XCHAL_DCACHE_IS_COHERENT
 # if XCHAL_HAVE_EXTERN_REGS && XCHAL_HAVE_MX && (XCHAL_HW_MIN_VERSION < XTENSA_HWVERSION_RE_2012_0)
@@ -574,7 +578,15 @@ unpackdone:
 	 *  needed (with -mlongcalls) which it doesn't with j or jx.
 	 *  Note:  This needs to be call0 regardless of the selected ABI.
 	 */
-	call0	_start		// jump to _start (in crt1-*.S)
+
+#if XCHAL_HAVE_BOOTLOADER
+		/*ToDo refine the _start*/
+		movi a0, REEF_TEXT_START
+		callx0 a0
+#else
+		call0	_start		// jump to _start (in crt1-*.S)
+#endif
+
 	/* does not return */
 
 #else /* XCHAL_HAVE_HALT */
-- 
2.14.1



More information about the Sound-open-firmware mailing list