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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <bl_common.h>
#include <cpu_macros.S>
#include <plat_macros.S>
#include <cortex_a75.h>
.globl cortex_a75_amu_cnt_read
.globl cortex_a75_amu_cnt_write
.globl cortex_a75_amu_read_cpuamcntenset_el0
.globl cortex_a75_amu_read_cpuamcntenclr_el0
.globl cortex_a75_amu_write_cpuamcntenset_el0
.globl cortex_a75_amu_write_cpuamcntenclr_el0
/*
* uint64_t cortex_a75_amu_cnt_read(int idx);
*
* Given `idx`, read the corresponding AMU counter
* and return it in `x0`.
*/
func cortex_a75_amu_cnt_read
adr x1, 1f
lsl x0, x0, #3
add x1, x1, x0
br x1
1:
mrs x0, CPUAMEVCNTR0_EL0
ret
mrs x0, CPUAMEVCNTR1_EL0
ret
mrs x0, CPUAMEVCNTR2_EL0
ret
mrs x0, CPUAMEVCNTR3_EL0
ret
mrs x0, CPUAMEVCNTR4_EL0
ret
endfunc cortex_a75_amu_cnt_read
/*
* void cortex_a75_amu_cnt_write(int idx, uint64_t val);
*
* Given `idx`, write `val` to the corresponding AMU counter.
*/
func cortex_a75_amu_cnt_write
adr x2, 1f
lsl x0, x0, #3
add x2, x2, x0
br x2
1:
msr CPUAMEVCNTR0_EL0, x0
ret
msr CPUAMEVCNTR1_EL0, x0
ret
msr CPUAMEVCNTR2_EL0, x0
ret
msr CPUAMEVCNTR3_EL0, x0
ret
msr CPUAMEVCNTR4_EL0, x0
ret
endfunc cortex_a75_amu_cnt_write
/*
* unsigned int cortex_a75_amu_read_cpuamcntenset_el0(void);
*
* Read the `CPUAMCNTENSET_EL0` CPU register and return
* it in `x0`.
*/
func cortex_a75_amu_read_cpuamcntenset_el0
mrs x0, CPUAMCNTENSET_EL0
ret
endfunc cortex_a75_amu_read_cpuamcntenset_el0
/*
* unsigned int cortex_a75_amu_read_cpuamcntenclr_el0(void);
*
* Read the `CPUAMCNTENCLR_EL0` CPU register and return
* it in `x0`.
*/
func cortex_a75_amu_read_cpuamcntenclr_el0
mrs x0, CPUAMCNTENCLR_EL0
ret
endfunc cortex_a75_amu_read_cpuamcntenclr_el0
/*
* void cortex_a75_amu_write_cpuamcntenset_el0(unsigned int mask);
*
* Write `mask` to the `CPUAMCNTENSET_EL0` CPU register.
*/
func cortex_a75_amu_write_cpuamcntenset_el0
msr CPUAMCNTENSET_EL0, x0
ret
endfunc cortex_a75_amu_write_cpuamcntenset_el0
/*
* void cortex_a75_amu_write_cpuamcntenclr_el0(unsigned int mask);
*
* Write `mask` to the `CPUAMCNTENCLR_EL0` CPU register.
*/
func cortex_a75_amu_write_cpuamcntenclr_el0
mrs x0, CPUAMCNTENCLR_EL0
ret
endfunc cortex_a75_amu_write_cpuamcntenclr_el0
func cortex_a75_reset_func
#if IMAGE_BL31 && WORKAROUND_CVE_2017_5715
mrs x0, id_aa64pfr0_el1
ubfx x0, x0, #ID_AA64PFR0_CSV2_SHIFT, #ID_AA64PFR0_CSV2_LENGTH
/*
* If the field equals to 1 then branch targets trained in one
* context cannot affect speculative execution in a different context.
*/
cmp x0, #1
beq 1f
adr x0, workaround_bpiall_vbar0_runtime_exceptions
msr vbar_el3, x0
1:
#endif
#if ENABLE_AMU
/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
mrs x0, actlr_el3
orr x0, x0, #CORTEX_A75_ACTLR_AMEN_BIT
msr actlr_el3, x0
isb
/* Make sure accesses from EL0/EL1 are not trapped to EL2 */
mrs x0, actlr_el2
orr x0, x0, #CORTEX_A75_ACTLR_AMEN_BIT
msr actlr_el2, x0
isb
/* Enable group0 counters */
mov x0, #CORTEX_A75_AMU_GROUP0_MASK
msr CPUAMCNTENSET_EL0, x0
isb
/* Enable group1 counters */
mov x0, #CORTEX_A75_AMU_GROUP1_MASK
msr CPUAMCNTENSET_EL0, x0
isb
#endif
ret
endfunc cortex_a75_reset_func
/* ---------------------------------------------
* HW will do the cache maintenance while powering down
* ---------------------------------------------
*/
func cortex_a75_core_pwr_dwn
/* ---------------------------------------------
* Enable CPU power down bit in power control register
* ---------------------------------------------
*/
mrs x0, CORTEX_A75_CPUPWRCTLR_EL1
orr x0, x0, #CORTEX_A75_CORE_PWRDN_EN_MASK
msr CORTEX_A75_CPUPWRCTLR_EL1, x0
isb
ret
endfunc cortex_a75_core_pwr_dwn
/* ---------------------------------------------
* This function provides cortex_a75 specific
* register information for crash reporting.
* It needs to return with x6 pointing to
* a list of register names in ascii and
* x8 - x15 having values of registers to be
* reported.
* ---------------------------------------------
*/
.section .rodata.cortex_a75_regs, "aS"
cortex_a75_regs: /* The ascii list of register names to be reported */
.asciz "cpuectlr_el1", ""
func cortex_a75_cpu_reg_dump
adr x6, cortex_a75_regs
mrs x8, CORTEX_A75_CPUECTLR_EL1
ret
endfunc cortex_a75_cpu_reg_dump
declare_cpu_ops cortex_a75, CORTEX_A75_MIDR, \
cortex_a75_reset_func, \
cortex_a75_core_pwr_dwn
|