hc
2024-05-14 bedbef8ad3e75a304af6361af235302bcc61d06b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
 * Secure entry function for CPU Core #1
 *
 * (C) Copyright 2016
 * Texas Instruments, <www.ti.com>
 *
 * Author :
 *    Harinarayan Bhatta <harinarayan@ti.com>
 *
 * SPDX-License-Identifier:    GPL-2.0+
 */
 
#include <config.h>
#include <asm/arch/omap.h>
#include <asm/omap_common.h>
#include <linux/linkage.h>
 
.arch_extension sec
 
#if !defined(CONFIG_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 !defined(CONFIG_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 !defined(CONFIG_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)