All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2] arm64 patch: gicv3 support
@ 2014-03-14  6:26 fenghua at phytium.com.cn
  2014-03-31  6:30 ` [U-Boot] why not enable ICache in vexpress_aemv8a.h TigerLiu at via-alliance.com
  2014-04-07 23:03 ` [U-Boot] [PATCH v2] arm64 patch: gicv3 support Albert ARIBAUD
  0 siblings, 2 replies; 5+ messages in thread
From: fenghua at phytium.com.cn @ 2014-03-14  6:26 UTC (permalink / raw)
  To: u-boot

From: David Feng <fenghua@phytium.com.cn>

This patch add gicv3 support to uboot armv8 platform.

Changes for v2:
  - rename arm/cpu/armv8/gic.S with arm/lib/gic_64.S
  - move smp_kick_all_cpus() from gic.S to start.S, it would be
    implementation dependent.
  - Each core initialize it's own ReDistributor instead of master
    initializeing all ReDistributors. This is advised by arnab.basu
    <arnab.basu@freescale.com>.

Signed-off-by: David Feng <fenghua@phytium.com.cn>
---
 arch/arm/cpu/armv8/Makefile       |    1 -
 arch/arm/cpu/armv8/gic.S          |  106 --------------------
 arch/arm/cpu/armv8/start.S        |   46 +++++++--
 arch/arm/include/asm/gic.h        |   56 +++++++++++
 arch/arm/lib/Makefile             |    1 +
 arch/arm/lib/gic_64.S             |  194 +++++++++++++++++++++++++++++++++++++
 include/configs/vexpress_aemv8a.h |    7 ++
 7 files changed, 297 insertions(+), 114 deletions(-)
 delete mode 100644 arch/arm/cpu/armv8/gic.S
 create mode 100644 arch/arm/lib/gic_64.S

diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
index b6eb6de..7d93f59 100644
--- a/arch/arm/cpu/armv8/Makefile
+++ b/arch/arm/cpu/armv8/Makefile
@@ -13,5 +13,4 @@ obj-y	+= cache_v8.o
 obj-y	+= exceptions.o
 obj-y	+= cache.o
 obj-y	+= tlb.o
-obj-y	+= gic.o
 obj-y	+= transition.o
diff --git a/arch/arm/cpu/armv8/gic.S b/arch/arm/cpu/armv8/gic.S
deleted file mode 100644
index 599aa8f..0000000
--- a/arch/arm/cpu/armv8/gic.S
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * GIC Initialization Routines.
- *
- * (C) Copyright 2013
- * David Feng <fenghua@phytium.com.cn>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <asm-offsets.h>
-#include <config.h>
-#include <linux/linkage.h>
-#include <asm/macro.h>
-#include <asm/gic.h>
-
-
-/*************************************************************************
- *
- * void gic_init(void) __attribute__((weak));
- *
- * Currently, this routine only initialize secure copy of GIC
- * with Security Extensions at EL3.
- *
- *************************************************************************/
-WEAK(gic_init)
-	branch_if_slave	x0, 2f
-
-	/* Initialize Distributor and SPIs */
-	ldr	x1, =GICD_BASE
-	mov	w0, #0x3		/* EnableGrp0 | EnableGrp1 */
-	str	w0, [x1, GICD_CTLR]	/* Secure GICD_CTLR */
-	ldr	w0, [x1, GICD_TYPER]
-	and	w2, w0, #0x1f		/* ITLinesNumber */
-	cbz	w2, 2f			/* No SPIs */
-	add	x1, x1, (GICD_IGROUPRn + 4)
-	mov	w0, #~0			/* Config SPIs as Grp1 */
-1:	str	w0, [x1], #0x4
-	sub	w2, w2, #0x1
-	cbnz	w2, 1b
-
-	/* Initialize SGIs and PPIs */
-2:	ldr	x1, =GICD_BASE
-	mov	w0, #~0			/* Config SGIs and PPIs as Grp1 */
-	str	w0, [x1, GICD_IGROUPRn]	/* GICD_IGROUPR0 */
-	mov	w0, #0x1		/* Enable SGI 0 */
-	str	w0, [x1, GICD_ISENABLERn]
-
-	/* Initialize Cpu Interface */
-	ldr	x1, =GICC_BASE
-	mov	w0, #0x1e7		/* Disable IRQ/FIQ Bypass & */
-					/* Enable Ack Group1 Interrupt & */
-					/* EnableGrp0 & EnableGrp1 */
-	str	w0, [x1, GICC_CTLR]	/* Secure GICC_CTLR */
-
-	mov	w0, #0x1 << 7		/* Non-Secure access to GICC_PMR */
-	str	w0, [x1, GICC_PMR]
-
-	ret
-ENDPROC(gic_init)
-
-
-/*************************************************************************
- *
- * void gic_send_sgi(u64 sgi) __attribute__((weak));
- *
- *************************************************************************/
-WEAK(gic_send_sgi)
-	ldr	x1, =GICD_BASE
-	mov	w2, #0x8000
-	movk	w2, #0x100, lsl #16
-	orr	w2, w2, w0
-	str	w2, [x1, GICD_SGIR]
-	ret
-ENDPROC(gic_send_sgi)
-
-
-/*************************************************************************
- *
- * void wait_for_wakeup(void) __attribute__((weak));
- *
- * Wait for SGI 0 from master.
- *
- *************************************************************************/
-WEAK(wait_for_wakeup)
-	ldr	x1, =GICC_BASE
-0:	wfi
-	ldr	w0, [x1, GICC_AIAR]
-	str	w0, [x1, GICC_AEOIR]
-	cbnz	w0, 0b
-	ret
-ENDPROC(wait_for_wakeup)
-
-
-/*************************************************************************
- *
- * void smp_kick_all_cpus(void) __attribute__((weak));
- *
- *************************************************************************/
-WEAK(smp_kick_all_cpus)
-	/* Kick secondary cpus up by SGI 0 interrupt */
-	mov	x0, xzr			/* SGI 0 */
-	mov	x29, lr			/* Save LR */
-	bl	gic_send_sgi
-	mov	lr, x29			/* Restore LR */
-	ret
-ENDPROC(smp_kick_all_cpus)
diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S
index bcc2603..4d304cf 100644
--- a/arch/arm/cpu/armv8/start.S
+++ b/arch/arm/cpu/armv8/start.S
@@ -50,7 +50,10 @@ reset:
 	 */
 	adr	x0, vectors
 	switch_el x1, 3f, 2f, 1f
-3:	msr	vbar_el3, x0
+3:	mrs	x0, scr_el3
+	orr	x0, x0, #0xf			/* SCR_EL3.NS|IRQ|FIQ|EA */
+	msr	scr_el3, x0
+	msr	vbar_el3, x0
 	msr	cptr_el3, xzr			/* Enable FP/SIMD */
 	ldr	x0, =COUNTER_FREQUENCY
 	msr	cntfrq_el0, x0			/* Initialize CNTFRQ */
@@ -93,32 +96,61 @@ master_cpu:
 /*-----------------------------------------------------------------------*/
 
 WEAK(lowlevel_init)
-	/* Initialize GIC Secure Bank Status */
 	mov	x29, lr			/* Save LR */
-	bl	gic_init
 
-	branch_if_master x0, x1, 1f
+#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
+	branch_if_slave x0, 1f
+	ldr	x0, =GICD_BASE
+	bl	gic_init_secure
+1:
+#if defined(CONFIG_GICV3)
+	ldr	x0, =GICR_BASE
+	bl	gic_init_secure_percpu
+#elif defined(CONFIG_GICV2)
+	ldr	x0, =GICD_BASE
+	ldr	x1, =GICC_BASE
+	bl	gic_init_secure_percpu
+#endif
+#endif
+
+	branch_if_master x0, x1, 2f
 
 	/*
 	 * Slave should wait for master clearing spin table.
 	 * This sync prevent salves observing incorrect
 	 * value of spin table and jumping to wrong place.
 	 */
-	bl	wait_for_wakeup
+#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
+#ifdef CONFIG_GICV2
+	ldr	x0, =GICC_BASE
+#endif
+	bl	gic_wait_for_interrupt
+#endif
 
 	/*
-	 * All processors will enter EL2 and optionally EL1.
+	 * All slaves will enter EL2 and optionally EL1.
 	 */
 	bl	armv8_switch_to_el2
 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
 	bl	armv8_switch_to_el1
 #endif
 
-1:
+2:
 	mov	lr, x29			/* Restore LR */
 	ret
 ENDPROC(lowlevel_init)
 
+WEAK(smp_kick_all_cpus)
+	/* Kick secondary cpus up by SGI 0 interrupt */
+	mov	x29, lr			/* Save LR */
+#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
+	ldr	x0, =GICD_BASE
+	bl	gic_kick_secondary_cpus
+#endif
+	mov	lr, x29			/* Restore LR */
+	ret
+ENDPROC(smp_kick_all_cpus)
+
 /*-----------------------------------------------------------------------*/
 
 ENTRY(c_runtime_cpu_setup)
diff --git a/arch/arm/include/asm/gic.h b/arch/arm/include/asm/gic.h
index ac2b2bf..bd3a80c 100644
--- a/arch/arm/include/asm/gic.h
+++ b/arch/arm/include/asm/gic.h
@@ -51,4 +51,60 @@
 #define GICC_IIDR		0x00fc
 #define GICC_DIR		0x1000
 
+/* ReDistributor Registers for Control and Physical LPIs */
+#define GICR_CTLR		0x0000
+#define GICR_IIDR		0x0004
+#define GICR_TYPER		0x0008
+#define GICR_STATUSR		0x0010
+#define GICR_WAKER		0x0014
+#define GICR_SETLPIR		0x0040
+#define GICR_CLRLPIR		0x0048
+#define GICR_SEIR		0x0068
+#define GICR_PROPBASER		0x0070
+#define GICR_PENDBASER		0x0078
+#define GICR_INVLPIR		0x00a0
+#define GICR_INVALLR		0x00b0
+#define GICR_SYNCR		0x00c0
+#define GICR_MOVLPIR		0x0100
+#define GICR_MOVALLR		0x0110
+
+/* ReDistributor Registers for SGIs and PPIs */
+#define GICR_IGROUPRn		0x0080
+#define GICR_ISENABLERn		0x0100
+#define GICR_ICENABLERn		0x0180
+#define GICR_ISPENDRn		0x0200
+#define GICR_ICPENDRn		0x0280
+#define GICR_ISACTIVERn		0x0300
+#define GICR_ICACTIVERn		0x0380
+#define GICR_IPRIORITYRn	0x0400
+#define GICR_ICFGR0		0x0c00
+#define GICR_ICFGR1		0x0c04
+#define GICR_IGROUPMODRn	0x0d00
+#define GICR_NSACRn		0x0e00
+
+/* Cpu Interface System Registers */
+#define ICC_IAR0_EL1		S3_0_C12_C8_0
+#define ICC_IAR1_EL1		S3_0_C12_C12_0
+#define ICC_EOIR0_EL1		S3_0_C12_C8_1
+#define ICC_EOIR1_EL1		S3_0_C12_C12_1
+#define ICC_HPPIR0_EL1		S3_0_C12_C8_2
+#define ICC_HPPIR1_EL1		S3_0_C12_C12_2
+#define ICC_BPR0_EL1		S3_0_C12_C8_3
+#define ICC_BPR1_EL1		S3_0_C12_C12_3
+#define ICC_DIR_EL1		S3_0_C12_C11_1
+#define ICC_PMR_EL1		S3_0_C4_C6_0
+#define ICC_RPR_EL1		S3_0_C12_C11_3
+#define ICC_CTLR_EL1		S3_0_C12_C12_4
+#define ICC_CTLR_EL3		S3_6_C12_C12_4
+#define ICC_SRE_EL1		S3_0_C12_C12_5
+#define ICC_SRE_EL2		S3_4_C12_C9_5
+#define ICC_SRE_EL3		S3_6_C12_C12_5
+#define ICC_IGRPEN0_EL1		S3_0_C12_C12_6
+#define ICC_IGRPEN1_EL1		S3_0_C12_C12_7
+#define ICC_IGRPEN1_EL3		S3_6_C12_C12_7
+#define ICC_SEIEN_EL1		S3_0_C12_C13_0
+#define ICC_SGI0R_EL1		S3_0_C12_C11_7
+#define ICC_SGI1R_EL1		S3_0_C12_C11_5
+#define ICC_ASGI1R_EL1		S3_0_C12_C11_6
+
 #endif /* __GIC_H__ */
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 9fc81cd..e035d6a 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -35,6 +35,7 @@ endif
 
 obj-y	+= sections.o
 ifdef CONFIG_ARM64
+obj-y	+= gic_64.o
 obj-y	+= interrupts_64.o
 else
 obj-y	+= interrupts.o
diff --git a/arch/arm/lib/gic_64.S b/arch/arm/lib/gic_64.S
new file mode 100644
index 0000000..d56396e
--- /dev/null
+++ b/arch/arm/lib/gic_64.S
@@ -0,0 +1,194 @@
+/*
+ * GIC Initialization Routines.
+ *
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/macro.h>
+#include <asm/gic.h>
+
+
+/*************************************************************************
+ *
+ * void gic_init_secure(DistributorBase);
+ *
+ * Initialize secure copy of GIC at EL3.
+ *
+ *************************************************************************/
+ENTRY(gic_init_secure)
+	/*
+	 * Initialize Distributor
+	 * x0: Distributor Base
+	 */
+#if defined(CONFIG_GICV3)
+	mov	w9, #0x37		/* EnableGrp0 | EnableGrp1NS */
+					/* EnableGrp1S | ARE_S | ARE_NS */
+	str	w9, [x0, GICD_CTLR]	/* Secure GICD_CTLR */
+	ldr	w9, [x0, GICD_TYPER]
+	and	w10, w9, #0x1f		/* ITLinesNumber */
+	cbz	w10, 1f			/* No SPIs */
+	add	x11, x0, (GICD_IGROUPRn + 4)
+	add	x12, x0, (GICD_IGROUPMODRn + 4)
+	mov	w9, #~0
+0:	str	w9, [x11], #0x4
+	str	wzr, [x12], #0x4	/* Config SPIs as Group1NS */
+	sub	w10, w10, #0x1
+	cbnz	w10, 0b
+#elif defined(CONFIG_GICV2)
+	mov	w9, #0x3		/* EnableGrp0 | EnableGrp1 */
+	str	w9, [x0, GICD_CTLR]	/* Secure GICD_CTLR */
+	ldr	w9, [x0, GICD_TYPER]
+	and	w10, w9, #0x1f		/* ITLinesNumber */
+	cbz	w10, 1f			/* No SPIs */
+	add	x11, x0, (GICD_IGROUPRn + 4)
+	mov	w9, #~0			/* Config SPIs as Grp1 */
+0:	str	w9, [x11], #0x4
+	sub	w10, w10, #0x1
+	cbnz	w10, 0b
+#endif
+1:
+	ret
+ENDPROC(gic_init_secure)
+
+
+/*************************************************************************
+ * For Gicv2:
+ * void gic_init_secure_percpu(DistributorBase, CpuInterfaceBase);
+ * For Gicv3:
+ * void gic_init_secure_percpu(ReDistributorBase);
+ *
+ * Initialize secure copy of GIC at EL3.
+ *
+ *************************************************************************/
+ENTRY(gic_init_secure_percpu)
+#if defined(CONFIG_GICV3)
+	/*
+	 * Initialize ReDistributor
+	 * x0: ReDistributor Base
+	 */
+	mrs	x10, mpidr_el1
+	lsr	x9, x10, #32
+	bfi	x10, x9, #24, #8	/* w10 is aff3:aff2:aff1:aff0 */
+	mov	x9, x0
+1:	ldr	x11, [x9, GICR_TYPER]
+	lsr	x11, x11, #32		/* w11 is aff3:aff2:aff1:aff0 */
+	cmp	w10, w11
+	b.eq	2f
+	add	x9, x9, #(2 << 16)
+	b	1b
+
+	/* x9: ReDistributor Base Address of Current CPU */
+2:	mov	w10, #~0x2
+	ldr	w11, [x9, GICR_WAKER]
+	and	w11, w11, w10		/* Clear ProcessorSleep */
+	str	w11, [x9, GICR_WAKER]
+	dsb	st
+	isb
+3:	ldr	w10, [x9, GICR_WAKER]
+	tbnz	w10, #2, 3b		/* Wait Children be Alive */
+
+	add	x10, x9, #(1 << 16)	/* SGI_Base */
+	mov	w11, #~0
+	str	w11, [x10, GICR_IGROUPRn]
+	str	wzr, [x10, GICR_IGROUPMODRn]	/* SGIs|PPIs Group1NS */
+	mov	w11, #0x1		/* Enable SGI 0 */
+	str	w11, [x10, GICR_ISENABLERn]
+
+	/* Initialize Cpu Interface */
+	mrs	x10, ICC_SRE_EL3
+	orr	x10, x10, #0xf		/* SRE & Disable IRQ/FIQ Bypass & */
+					/* Allow EL2 access to ICC_SRE_EL2 */
+	msr	ICC_SRE_EL3, x10
+	isb
+
+	mrs	x10, ICC_SRE_EL2
+	orr	x10, x10, #0xf		/* SRE & Disable IRQ/FIQ Bypass & */
+					/* Allow EL1 access to ICC_SRE_EL1 */
+	msr	ICC_SRE_EL2, x10
+	isb
+
+	mov	x10, #0x3		/* EnableGrp1NS | EnableGrp1S */
+	msr	ICC_IGRPEN1_EL3, x10
+	isb
+
+	msr	ICC_CTLR_EL3, xzr
+	isb
+
+	msr	ICC_CTLR_EL1, xzr	/* NonSecure ICC_CTLR_EL1 */
+	isb
+
+	mov	x10, #0x1 << 7		/* Non-Secure access to ICC_PMR_EL1 */
+	msr	ICC_PMR_EL1, x10
+	isb
+#elif defined(CONFIG_GICV2)
+	/*
+	 * Initialize SGIs and PPIs
+	 * x0: Distributor Base
+	 * x1: Cpu Interface Base
+	 */
+	mov	w9, #~0			/* Config SGIs and PPIs as Grp1 */
+	str	w9, [x0, GICD_IGROUPRn]	/* GICD_IGROUPR0 */
+	mov	w9, #0x1		/* Enable SGI 0 */
+	str	w9, [x0, GICD_ISENABLERn]
+
+	/* Initialize Cpu Interface */
+	mov	w9, #0x1e7		/* Disable IRQ/FIQ Bypass & */
+					/* Enable Ack Group1 Interrupt & */
+					/* EnableGrp0 & EnableGrp1 */
+	str	w9, [x1, GICC_CTLR]	/* Secure GICC_CTLR */
+
+	mov	w9, #0x1 << 7		/* Non-Secure access to GICC_PMR */
+	str	w9, [x1, GICC_PMR]
+#endif
+	ret
+ENDPROC(gic_init_secure_percpu)
+
+
+/*************************************************************************
+ * For Gicv2:
+ * void gic_kick_secondary_cpus(DistributorBase);
+ * For Gicv3:
+ * void gic_kick_secondary_cpus(void);
+ *
+ *************************************************************************/
+ENTRY(gic_kick_secondary_cpus)
+#if defined(CONFIG_GICV3)
+	mov	x9, #(1 << 40)
+	msr	ICC_ASGI1R_EL1, x9
+	isb
+#elif defined(CONFIG_GICV2)
+	mov	w9, #0x8000
+	movk	w9, #0x100, lsl #16
+	str	w9, [x0, GICD_SGIR]
+#endif
+	ret
+ENDPROC(gic_kick_secondary_cpus)
+
+
+/*************************************************************************
+ * For Gicv2:
+ * void gic_wait_for_interrupt(CpuInterfaceBase);
+ * For Gicv3:
+ * void gic_wait_for_interrupt(void);
+ *
+ * Wait for SGI 0 from master.
+ *
+ *************************************************************************/
+ENTRY(gic_wait_for_interrupt)
+0:	wfi
+#if defined(CONFIG_GICV3)
+	mrs	x9, ICC_IAR1_EL1
+	msr	ICC_EOIR1_EL1, x9
+#elif defined(CONFIG_GICV2)
+	ldr	w9, [x0, GICC_AIAR]
+	str	w9, [x0, GICC_AEOIR]
+#endif
+	cbnz	w9, 0b
+	ret
+ENDPROC(gic_wait_for_interrupt)
diff --git a/include/configs/vexpress_aemv8a.h b/include/configs/vexpress_aemv8a.h
index e851702..dff6adc 100644
--- a/include/configs/vexpress_aemv8a.h
+++ b/include/configs/vexpress_aemv8a.h
@@ -12,6 +12,8 @@
 
 #define CONFIG_REMAKE_ELF
 
+#define CONFIG_GICV3
+
 /*#define CONFIG_ARMV8_SWITCH_TO_EL1*/
 
 /*#define CONFIG_SYS_GENERIC_BOARD*/
@@ -93,8 +95,13 @@
 #define COUNTER_FREQUENCY		(0x1800000)	/* 24MHz */
 
 /* Generic Interrupt Controller Definitions */
+#ifdef CONFIG_GICV3
+#define GICD_BASE			(0x2f000000)
+#define GICR_BASE			(0x2f100000)
+#else
 #define GICD_BASE			(0x2C001000)
 #define GICC_BASE			(0x2C002000)
+#endif
 
 #define CONFIG_SYS_MEMTEST_START	V2M_BASE
 #define CONFIG_SYS_MEMTEST_END		(V2M_BASE + 0x80000000)
-- 
1.7.9.5

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

end of thread, other threads:[~2014-04-07 23:03 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-14  6:26 [U-Boot] [PATCH v2] arm64 patch: gicv3 support fenghua at phytium.com.cn
2014-03-31  6:30 ` [U-Boot] why not enable ICache in vexpress_aemv8a.h TigerLiu at via-alliance.com
2014-04-01 16:21   ` York Sun
2014-04-02  0:43     ` TigerLiu at via-alliance.com
2014-04-07 23:03 ` [U-Boot] [PATCH v2] arm64 patch: gicv3 support Albert ARIBAUD

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.