Commit 4c158b9a7d05973e6924835726a2358b383d622f
Committed by
Tom Rini
1 parent
7e719ee7d8
Exists in
v2017.01-smarct4x
and in
25 other branches
arm: omap5: Add function to make an SMC call on cpu1
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>
Showing 3 changed files with 125 additions and 0 deletions Side-by-side Diff
arch/arm/include/asm/omap_common.h
... | ... | @@ -632,6 +632,7 @@ |
632 | 632 | * security (HS) device variants by doing a specially-formed smc entry. |
633 | 633 | */ |
634 | 634 | u32 omap_smc_sec(u32 service, u32 proc_id, u32 flag, u32 *params); |
635 | +u32 omap_smc_sec_cpu1(u32 service, u32 proc_id, u32 flag, u32 *params); | |
635 | 636 | |
636 | 637 | void enable_edma3_clocks(void); |
637 | 638 | void disable_edma3_clocks(void); |
arch/arm/mach-omap2/omap5/Makefile
arch/arm/mach-omap2/omap5/sec_entry_cpu1.S
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 | + */ | |
38 | +LENTRY(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 | |
70 | +END(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 | + */ | |
79 | +ENTRY(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} | |
106 | +ENDPROC(omap_smc_sec_cpu1) | |
107 | + | |
108 | +/* | |
109 | + * Buffer to save function arguments and return value for omap_smc_sec_cpu1 | |
110 | + */ | |
111 | +.section .data | |
112 | +omap_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 | |
123 | +END(omap_smc_sec_cpu1_args) |