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