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