summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorHarinarayan Bhatta <harinarayan@ti.com>2016-11-29 16:33:22 -0600
committerTom Rini <trini@konsulko.com>2016-12-03 13:21:20 -0500
commit4c158b9a7d05973e6924835726a2358b383d622f (patch)
tree2e41f4963f656d3f350016a33c2fb7526576eefc /arch
parent7e719ee7d8eb61f459a38f69a825823603879258 (diff)
downloadu-boot-imx-4c158b9a7d05973e6924835726a2358b383d622f.zip
u-boot-imx-4c158b9a7d05973e6924835726a2358b383d622f.tar.gz
u-boot-imx-4c158b9a7d05973e6924835726a2358b383d622f.tar.bz2
arm: omap5: Add function to make an SMC call on cpu1
On DRA7xx platform, CPU Core 1 is not used in u-boot. However, in some cases it is need to make secure API calls from Core 1. This patch adds an assembly function to make a secure (SMC) call from CPU Core #1. Signed-off-by: Harinarayan Bhatta <harinarayan@ti.com> Signed-off-by: Andrew F. Davis <afd@ti.com> Reviewed-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/include/asm/omap_common.h1
-rw-r--r--arch/arm/mach-omap2/omap5/Makefile1
-rw-r--r--arch/arm/mach-omap2/omap5/sec_entry_cpu1.S123
3 files changed, 125 insertions, 0 deletions
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h
index 605c549..290a190 100644
--- a/arch/arm/include/asm/omap_common.h
+++ b/arch/arm/include/asm/omap_common.h
@@ -632,6 +632,7 @@ void omap_smc1(u32 service, u32 val);
* security (HS) device variants by doing a specially-formed smc entry.
*/
u32 omap_smc_sec(u32 service, u32 proc_id, u32 flag, u32 *params);
+u32 omap_smc_sec_cpu1(u32 service, u32 proc_id, u32 flag, u32 *params);
void enable_edma3_clocks(void);
void disable_edma3_clocks(void);
diff --git a/arch/arm/mach-omap2/omap5/Makefile b/arch/arm/mach-omap2/omap5/Makefile
index 0212df7..af17a3d 100644
--- a/arch/arm/mach-omap2/omap5/Makefile
+++ b/arch/arm/mach-omap2/omap5/Makefile
@@ -15,3 +15,4 @@ obj-y += abb.o
obj-y += fdt.o
obj-$(CONFIG_IODELAY_RECALIBRATION) += dra7xx_iodelay.o
obj-$(CONFIG_TI_SECURE_DEVICE) += sec-fxns.o
+obj-$(CONFIG_DRA7XX) += sec_entry_cpu1.o
diff --git a/arch/arm/mach-omap2/omap5/sec_entry_cpu1.S b/arch/arm/mach-omap2/omap5/sec_entry_cpu1.S
new file mode 100644
index 0000000..c2a35ee
--- /dev/null
+++ b/arch/arm/mach-omap2/omap5/sec_entry_cpu1.S
@@ -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)