1/* 2 * Secure entry function for CPU Core #1 3 * 4 * (C) Copyright 2016 5 * Texas Instruments, <www.ti.com> 6 * 7 * Author : 8 * Harinarayan Bhatta <harinarayan@ti.com> 9 * 10 * SPDX-License-Identifier: GPL-2.0+ 11 */ 12 13#include <config.h> 14#include <asm/arch/omap.h> 15#include <asm/omap_common.h> 16#include <linux/linkage.h> 17 18.arch_extension sec 19 20#if !defined(CONFIG_SYS_DCACHE_OFF) 21.global flush_dcache_range 22#endif 23 24#define AUX_CORE_BOOT_0 0x48281800 25#define AUX_CORE_BOOT_1 0x48281804 26 27#ifdef CONFIG_DRA7XX 28/* DRA7xx ROM code function "startup_BootSlave". This function is where CPU1 29 * waits on WFE, polling on AUX_CORE_BOOT_x registers. 30 * This address is same for J6 and J6 Eco. 31 */ 32#define ROM_FXN_STARTUP_BOOTSLAVE 0x00038a64 33#endif 34 35/* Assembly core where CPU1 is woken up into 36 * No need to save-restore registers, does not use stack. 37 */ 38LENTRY(cpu1_entry) 39 ldr r4, =omap_smc_sec_cpu1_args 40 ldm r4, {r0,r1,r2,r3} @ Retrieve args 41 42 mov r6, #0xFF @ Indicate new Task call 43 mov r12, #0x00 @ Secure Service ID in R12 44 45 dsb 46 dmb 47 smc 0 @ SMC #0 to enter monitor mode 48 49 b .Lend @ exit at end of the service execution 50 nop 51 52 @ In case of IRQ happening in Secure, then ARM will branch here. 53 @ At that moment, IRQ will be pending and ARM will jump to Non Secure 54 @ IRQ handler 55 mov r12, #0xFE 56 57 dsb 58 dmb 59 smc 0 @ SMC #0 to enter monitor mode 60 61.Lend: 62 ldr r4, =omap_smc_sec_cpu1_args 63 str r0, [r4, #0x10] @ save return value 64 ldr r4, =AUX_CORE_BOOT_0 65 mov r5, #0x0 66 str r5, [r4] 67 ldr r4, =ROM_FXN_STARTUP_BOOTSLAVE 68 sev @ Tell CPU0 we are done 69 bx r4 @ Jump back to ROM 70END(cpu1_entry) 71 72/* 73 * u32 omap_smc_sec_cpu1(u32 service, u32 proc_id, u32 flag, u32 *params); 74 * 75 * Makes a secure ROM/PPA call on CPU Core #1 on supported platforms. 76 * Assumes that CPU #1 is waiting in ROM code and not yet woken up or used by 77 * u-boot. 78 */ 79ENTRY(omap_smc_sec_cpu1) 80 push {r4, r5, lr} 81 ldr r4, =omap_smc_sec_cpu1_args 82 stm r4, {r0,r1,r2,r3} @ Save args to memory 83#if !defined(CONFIG_SYS_DCACHE_OFF) 84 mov r0, r4 85 mov r1, #CONFIG_SYS_CACHELINE_SIZE 86 add r1, r0, r1 @ dcache is not enabled on CPU1, so 87 blx flush_dcache_range @ flush the cache on args buffer 88#endif 89 ldr r4, =AUX_CORE_BOOT_1 90 ldr r5, =cpu1_entry 91 str r5, [r4] @ Setup CPU1 entry function 92 ldr r4, =AUX_CORE_BOOT_0 93 mov r5, #0x10 94 str r5, [r4] @ Tell ROM to exit while loop 95 sev @ Wake up CPU1 96.Lwait: 97 wfe @ Wait for CPU1 to finish 98 nop 99 ldr r5, [r4] @ Check if CPU1 is done 100 cmp r5, #0 101 bne .Lwait 102 103 ldr r4, =omap_smc_sec_cpu1_args 104 ldr r0, [r4, #0x10] @ Retrieve return value 105 pop {r4, r5, pc} 106ENDPROC(omap_smc_sec_cpu1) 107 108/* 109 * Buffer to save function arguments and return value for omap_smc_sec_cpu1 110 */ 111.section .data 112omap_smc_sec_cpu1_args: 113#if !defined(CONFIG_SYS_DCACHE_OFF) 114 .balign CONFIG_SYS_CACHELINE_SIZE 115 .rept CONFIG_SYS_CACHELINE_SIZE/4 116 .word 0 117 .endr 118#else 119 .rept 5 120 .word 0 121 .endr 122#endif 123END(omap_smc_sec_cpu1_args) 124