target/arm: Move TCG-specific code out of debug_helper.c
The target/arm/debug_helper.c file has some code which we need for non-TCG accelerators, but quite a lot which is guarded by a CONFIG_TCG ifdef. Move all this TCG-only code out to a new file target/arm/tcg/debug.c. In particular all the code requiring access to the TCG helper function prototypes is in the moved code, so we can drop the use of tcg/helper.h from debug_helper.c. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Message-id: 20260219040150.2098396-2-pierrick.bouvier@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Peter Maydell committed
Feb 18, 2026 at 20:01 UTC
7bea97639e0505e911a639e8b7f12e2ddf2cabb0
3 files changed
+784
-769
target/arm/debug_helper.c
-769
@@ -14,775 +14,6 @@
14
#include "exec/watchpoint.h"
15
#include "system/tcg.h"
16
17
-#define HELPER_H "tcg/helper.h"
18
-#include "exec/helper-proto.h.inc"
19
-
20
-#ifdef CONFIG_TCG
21
-/* Return the Exception Level targeted by debug exceptions. */
22
-static int arm_debug_target_el(CPUARMState *env)
23
-{
24
- bool secure = arm_is_secure(env);
25
- bool route_to_el2 = false;
26
-
27
- if (arm_feature(env, ARM_FEATURE_M)) {
28
- return 1;
29
- }
30
-
31
- if (arm_is_el2_enabled(env)) {
32
- route_to_el2 = env->cp15.hcr_el2 & HCR_TGE ||
33
- env->cp15.mdcr_el2 & MDCR_TDE;
34
- }
35
-
36
- if (route_to_el2) {
37
- return 2;
38
- } else if (arm_feature(env, ARM_FEATURE_EL3) &&
39
- !arm_el_is_aa64(env, 3) && secure) {
40
- return 3;
41
- } else {
42
- return 1;
43
- }
44
-}
45
-
46
-/*
47
- * Raise an exception to the debug target el.
48
- * Modify syndrome to indicate when origin and target EL are the same.
49
- */
50
-G_NORETURN static void
51
-raise_exception_debug(CPUARMState *env, uint32_t excp, uint32_t syndrome)
52
-{
53
- int debug_el = arm_debug_target_el(env);
54
- int cur_el = arm_current_el(env);
55
-
56
- /*
57
- * If singlestep is targeting a lower EL than the current one, then
58
- * DisasContext.ss_active must be false and we can never get here.
59
- * Similarly for watchpoint and breakpoint matches.
60
- */
61
- assert(debug_el >= cur_el);
62
- syndrome |= (debug_el == cur_el) << ARM_EL_EC_SHIFT;
63
- raise_exception(env, excp, syndrome, debug_el);
64
-}
65
-
66
-/* See AArch64.GenerateDebugExceptionsFrom() in ARM ARM pseudocode */
67
-static bool aa64_generate_debug_exceptions(CPUARMState *env)
68
-{
69
- int cur_el = arm_current_el(env);
70
- int debug_el;
71
-
72
- if (cur_el == 3) {
73
- return false;
74
- }
75
-
76
- /* MDCR_EL3.SDD disables debug events from Secure state */
77
- if (arm_is_secure_below_el3(env)
78
- && extract32(env->cp15.mdcr_el3, 16, 1)) {
79
- return false;
80
- }
81
-
82
- /*
83
- * Same EL to same EL debug exceptions need MDSCR_KDE enabled
84
- * while not masking the (D)ebug bit in DAIF.
85
- */
86
- debug_el = arm_debug_target_el(env);
87
-
88
- if (cur_el == debug_el) {
89
- return extract32(env->cp15.mdscr_el1, 13, 1)
90
- && !(env->daif & PSTATE_D);
91
- }
92
-
93
- /* Otherwise the debug target needs to be a higher EL */
94
- return debug_el > cur_el;
95
-}
96
-
97
-static bool aa32_generate_debug_exceptions(CPUARMState *env)
98
-{
99
- int el = arm_current_el(env);
100
-
101
- if (el == 0 && arm_el_is_aa64(env, 1)) {
102
- return aa64_generate_debug_exceptions(env);
103
- }
104
-
105
- if (arm_is_secure(env)) {
106
- int spd;
107
-
108
- if (el == 0 && (env->cp15.sder & 1)) {
109
- /*
110
- * SDER.SUIDEN means debug exceptions from Secure EL0
111
- * are always enabled. Otherwise they are controlled by
112
- * SDCR.SPD like those from other Secure ELs.
113
- */
114
- return true;
115
- }
116
-
117
- spd = extract32(env->cp15.mdcr_el3, 14, 2);
118
- switch (spd) {
119
- case 1:
120
- /* SPD == 0b01 is reserved, but behaves as 0b00. */
121
- case 0:
122
- /*
123
- * For 0b00 we return true if external secure invasive debug
124
- * is enabled. On real hardware this is controlled by external
125
- * signals to the core. QEMU always permits debug, and behaves
126
- * as if DBGEN, SPIDEN, NIDEN and SPNIDEN are all tied high.
127
- */
128
- return true;
129
- case 2:
130
- return false;
131
- case 3:
132
- return true;
133
- }
134
- }
135
-
136
- return el != 2;
137
-}
138
-
139
-/*
140
- * Return true if debugging exceptions are currently enabled.
141
- * This corresponds to what in ARM ARM pseudocode would be
142
- * if UsingAArch32() then
143
- * return AArch32.GenerateDebugExceptions()
144
- * else
145
- * return AArch64.GenerateDebugExceptions()
146
- * We choose to push the if() down into this function for clarity,
147
- * since the pseudocode has it at all callsites except for the one in
148
- * CheckSoftwareStep(), where it is elided because both branches would
149
- * always return the same value.
150
- */
151
-bool arm_generate_debug_exceptions(CPUARMState *env)
152
-{
153
- if ((env->cp15.oslsr_el1 & 1) || (env->cp15.osdlr_el1 & 1)) {
154
- return false;
155
- }
156
- if (is_a64(env)) {
157
- return aa64_generate_debug_exceptions(env);
158
- } else {
159
- return aa32_generate_debug_exceptions(env);
160
- }
161
-}
162
-
163
-/*
164
- * Is single-stepping active? (Note that the "is EL_D AArch64?" check
165
- * implicitly means this always returns false in pre-v8 CPUs.)
166
- */
167
-bool arm_singlestep_active(CPUARMState *env)
168
-{
169
- return extract32(env->cp15.mdscr_el1, 0, 1)
170
- && arm_el_is_aa64(env, arm_debug_target_el(env))
171
- && arm_generate_debug_exceptions(env);
172
-}
173
-
174
-/* Return true if the linked breakpoint entry lbn passes its checks */
175
-static bool linked_bp_matches(ARMCPU *cpu, int lbn)
176
-{
177
- CPUARMState *env = &cpu->env;
178
- uint64_t bcr = env->cp15.dbgbcr[lbn];
179
- int brps = arm_num_brps(cpu);
180
- int ctx_cmps = arm_num_ctx_cmps(cpu);
181
- int bt;
182
- uint32_t contextidr;
183
- uint64_t hcr_el2;
184
-
185
- /*
186
- * Links to unimplemented or non-context aware breakpoints are
187
- * CONSTRAINED UNPREDICTABLE: either behave as if disabled, or
188
- * as if linked to an UNKNOWN context-aware breakpoint (in which
189
- * case DBGWCR<n>_EL1.LBN must indicate that breakpoint).
190
- * We choose the former.
191
- */
192
- if (lbn >= brps || lbn < (brps - ctx_cmps)) {
193
- return false;
194
- }
195
-
196
- bcr = env->cp15.dbgbcr[lbn];
197
-
198
- if (extract64(bcr, 0, 1) == 0) {
199
- /* Linked breakpoint disabled : generate no events */
200
- return false;
201
- }
202
-
203
- bt = extract64(bcr, 20, 4);
204
- hcr_el2 = arm_hcr_el2_eff(env);
205
-
206
- switch (bt) {
207
- case 3: /* linked context ID match */
208
- switch (arm_current_el(env)) {
209
- default:
210
- /* Context matches never fire in AArch64 EL3 */
211
- return false;
212
- case 2:
213
- if (!(hcr_el2 & HCR_E2H)) {
214
- /* Context matches never fire in EL2 without E2H enabled. */
215
- return false;
216
- }
217
- contextidr = env->cp15.contextidr_el[2];
218
- break;
219
- case 1:
220
- contextidr = env->cp15.contextidr_el[1];
221
- break;
222
- case 0:
223
- if ((hcr_el2 & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
224
- contextidr = env->cp15.contextidr_el[2];
225
- } else {
226
- contextidr = env->cp15.contextidr_el[1];
227
- }
228
- break;
229
- }
230
- break;
231
-
232
- case 7: /* linked contextidr_el1 match */
233
- contextidr = env->cp15.contextidr_el[1];
234
- break;
235
- case 13: /* linked contextidr_el2 match */
236
- contextidr = env->cp15.contextidr_el[2];
237
- break;
238
-
239
- case 9: /* linked VMID match (reserved if no EL2) */
240
- case 11: /* linked context ID and VMID match (reserved if no EL2) */
241
- case 15: /* linked full context ID match */
242
- default:
243
- /*
244
- * Links to Unlinked context breakpoints must generate no
245
- * events; we choose to do the same for reserved values too.
246
- */
247
- return false;
248
- }
249
-
250
- /*
251
- * We match the whole register even if this is AArch32 using the
252
- * short descriptor format (in which case it holds both PROCID and ASID),
253
- * since we don't implement the optional v7 context ID masking.
254
- */
255
- return contextidr == (uint32_t)env->cp15.dbgbvr[lbn];
256
-}
257
-
258
-static bool bp_wp_matches(ARMCPU *cpu, int n, bool is_wp)
259
-{
260
- CPUARMState *env = &cpu->env;
261
- uint64_t cr;
262
- int pac, hmc, ssc, wt, lbn;
263
- /*
264
- * Note that for watchpoints the check is against the CPU security
265
- * state, not the S/NS attribute on the offending data access.
266
- */
267
- bool is_secure = arm_is_secure(env);
268
- int access_el = arm_current_el(env);
269
-
270
- if (is_wp) {
271
- CPUWatchpoint *wp = env->cpu_watchpoint[n];
272
-
273
- if (!wp || !(wp->flags & BP_WATCHPOINT_HIT)) {
274
- return false;
275
- }
276
- cr = env->cp15.dbgwcr[n];
277
- if (wp->hitattrs.user) {
278
- /*
279
- * The LDRT/STRT/LDT/STT "unprivileged access" instructions should
280
- * match watchpoints as if they were accesses done at EL0, even if
281
- * the CPU is at EL1 or higher.
282
- */
283
- access_el = 0;
284
- }
285
- } else {
286
- uint64_t pc = is_a64(env) ? env->pc : env->regs[15];
287
-
288
- if (!env->cpu_breakpoint[n] || env->cpu_breakpoint[n]->pc != pc) {
289
- return false;
290
- }
291
- cr = env->cp15.dbgbcr[n];
292
- }
293
- /*
294
- * The WATCHPOINT_HIT flag guarantees us that the watchpoint is
295
- * enabled and that the address and access type match; for breakpoints
296
- * we know the address matched; check the remaining fields, including
297
- * linked breakpoints. We rely on WCR and BCR having the same layout
298
- * for the LBN, SSC, HMC, PAC/PMC and is-linked fields.
299
- * Note that some combinations of {PAC, HMC, SSC} are reserved and
300
- * must act either like some valid combination or as if the watchpoint
301
- * were disabled. We choose the former, and use this together with
302
- * the fact that EL3 must always be Secure and EL2 must always be
303
- * Non-Secure to simplify the code slightly compared to the full
304
- * table in the ARM ARM.
305
- */
306
- pac = FIELD_EX64(cr, DBGWCR, PAC);
307
- hmc = FIELD_EX64(cr, DBGWCR, HMC);
308
- ssc = FIELD_EX64(cr, DBGWCR, SSC);
309
-
310
- switch (ssc) {
311
- case 0:
312
- break;
313
- case 1:
314
- case 3:
315
- if (is_secure) {
316
- return false;
317
- }
318
- break;
319
- case 2:
320
- if (!is_secure) {
321
- return false;
322
- }
323
- break;
324
- }
325
-
326
- switch (access_el) {
327
- case 3:
328
- case 2:
329
- if (!hmc) {
330
- return false;
331
- }
332
- break;
333
- case 1:
334
- if (extract32(pac, 0, 1) == 0) {
335
- return false;
336
- }
337
- break;
338
- case 0:
339
- if (extract32(pac, 1, 1) == 0) {
340
- return false;
341
- }
342
- break;
343
- default:
344
- g_assert_not_reached();
345
- }
346
-
347
- wt = FIELD_EX64(cr, DBGWCR, WT);
348
- lbn = FIELD_EX64(cr, DBGWCR, LBN);
349
-
350
- if (wt && !linked_bp_matches(cpu, lbn)) {
351
- return false;
352
- }
353
-
354
- return true;
355
-}
356
-
357
-static bool check_watchpoints(ARMCPU *cpu)
358
-{
359
- CPUARMState *env = &cpu->env;
360
- int n;
361
-
362
- /*
363
- * If watchpoints are disabled globally or we can't take debug
364
- * exceptions here then watchpoint firings are ignored.
365
- */
366
- if (extract32(env->cp15.mdscr_el1, 15, 1) == 0
367
- || !arm_generate_debug_exceptions(env)) {
368
- return false;
369
- }
370
-
371
- for (n = 0; n < ARRAY_SIZE(env->cpu_watchpoint); n++) {
372
- if (bp_wp_matches(cpu, n, true)) {
373
- return true;
374
- }
375
- }
376
- return false;
377
-}
378
-
379
-bool arm_debug_check_breakpoint(CPUState *cs)
380
-{
381
- ARMCPU *cpu = ARM_CPU(cs);
382
- CPUARMState *env = &cpu->env;
383
- vaddr pc;
384
- int n;
385
-
386
- /*
387
- * If breakpoints are disabled globally or we can't take debug
388
- * exceptions here then breakpoint firings are ignored.
389
- */
390
- if (extract32(env->cp15.mdscr_el1, 15, 1) == 0
391
- || !arm_generate_debug_exceptions(env)) {
392
- return false;
393
- }
394
-
395
- /*
396
- * Single-step exceptions have priority over breakpoint exceptions.
397
- * If single-step state is active-pending, suppress the bp.
398
- */
399
- if (arm_singlestep_active(env) && !(env->pstate & PSTATE_SS)) {
400
- return false;
401
- }
402
-
403
- /*
404
- * PC alignment faults have priority over breakpoint exceptions.
405
- */
406
- pc = is_a64(env) ? env->pc : env->regs[15];
407
- if ((is_a64(env) || !env->thumb) && (pc & 3) != 0) {
408
- return false;
409
- }
410
-
411
- /*
412
- * Instruction aborts have priority over breakpoint exceptions.
413
- * TODO: We would need to look up the page for PC and verify that
414
- * it is present and executable.
415
- */
416
-
417
- for (n = 0; n < ARRAY_SIZE(env->cpu_breakpoint); n++) {
418
- if (bp_wp_matches(cpu, n, false)) {
419
- return true;
420
- }
421
- }
422
- return false;
423
-}
424
-
425
-bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
426
-{
427
- /*
428
- * Called by core code when a CPU watchpoint fires; need to check if this
429
- * is also an architectural watchpoint match.
430
- */
431
- ARMCPU *cpu = ARM_CPU(cs);
432
-
433
- return check_watchpoints(cpu);
434
-}
435
-
436
-/*
437
- * Return the FSR value for a debug exception (watchpoint, hardware
438
- * breakpoint or BKPT insn) targeting the specified exception level.
439
- */
440
-static uint32_t arm_debug_exception_fsr(CPUARMState *env)
441
-{
442
- ARMMMUFaultInfo fi = { .type = ARMFault_Debug };
443
- int target_el = arm_debug_target_el(env);
444
- bool using_lpae;
445
-
446
- if (arm_feature(env, ARM_FEATURE_M)) {
447
- using_lpae = false;
448
- } else if (target_el == 2 || arm_el_is_aa64(env, target_el)) {
449
- using_lpae = true;
450
- } else if (arm_feature(env, ARM_FEATURE_PMSA) &&
451
- arm_feature(env, ARM_FEATURE_V8)) {
452
- using_lpae = true;
453
- } else if (arm_feature(env, ARM_FEATURE_LPAE) &&
454
- (env->cp15.tcr_el[target_el] & TTBCR_EAE)) {
455
- using_lpae = true;
456
- } else {
457
- using_lpae = false;
458
- }
459
-
460
- if (using_lpae) {
461
- return arm_fi_to_lfsc(&fi);
462
- } else {
463
- return arm_fi_to_sfsc(&fi);
464
- }
465
-}
466
-
467
-void arm_debug_excp_handler(CPUState *cs)
468
-{
469
- /*
470
- * Called by core code when a watchpoint or breakpoint fires;
471
- * need to check which one and raise the appropriate exception.
472
- */
473
- ARMCPU *cpu = ARM_CPU(cs);
474
- CPUARMState *env = &cpu->env;
475
- CPUWatchpoint *wp_hit = cs->watchpoint_hit;
476
-
477
- if (wp_hit) {
478
- if (wp_hit->flags & BP_CPU) {
479
- bool wnr = (wp_hit->flags & BP_WATCHPOINT_HIT_WRITE) != 0;
480
-
481
- cs->watchpoint_hit = NULL;
482
-
483
- env->exception.fsr = arm_debug_exception_fsr(env);
484
- env->exception.vaddress = wp_hit->hitaddr;
485
- raise_exception_debug(env, EXCP_DATA_ABORT,
486
- syn_watchpoint(0, 0, wnr));
487
- }
488
- } else {
489
- uint64_t pc = is_a64(env) ? env->pc : env->regs[15];
490
-
491
- /*
492
- * (1) GDB breakpoints should be handled first.
493
- * (2) Do not raise a CPU exception if no CPU breakpoint has fired,
494
- * since singlestep is also done by generating a debug internal
495
- * exception.
496
- */
497
- if (cpu_breakpoint_test(cs, pc, BP_GDB)
498
- || !cpu_breakpoint_test(cs, pc, BP_CPU)) {
499
- return;
500
- }
501
-
502
- env->exception.fsr = arm_debug_exception_fsr(env);
503
- /*
504
- * FAR is UNKNOWN: clear vaddress to avoid potentially exposing
505
- * values to the guest that it shouldn't be able to see at its
506
- * exception/security level.
507
- */
508
- env->exception.vaddress = 0;
509
- raise_exception_debug(env, EXCP_PREFETCH_ABORT, syn_breakpoint(0));
510
- }
511
-}
512
-
513
-/*
514
- * Raise an EXCP_BKPT with the specified syndrome register value,
515
- * targeting the correct exception level for debug exceptions.
516
- */
517
-void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome)
518
-{
519
- int debug_el = arm_debug_target_el(env);
520
- int cur_el = arm_current_el(env);
521
-
522
- /* FSR will only be used if the debug target EL is AArch32. */
523
- env->exception.fsr = arm_debug_exception_fsr(env);
524
- /*
525
- * FAR is UNKNOWN: clear vaddress to avoid potentially exposing
526
- * values to the guest that it shouldn't be able to see at its
527
- * exception/security level.
528
- */
529
- env->exception.vaddress = 0;
530
- /*
531
- * Other kinds of architectural debug exception are ignored if
532
- * they target an exception level below the current one (in QEMU
533
- * this is checked by arm_generate_debug_exceptions()). Breakpoint
534
- * instructions are special because they always generate an exception
535
- * to somewhere: if they can't go to the configured debug exception
536
- * level they are taken to the current exception level.
537
- */
538
- if (debug_el < cur_el) {
539
- debug_el = cur_el;
540
- }
541
- raise_exception(env, EXCP_BKPT, syndrome, debug_el);
542
-}
543
-
544
-void HELPER(exception_swstep)(CPUARMState *env, uint32_t syndrome)
545
-{
546
- raise_exception_debug(env, EXCP_UDEF, syndrome);
547
-}
548
-
549
-void hw_watchpoint_update(ARMCPU *cpu, int n)
550
-{
551
- CPUARMState *env = &cpu->env;
552
- vaddr len = 0;
553
- vaddr wvr = env->cp15.dbgwvr[n];
554
- uint64_t wcr = env->cp15.dbgwcr[n];
555
- int mask;
556
- int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
557
-
558
- if (env->cpu_watchpoint[n]) {
559
- cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]);
560
- env->cpu_watchpoint[n] = NULL;
561
- }
562
-
563
- if (!FIELD_EX64(wcr, DBGWCR, E)) {
564
- /* E bit clear : watchpoint disabled */
565
- return;
566
- }
567
-
568
- switch (FIELD_EX64(wcr, DBGWCR, LSC)) {
569
- case 0:
570
- /* LSC 00 is reserved and must behave as if the wp is disabled */
571
- return;
572
- case 1:
573
- flags |= BP_MEM_READ;
574
- break;
575
- case 2:
576
- flags |= BP_MEM_WRITE;
577
- break;
578
- case 3:
579
- flags |= BP_MEM_ACCESS;
580
- break;
581
- }
582
-
583
- /*
584
- * Attempts to use both MASK and BAS fields simultaneously are
585
- * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case,
586
- * thus generating a watchpoint for every byte in the masked region.
587
- */
588
- mask = FIELD_EX64(wcr, DBGWCR, MASK);
589
- if (mask == 1 || mask == 2) {
590
- /*
591
- * Reserved values of MASK; we must act as if the mask value was
592
- * some non-reserved value, or as if the watchpoint were disabled.
593
- * We choose the latter.
594
- */
595
- return;
596
- } else if (mask) {
597
- /* Watchpoint covers an aligned area up to 2GB in size */
598
- len = 1ULL << mask;
599
- /*
600
- * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE
601
- * whether the watchpoint fires when the unmasked bits match; we opt
602
- * to generate the exceptions.
603
- */
604
- wvr &= ~(len - 1);
605
- } else {
606
- /* Watchpoint covers bytes defined by the byte address select bits */
607
- int bas = FIELD_EX64(wcr, DBGWCR, BAS);
608
- int basstart;
609
-
610
- if (extract64(wvr, 2, 1)) {
611
- /*
612
- * Deprecated case of an only 4-aligned address. BAS[7:4] are
613
- * ignored, and BAS[3:0] define which bytes to watch.
614
- */
615
- bas &= 0xf;
616
- }
617
-
618
- if (bas == 0) {
619
- /* This must act as if the watchpoint is disabled */
620
- return;
621
- }
622
-
623
- /*
624
- * The BAS bits are supposed to be programmed to indicate a contiguous
625
- * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether
626
- * we fire for each byte in the word/doubleword addressed by the WVR.
627
- * We choose to ignore any non-zero bits after the first range of 1s.
628
- */
629
- basstart = ctz32(bas);
630
- len = cto32(bas >> basstart);
631
- wvr += basstart;
632
- }
633
-
634
- cpu_watchpoint_insert(CPU(cpu), wvr, len, flags,
635
- &env->cpu_watchpoint[n]);
636
-}
637
-
638
-void hw_watchpoint_update_all(ARMCPU *cpu)
639
-{
640
- int i;
641
- CPUARMState *env = &cpu->env;
642
-
643
- /*
644
- * Completely clear out existing QEMU watchpoints and our array, to
645
- * avoid possible stale entries following migration load.
646
- */
647
- cpu_watchpoint_remove_all(CPU(cpu), BP_CPU);
648
- memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint));
649
-
650
- for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) {
651
- hw_watchpoint_update(cpu, i);
652
- }
653
-}
654
-
655
-void hw_breakpoint_update(ARMCPU *cpu, int n)
656
-{
657
- CPUARMState *env = &cpu->env;
658
- uint64_t bvr = env->cp15.dbgbvr[n];
659
- uint64_t bcr = env->cp15.dbgbcr[n];
660
- vaddr addr;
661
- int bt;
662
- int flags = BP_CPU;
663
-
664
- if (env->cpu_breakpoint[n]) {
665
- cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]);
666
- env->cpu_breakpoint[n] = NULL;
667
- }
668
-
669
- if (!extract64(bcr, 0, 1)) {
670
- /* E bit clear : watchpoint disabled */
671
- return;
672
- }
673
-
674
- bt = extract64(bcr, 20, 4);
675
-
676
- switch (bt) {
677
- case 4: /* unlinked address mismatch (reserved if AArch64) */
678
- case 5: /* linked address mismatch (reserved if AArch64) */
679
- qemu_log_mask(LOG_UNIMP,
680
- "arm: address mismatch breakpoint types not implemented\n");
681
- return;
682
- case 0: /* unlinked address match */
683
- case 1: /* linked address match */
684
- {
685
- /*
686
- * Bits [1:0] are RES0.
687
- *
688
- * It is IMPLEMENTATION DEFINED whether bits [63:49]
689
- * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit
690
- * of the VA field ([48] or [52] for FEAT_LVA), or whether the
691
- * value is read as written. It is CONSTRAINED UNPREDICTABLE
692
- * whether the RESS bits are ignored when comparing an address.
693
- * Therefore we are allowed to compare the entire register, which
694
- * lets us avoid considering whether FEAT_LVA is actually enabled.
695
- *
696
- * The BAS field is used to allow setting breakpoints on 16-bit
697
- * wide instructions; it is CONSTRAINED UNPREDICTABLE whether
698
- * a bp will fire if the addresses covered by the bp and the addresses
699
- * covered by the insn overlap but the insn doesn't start at the
700
- * start of the bp address range. We choose to require the insn and
701
- * the bp to have the same address. The constraints on writing to
702
- * BAS enforced in dbgbcr_write mean we have only four cases:
703
- * 0b0000 => no breakpoint
704
- * 0b0011 => breakpoint on addr
705
- * 0b1100 => breakpoint on addr + 2
706
- * 0b1111 => breakpoint on addr
707
- * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c).
708
- */
709
- int bas = extract64(bcr, 5, 4);
710
- addr = bvr & ~3ULL;
711
- if (bas == 0) {
712
- return;
713
- }
714
- if (bas == 0xc) {
715
- addr += 2;
716
- }
717
- break;
718
- }
719
- case 2: /* unlinked context ID match */
720
- case 8: /* unlinked VMID match (reserved if no EL2) */
721
- case 10: /* unlinked context ID and VMID match (reserved if no EL2) */
722
- qemu_log_mask(LOG_UNIMP,
723
- "arm: unlinked context breakpoint types not implemented\n");
724
- return;
725
- case 9: /* linked VMID match (reserved if no EL2) */
726
- case 11: /* linked context ID and VMID match (reserved if no EL2) */
727
- case 3: /* linked context ID match */
728
- default:
729
- /*
730
- * We must generate no events for Linked context matches (unless
731
- * they are linked to by some other bp/wp, which is handled in
732
- * updates for the linking bp/wp). We choose to also generate no events
733
- * for reserved values.
734
- */
735
- return;
736
- }
737
-
738
- cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]);
739
-}
740
-
741
-void hw_breakpoint_update_all(ARMCPU *cpu)
742
-{
743
- int i;
744
- CPUARMState *env = &cpu->env;
745
-
746
- /*
747
- * Completely clear out existing QEMU breakpoints and our array, to
748
- * avoid possible stale entries following migration load.
749
- */
750
- cpu_breakpoint_remove_all(CPU(cpu), BP_CPU);
751
- memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint));
752
-
753
- for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) {
754
- hw_breakpoint_update(cpu, i);
755
- }
756
-}
757
-
758
-#if !defined(CONFIG_USER_ONLY)
759
-
760
-vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len)
761
-{
762
- ARMCPU *cpu = ARM_CPU(cs);
763
- CPUARMState *env = &cpu->env;
764
-
765
- /*
766
- * In BE32 system mode, target memory is stored byteswapped (on a
767
- * little-endian host system), and by the time we reach here (via an
768
- * opcode helper) the addresses of subword accesses have been adjusted
769
- * to account for that, which means that watchpoints will not match.
770
- * Undo the adjustment here.
771
- */
772
- if (arm_sctlr_b(env)) {
773
- if (len == 1) {
774
- addr ^= 3;
775
- } else if (len == 2) {
776
- addr ^= 2;
777
- }
778
- }
779
-
780
- return addr;
781
-}
782
-
783
-#endif /* !CONFIG_USER_ONLY */
784
-#endif /* CONFIG_TCG */
785
-
17
/*
18
* Check for traps to "powerdown debug" registers, which are controlled
19
* by MDCR.TDOSA
target/arm/tcg/debug.c
new
+782
@@ -0,0 +1,782 @@
1
+/*
2
+ * ARM debug helpers used by TCG
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
+#define HELPER_H "tcg/helper.h"
18
+#include "exec/helper-proto.h.inc"
19
+
20
+/* Return the Exception Level targeted by debug exceptions. */
21
+static int arm_debug_target_el(CPUARMState *env)
22
+{
23
+ bool secure = arm_is_secure(env);
24
+ bool route_to_el2 = false;
25
+
26
+ if (arm_feature(env, ARM_FEATURE_M)) {
27
+ return 1;
28
+ }
29
+
30
+ if (arm_is_el2_enabled(env)) {
31
+ route_to_el2 = env->cp15.hcr_el2 & HCR_TGE ||
32
+ env->cp15.mdcr_el2 & MDCR_TDE;
33
+ }
34
+
35
+ if (route_to_el2) {
36
+ return 2;
37
+ } else if (arm_feature(env, ARM_FEATURE_EL3) &&
38
+ !arm_el_is_aa64(env, 3) && secure) {
39
+ return 3;
40
+ } else {
41
+ return 1;
42
+ }
43
+}
44
+
45
+/*
46
+ * Raise an exception to the debug target el.
47
+ * Modify syndrome to indicate when origin and target EL are the same.
48
+ */
49
+static G_NORETURN void
50
+raise_exception_debug(CPUARMState *env, uint32_t excp, uint32_t syndrome)
51
+{
52
+ int debug_el = arm_debug_target_el(env);
53
+ int cur_el = arm_current_el(env);
54
+
55
+ /*
56
+ * If singlestep is targeting a lower EL than the current one, then
57
+ * DisasContext.ss_active must be false and we can never get here.
58
+ * Similarly for watchpoint and breakpoint matches.
59
+ */
60
+ assert(debug_el >= cur_el);
61
+ syndrome |= (debug_el == cur_el) << ARM_EL_EC_SHIFT;
62
+ raise_exception(env, excp, syndrome, debug_el);
63
+}
64
+
65
+/* See AArch64.GenerateDebugExceptionsFrom() in ARM ARM pseudocode */
66
+static bool aa64_generate_debug_exceptions(CPUARMState *env)
67
+{
68
+ int cur_el = arm_current_el(env);
69
+ int debug_el;
70
+
71
+ if (cur_el == 3) {
72
+ return false;
73
+ }
74
+
75
+ /* MDCR_EL3.SDD disables debug events from Secure state */
76
+ if (arm_is_secure_below_el3(env)
77
+ && extract32(env->cp15.mdcr_el3, 16, 1)) {
78
+ return false;
79
+ }
80
+
81
+ /*
82
+ * Same EL to same EL debug exceptions need MDSCR_KDE enabled
83
+ * while not masking the (D)ebug bit in DAIF.
84
+ */
85
+ debug_el = arm_debug_target_el(env);
86
+
87
+ if (cur_el == debug_el) {
88
+ return extract32(env->cp15.mdscr_el1, 13, 1)
89
+ && !(env->daif & PSTATE_D);
90
+ }
91
+
92
+ /* Otherwise the debug target needs to be a higher EL */
93
+ return debug_el > cur_el;
94
+}
95
+
96
+static bool aa32_generate_debug_exceptions(CPUARMState *env)
97
+{
98
+ int el = arm_current_el(env);
99
+
100
+ if (el == 0 && arm_el_is_aa64(env, 1)) {
101
+ return aa64_generate_debug_exceptions(env);
102
+ }
103
+
104
+ if (arm_is_secure(env)) {
105
+ int spd;
106
+
107
+ if (el == 0 && (env->cp15.sder & 1)) {
108
+ /*
109
+ * SDER.SUIDEN means debug exceptions from Secure EL0
110
+ * are always enabled. Otherwise they are controlled by
111
+ * SDCR.SPD like those from other Secure ELs.
112
+ */
113
+ return true;
114
+ }
115
+
116
+ spd = extract32(env->cp15.mdcr_el3, 14, 2);
117
+ switch (spd) {
118
+ case 1:
119
+ /* SPD == 0b01 is reserved, but behaves as 0b00. */
120
+ case 0:
121
+ /*
122
+ * For 0b00 we return true if external secure invasive debug
123
+ * is enabled. On real hardware this is controlled by external
124
+ * signals to the core. QEMU always permits debug, and behaves
125
+ * as if DBGEN, SPIDEN, NIDEN and SPNIDEN are all tied high.
126
+ */
127
+ return true;
128
+ case 2:
129
+ return false;
130
+ case 3:
131
+ return true;
132
+ }
133
+ }
134
+
135
+ return el != 2;
136
+}
137
+
138
+/*
139
+ * Return true if debugging exceptions are currently enabled.
140
+ * This corresponds to what in ARM ARM pseudocode would be
141
+ * if UsingAArch32() then
142
+ * return AArch32.GenerateDebugExceptions()
143
+ * else
144
+ * return AArch64.GenerateDebugExceptions()
145
+ * We choose to push the if() down into this function for clarity,
146
+ * since the pseudocode has it at all callsites except for the one in
147
+ * CheckSoftwareStep(), where it is elided because both branches would
148
+ * always return the same value.
149
+ */
150
+bool arm_generate_debug_exceptions(CPUARMState *env)
151
+{
152
+ if ((env->cp15.oslsr_el1 & 1) || (env->cp15.osdlr_el1 & 1)) {
153
+ return false;
154
+ }
155
+ if (is_a64(env)) {
156
+ return aa64_generate_debug_exceptions(env);
157
+ } else {
158
+ return aa32_generate_debug_exceptions(env);
159
+ }
160
+}
161
+
162
+/*
163
+ * Is single-stepping active? (Note that the "is EL_D AArch64?" check
164
+ * implicitly means this always returns false in pre-v8 CPUs.)
165
+ */
166
+bool arm_singlestep_active(CPUARMState *env)
167
+{
168
+ return extract32(env->cp15.mdscr_el1, 0, 1)
169
+ && arm_el_is_aa64(env, arm_debug_target_el(env))
170
+ && arm_generate_debug_exceptions(env);
171
+}
172
+
173
+/* Return true if the linked breakpoint entry lbn passes its checks */
174
+static bool linked_bp_matches(ARMCPU *cpu, int lbn)
175
+{
176
+ CPUARMState *env = &cpu->env;
177
+ uint64_t bcr = env->cp15.dbgbcr[lbn];
178
+ int brps = arm_num_brps(cpu);
179
+ int ctx_cmps = arm_num_ctx_cmps(cpu);
180
+ int bt;
181
+ uint32_t contextidr;
182
+ uint64_t hcr_el2;
183
+
184
+ /*
185
+ * Links to unimplemented or non-context aware breakpoints are
186
+ * CONSTRAINED UNPREDICTABLE: either behave as if disabled, or
187
+ * as if linked to an UNKNOWN context-aware breakpoint (in which
188
+ * case DBGWCR<n>_EL1.LBN must indicate that breakpoint).
189
+ * We choose the former.
190
+ */
191
+ if (lbn >= brps || lbn < (brps - ctx_cmps)) {
192
+ return false;
193
+ }
194
+
195
+ bcr = env->cp15.dbgbcr[lbn];
196
+
197
+ if (extract64(bcr, 0, 1) == 0) {
198
+ /* Linked breakpoint disabled : generate no events */
199
+ return false;
200
+ }
201
+
202
+ bt = extract64(bcr, 20, 4);
203
+ hcr_el2 = arm_hcr_el2_eff(env);
204
+
205
+ switch (bt) {
206
+ case 3: /* linked context ID match */
207
+ switch (arm_current_el(env)) {
208
+ default:
209
+ /* Context matches never fire in AArch64 EL3 */
210
+ return false;
211
+ case 2:
212
+ if (!(hcr_el2 & HCR_E2H)) {
213
+ /* Context matches never fire in EL2 without E2H enabled. */
214
+ return false;
215
+ }
216
+ contextidr = env->cp15.contextidr_el[2];
217
+ break;
218
+ case 1:
219
+ contextidr = env->cp15.contextidr_el[1];
220
+ break;
221
+ case 0:
222
+ if ((hcr_el2 & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
223
+ contextidr = env->cp15.contextidr_el[2];
224
+ } else {
225
+ contextidr = env->cp15.contextidr_el[1];
226
+ }
227
+ break;
228
+ }
229
+ break;
230
+
231
+ case 7: /* linked contextidr_el1 match */
232
+ contextidr = env->cp15.contextidr_el[1];
233
+ break;
234
+ case 13: /* linked contextidr_el2 match */
235
+ contextidr = env->cp15.contextidr_el[2];
236
+ break;
237
+
238
+ case 9: /* linked VMID match (reserved if no EL2) */
239
+ case 11: /* linked context ID and VMID match (reserved if no EL2) */
240
+ case 15: /* linked full context ID match */
241
+ default:
242
+ /*
243
+ * Links to Unlinked context breakpoints must generate no
244
+ * events; we choose to do the same for reserved values too.
245
+ */
246
+ return false;
247
+ }
248
+
249
+ /*
250
+ * We match the whole register even if this is AArch32 using the
251
+ * short descriptor format (in which case it holds both PROCID and ASID),
252
+ * since we don't implement the optional v7 context ID masking.
253
+ */
254
+ return contextidr == (uint32_t)env->cp15.dbgbvr[lbn];
255
+}
256
+
257
+static bool bp_wp_matches(ARMCPU *cpu, int n, bool is_wp)
258
+{
259
+ CPUARMState *env = &cpu->env;
260
+ uint64_t cr;
261
+ int pac, hmc, ssc, wt, lbn;
262
+ /*
263
+ * Note that for watchpoints the check is against the CPU security
264
+ * state, not the S/NS attribute on the offending data access.
265
+ */
266
+ bool is_secure = arm_is_secure(env);
267
+ int access_el = arm_current_el(env);
268
+
269
+ if (is_wp) {
270
+ CPUWatchpoint *wp = env->cpu_watchpoint[n];
271
+
272
+ if (!wp || !(wp->flags & BP_WATCHPOINT_HIT)) {
273
+ return false;
274
+ }
275
+ cr = env->cp15.dbgwcr[n];
276
+ if (wp->hitattrs.user) {
277
+ /*
278
+ * The LDRT/STRT/LDT/STT "unprivileged access" instructions should
279
+ * match watchpoints as if they were accesses done at EL0, even if
280
+ * the CPU is at EL1 or higher.
281
+ */
282
+ access_el = 0;
283
+ }
284
+ } else {
285
+ uint64_t pc = is_a64(env) ? env->pc : env->regs[15];
286
+
287
+ if (!env->cpu_breakpoint[n] || env->cpu_breakpoint[n]->pc != pc) {
288
+ return false;
289
+ }
290
+ cr = env->cp15.dbgbcr[n];
291
+ }
292
+ /*
293
+ * The WATCHPOINT_HIT flag guarantees us that the watchpoint is
294
+ * enabled and that the address and access type match; for breakpoints
295
+ * we know the address matched; check the remaining fields, including
296
+ * linked breakpoints. We rely on WCR and BCR having the same layout
297
+ * for the LBN, SSC, HMC, PAC/PMC and is-linked fields.
298
+ * Note that some combinations of {PAC, HMC, SSC} are reserved and
299
+ * must act either like some valid combination or as if the watchpoint
300
+ * were disabled. We choose the former, and use this together with
301
+ * the fact that EL3 must always be Secure and EL2 must always be
302
+ * Non-Secure to simplify the code slightly compared to the full
303
+ * table in the ARM ARM.
304
+ */
305
+ pac = FIELD_EX64(cr, DBGWCR, PAC);
306
+ hmc = FIELD_EX64(cr, DBGWCR, HMC);
307
+ ssc = FIELD_EX64(cr, DBGWCR, SSC);
308
+
309
+ switch (ssc) {
310
+ case 0:
311
+ break;
312
+ case 1:
313
+ case 3:
314
+ if (is_secure) {
315
+ return false;
316
+ }
317
+ break;
318
+ case 2:
319
+ if (!is_secure) {
320
+ return false;
321
+ }
322
+ break;
323
+ }
324
+
325
+ switch (access_el) {
326
+ case 3:
327
+ case 2:
328
+ if (!hmc) {
329
+ return false;
330
+ }
331
+ break;
332
+ case 1:
333
+ if (extract32(pac, 0, 1) == 0) {
334
+ return false;
335
+ }
336
+ break;
337
+ case 0:
338
+ if (extract32(pac, 1, 1) == 0) {
339
+ return false;
340
+ }
341
+ break;
342
+ default:
343
+ g_assert_not_reached();
344
+ }
345
+
346
+ wt = FIELD_EX64(cr, DBGWCR, WT);
347
+ lbn = FIELD_EX64(cr, DBGWCR, LBN);
348
+
349
+ if (wt && !linked_bp_matches(cpu, lbn)) {
350
+ return false;
351
+ }
352
+
353
+ return true;
354
+}
355
+
356
+static bool check_watchpoints(ARMCPU *cpu)
357
+{
358
+ CPUARMState *env = &cpu->env;
359
+ int n;
360
+
361
+ /*
362
+ * If watchpoints are disabled globally or we can't take debug
363
+ * exceptions here then watchpoint firings are ignored.
364
+ */
365
+ if (extract32(env->cp15.mdscr_el1, 15, 1) == 0
366
+ || !arm_generate_debug_exceptions(env)) {
367
+ return false;
368
+ }
369
+
370
+ for (n = 0; n < ARRAY_SIZE(env->cpu_watchpoint); n++) {
371
+ if (bp_wp_matches(cpu, n, true)) {
372
+ return true;
373
+ }
374
+ }
375
+ return false;
376
+}
377
+
378
+bool arm_debug_check_breakpoint(CPUState *cs)
379
+{
380
+ ARMCPU *cpu = ARM_CPU(cs);
381
+ CPUARMState *env = &cpu->env;
382
+ vaddr pc;
383
+ int n;
384
+
385
+ /*
386
+ * If breakpoints are disabled globally or we can't take debug
387
+ * exceptions here then breakpoint firings are ignored.
388
+ */
389
+ if (extract32(env->cp15.mdscr_el1, 15, 1) == 0
390
+ || !arm_generate_debug_exceptions(env)) {
391
+ return false;
392
+ }
393
+
394
+ /*
395
+ * Single-step exceptions have priority over breakpoint exceptions.
396
+ * If single-step state is active-pending, suppress the bp.
397
+ */
398
+ if (arm_singlestep_active(env) && !(env->pstate & PSTATE_SS)) {
399
+ return false;
400
+ }
401
+
402
+ /*
403
+ * PC alignment faults have priority over breakpoint exceptions.
404
+ */
405
+ pc = is_a64(env) ? env->pc : env->regs[15];
406
+ if ((is_a64(env) || !env->thumb) && (pc & 3) != 0) {
407
+ return false;
408
+ }
409
+
410
+ /*
411
+ * Instruction aborts have priority over breakpoint exceptions.
412
+ * TODO: We would need to look up the page for PC and verify that
413
+ * it is present and executable.
414
+ */
415
+
416
+ for (n = 0; n < ARRAY_SIZE(env->cpu_breakpoint); n++) {
417
+ if (bp_wp_matches(cpu, n, false)) {
418
+ return true;
419
+ }
420
+ }
421
+ return false;
422
+}
423
+
424
+bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
425
+{
426
+ /*
427
+ * Called by core code when a CPU watchpoint fires; need to check if this
428
+ * is also an architectural watchpoint match.
429
+ */
430
+ ARMCPU *cpu = ARM_CPU(cs);
431
+
432
+ return check_watchpoints(cpu);
433
+}
434
+
435
+/*
436
+ * Return the FSR value for a debug exception (watchpoint, hardware
437
+ * breakpoint or BKPT insn) targeting the specified exception level.
438
+ */
439
+static uint32_t arm_debug_exception_fsr(CPUARMState *env)
440
+{
441
+ ARMMMUFaultInfo fi = { .type = ARMFault_Debug };
442
+ int target_el = arm_debug_target_el(env);
443
+ bool using_lpae;
444
+
445
+ if (arm_feature(env, ARM_FEATURE_M)) {
446
+ using_lpae = false;
447
+ } else if (target_el == 2 || arm_el_is_aa64(env, target_el)) {
448
+ using_lpae = true;
449
+ } else if (arm_feature(env, ARM_FEATURE_PMSA) &&
450
+ arm_feature(env, ARM_FEATURE_V8)) {
451
+ using_lpae = true;
452
+ } else if (arm_feature(env, ARM_FEATURE_LPAE) &&
453
+ (env->cp15.tcr_el[target_el] & TTBCR_EAE)) {
454
+ using_lpae = true;
455
+ } else {
456
+ using_lpae = false;
457
+ }
458
+
459
+ if (using_lpae) {
460
+ return arm_fi_to_lfsc(&fi);
461
+ } else {
462
+ return arm_fi_to_sfsc(&fi);
463
+ }
464
+}
465
+
466
+void arm_debug_excp_handler(CPUState *cs)
467
+{
468
+ /*
469
+ * Called by core code when a watchpoint or breakpoint fires;
470
+ * need to check which one and raise the appropriate exception.
471
+ */
472
+ ARMCPU *cpu = ARM_CPU(cs);
473
+ CPUARMState *env = &cpu->env;
474
+ CPUWatchpoint *wp_hit = cs->watchpoint_hit;
475
+
476
+ if (wp_hit) {
477
+ if (wp_hit->flags & BP_CPU) {
478
+ bool wnr = (wp_hit->flags & BP_WATCHPOINT_HIT_WRITE) != 0;
479
+
480
+ cs->watchpoint_hit = NULL;
481
+
482
+ env->exception.fsr = arm_debug_exception_fsr(env);
483
+ env->exception.vaddress = wp_hit->hitaddr;
484
+ raise_exception_debug(env, EXCP_DATA_ABORT,
485
+ syn_watchpoint(0, 0, wnr));
486
+ }
487
+ } else {
488
+ uint64_t pc = is_a64(env) ? env->pc : env->regs[15];
489
+
490
+ /*
491
+ * (1) GDB breakpoints should be handled first.
492
+ * (2) Do not raise a CPU exception if no CPU breakpoint has fired,
493
+ * since singlestep is also done by generating a debug internal
494
+ * exception.
495
+ */
496
+ if (cpu_breakpoint_test(cs, pc, BP_GDB)
497
+ || !cpu_breakpoint_test(cs, pc, BP_CPU)) {
498
+ return;
499
+ }
500
+
501
+ env->exception.fsr = arm_debug_exception_fsr(env);
502
+ /*
503
+ * FAR is UNKNOWN: clear vaddress to avoid potentially exposing
504
+ * values to the guest that it shouldn't be able to see at its
505
+ * exception/security level.
506
+ */
507
+ env->exception.vaddress = 0;
508
+ raise_exception_debug(env, EXCP_PREFETCH_ABORT, syn_breakpoint(0));
509
+ }
510
+}
511
+
512
+/*
513
+ * Raise an EXCP_BKPT with the specified syndrome register value,
514
+ * targeting the correct exception level for debug exceptions.
515
+ */
516
+void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome)
517
+{
518
+ int debug_el = arm_debug_target_el(env);
519
+ int cur_el = arm_current_el(env);
520
+
521
+ /* FSR will only be used if the debug target EL is AArch32. */
522
+ env->exception.fsr = arm_debug_exception_fsr(env);
523
+ /*
524
+ * FAR is UNKNOWN: clear vaddress to avoid potentially exposing
525
+ * values to the guest that it shouldn't be able to see at its
526
+ * exception/security level.
527
+ */
528
+ env->exception.vaddress = 0;
529
+ /*
530
+ * Other kinds of architectural debug exception are ignored if
531
+ * they target an exception level below the current one (in QEMU
532
+ * this is checked by arm_generate_debug_exceptions()). Breakpoint
533
+ * instructions are special because they always generate an exception
534
+ * to somewhere: if they can't go to the configured debug exception
535
+ * level they are taken to the current exception level.
536
+ */
537
+ if (debug_el < cur_el) {
538
+ debug_el = cur_el;
539
+ }
540
+ raise_exception(env, EXCP_BKPT, syndrome, debug_el);
541
+}
542
+
543
+void HELPER(exception_swstep)(CPUARMState *env, uint32_t syndrome)
544
+{
545
+ raise_exception_debug(env, EXCP_UDEF, syndrome);
546
+}
547
+
548
+void hw_watchpoint_update(ARMCPU *cpu, int n)
549
+{
550
+ CPUARMState *env = &cpu->env;
551
+ vaddr len = 0;
552
+ vaddr wvr = env->cp15.dbgwvr[n];
553
+ uint64_t wcr = env->cp15.dbgwcr[n];
554
+ int mask;
555
+ int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
556
+
557
+ if (env->cpu_watchpoint[n]) {
558
+ cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]);
559
+ env->cpu_watchpoint[n] = NULL;
560
+ }
561
+
562
+ if (!FIELD_EX64(wcr, DBGWCR, E)) {
563
+ /* E bit clear : watchpoint disabled */
564
+ return;
565
+ }
566
+
567
+ switch (FIELD_EX64(wcr, DBGWCR, LSC)) {
568
+ case 0:
569
+ /* LSC 00 is reserved and must behave as if the wp is disabled */
570
+ return;
571
+ case 1:
572
+ flags |= BP_MEM_READ;
573
+ break;
574
+ case 2:
575
+ flags |= BP_MEM_WRITE;
576
+ break;
577
+ case 3:
578
+ flags |= BP_MEM_ACCESS;
579
+ break;
580
+ }
581
+
582
+ /*
583
+ * Attempts to use both MASK and BAS fields simultaneously are
584
+ * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case,
585
+ * thus generating a watchpoint for every byte in the masked region.
586
+ */
587
+ mask = FIELD_EX64(wcr, DBGWCR, MASK);
588
+ if (mask == 1 || mask == 2) {
589
+ /*
590
+ * Reserved values of MASK; we must act as if the mask value was
591
+ * some non-reserved value, or as if the watchpoint were disabled.
592
+ * We choose the latter.
593
+ */
594
+ return;
595
+ } else if (mask) {
596
+ /* Watchpoint covers an aligned area up to 2GB in size */
597
+ len = 1ULL << mask;
598
+ /*
599
+ * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE
600
+ * whether the watchpoint fires when the unmasked bits match; we opt
601
+ * to generate the exceptions.
602
+ */
603
+ wvr &= ~(len - 1);
604
+ } else {
605
+ /* Watchpoint covers bytes defined by the byte address select bits */
606
+ int bas = FIELD_EX64(wcr, DBGWCR, BAS);
607
+ int basstart;
608
+
609
+ if (extract64(wvr, 2, 1)) {
610
+ /*
611
+ * Deprecated case of an only 4-aligned address. BAS[7:4] are
612
+ * ignored, and BAS[3:0] define which bytes to watch.
613
+ */
614
+ bas &= 0xf;
615
+ }
616
+
617
+ if (bas == 0) {
618
+ /* This must act as if the watchpoint is disabled */
619
+ return;
620
+ }
621
+
622
+ /*
623
+ * The BAS bits are supposed to be programmed to indicate a contiguous
624
+ * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether
625
+ * we fire for each byte in the word/doubleword addressed by the WVR.
626
+ * We choose to ignore any non-zero bits after the first range of 1s.
627
+ */
628
+ basstart = ctz32(bas);
629
+ len = cto32(bas >> basstart);
630
+ wvr += basstart;
631
+ }
632
+
633
+ cpu_watchpoint_insert(CPU(cpu), wvr, len, flags,
634
+ &env->cpu_watchpoint[n]);
635
+}
636
+
637
+void hw_watchpoint_update_all(ARMCPU *cpu)
638
+{
639
+ int i;
640
+ CPUARMState *env = &cpu->env;
641
+
642
+ /*
643
+ * Completely clear out existing QEMU watchpoints and our array, to
644
+ * avoid possible stale entries following migration load.
645
+ */
646
+ cpu_watchpoint_remove_all(CPU(cpu), BP_CPU);
647
+ memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint));
648
+
649
+ for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) {
650
+ hw_watchpoint_update(cpu, i);
651
+ }
652
+}
653
+
654
+void hw_breakpoint_update(ARMCPU *cpu, int n)
655
+{
656
+ CPUARMState *env = &cpu->env;
657
+ uint64_t bvr = env->cp15.dbgbvr[n];
658
+ uint64_t bcr = env->cp15.dbgbcr[n];
659
+ vaddr addr;
660
+ int bt;
661
+ int flags = BP_CPU;
662
+
663
+ if (env->cpu_breakpoint[n]) {
664
+ cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]);
665
+ env->cpu_breakpoint[n] = NULL;
666
+ }
667
+
668
+ if (!extract64(bcr, 0, 1)) {
669
+ /* E bit clear : watchpoint disabled */
670
+ return;
671
+ }
672
+
673
+ bt = extract64(bcr, 20, 4);
674
+
675
+ switch (bt) {
676
+ case 4: /* unlinked address mismatch (reserved if AArch64) */
677
+ case 5: /* linked address mismatch (reserved if AArch64) */
678
+ qemu_log_mask(LOG_UNIMP,
679
+ "arm: address mismatch breakpoint types not implemented\n");
680
+ return;
681
+ case 0: /* unlinked address match */
682
+ case 1: /* linked address match */
683
+ {
684
+ /*
685
+ * Bits [1:0] are RES0.
686
+ *
687
+ * It is IMPLEMENTATION DEFINED whether bits [63:49]
688
+ * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit
689
+ * of the VA field ([48] or [52] for FEAT_LVA), or whether the
690
+ * value is read as written. It is CONSTRAINED UNPREDICTABLE
691
+ * whether the RESS bits are ignored when comparing an address.
692
+ * Therefore we are allowed to compare the entire register, which
693
+ * lets us avoid considering whether FEAT_LVA is actually enabled.
694
+ *
695
+ * The BAS field is used to allow setting breakpoints on 16-bit
696
+ * wide instructions; it is CONSTRAINED UNPREDICTABLE whether
697
+ * a bp will fire if the addresses covered by the bp and the addresses
698
+ * covered by the insn overlap but the insn doesn't start at the
699
+ * start of the bp address range. We choose to require the insn and
700
+ * the bp to have the same address. The constraints on writing to
701
+ * BAS enforced in dbgbcr_write mean we have only four cases:
702
+ * 0b0000 => no breakpoint
703
+ * 0b0011 => breakpoint on addr
704
+ * 0b1100 => breakpoint on addr + 2
705
+ * 0b1111 => breakpoint on addr
706
+ * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c).
707
+ */
708
+ int bas = extract64(bcr, 5, 4);
709
+ addr = bvr & ~3ULL;
710
+ if (bas == 0) {
711
+ return;
712
+ }
713
+ if (bas == 0xc) {
714
+ addr += 2;
715
+ }
716
+ break;
717
+ }
718
+ case 2: /* unlinked context ID match */
719
+ case 8: /* unlinked VMID match (reserved if no EL2) */
720
+ case 10: /* unlinked context ID and VMID match (reserved if no EL2) */
721
+ qemu_log_mask(LOG_UNIMP,
722
+ "arm: unlinked context breakpoint types not implemented\n");
723
+ return;
724
+ case 9: /* linked VMID match (reserved if no EL2) */
725
+ case 11: /* linked context ID and VMID match (reserved if no EL2) */
726
+ case 3: /* linked context ID match */
727
+ default:
728
+ /*
729
+ * We must generate no events for Linked context matches (unless
730
+ * they are linked to by some other bp/wp, which is handled in
731
+ * updates for the linking bp/wp). We choose to also generate no events
732
+ * for reserved values.
733
+ */
734
+ return;
735
+ }
736
+
737
+ cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]);
738
+}
739
+
740
+void hw_breakpoint_update_all(ARMCPU *cpu)
741
+{
742
+ int i;
743
+ CPUARMState *env = &cpu->env;
744
+
745
+ /*
746
+ * Completely clear out existing QEMU breakpoints and our array, to
747
+ * avoid possible stale entries following migration load.
748
+ */
749
+ cpu_breakpoint_remove_all(CPU(cpu), BP_CPU);
750
+ memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint));
751
+
752
+ for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) {
753
+ hw_breakpoint_update(cpu, i);
754
+ }
755
+}
756
+
757
+#if !defined(CONFIG_USER_ONLY)
758
+
759
+vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len)
760
+{
761
+ ARMCPU *cpu = ARM_CPU(cs);
762
+ CPUARMState *env = &cpu->env;
763
+
764
+ /*
765
+ * In BE32 system mode, target memory is stored byteswapped (on a
766
+ * little-endian host system), and by the time we reach here (via an
767
+ * opcode helper) the addresses of subword accesses have been adjusted
768
+ * to account for that, which means that watchpoints will not match.
769
+ * Undo the adjustment here.
770
+ */
771
+ if (arm_sctlr_b(env)) {
772
+ if (len == 1) {
773
+ addr ^= 3;
774
+ } else if (len == 2) {
775
+ addr ^= 2;
776
+ }
777
+ }
778
+
779
+ return addr;
780
+}
781
+
782
+#endif /* !CONFIG_USER_ONLY */
target/arm/tcg/meson.build
+2
@@ -65,6 +65,7 @@ arm_common_ss.add(files(
65
66
arm_common_system_ss.add(files(
67
'cpregs-at.c',
68
+ 'debug.c',
69
'hflags.c',
70
'neon_helper.c',
71
'tlb_helper.c',
@@ -72,6 +73,7 @@ arm_common_system_ss.add(files(
73
'vfp_helper.c',
74
))
75
arm_user_ss.add(files(
76
+ 'debug.c',
77
'hflags.c',
78
'neon_helper.c',
79
'tlb_helper.c',