Hi

I am currently trying to configure either Altera Soc and Xilinx Zynq to boot 
Linux in nonsecure-mode.
This mail focusses on the Altera SOC.

As soon as the u-boot switched to normal mode it seems there is a problem with 
code alignment handling? 
At least it seems the code which is running beforehand stops working in normal 
mode and stops in either
data_abort or prefetch handler. It stopps working when it hits the call to
stdio_devices[file]->puts(s); in console_puts (console.c:255).

print *stdio_devices[file]
$2 = {flags = 16978471, ext = 16978464, 
name = "$\022\003\001\202\022\003\001\360\031\003\001\020\060\220", <incomplete 
sequence \345>, 
  start = 0xe92d4070, stop = 0xe2806010, putc = 0xe1530006, puts = 0xe1a04000, 
tstc = 0xe1a05001, 
  getc = 0xe5810024, priv = 0x1a000007, list = { next = 0xe5831004, prev = 
0xe5813000}}

As there are unaligned addresses (putc?) in these function calls i have the 
impression that this is not working in
normal mode but in secure mode.

Unfortunatly i was not able to get the mainline u-boot to boot on the altera 
soc so i patched the altera release:
git://git.rocketboards.org/u-boot-socfpga.git
with the 1740999a39ea4217bf926002d10869c0d925a5dc aka socfpga_v2013.01.01-rel 
branch.

As the altera u-boot release socfpga_v2013.01.01-rel is to old to have the 
CONFIG_ARMV7_NONSEC patches
i cherry-picked the following patches:
d4296887544ddf95808bfb62f312008f519efb7b        extend non-secure switch to 
also go into HYP mode
ba6a1698116da272f14c53a3ae41467cb7fc4372        add SMP support for non-secure 
switch
bb975455650b1f36681de31a93ffe54952ed3a6b        trigger non-secure state switch 
during bootm execution
1ef923851ab8ffcc4265fd991815b88d9c1f12d7        add C function to switch to 
non-secure state
16212b594f385bd594d5d316bf11b13c1186e3d7        add assembly routine to switch 
to non-secure state
45b940d6f9a9d4989452ea67480e299bfa51ee19        add secure monitor handler to 
switch to non-secure state
d75ba503a972df09784f1a332ba356ef8b42a0a6        ARM: prepare armv7.h to be 
included from assembly source

I also applied the attached hacked together patches to get the system running 
and fix up the stack pointer in 
normal mode as it pointed to 0. 

Best regards
Tim
>From ada1a10d612d8f123ff63b17a7b4e5d586a9a43a Mon Sep 17 00:00:00 2001
From: Tim Sander <t...@krieglstein.org>
Date: Mon, 24 Mar 2014 15:12:47 +0100
Subject: [PATCH 1/3] CONFIG_ARMV7_NONSEC compile fixes

---
 arch/arm/cpu/u-boot.lds               |    1 +
 board/altera/socfpga/socfpga_common.c |   16 ++++++++++++++++
 include/configs/socfpga_cyclone5.h    |    4 ++++
 3 files changed, 21 insertions(+)

diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds
index e6b202b..1ea1ac2 100644
--- a/arch/arm/cpu/u-boot.lds
+++ b/arch/arm/cpu/u-boot.lds
@@ -88,6 +88,7 @@ SECTIONS
 		__bss_end__ = .;
 	}
 
+	.rel.plt : { *(.rel.plt) }
 	/DISCARD/ : { *(.dynstr*) }
 	/DISCARD/ : { *(.dynamic*) }
 	/DISCARD/ : { *(.plt*) }
diff --git a/board/altera/socfpga/socfpga_common.c b/board/altera/socfpga/socfpga_common.c
index 5e459bb..8f6d215 100644
--- a/board/altera/socfpga/socfpga_common.c
+++ b/board/altera/socfpga/socfpga_common.c
@@ -81,4 +81,20 @@ int designware_board_phy_init(struct eth_device *dev, int phy_addr,
 	}
 	return 0;
 }
+
+#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT)
+/* Setting the address at which secondary cores start from.
+ * Versatile Express uses one address for all cores, so ignore corenr
+ */
+void smp_set_core_boot_addr(unsigned long addr, int corenr)
+{
+    /* The SYSFLAGS register on VExpress needs to be cleared first
+     * by writing to the next address, since any writes to the address
+     * at offset 0 will only be ORed in
+     */
+    writel(~0, CONFIG_SYSFLAGS_ADDR + 4);
+    writel(addr, CONFIG_SYSFLAGS_ADDR);
+}
+#endif
+
 #endif
diff --git a/include/configs/socfpga_cyclone5.h b/include/configs/socfpga_cyclone5.h
index 106c52c..a2b8b3b 100644
--- a/include/configs/socfpga_cyclone5.h
+++ b/include/configs/socfpga_cyclone5.h
@@ -35,4 +35,8 @@
 #define CONFIG_EPHY_PHY_ADDR		CONFIG_EPHY1_PHY_ADDR
 #define CONFIG_PHY_INTERFACE_MODE	SOCFPGA_PHYSEL_ENUM_RGMII
 
+#define CONFIG_ARMV7_NONSEC
+#define CONFIG_SYSFLAGS_ADDR        0x1c010030
+#define CONFIG_SMP_PEN_ADDR CONFIG_SYSFLAGS_ADDR
+
 #endif	/* __CONFIG_H */
-- 
1.7.9.5

>From 7ead8c23659ad64dfdf54994f0e1c9f6e376b6aa Mon Sep 17 00:00:00 2001
From: Tim Sander <t...@krieglstein.org>
Date: Wed, 26 Mar 2014 13:37:17 +0100
Subject: [PATCH 2/3] restore stack pointer in normal mode, remove prints in
 u-boot final stage, add GIC_BASE_ADDRESS

---
 arch/arm/cpu/armv7/nonsec_virt.S   |    5 +++++
 arch/arm/cpu/armv7/virt-v7.c       |   18 +++++++++++++++---
 arch/arm/include/asm/armv7.h       |    7 ++++---
 arch/arm/lib/bootm.c               |    2 +-
 common/bootstage.c                 |    3 +++
 include/configs/socfpga_common.h   |    2 ++
 include/configs/socfpga_cyclone5.h |    1 +
 7 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S
index 358348f..3048599 100644
--- a/arch/arm/cpu/armv7/nonsec_virt.S
+++ b/arch/arm/cpu/armv7/nonsec_virt.S
@@ -50,6 +50,7 @@ _monitor_vectors:
  */
 	.align	5
 _secure_monitor:
+	mov r2,r1
 	mrc	p15, 0, r1, c1, c1, 0		@ read SCR
 	bic	r1, r1, #0x4e			@ clear IRQ, FIQ, EA, nET bits
 	orr	r1, r1, #0x31			@ enable NS, AW, FW bits
@@ -68,6 +69,7 @@ _secure_monitor:
 	mcreq	p15, 4, r0, c12, c0, 0		@ write HVBAR
 #endif
 
+	mov		sp,r2				@ restore stack pointer from caller (eq to secure mode stack)
 	movs	pc, lr				@ return to non-secure SVC
 
 _hyp_trap:
@@ -168,12 +170,15 @@ ENTRY(_nonsec_init)
 
 	mrc	p15, 0, ip, c12, c0, 0		@ save secure copy of VBAR
 
+	stmfd sp!,{r2}					@ save r2 as it is clobbered in monitor mode
+	mov r1,sp
 	isb
 	smc	#0				@ call into MONITOR mode
 
 	mcr	p15, 0, ip, c12, c0, 0		@ write non-secure copy of VBAR
 
 	mov	r1, #1
+	ldmfd sp!,{r2}					@ restore r2 
 	str	r1, [r3, #GICC_CTLR]		@ enable non-secure CPU i/f
 	add	r2, r2, #GIC_DIST_OFFSET
 	str	r1, [r2, #GICD_CTLR]		@ allow private interrupts
diff --git a/arch/arm/cpu/armv7/virt-v7.c b/arch/arm/cpu/armv7/virt-v7.c
index 6de7fe7..322b587 100644
--- a/arch/arm/cpu/armv7/virt-v7.c
+++ b/arch/arm/cpu/armv7/virt-v7.c
@@ -62,7 +62,9 @@ static unsigned long get_gicd_base_address(void)
 	 * which we know only for sure for those two CPUs.
 	 */
 	asm("mrc p15, 0, %0, c0, c0, 0\n" : "=r"(midr));
+	printf("midr: %x masked:%x\n",midr,midr & MIDR_PRIMARY_PART_MASK);
 	switch (midr & MIDR_PRIMARY_PART_MASK) {
+	case MIDR_CORTEX_A9_R0P0:
 	case MIDR_CORTEX_A9_R0P1:
 	case MIDR_CORTEX_A15_R0P0:
 	case MIDR_CORTEX_A7_R0P0:
@@ -75,6 +77,7 @@ static unsigned long get_gicd_base_address(void)
 	/* get the GIC base address from the CBAR register */
 	asm("mrc p15, 4, %0, c15, c0, 0\n" : "=r" (periphbase));
 
+	printf("periphbase: %x working_address:%x\n",periphbase, (periphbase & CBAR_MASK)+GIC_DIST_OFFSET);
 	/* the PERIPHBASE can be mapped above 4 GB (lower 8 bits used to
 	 * encode this). Bail out here since we cannot access this without
 	 * enabling paging.
@@ -105,7 +108,7 @@ int armv7_switch_hyp(void)
 
 	/* check whether we are in HYP mode already */
 	if ((read_cpsr() & 0x1f) == 0x1a) {
-		debug("CPU already in HYP mode\n");
+		printf("CPU already in HYP mode\n");
 		return 0;
 	}
 
@@ -148,11 +151,13 @@ int armv7_switch_nonsec(void)
 	gic_dist_addr = get_gicd_base_address();
 	if (gic_dist_addr == -1)
 		return -1;
-
+	
+	printf("enable GIC addr:%x \n", gic_dist_addr + GICD_CTLR);
 	/* enable the GIC distributor */
 	writel(readl(gic_dist_addr + GICD_CTLR) | 0x03,
 	       gic_dist_addr + GICD_CTLR);
 
+	printf("typer register: %x\n", gic_dist_addr + GICD_TYPER);
 	/* TYPER[4:0] contains an encoded number of available interrupts */
 	itlinesnr = readl(gic_dist_addr + GICD_TYPER) & 0x1f;
 
@@ -160,14 +165,21 @@ int armv7_switch_nonsec(void)
 	 * from non-secure state. The first 32 interrupts are private per
 	 * CPU and will be set later when enabling the GIC for each core
 	 */
+	printf("allow non secure access\n");
 	for (i = 1; i <= itlinesnr; i++)
 		writel((unsigned)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i);
 
+	printf("set core boot addr\n");
 	smp_set_core_boot_addr((unsigned long)_smp_pen, -1);
+	printf("kick cpus\n");
 	smp_kick_all_cpus();
 
+	/* read Monitor Vector Base Address Register */
+	asm("mrc p15, 0, %0, c12, c0, 1" : "=r"(reg) : : "cc");
+    printf("MVBAR (p15,0,c12,c0,1):%x\n",reg);
+
 	/* call the non-sec switching code on this CPU also */
+	printf("nonsec init");
 	_nonsec_init();
-
 	return 0;
 }
diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h
index 73c7d2a..e581fd3 100644
--- a/arch/arm/include/asm/armv7.h
+++ b/arch/arm/include/asm/armv7.h
@@ -25,9 +25,10 @@
 #define ARMV7_H
 
 /* Cortex-A9 revisions */
-#define MIDR_CORTEX_A9_R0P1	0x410FC091
-#define MIDR_CORTEX_A9_R1P2	0x411FC092
-#define MIDR_CORTEX_A9_R1P3	0x411FC093
+#define MIDR_CORTEX_A9_R0P0		0x410FC090
+#define MIDR_CORTEX_A9_R0P1		0x410FC091
+#define MIDR_CORTEX_A9_R1P2		0x411FC092
+#define MIDR_CORTEX_A9_R1P3		0x411FC093
 #define MIDR_CORTEX_A9_R2P10	0x412FC09A
 
 /* Cortex-A15 revisions */
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 51158eb..35abccf 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -99,7 +99,7 @@ static int fixup_memory_node(void *blob)
 
 static void announce_and_cleanup(void)
 {
-	printf("\nStarting kernel ...\n\n");
+	//printf("\nStarting kernel ...\n\n");
 	bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
 #ifdef CONFIG_BOOTSTAGE_FDT
 	bootstage_fdt_add_report();
diff --git a/common/bootstage.c b/common/bootstage.c
index a1e0939..b4e7c07 100644
--- a/common/bootstage.c
+++ b/common/bootstage.c
@@ -239,8 +239,11 @@ static int add_bootstages_devicetree(struct fdt_header *blob)
 int bootstage_fdt_add_report(void)
 {
 	if (add_bootstages_devicetree(working_fdt))
+		return 0;
+	/* FIXME q
 		puts("bootstage: Failed to add to device tree\n");
 
+    */
 	return 0;
 }
 #endif
diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h
index ff8824f..b30ae06 100644
--- a/include/configs/socfpga_common.h
+++ b/include/configs/socfpga_common.h
@@ -371,10 +371,12 @@
 /*
  * L4 Watchdog
  */
+ /*
 #define CONFIG_HW_WATCHDOG
 #define CONFIG_HW_WATCHDOG_TIMEOUT_MS	(2000)
 #define CONFIG_DESIGNWARE_WATCHDOG
 #define CONFIG_DW_WDT_BASE		SOCFPGA_L4WD0_ADDRESS
+ */
 /* Clocks source frequency to watchdog timer */
 #if defined(CONFIG_SOCFPGA_VIRTUAL_TARGET)
 #define CONFIG_DW_WDT_CLOCK_KHZ		2400
diff --git a/include/configs/socfpga_cyclone5.h b/include/configs/socfpga_cyclone5.h
index a2b8b3b..2eac0e1 100644
--- a/include/configs/socfpga_cyclone5.h
+++ b/include/configs/socfpga_cyclone5.h
@@ -38,5 +38,6 @@
 #define CONFIG_ARMV7_NONSEC
 #define CONFIG_SYSFLAGS_ADDR        0x1c010030
 #define CONFIG_SMP_PEN_ADDR CONFIG_SYSFLAGS_ADDR
+#define CONFIG_ARM_GIC_BASE_ADDRESS 0xfffed000 - 0x1000  //GIC_DIST_OFFSET
 
 #endif	/* __CONFIG_H */
-- 
1.7.9.5

>From a2b7d1cf22a41f09f00a7088ca69acd03329cc0c Mon Sep 17 00:00:00 2001
From: Tim Sander <t...@krieglstein.org>
Date: Wed, 26 Mar 2014 13:51:30 +0100
Subject: [PATCH 3/3] move secure mode switch directly in front of kernel boot

---
 arch/arm/lib/bootm.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 35abccf..39dcf9c 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -337,7 +337,6 @@ static void boot_prep_linux(bootm_headers_t *images)
 		hang();
 #endif /* all tags */
 	}
-	do_nonsec_virt_switch();
 }
 
 /* Subcommand: GO */
@@ -368,6 +367,7 @@ static void boot_jump_linux(bootm_headers_t *images)
 #endif
 		r2 = gd->bd->bi_boot_params;
 
+	do_nonsec_virt_switch();
 	kernel_entry(0, machid, r2);
 }
 
-- 
1.7.9.5

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to