blob: baa2c695123031594e63d9f19a8a7bec046d644d [file] [log] [blame]
Fuad Tabbac76466d2019-09-06 10:42:12 +01001/*
2 * Copyright 2019 The Hafnium Authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "debug_el1.h"
18
19#include "hf/check.h"
20#include "hf/dlog.h"
21#include "hf/panic.h"
22#include "hf/types.h"
23
24#include "msr.h"
25
26/**
27 * Controls traps for Trace Filter.
28 */
Fuad Tabbaa5681492019-09-12 11:10:11 +010029#define MDCR_EL2_TTRF (0x1u << 19)
30
31/**
32 * Controls the owning translation regime and access to Profiling Buffer control
33 * registers from EL1. Depends on whether SPE is implemented.
34 */
35#define MDCR_EL2_E2PB (0x3u << 12)
Fuad Tabbac76466d2019-09-06 10:42:12 +010036
37/**
38 * Controls traps for Debug ROM.
39 */
Fuad Tabbaa5681492019-09-12 11:10:11 +010040#define MDCR_EL2_TDRA (0x1u << 11)
Fuad Tabbac76466d2019-09-06 10:42:12 +010041
42/**
43 * Controls traps for OS-Related Register Access.
44 */
Fuad Tabbaa5681492019-09-12 11:10:11 +010045#define MDCR_EL2_TDOSA (0x1u << 10)
Fuad Tabbac76466d2019-09-06 10:42:12 +010046
47/**
48 * Controls traps for remaining Debug Registers not trapped by TDRA and TDOSA.
49 */
Fuad Tabbaa5681492019-09-12 11:10:11 +010050#define MDCR_EL2_TDA (0x1u << 9)
Fuad Tabbac76466d2019-09-06 10:42:12 +010051
52/**
53 * Controls traps for all debug exceptions (e.g., breakpoints).
54 */
Fuad Tabbaa5681492019-09-12 11:10:11 +010055#define MDCR_EL2_TDE (0x1u << 8)
56
57/**
58 * Defines the number of event counters that are accessible from various
59 * exception levels, if permitted. Dependant on whether PMUv3 is implemented.
60 */
61#define MDCR_EL2_HPMN (0x1fu << 0)
Fuad Tabbac76466d2019-09-06 10:42:12 +010062
63/**
64 * Controls traps for debug events, i.e., breakpoints, watchpoints, and vector.
65 * catch exceptions.
66 */
Fuad Tabbaa5681492019-09-12 11:10:11 +010067#define MDSCR_EL1_MDE (0x1u << 15)
Fuad Tabbac76466d2019-09-06 10:42:12 +010068
69/**
70 * System register are identified by op0, op2, op1, crn, crm. The ISS encoding
71 * includes also rt and direction. Exclude them, @see D13.2.37 (D13-2977).
72 */
73#define ISS_SYSREG_MASK \
74 (((1u << 22) - 1u) & /* Select the ISS bits*/ \
75 ~(0x1fu << 5) & /* exclude rt */ \
76 ~1u /* exclude direction */)
77
78#define GET_ISS_SYSREG(esr) (ISS_SYSREG_MASK & (esr))
79
80/**
81 * Op0 from the ISS encoding in the ESR.
82 */
83#define ISS_OP0_MASK 0x300000
84#define ISS_OP0_SHIFT 20
85#define GET_ISS_OP0(esr) ((ISS_OP0_MASK & (esr)) >> ISS_OP0_SHIFT)
86
87/**
88 * Op1 from the ISS encoding in the ESR.
89 */
90#define ISS_OP1_MASK 0x1c000
91#define ISS_OP1_SHIFT 14
92#define GET_ISS_OP1(esr) ((ISS_OP1_MASK & (esr)) >> ISS_OP1_SHIFT)
93
94/**
95 * Direction (i.e., read (1) or write (0), is the first bit in the ISS/ESR.
96 */
97#define ISS_DIRECTION_MASK 1u
98
99/**
100 * Gets the direction of the system register access, read (1) or write (0).
101 */
102#define GET_ISS_DIRECTION(esr) (ISS_DIRECTION_MASK & (esr))
103
104/**
105 * True if the ISS encoded in the esr indicates a read of the system register.
106 */
107#define ISS_IS_READ(esr) (ISS_DIRECTION_MASK & (esr))
108
109/**
110 * Rt, which identifies the general purpose register used for the operation.
111 */
112#define ISS_RT_MASK 0x3e0
113#define ISS_RT_SHIFT 5
114#define GET_ISS_RT(esr) ((ISS_RT_MASK & (esr)) >> ISS_RT_SHIFT)
115
116/**
117 * Definitions of read-only debug registers' ISS signatures.
118 */
119#define EL1_DEBUG_REGISTERS_READ \
120 X(MDRAR_EL1, 0x200400) \
121 X(DBGAUTHSTATUS_EL1, 0x2c1c1c) \
122 X(OSLSR_EL1, 0x280402)
123
124/**
125 * Definitions of readable and writeable debug registers' ISS signatures.
126 */
127#define EL1_DEBUG_REGISTERS_READ_WRITE \
128 X(DBGCLAIMCLR_EL1, 0x2c1c12) \
129 X(DBGCLAIMSET_EL1, 0x2c1c10) \
130 X(DBGPRCR_EL1, 0x280408) \
131 X(MDCCINT_EL1, 0x200004) \
132 X(MDSCR_EL1, 0x240004) \
133 X(OSDLR_EL1, 0x280406) \
134 X(OSDTRRX_EL1, 0x240000) \
135 X(OSDTRTX_EL1, 0x240006) \
136 X(OSECCR_EL1, 0x24000c) \
137 X(DBGBCR0_EL1, 0x2a0000) \
138 X(DBGBCR1_EL1, 0x2a0002) \
139 X(DBGBCR2_EL1, 0x2a0004) \
140 X(DBGBCR3_EL1, 0x2a0006) \
141 X(DBGBCR4_EL1, 0x2a0008) \
142 X(DBGBCR5_EL1, 0x2a000a) \
143 X(DBGBCR6_EL1, 0x2a000c) \
144 X(DBGBCR7_EL1, 0x2a000e) \
145 X(DBGBCR8_EL1, 0x2a0010) \
146 X(DBGBCR9_EL1, 0x2a0012) \
147 X(DBGBCR10_EL1, 0x2a0014) \
148 X(DBGBCR11_EL1, 0x2a0016) \
149 X(DBGBCR12_EL1, 0x2a0018) \
150 X(DBGBCR13_EL1, 0x2a001a) \
151 X(DBGBCR14_EL1, 0x2a001c) \
152 X(DBGBCR15_EL1, 0x2a001e) \
153 X(DBGBVR0_EL1, 0x280000) \
154 X(DBGBVR1_EL1, 0x280002) \
155 X(DBGBVR2_EL1, 0x280004) \
156 X(DBGBVR3_EL1, 0x280006) \
157 X(DBGBVR4_EL1, 0x280008) \
158 X(DBGBVR5_EL1, 0x28000a) \
159 X(DBGBVR6_EL1, 0x28000c) \
160 X(DBGBVR7_EL1, 0x28000e) \
161 X(DBGBVR8_EL1, 0x280010) \
162 X(DBGBVR9_EL1, 0x280012) \
163 X(DBGBVR10_EL1, 0x280014) \
164 X(DBGBVR11_EL1, 0x280016) \
165 X(DBGBVR12_EL1, 0x280018) \
166 X(DBGBVR13_EL1, 0x28001a) \
167 X(DBGBVR14_EL1, 0x28001c) \
168 X(DBGBVR15_EL1, 0x28001e) \
169 X(DBGWCR0_EL1, 0x2e0000) \
170 X(DBGWCR1_EL1, 0x2e0002) \
171 X(DBGWCR2_EL1, 0x2e0004) \
172 X(DBGWCR3_EL1, 0x2e0006) \
173 X(DBGWCR4_EL1, 0x2e0008) \
174 X(DBGWCR5_EL1, 0x2e000a) \
175 X(DBGWCR6_EL1, 0x2e000c) \
176 X(DBGWCR7_EL1, 0x2e000e) \
177 X(DBGWCR8_EL1, 0x2e0010) \
178 X(DBGWCR9_EL1, 0x2e0012) \
179 X(DBGWCR10_EL1, 0x2e0014) \
180 X(DBGWCR11_EL1, 0x2e0016) \
181 X(DBGWCR12_EL1, 0x2e0018) \
182 X(DBGWCR13_EL1, 0x2e001a) \
183 X(DBGWCR14_EL1, 0x2e001c) \
184 X(DBGWCR15_EL1, 0x2e001e) \
185 X(DBGWVR0_EL1, 0x2c0000) \
186 X(DBGWVR1_EL1, 0x2c0002) \
187 X(DBGWVR2_EL1, 0x2c0004) \
188 X(DBGWVR3_EL1, 0x2c0006) \
189 X(DBGWVR4_EL1, 0x2c0008) \
190 X(DBGWVR5_EL1, 0x2c000a) \
191 X(DBGWVR6_EL1, 0x2c000c) \
192 X(DBGWVR7_EL1, 0x2c000e) \
193 X(DBGWVR8_EL1, 0x2c0010) \
194 X(DBGWVR9_EL1, 0x2c0012) \
195 X(DBGWVR10_EL1, 0x2c0014) \
196 X(DBGWVR11_EL1, 0x2c0016) \
197 X(DBGWVR12_EL1, 0x2c0018) \
198 X(DBGWVR13_EL1, 0x2c001a) \
199 X(DBGWVR14_EL1, 0x2c001c) \
200 X(DBGWVR15_EL1, 0x2c001e)
201
202/**
203 * Definitions of all debug registers' ISS signatures.
204 */
205#define EL1_DEBUG_REGISTERS \
206 EL1_DEBUG_REGISTERS_READ \
207 EL1_DEBUG_REGISTERS_READ_WRITE
208
209/**
Fuad Tabbaa5681492019-09-12 11:10:11 +0100210 * Returns the value for MDCR_EL2 for the particular VM.
Fuad Tabbac76466d2019-09-06 10:42:12 +0100211 * For now, the primary VM has one value and all secondary VMs share a value.
212 */
213uintreg_t get_mdcr_el2_value(spci_vm_id_t vm_id)
214{
Fuad Tabbaa5681492019-09-12 11:10:11 +0100215 uintreg_t mdcr_el2_preserve = read_msr(MDCR_EL2);
216
217 /*
218 * Preserve the values of HPMN and E2PB, which are dependent on whether
219 * certain features are enabled, and should be set up by the bootcode.
220 */
221 mdcr_el2_preserve &= (MDCR_EL2_HPMN | MDCR_EL2_E2PB);
222
Fuad Tabbac76466d2019-09-06 10:42:12 +0100223 if (vm_id == HF_PRIMARY_VM_ID) {
224 /*
225 * Trap primary VM accesses to debug registers to have fine
226 * grained control over system register accesses.
227 * Do not trap the Primary VM's debug events (!MDCR_EL2_TDE).
228 */
Fuad Tabbaa5681492019-09-12 11:10:11 +0100229 return mdcr_el2_preserve | MDCR_EL2_TTRF | MDCR_EL2_TDRA |
230 MDCR_EL2_TDOSA | MDCR_EL2_TDA;
Fuad Tabbac76466d2019-09-06 10:42:12 +0100231 }
232
233 /*
234 * Trap all secondary VM debug register accesses as well as debug
235 * event exceptions.
236 * Debug event exceptions should be disabled in secondary VMs, but trap
237 * them for additional security (MDCR_EL2_TDE).
238 */
Fuad Tabbaa5681492019-09-12 11:10:11 +0100239 return mdcr_el2_preserve | MDCR_EL2_TTRF | MDCR_EL2_TDRA |
240 MDCR_EL2_TDOSA | MDCR_EL2_TDA | MDCR_EL2_TDE;
Fuad Tabbac76466d2019-09-06 10:42:12 +0100241}
242
243/**
244 * Returns true if the ESR register shows an access to an EL1 debug register.
245 */
246bool is_debug_el1_register_access(uintreg_t esr_el2)
247{
248 /*
249 * Architecture Reference Manual D12.2: op0 == 0b10 is for debug and
250 * trace system registers. op1 = 0x1 for trace, remaining are debug.
251 */
252 return GET_ISS_OP0(esr_el2) == 0x2 && GET_ISS_OP1(esr_el2) != 0x1;
253}
254
255/**
256 * Processes an access (msr, mrs) to an EL1 debug register.
257 * Returns true if the access was allowed and performed, false otherwise.
258 */
259bool debug_el1_process_access(struct vcpu *vcpu, spci_vm_id_t vm_id,
260 uintreg_t esr_el2)
261{
262 /*
263 * For now, debug registers are not supported by secondary VMs.
264 * Disallow accesses to them.
265 */
266 if (vm_id != HF_PRIMARY_VM_ID) {
267 return false;
268 }
269
270 uintreg_t sys_register = GET_ISS_SYSREG(esr_el2);
271 uintreg_t rt_register = GET_ISS_RT(esr_el2);
272 uintreg_t value;
273
274 CHECK(rt_register < NUM_GP_REGS);
275
276 if (ISS_IS_READ(esr_el2)) {
277 switch (sys_register) {
278#define X(reg_name, reg_sig) \
279 case reg_sig: \
280 value = read_msr(reg_name); \
281 break;
282 EL1_DEBUG_REGISTERS
283#undef X
284 default:
285 value = vcpu->regs.r[rt_register];
286 dlog("Unsupported system register read 0x%x\n",
287 sys_register);
288 break;
289 }
290 vcpu->regs.r[rt_register] = value;
291
292 } else {
293 value = vcpu->regs.r[rt_register];
294 switch (sys_register) {
295#define X(reg_name, reg_sig) \
296 case reg_sig: \
297 write_msr(reg_name, value); \
298 break;
299 EL1_DEBUG_REGISTERS_READ_WRITE
300#undef X
301 default:
302 dlog("Unsupported system register write 0x%x\n",
303 sys_register);
304 break;
305 }
306 }
307
308 return true;
309}