From: Harinarayan Bhatta Date: Tue, 29 Nov 2016 22:33:22 +0000 (-0600) Subject: arm: omap5: Add function to make an SMC call on cpu1 X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=4c158b9a7d05973e6924835726a2358b383d622f;p=u-boot.git 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 Signed-off-by: Andrew F. Davis Reviewed-by: Tom Rini --- diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 605c549f0a..290a190c7b 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 0212df73c1..af17a3deab 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 0000000000..c2a35eeccb --- /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, + * + * Author : + * Harinarayan Bhatta + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +.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)