|
@@ -57,6 +57,28 @@ _secure_monitor:
|
|
|
|
|
|
movs pc, lr @ return to non-secure SVC
|
|
|
|
|
|
+/*
|
|
|
+ * Secondary CPUs start here and call the code for the core specific parts
|
|
|
+ * of the non-secure and HYP mode transition. The GIC distributor specific
|
|
|
+ * code has already been executed by a C function before.
|
|
|
+ * Then they go back to wfi and wait to be woken up by the kernel again.
|
|
|
+ */
|
|
|
+ENTRY(_smp_pen)
|
|
|
+ mrs r0, cpsr
|
|
|
+ orr r0, r0, #0xc0
|
|
|
+ msr cpsr, r0 @ disable interrupts
|
|
|
+ ldr r1, =_start
|
|
|
+ mcr p15, 0, r1, c12, c0, 0 @ set VBAR
|
|
|
+
|
|
|
+ bl _nonsec_init
|
|
|
+
|
|
|
+ ldr r1, [r0, #GICC_IAR] @ acknowledge IPI
|
|
|
+ str r1, [r0, #GICC_EOIR] @ signal end of interrupt
|
|
|
+
|
|
|
+ adr r0, _smp_pen @ do not use this address again
|
|
|
+ b smp_waitloop @ wait for IPIs, board specific
|
|
|
+ENDPROC(_smp_pen)
|
|
|
+
|
|
|
/*
|
|
|
* Switch a core to non-secure state.
|
|
|
*
|
|
@@ -138,3 +160,16 @@ ENTRY(_nonsec_init)
|
|
|
|
|
|
bx lr
|
|
|
ENDPROC(_nonsec_init)
|
|
|
+
|
|
|
+#ifdef CONFIG_SMP_PEN_ADDR
|
|
|
+/* void __weak smp_waitloop(unsigned previous_address); */
|
|
|
+ENTRY(smp_waitloop)
|
|
|
+ wfi
|
|
|
+ ldr r1, =CONFIG_SMP_PEN_ADDR @ load start address
|
|
|
+ ldr r1, [r1]
|
|
|
+ cmp r0, r1 @ make sure we dont execute this code
|
|
|
+ beq smp_waitloop @ again (due to a spurious wakeup)
|
|
|
+ mov pc, r1
|
|
|
+ENDPROC(smp_waitloop)
|
|
|
+.weak smp_waitloop
|
|
|
+#endif
|