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>master
parent
7e719ee7d8
commit
4c158b9a7d
@ -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) |
Loading…
Reference in new issue