@samitouri / QOSamiQemu / commits / 7bea97639e

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',