|
@@ -0,0 +1,123 @@
|
|
|
+/*
|
|
|
+ * Secure entry function for CPU Core #1
|
|
|
+ *
|
|
|
+ * (C) Copyright 2016
|
|
|
+ * Texas Instruments, <www.ti.com>
|
|
|
+ *
|
|
|
+ * Author :
|
|
|
+ * Harinarayan Bhatta <harinarayan@ti.com>
|
|
|
+ *
|
|
|
+ * SPDX-License-Identifier: GPL-2.0+
|
|
|
+ */
|
|
|
+
|
|
|
+#include <config.h>
|
|
|
+#include <asm/arch/omap.h>
|
|
|
+#include <asm/omap_common.h>
|
|
|
+#include <linux/linkage.h>
|
|
|
+
|
|
|
+.arch_extension sec
|
|
|
+
|
|
|
+#if !defined(CONFIG_SYS_DCACHE_OFF)
|
|
|
+.global flush_dcache_range
|
|
|
+#endif
|
|
|
+
|
|
|
+#define AUX_CORE_BOOT_0 0x48281800
|
|
|
+#define AUX_CORE_BOOT_1 0x48281804
|
|
|
+
|
|
|
+#ifdef CONFIG_DRA7XX
|
|
|
+/* DRA7xx ROM code function "startup_BootSlave". This function is where CPU1
|
|
|
+ * waits on WFE, polling on AUX_CORE_BOOT_x registers.
|
|
|
+ * This address is same for J6 and J6 Eco.
|
|
|
+ */
|
|
|
+#define ROM_FXN_STARTUP_BOOTSLAVE 0x00038a64
|
|
|
+#endif
|
|
|
+
|
|
|
+/* Assembly core where CPU1 is woken up into
|
|
|
+ * No need to save-restore registers, does not use stack.
|
|
|
+ */
|
|
|
+LENTRY(cpu1_entry)
|
|
|
+ ldr r4, =omap_smc_sec_cpu1_args
|
|
|
+ ldm r4, {r0,r1,r2,r3} @ Retrieve args
|
|
|
+
|
|
|
+ mov r6, #0xFF @ Indicate new Task call
|
|
|
+ mov r12, #0x00 @ Secure Service ID in R12
|
|
|
+
|
|
|
+ dsb
|
|
|
+ dmb
|
|
|
+ smc 0 @ SMC #0 to enter monitor mode
|
|
|
+
|
|
|
+ b .Lend @ exit at end of the service execution
|
|
|
+ nop
|
|
|
+
|
|
|
+ @ In case of IRQ happening in Secure, then ARM will branch here.
|
|
|
+ @ At that moment, IRQ will be pending and ARM will jump to Non Secure
|
|
|
+ @ IRQ handler
|
|
|
+ mov r12, #0xFE
|
|
|
+
|
|
|
+ dsb
|
|
|
+ dmb
|
|
|
+ smc 0 @ SMC #0 to enter monitor mode
|
|
|
+
|
|
|
+.Lend:
|
|
|
+ ldr r4, =omap_smc_sec_cpu1_args
|
|
|
+ str r0, [r4, #0x10] @ save return value
|
|
|
+ ldr r4, =AUX_CORE_BOOT_0
|
|
|
+ mov r5, #0x0
|
|
|
+ str r5, [r4]
|
|
|
+ ldr r4, =ROM_FXN_STARTUP_BOOTSLAVE
|
|
|
+ sev @ Tell CPU0 we are done
|
|
|
+ bx r4 @ Jump back to ROM
|
|
|
+END(cpu1_entry)
|
|
|
+
|
|
|
+/*
|
|
|
+ * u32 omap_smc_sec_cpu1(u32 service, u32 proc_id, u32 flag, u32 *params);
|
|
|
+ *
|
|
|
+ * Makes a secure ROM/PPA call on CPU Core #1 on supported platforms.
|
|
|
+ * Assumes that CPU #1 is waiting in ROM code and not yet woken up or used by
|
|
|
+ * u-boot.
|
|
|
+ */
|
|
|
+ENTRY(omap_smc_sec_cpu1)
|
|
|
+ push {r4, r5, lr}
|
|
|
+ ldr r4, =omap_smc_sec_cpu1_args
|
|
|
+ stm r4, {r0,r1,r2,r3} @ Save args to memory
|
|
|
+#if !defined(CONFIG_SYS_DCACHE_OFF)
|
|
|
+ mov r0, r4
|
|
|
+ mov r1, #CONFIG_SYS_CACHELINE_SIZE
|
|
|
+ add r1, r0, r1 @ dcache is not enabled on CPU1, so
|
|
|
+ blx flush_dcache_range @ flush the cache on args buffer
|
|
|
+#endif
|
|
|
+ ldr r4, =AUX_CORE_BOOT_1
|
|
|
+ ldr r5, =cpu1_entry
|
|
|
+ str r5, [r4] @ Setup CPU1 entry function
|
|
|
+ ldr r4, =AUX_CORE_BOOT_0
|
|
|
+ mov r5, #0x10
|
|
|
+ str r5, [r4] @ Tell ROM to exit while loop
|
|
|
+ sev @ Wake up CPU1
|
|
|
+.Lwait:
|
|
|
+ wfe @ Wait for CPU1 to finish
|
|
|
+ nop
|
|
|
+ ldr r5, [r4] @ Check if CPU1 is done
|
|
|
+ cmp r5, #0
|
|
|
+ bne .Lwait
|
|
|
+
|
|
|
+ ldr r4, =omap_smc_sec_cpu1_args
|
|
|
+ ldr r0, [r4, #0x10] @ Retrieve return value
|
|
|
+ pop {r4, r5, pc}
|
|
|
+ENDPROC(omap_smc_sec_cpu1)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Buffer to save function arguments and return value for omap_smc_sec_cpu1
|
|
|
+ */
|
|
|
+.section .data
|
|
|
+omap_smc_sec_cpu1_args:
|
|
|
+#if !defined(CONFIG_SYS_DCACHE_OFF)
|
|
|
+ .balign CONFIG_SYS_CACHELINE_SIZE
|
|
|
+ .rept CONFIG_SYS_CACHELINE_SIZE/4
|
|
|
+ .word 0
|
|
|
+ .endr
|
|
|
+#else
|
|
|
+ .rept 5
|
|
|
+ .word 0
|
|
|
+ .endr
|
|
|
+#endif
|
|
|
+END(omap_smc_sec_cpu1_args)
|