/* SPDX-License-Identifier: GPL-2.0+ */ /* * Secure entry function for CPU Core #1 * * (C) Copyright 2016 * Texas Instruments, <www.ti.com> * * Author : * Harinarayan Bhatta <harinarayan@ti.com> */ #include <config.h> #include <asm/arch/omap.h> #include <asm/omap_common.h> #include <linux/linkage.h> .arch_extension sec #if !CONFIG_IS_ENABLED(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 !CONFIG_IS_ENABLED(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 !CONFIG_IS_ENABLED(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)