master
c 524 lines 19 KB
Raw
1 /*
2 * ARM debug helpers.
3 *
4 * This code is licensed under the GNU GPL v2 or later.
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8 #include "qemu/osdep.h"
9 #include "qemu/log.h"
10 #include "cpu.h"
11 #include "internals.h"
12 #include "cpu-features.h"
13 #include "cpregs.h"
14 #include "exec/watchpoint.h"
15 #include "system/tcg.h"
16
17 /*
18 * Check for traps to "powerdown debug" registers, which are controlled
19 * by MDCR.TDOSA
20 */
21 static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri,
22 bool isread)
23 {
24 int el = arm_current_el(env);
25 uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
26 bool mdcr_el2_tdosa = (mdcr_el2 & MDCR_TDOSA) || (mdcr_el2 & MDCR_TDE) ||
27 (arm_hcr_el2_eff(env) & HCR_TGE);
28
29 if (el < 2 && mdcr_el2_tdosa) {
30 return CP_ACCESS_TRAP_EL2;
31 }
32 if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDOSA)) {
33 return CP_ACCESS_TRAP_EL3;
34 }
35 return CP_ACCESS_OK;
36 }
37
38 /*
39 * Check for traps to "debug ROM" registers, which are controlled
40 * by MDCR_EL2.TDRA for EL2 but by the more general MDCR_EL3.TDA for EL3.
41 */
42 static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri,
43 bool isread)
44 {
45 int el = arm_current_el(env);
46 uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
47 bool mdcr_el2_tdra = (mdcr_el2 & MDCR_TDRA) || (mdcr_el2 & MDCR_TDE) ||
48 (arm_hcr_el2_eff(env) & HCR_TGE);
49
50 if (el < 2 && mdcr_el2_tdra) {
51 return CP_ACCESS_TRAP_EL2;
52 }
53 if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
54 return CP_ACCESS_TRAP_EL3;
55 }
56 return CP_ACCESS_OK;
57 }
58
59 /*
60 * Check for traps to general debug registers, which are controlled
61 * by MDCR_EL2.TDA for EL2 and MDCR_EL3.TDA for EL3.
62 */
63 static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri,
64 bool isread)
65 {
66 int el = arm_current_el(env);
67 uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
68 bool mdcr_el2_tda = (mdcr_el2 & MDCR_TDA) || (mdcr_el2 & MDCR_TDE) ||
69 (arm_hcr_el2_eff(env) & HCR_TGE);
70
71 if (el < 2 && mdcr_el2_tda) {
72 return CP_ACCESS_TRAP_EL2;
73 }
74 if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
75 return CP_ACCESS_TRAP_EL3;
76 }
77 return CP_ACCESS_OK;
78 }
79
80 static CPAccessResult access_dbgvcr32(CPUARMState *env, const ARMCPRegInfo *ri,
81 bool isread)
82 {
83 /* MCDR_EL3.TDMA doesn't apply for FEAT_NV traps */
84 if (arm_current_el(env) == 2 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
85 return CP_ACCESS_TRAP_EL3;
86 }
87 return CP_ACCESS_OK;
88 }
89
90 /*
91 * Check for traps to Debug Comms Channel registers. If FEAT_FGT
92 * is implemented then these are controlled by MDCR_EL2.TDCC for
93 * EL2 and MDCR_EL3.TDCC for EL3. They are also controlled by
94 * the general debug access trap bits MDCR_EL2.TDA and MDCR_EL3.TDA.
95 * For EL0, they are also controlled by MDSCR_EL1.TDCC.
96 */
97 static CPAccessResult access_tdcc(CPUARMState *env, const ARMCPRegInfo *ri,
98 bool isread)
99 {
100 int el = arm_current_el(env);
101 uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
102 bool mdscr_el1_tdcc = extract32(env->cp15.mdscr_el1, 12, 1);
103 bool mdcr_el2_tda = (mdcr_el2 & MDCR_TDA) || (mdcr_el2 & MDCR_TDE) ||
104 (arm_hcr_el2_eff(env) & HCR_TGE);
105 bool mdcr_el2_tdcc = cpu_isar_feature(aa64_fgt, env_archcpu(env)) &&
106 (mdcr_el2 & MDCR_TDCC);
107 bool mdcr_el3_tdcc = cpu_isar_feature(aa64_fgt, env_archcpu(env)) &&
108 (env->cp15.mdcr_el3 & MDCR_TDCC);
109
110 if (el < 1 && mdscr_el1_tdcc) {
111 return CP_ACCESS_TRAP_EL1;
112 }
113 if (el < 2 && (mdcr_el2_tda || mdcr_el2_tdcc)) {
114 return CP_ACCESS_TRAP_EL2;
115 }
116 if (!arm_is_el3_or_mon(env) &&
117 ((env->cp15.mdcr_el3 & MDCR_TDA) || mdcr_el3_tdcc)) {
118 return CP_ACCESS_TRAP_EL3;
119 }
120 return CP_ACCESS_OK;
121 }
122
123 static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri,
124 uint64_t value)
125 {
126 /*
127 * Writes to OSLAR_EL1 may update the OS lock status, which can be
128 * read via a bit in OSLSR_EL1.
129 */
130 int oslock;
131
132 if (ri->state == ARM_CP_STATE_AA32) {
133 oslock = (value == 0xC5ACCE55);
134 } else {
135 oslock = value & 1;
136 }
137
138 env->cp15.oslsr_el1 = deposit32(env->cp15.oslsr_el1, 1, 1, oslock);
139 }
140
141 static void osdlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
142 uint64_t value)
143 {
144 ARMCPU *cpu = env_archcpu(env);
145 /*
146 * Only defined bit is bit 0 (DLK); if Feat_DoubleLock is not
147 * implemented this is RAZ/WI.
148 */
149 if(arm_feature(env, ARM_FEATURE_AARCH64)
150 ? cpu_isar_feature(aa64_doublelock, cpu)
151 : cpu_isar_feature(aa32_doublelock, cpu)) {
152 env->cp15.osdlr_el1 = value & 1;
153 }
154 }
155
156 static void dbgclaimset_write(CPUARMState *env, const ARMCPRegInfo *ri,
157 uint64_t value)
158 {
159 env->cp15.dbgclaim |= (value & 0xFF);
160 }
161
162 static uint64_t dbgclaimset_read(CPUARMState *env, const ARMCPRegInfo *ri)
163 {
164 /* CLAIM bits are RAO */
165 return 0xFF;
166 }
167
168 static void dbgclaimclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
169 uint64_t value)
170 {
171 env->cp15.dbgclaim &= ~(value & 0xFF);
172 }
173
174 static const ARMCPRegInfo debug_cp_reginfo[] = {
175 /*
176 * DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped
177 * debug components. The AArch64 version of DBGDRAR is named MDRAR_EL1;
178 * unlike DBGDRAR it is never accessible from EL0.
179 * DBGDSAR is deprecated and must RAZ from v8 anyway, so it has no AArch64
180 * accessor.
181 */
182 { .name = "DBGDRAR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
183 .access = PL0_R, .accessfn = access_tdra,
184 .type = ARM_CP_CONST | ARM_CP_NO_GDB, .resetvalue = 0 },
185 { .name = "MDRAR_EL1", .state = ARM_CP_STATE_AA64,
186 .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
187 .access = PL1_R, .accessfn = access_tdra,
188 .type = ARM_CP_CONST, .resetvalue = 0 },
189 { .name = "DBGDSAR", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
190 .access = PL0_R, .accessfn = access_tdra,
191 .type = ARM_CP_CONST | ARM_CP_NO_GDB, .resetvalue = 0 },
192 /* Monitor debug system control register; the 32-bit alias is DBGDSCRext. */
193 { .name = "MDSCR_EL1", .state = ARM_CP_STATE_BOTH,
194 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
195 .access = PL1_RW, .accessfn = access_tda,
196 .fgt = FGT_MDSCR_EL1,
197 .nv2_redirect_offset = 0x158,
198 .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1),
199 .resetvalue = 0 },
200 /*
201 * MDCCSR_EL0[30:29] map to EDSCR[30:29]. Simply RAZ as the external
202 * Debug Communication Channel is not implemented.
203 */
204 { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_AA64,
205 .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 1, .opc2 = 0,
206 .access = PL0_R, .accessfn = access_tdcc,
207 .type = ARM_CP_CONST, .resetvalue = 0 },
208 /*
209 * These registers belong to the Debug Communications Channel,
210 * which is not implemented. However we implement RAZ/WI behaviour
211 * with trapping to prevent spurious SIGILLs if the guest OS does
212 * access them as the support cannot be probed for.
213 */
214 { .name = "OSDTRRX_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
215 .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 2,
216 .access = PL1_RW, .accessfn = access_tdcc,
217 .type = ARM_CP_CONST, .resetvalue = 0 },
218 { .name = "OSDTRTX_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
219 .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
220 .access = PL1_RW, .accessfn = access_tdcc,
221 .type = ARM_CP_CONST, .resetvalue = 0 },
222 /* Architecturally DBGDTRTX is named DBGDTRRX when used for reads */
223 { .name = "DBGDTRTX_EL0", .state = ARM_CP_STATE_AA64,
224 .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 5, .opc2 = 0,
225 .access = PL0_RW, .accessfn = access_tdcc,
226 .type = ARM_CP_CONST, .resetvalue = 0 },
227 { .name = "DBGDTRTX", .state = ARM_CP_STATE_AA32, .cp = 14,
228 .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
229 .access = PL0_RW, .accessfn = access_tdcc,
230 .type = ARM_CP_CONST, .resetvalue = 0 },
231 /* This is AArch64-only and is a combination of DBGDTRTX and DBGDTRRX */
232 { .name = "DBGDTR_EL0", .state = ARM_CP_STATE_AA64,
233 .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 4, .opc2 = 0,
234 .access = PL0_RW, .accessfn = access_tdcc,
235 .type = ARM_CP_CONST, .resetvalue = 0 },
236 /*
237 * OSECCR_EL1 provides a mechanism for an operating system
238 * to access the contents of EDECCR. EDECCR is not implemented though,
239 * as is the rest of external device mechanism.
240 */
241 { .name = "OSECCR_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
242 .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
243 .access = PL1_RW, .accessfn = access_tda,
244 .fgt = FGT_OSECCR_EL1,
245 .type = ARM_CP_CONST, .resetvalue = 0 },
246 /*
247 * DBGDSCRint[15,12,5:2] map to MDSCR_EL1[15,12,5:2]. Map all bits as
248 * it is unlikely a guest will care.
249 * We don't implement the configurable EL0 access.
250 */
251 { .name = "DBGDSCRint", .state = ARM_CP_STATE_AA32,
252 .cp = 14, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
253 .type = ARM_CP_ALIAS,
254 .access = PL1_R, .accessfn = access_tda,
255 .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), },
256 { .name = "OSLAR_EL1", .state = ARM_CP_STATE_BOTH,
257 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4,
258 .access = PL1_W, .type = ARM_CP_NO_RAW,
259 .accessfn = access_tdosa,
260 .fgt = FGT_OSLAR_EL1,
261 .writefn = oslar_write },
262 { .name = "OSLSR_EL1", .state = ARM_CP_STATE_BOTH,
263 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 4,
264 .access = PL1_R, .resetvalue = 10,
265 .accessfn = access_tdosa,
266 .fgt = FGT_OSLSR_EL1,
267 .fieldoffset = offsetof(CPUARMState, cp15.oslsr_el1) },
268 /* Dummy OSDLR_EL1: 32-bit Linux will read this */
269 { .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH,
270 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4,
271 .access = PL1_RW, .accessfn = access_tdosa,
272 .fgt = FGT_OSDLR_EL1,
273 .writefn = osdlr_write,
274 .fieldoffset = offsetof(CPUARMState, cp15.osdlr_el1) },
275 /*
276 * Dummy DBGVCR: Linux wants to clear this on startup, but we don't
277 * implement vector catch debug events yet.
278 */
279 { .name = "DBGVCR",
280 .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
281 .access = PL1_RW, .accessfn = access_tda,
282 .type = ARM_CP_CONST, .resetvalue = 0 },
283 /*
284 * Dummy MDCCINT_EL1, since we don't implement the Debug Communications
285 * Channel but Linux may try to access this register. The 32-bit
286 * alias is DBGDCCINT.
287 */
288 { .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH,
289 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
290 .access = PL1_RW, .accessfn = access_tdcc,
291 .type = ARM_CP_CONST, .resetvalue = 0 },
292 /*
293 * Dummy DBGCLAIM registers.
294 * "The architecture does not define any functionality for the CLAIM tag bits.",
295 * so we only keep the raw bits
296 */
297 { .name = "DBGCLAIMSET_EL1", .state = ARM_CP_STATE_BOTH,
298 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 6,
299 .type = ARM_CP_ALIAS,
300 .access = PL1_RW, .accessfn = access_tda,
301 .fgt = FGT_DBGCLAIM,
302 .writefn = dbgclaimset_write, .readfn = dbgclaimset_read },
303 { .name = "DBGCLAIMCLR_EL1", .state = ARM_CP_STATE_BOTH,
304 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 6,
305 .access = PL1_RW, .accessfn = access_tda,
306 .fgt = FGT_DBGCLAIM,
307 .writefn = dbgclaimclr_write, .raw_writefn = raw_write,
308 .fieldoffset = offsetof(CPUARMState, cp15.dbgclaim) },
309 };
310
311 /* These are present only when EL1 supports AArch32 */
312 static const ARMCPRegInfo debug_aa32_el1_reginfo[] = {
313 /*
314 * Dummy DBGVCR32_EL2 (which is only for a 64-bit hypervisor
315 * to save and restore a 32-bit guest's DBGVCR)
316 */
317 { .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
318 .opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
319 .access = PL2_RW, .accessfn = access_dbgvcr32,
320 .type = ARM_CP_CONST | ARM_CP_EL3_NO_EL2_KEEP,
321 .resetvalue = 0 },
322 };
323
324 static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
325 /* 64 bit access versions of the (dummy) debug registers */
326 { .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0,
327 .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT | ARM_CP_NO_GDB,
328 .resetvalue = 0 },
329 { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0,
330 .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT | ARM_CP_NO_GDB,
331 .resetvalue = 0 },
332 };
333
334 static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
335 uint64_t value)
336 {
337 ARMCPU *cpu = env_archcpu(env);
338 int i = ri->crm;
339
340 /*
341 * Bits [1:0] are RES0.
342 *
343 * It is IMPLEMENTATION DEFINED whether [63:49] ([63:53] with FEAT_LVA)
344 * are hardwired to the value of bit [48] ([52] with FEAT_LVA), or if
345 * they contain the value written. It is CONSTRAINED UNPREDICTABLE
346 * whether the RESS bits are ignored when comparing an address.
347 *
348 * Therefore we are allowed to compare the entire register, which lets
349 * us avoid considering whether or not FEAT_LVA is actually enabled.
350 */
351 value &= ~3ULL;
352
353 raw_write(env, ri, value);
354 if (tcg_enabled()) {
355 hw_watchpoint_update(cpu, i);
356 }
357 }
358
359 static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
360 uint64_t value)
361 {
362 ARMCPU *cpu = env_archcpu(env);
363 int i = ri->crm;
364
365 raw_write(env, ri, value);
366 if (tcg_enabled()) {
367 hw_watchpoint_update(cpu, i);
368 }
369 }
370
371 static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
372 uint64_t value)
373 {
374 ARMCPU *cpu = env_archcpu(env);
375 int i = ri->crm;
376
377 raw_write(env, ri, value);
378 if (tcg_enabled()) {
379 hw_breakpoint_update(cpu, i);
380 }
381 }
382
383 static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
384 uint64_t value)
385 {
386 ARMCPU *cpu = env_archcpu(env);
387 int i = ri->crm;
388
389 /*
390 * BAS[3] is a read-only copy of BAS[2], and BAS[1] a read-only
391 * copy of BAS[0].
392 */
393 value = deposit64(value, 6, 1, extract64(value, 5, 1));
394 value = deposit64(value, 8, 1, extract64(value, 7, 1));
395
396 raw_write(env, ri, value);
397 if (tcg_enabled()) {
398 hw_breakpoint_update(cpu, i);
399 }
400 }
401
402 void define_debug_regs(ARMCPU *cpu)
403 {
404 /*
405 * Define v7 and v8 architectural debug registers.
406 * These are just dummy implementations for now.
407 */
408 int i;
409 int wrps, brps, ctx_cmps;
410
411 /*
412 * The Arm ARM says DBGDIDR is optional and deprecated if EL1 cannot
413 * use AArch32. Given that bit 15 is RES1, if the value is 0 then
414 * the register must not exist for this cpu.
415 */
416 if (cpu->isar.dbgdidr != 0) {
417 ARMCPRegInfo dbgdidr = {
418 .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0,
419 .opc1 = 0, .opc2 = 0,
420 .access = PL0_R, .accessfn = access_tda,
421 .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
422 };
423 define_one_arm_cp_reg(cpu, &dbgdidr);
424 }
425
426 /*
427 * DBGDEVID is present in the v7 debug architecture if
428 * DBGDIDR.DEVID_imp is 1 (bit 15); from v7.1 and on it is
429 * mandatory (and bit 15 is RES1). DBGDEVID1 and DBGDEVID2 exist
430 * from v7.1 of the debug architecture. Because no fields have yet
431 * been defined in DBGDEVID2 (and quite possibly none will ever
432 * be) we don't define an ARMISARegisters field for it.
433 * These registers exist only if EL1 can use AArch32, but that
434 * happens naturally because they are only PL1 accessible anyway.
435 */
436 if (extract32(cpu->isar.dbgdidr, 15, 1)) {
437 ARMCPRegInfo dbgdevid = {
438 .name = "DBGDEVID",
439 .cp = 14, .opc1 = 0, .crn = 7, .opc2 = 2, .crn = 7,
440 .access = PL1_R, .accessfn = access_tda,
441 .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdevid,
442 };
443 define_one_arm_cp_reg(cpu, &dbgdevid);
444 }
445 if (cpu_isar_feature(aa32_debugv7p1, cpu)) {
446 ARMCPRegInfo dbgdevid12[] = {
447 {
448 .name = "DBGDEVID1",
449 .cp = 14, .opc1 = 0, .crn = 7, .opc2 = 1, .crn = 7,
450 .access = PL1_R, .accessfn = access_tda,
451 .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdevid1,
452 }, {
453 .name = "DBGDEVID2",
454 .cp = 14, .opc1 = 0, .crn = 7, .opc2 = 0, .crn = 7,
455 .access = PL1_R, .accessfn = access_tda,
456 .type = ARM_CP_CONST, .resetvalue = 0,
457 },
458 };
459 define_arm_cp_regs(cpu, dbgdevid12);
460 }
461
462 brps = arm_num_brps(cpu);
463 wrps = arm_num_wrps(cpu);
464 ctx_cmps = arm_num_ctx_cmps(cpu);
465
466 assert(ctx_cmps <= brps);
467
468 define_arm_cp_regs(cpu, debug_cp_reginfo);
469 if (cpu_isar_feature(aa64_aa32_el1, cpu)) {
470 define_arm_cp_regs(cpu, debug_aa32_el1_reginfo);
471 }
472
473 if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {
474 define_arm_cp_regs(cpu, debug_lpae_cp_reginfo);
475 }
476
477 for (i = 0; i < brps; i++) {
478 char *dbgbvr_el1_name = g_strdup_printf("DBGBVR%d_EL1", i);
479 char *dbgbcr_el1_name = g_strdup_printf("DBGBCR%d_EL1", i);
480 ARMCPRegInfo dbgregs[] = {
481 { .name = dbgbvr_el1_name, .state = ARM_CP_STATE_BOTH,
482 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
483 .access = PL1_RW, .accessfn = access_tda,
484 .fgt = FGT_DBGBVRN_EL1,
485 .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]),
486 .writefn = dbgbvr_write, .raw_writefn = raw_write
487 },
488 { .name = dbgbcr_el1_name, .state = ARM_CP_STATE_BOTH,
489 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
490 .access = PL1_RW, .accessfn = access_tda,
491 .fgt = FGT_DBGBCRN_EL1,
492 .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
493 .writefn = dbgbcr_write, .raw_writefn = raw_write
494 },
495 };
496 define_arm_cp_regs(cpu, dbgregs);
497 g_free(dbgbvr_el1_name);
498 g_free(dbgbcr_el1_name);
499 }
500
501 for (i = 0; i < wrps; i++) {
502 char *dbgwvr_el1_name = g_strdup_printf("DBGWVR%d_EL1", i);
503 char *dbgwcr_el1_name = g_strdup_printf("DBGWCR%d_EL1", i);
504 ARMCPRegInfo dbgregs[] = {
505 { .name = dbgwvr_el1_name, .state = ARM_CP_STATE_BOTH,
506 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
507 .access = PL1_RW, .accessfn = access_tda,
508 .fgt = FGT_DBGWVRN_EL1,
509 .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]),
510 .writefn = dbgwvr_write, .raw_writefn = raw_write
511 },
512 { .name = dbgwcr_el1_name, .state = ARM_CP_STATE_BOTH,
513 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
514 .access = PL1_RW, .accessfn = access_tda,
515 .fgt = FGT_DBGWCRN_EL1,
516 .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
517 .writefn = dbgwcr_write, .raw_writefn = raw_write
518 },
519 };
520 define_arm_cp_regs(cpu, dbgregs);
521 g_free(dbgwvr_el1_name);
522 g_free(dbgwcr_el1_name);
523 }
524 }