19dd5cca4SPhilippe Mathieu-Daudé /*
29dd5cca4SPhilippe Mathieu-Daudé * ARM debug helpers.
39dd5cca4SPhilippe Mathieu-Daudé *
49dd5cca4SPhilippe Mathieu-Daudé * This code is licensed under the GNU GPL v2 or later.
59dd5cca4SPhilippe Mathieu-Daudé *
69dd5cca4SPhilippe Mathieu-Daudé * SPDX-License-Identifier: GPL-2.0-or-later
79dd5cca4SPhilippe Mathieu-Daudé */
89dd5cca4SPhilippe Mathieu-Daudé #include "qemu/osdep.h"
9f43ee493SPeter Maydell #include "qemu/log.h"
109dd5cca4SPhilippe Mathieu-Daudé #include "cpu.h"
119dd5cca4SPhilippe Mathieu-Daudé #include "internals.h"
125a534314SPeter Maydell #include "cpu-features.h"
13f43ee493SPeter Maydell #include "cpregs.h"
149dd5cca4SPhilippe Mathieu-Daudé #include "exec/exec-all.h"
159dd5cca4SPhilippe Mathieu-Daudé #include "exec/helper-proto.h"
162059ec75SFabiano Rosas #include "sysemu/tcg.h"
179dd5cca4SPhilippe Mathieu-Daudé
182059ec75SFabiano Rosas #ifdef CONFIG_TCG
1938e8a13cSRichard Henderson /* Return the Exception Level targeted by debug exceptions. */
arm_debug_target_el(CPUARMState * env)2038e8a13cSRichard Henderson static int arm_debug_target_el(CPUARMState *env)
2138e8a13cSRichard Henderson {
2238e8a13cSRichard Henderson bool secure = arm_is_secure(env);
2338e8a13cSRichard Henderson bool route_to_el2 = false;
2438e8a13cSRichard Henderson
255d78893fSPeter Maydell if (arm_feature(env, ARM_FEATURE_M)) {
265d78893fSPeter Maydell return 1;
275d78893fSPeter Maydell }
285d78893fSPeter Maydell
2938e8a13cSRichard Henderson if (arm_is_el2_enabled(env)) {
3038e8a13cSRichard Henderson route_to_el2 = env->cp15.hcr_el2 & HCR_TGE ||
3138e8a13cSRichard Henderson env->cp15.mdcr_el2 & MDCR_TDE;
3238e8a13cSRichard Henderson }
3338e8a13cSRichard Henderson
3438e8a13cSRichard Henderson if (route_to_el2) {
3538e8a13cSRichard Henderson return 2;
3638e8a13cSRichard Henderson } else if (arm_feature(env, ARM_FEATURE_EL3) &&
3738e8a13cSRichard Henderson !arm_el_is_aa64(env, 3) && secure) {
3838e8a13cSRichard Henderson return 3;
3938e8a13cSRichard Henderson } else {
4038e8a13cSRichard Henderson return 1;
4138e8a13cSRichard Henderson }
4238e8a13cSRichard Henderson }
4338e8a13cSRichard Henderson
4404eacf6eSRichard Henderson /*
4504eacf6eSRichard Henderson * Raise an exception to the debug target el.
4604eacf6eSRichard Henderson * Modify syndrome to indicate when origin and target EL are the same.
4704eacf6eSRichard Henderson */
4804eacf6eSRichard Henderson G_NORETURN static void
raise_exception_debug(CPUARMState * env,uint32_t excp,uint32_t syndrome)4904eacf6eSRichard Henderson raise_exception_debug(CPUARMState *env, uint32_t excp, uint32_t syndrome)
5004eacf6eSRichard Henderson {
5104eacf6eSRichard Henderson int debug_el = arm_debug_target_el(env);
5204eacf6eSRichard Henderson int cur_el = arm_current_el(env);
5304eacf6eSRichard Henderson
5404eacf6eSRichard Henderson /*
5504eacf6eSRichard Henderson * If singlestep is targeting a lower EL than the current one, then
5604eacf6eSRichard Henderson * DisasContext.ss_active must be false and we can never get here.
5704eacf6eSRichard Henderson * Similarly for watchpoint and breakpoint matches.
5804eacf6eSRichard Henderson */
5904eacf6eSRichard Henderson assert(debug_el >= cur_el);
6004eacf6eSRichard Henderson syndrome |= (debug_el == cur_el) << ARM_EL_EC_SHIFT;
6104eacf6eSRichard Henderson raise_exception(env, excp, syndrome, debug_el);
6204eacf6eSRichard Henderson }
6304eacf6eSRichard Henderson
6431c8df53SRichard Henderson /* See AArch64.GenerateDebugExceptionsFrom() in ARM ARM pseudocode */
aa64_generate_debug_exceptions(CPUARMState * env)6531c8df53SRichard Henderson static bool aa64_generate_debug_exceptions(CPUARMState *env)
6631c8df53SRichard Henderson {
6731c8df53SRichard Henderson int cur_el = arm_current_el(env);
6831c8df53SRichard Henderson int debug_el;
6931c8df53SRichard Henderson
7031c8df53SRichard Henderson if (cur_el == 3) {
7131c8df53SRichard Henderson return false;
7231c8df53SRichard Henderson }
7331c8df53SRichard Henderson
7431c8df53SRichard Henderson /* MDCR_EL3.SDD disables debug events from Secure state */
7531c8df53SRichard Henderson if (arm_is_secure_below_el3(env)
7631c8df53SRichard Henderson && extract32(env->cp15.mdcr_el3, 16, 1)) {
7731c8df53SRichard Henderson return false;
7831c8df53SRichard Henderson }
7931c8df53SRichard Henderson
8031c8df53SRichard Henderson /*
8131c8df53SRichard Henderson * Same EL to same EL debug exceptions need MDSCR_KDE enabled
8231c8df53SRichard Henderson * while not masking the (D)ebug bit in DAIF.
8331c8df53SRichard Henderson */
8431c8df53SRichard Henderson debug_el = arm_debug_target_el(env);
8531c8df53SRichard Henderson
8631c8df53SRichard Henderson if (cur_el == debug_el) {
8731c8df53SRichard Henderson return extract32(env->cp15.mdscr_el1, 13, 1)
8831c8df53SRichard Henderson && !(env->daif & PSTATE_D);
8931c8df53SRichard Henderson }
9031c8df53SRichard Henderson
9131c8df53SRichard Henderson /* Otherwise the debug target needs to be a higher EL */
9231c8df53SRichard Henderson return debug_el > cur_el;
9331c8df53SRichard Henderson }
9431c8df53SRichard Henderson
aa32_generate_debug_exceptions(CPUARMState * env)9531c8df53SRichard Henderson static bool aa32_generate_debug_exceptions(CPUARMState *env)
9631c8df53SRichard Henderson {
9731c8df53SRichard Henderson int el = arm_current_el(env);
9831c8df53SRichard Henderson
9931c8df53SRichard Henderson if (el == 0 && arm_el_is_aa64(env, 1)) {
10031c8df53SRichard Henderson return aa64_generate_debug_exceptions(env);
10131c8df53SRichard Henderson }
10231c8df53SRichard Henderson
10331c8df53SRichard Henderson if (arm_is_secure(env)) {
10431c8df53SRichard Henderson int spd;
10531c8df53SRichard Henderson
10631c8df53SRichard Henderson if (el == 0 && (env->cp15.sder & 1)) {
10731c8df53SRichard Henderson /*
10831c8df53SRichard Henderson * SDER.SUIDEN means debug exceptions from Secure EL0
10931c8df53SRichard Henderson * are always enabled. Otherwise they are controlled by
11031c8df53SRichard Henderson * SDCR.SPD like those from other Secure ELs.
11131c8df53SRichard Henderson */
11231c8df53SRichard Henderson return true;
11331c8df53SRichard Henderson }
11431c8df53SRichard Henderson
11531c8df53SRichard Henderson spd = extract32(env->cp15.mdcr_el3, 14, 2);
11631c8df53SRichard Henderson switch (spd) {
11731c8df53SRichard Henderson case 1:
11831c8df53SRichard Henderson /* SPD == 0b01 is reserved, but behaves as 0b00. */
11931c8df53SRichard Henderson case 0:
12031c8df53SRichard Henderson /*
12131c8df53SRichard Henderson * For 0b00 we return true if external secure invasive debug
12231c8df53SRichard Henderson * is enabled. On real hardware this is controlled by external
12331c8df53SRichard Henderson * signals to the core. QEMU always permits debug, and behaves
12431c8df53SRichard Henderson * as if DBGEN, SPIDEN, NIDEN and SPNIDEN are all tied high.
12531c8df53SRichard Henderson */
12631c8df53SRichard Henderson return true;
12731c8df53SRichard Henderson case 2:
12831c8df53SRichard Henderson return false;
12931c8df53SRichard Henderson case 3:
13031c8df53SRichard Henderson return true;
13131c8df53SRichard Henderson }
13231c8df53SRichard Henderson }
13331c8df53SRichard Henderson
13431c8df53SRichard Henderson return el != 2;
13531c8df53SRichard Henderson }
13631c8df53SRichard Henderson
13731c8df53SRichard Henderson /*
13831c8df53SRichard Henderson * Return true if debugging exceptions are currently enabled.
13931c8df53SRichard Henderson * This corresponds to what in ARM ARM pseudocode would be
14031c8df53SRichard Henderson * if UsingAArch32() then
14131c8df53SRichard Henderson * return AArch32.GenerateDebugExceptions()
14231c8df53SRichard Henderson * else
14331c8df53SRichard Henderson * return AArch64.GenerateDebugExceptions()
14431c8df53SRichard Henderson * We choose to push the if() down into this function for clarity,
14531c8df53SRichard Henderson * since the pseudocode has it at all callsites except for the one in
14631c8df53SRichard Henderson * CheckSoftwareStep(), where it is elided because both branches would
14731c8df53SRichard Henderson * always return the same value.
14831c8df53SRichard Henderson */
arm_generate_debug_exceptions(CPUARMState * env)14931c8df53SRichard Henderson bool arm_generate_debug_exceptions(CPUARMState *env)
15031c8df53SRichard Henderson {
151f94a6df5SPeter Maydell if ((env->cp15.oslsr_el1 & 1) || (env->cp15.osdlr_el1 & 1)) {
15240b20027SPeter Maydell return false;
15340b20027SPeter Maydell }
154831c1b10SRichard Henderson if (is_a64(env)) {
15531c8df53SRichard Henderson return aa64_generate_debug_exceptions(env);
15631c8df53SRichard Henderson } else {
15731c8df53SRichard Henderson return aa32_generate_debug_exceptions(env);
15831c8df53SRichard Henderson }
15931c8df53SRichard Henderson }
16031c8df53SRichard Henderson
16155ba15b7SRichard Henderson /*
16255ba15b7SRichard Henderson * Is single-stepping active? (Note that the "is EL_D AArch64?" check
16355ba15b7SRichard Henderson * implicitly means this always returns false in pre-v8 CPUs.)
16455ba15b7SRichard Henderson */
arm_singlestep_active(CPUARMState * env)16555ba15b7SRichard Henderson bool arm_singlestep_active(CPUARMState *env)
16655ba15b7SRichard Henderson {
16755ba15b7SRichard Henderson return extract32(env->cp15.mdscr_el1, 0, 1)
16855ba15b7SRichard Henderson && arm_el_is_aa64(env, arm_debug_target_el(env))
16955ba15b7SRichard Henderson && arm_generate_debug_exceptions(env);
17055ba15b7SRichard Henderson }
17155ba15b7SRichard Henderson
1729dd5cca4SPhilippe Mathieu-Daudé /* Return true if the linked breakpoint entry lbn passes its checks */
linked_bp_matches(ARMCPU * cpu,int lbn)1739dd5cca4SPhilippe Mathieu-Daudé static bool linked_bp_matches(ARMCPU *cpu, int lbn)
1749dd5cca4SPhilippe Mathieu-Daudé {
1759dd5cca4SPhilippe Mathieu-Daudé CPUARMState *env = &cpu->env;
1769dd5cca4SPhilippe Mathieu-Daudé uint64_t bcr = env->cp15.dbgbcr[lbn];
17788ce6c6eSPeter Maydell int brps = arm_num_brps(cpu);
17888ce6c6eSPeter Maydell int ctx_cmps = arm_num_ctx_cmps(cpu);
1799dd5cca4SPhilippe Mathieu-Daudé int bt;
1809dd5cca4SPhilippe Mathieu-Daudé uint32_t contextidr;
181e2a1a461SRichard Henderson uint64_t hcr_el2;
1829dd5cca4SPhilippe Mathieu-Daudé
1839dd5cca4SPhilippe Mathieu-Daudé /*
1849dd5cca4SPhilippe Mathieu-Daudé * Links to unimplemented or non-context aware breakpoints are
1859dd5cca4SPhilippe Mathieu-Daudé * CONSTRAINED UNPREDICTABLE: either behave as if disabled, or
1869dd5cca4SPhilippe Mathieu-Daudé * as if linked to an UNKNOWN context-aware breakpoint (in which
1879dd5cca4SPhilippe Mathieu-Daudé * case DBGWCR<n>_EL1.LBN must indicate that breakpoint).
1889dd5cca4SPhilippe Mathieu-Daudé * We choose the former.
1899dd5cca4SPhilippe Mathieu-Daudé */
19088ce6c6eSPeter Maydell if (lbn >= brps || lbn < (brps - ctx_cmps)) {
1919dd5cca4SPhilippe Mathieu-Daudé return false;
1929dd5cca4SPhilippe Mathieu-Daudé }
1939dd5cca4SPhilippe Mathieu-Daudé
1949dd5cca4SPhilippe Mathieu-Daudé bcr = env->cp15.dbgbcr[lbn];
1959dd5cca4SPhilippe Mathieu-Daudé
1969dd5cca4SPhilippe Mathieu-Daudé if (extract64(bcr, 0, 1) == 0) {
1979dd5cca4SPhilippe Mathieu-Daudé /* Linked breakpoint disabled : generate no events */
1989dd5cca4SPhilippe Mathieu-Daudé return false;
1999dd5cca4SPhilippe Mathieu-Daudé }
2009dd5cca4SPhilippe Mathieu-Daudé
2019dd5cca4SPhilippe Mathieu-Daudé bt = extract64(bcr, 20, 4);
202e2a1a461SRichard Henderson hcr_el2 = arm_hcr_el2_eff(env);
2039dd5cca4SPhilippe Mathieu-Daudé
2049dd5cca4SPhilippe Mathieu-Daudé switch (bt) {
2059dd5cca4SPhilippe Mathieu-Daudé case 3: /* linked context ID match */
206e2a1a461SRichard Henderson switch (arm_current_el(env)) {
207e2a1a461SRichard Henderson default:
208e2a1a461SRichard Henderson /* Context matches never fire in AArch64 EL3 */
209e2a1a461SRichard Henderson return false;
210e2a1a461SRichard Henderson case 2:
211e2a1a461SRichard Henderson if (!(hcr_el2 & HCR_E2H)) {
212e2a1a461SRichard Henderson /* Context matches never fire in EL2 without E2H enabled. */
2139dd5cca4SPhilippe Mathieu-Daudé return false;
2149dd5cca4SPhilippe Mathieu-Daudé }
215e2a1a461SRichard Henderson contextidr = env->cp15.contextidr_el[2];
216e2a1a461SRichard Henderson break;
217e2a1a461SRichard Henderson case 1:
218e2a1a461SRichard Henderson contextidr = env->cp15.contextidr_el[1];
219e2a1a461SRichard Henderson break;
220e2a1a461SRichard Henderson case 0:
221e2a1a461SRichard Henderson if ((hcr_el2 & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
222e2a1a461SRichard Henderson contextidr = env->cp15.contextidr_el[2];
223e2a1a461SRichard Henderson } else {
224e2a1a461SRichard Henderson contextidr = env->cp15.contextidr_el[1];
225e2a1a461SRichard Henderson }
226e2a1a461SRichard Henderson break;
227e2a1a461SRichard Henderson }
228e2a1a461SRichard Henderson break;
229e2a1a461SRichard Henderson
230e2a1a461SRichard Henderson case 7: /* linked contextidr_el1 match */
231e2a1a461SRichard Henderson contextidr = env->cp15.contextidr_el[1];
232e2a1a461SRichard Henderson break;
233e2a1a461SRichard Henderson case 13: /* linked contextidr_el2 match */
234e2a1a461SRichard Henderson contextidr = env->cp15.contextidr_el[2];
235e2a1a461SRichard Henderson break;
236e2a1a461SRichard Henderson
2379dd5cca4SPhilippe Mathieu-Daudé case 9: /* linked VMID match (reserved if no EL2) */
2389dd5cca4SPhilippe Mathieu-Daudé case 11: /* linked context ID and VMID match (reserved if no EL2) */
239e2a1a461SRichard Henderson case 15: /* linked full context ID match */
2409dd5cca4SPhilippe Mathieu-Daudé default:
2419dd5cca4SPhilippe Mathieu-Daudé /*
2429dd5cca4SPhilippe Mathieu-Daudé * Links to Unlinked context breakpoints must generate no
2439dd5cca4SPhilippe Mathieu-Daudé * events; we choose to do the same for reserved values too.
2449dd5cca4SPhilippe Mathieu-Daudé */
2459dd5cca4SPhilippe Mathieu-Daudé return false;
2469dd5cca4SPhilippe Mathieu-Daudé }
2479dd5cca4SPhilippe Mathieu-Daudé
248e2a1a461SRichard Henderson /*
249e2a1a461SRichard Henderson * We match the whole register even if this is AArch32 using the
250e2a1a461SRichard Henderson * short descriptor format (in which case it holds both PROCID and ASID),
251e2a1a461SRichard Henderson * since we don't implement the optional v7 context ID masking.
252e2a1a461SRichard Henderson */
253e2a1a461SRichard Henderson return contextidr == (uint32_t)env->cp15.dbgbvr[lbn];
2549dd5cca4SPhilippe Mathieu-Daudé }
2559dd5cca4SPhilippe Mathieu-Daudé
bp_wp_matches(ARMCPU * cpu,int n,bool is_wp)2569dd5cca4SPhilippe Mathieu-Daudé static bool bp_wp_matches(ARMCPU *cpu, int n, bool is_wp)
2579dd5cca4SPhilippe Mathieu-Daudé {
2589dd5cca4SPhilippe Mathieu-Daudé CPUARMState *env = &cpu->env;
2599dd5cca4SPhilippe Mathieu-Daudé uint64_t cr;
2609dd5cca4SPhilippe Mathieu-Daudé int pac, hmc, ssc, wt, lbn;
2619dd5cca4SPhilippe Mathieu-Daudé /*
2629dd5cca4SPhilippe Mathieu-Daudé * Note that for watchpoints the check is against the CPU security
2639dd5cca4SPhilippe Mathieu-Daudé * state, not the S/NS attribute on the offending data access.
2649dd5cca4SPhilippe Mathieu-Daudé */
2659dd5cca4SPhilippe Mathieu-Daudé bool is_secure = arm_is_secure(env);
2669dd5cca4SPhilippe Mathieu-Daudé int access_el = arm_current_el(env);
2679dd5cca4SPhilippe Mathieu-Daudé
2689dd5cca4SPhilippe Mathieu-Daudé if (is_wp) {
2699dd5cca4SPhilippe Mathieu-Daudé CPUWatchpoint *wp = env->cpu_watchpoint[n];
2709dd5cca4SPhilippe Mathieu-Daudé
2719dd5cca4SPhilippe Mathieu-Daudé if (!wp || !(wp->flags & BP_WATCHPOINT_HIT)) {
2729dd5cca4SPhilippe Mathieu-Daudé return false;
2739dd5cca4SPhilippe Mathieu-Daudé }
2749dd5cca4SPhilippe Mathieu-Daudé cr = env->cp15.dbgwcr[n];
2759dd5cca4SPhilippe Mathieu-Daudé if (wp->hitattrs.user) {
2769dd5cca4SPhilippe Mathieu-Daudé /*
2779dd5cca4SPhilippe Mathieu-Daudé * The LDRT/STRT/LDT/STT "unprivileged access" instructions should
2789dd5cca4SPhilippe Mathieu-Daudé * match watchpoints as if they were accesses done at EL0, even if
2799dd5cca4SPhilippe Mathieu-Daudé * the CPU is at EL1 or higher.
2809dd5cca4SPhilippe Mathieu-Daudé */
2819dd5cca4SPhilippe Mathieu-Daudé access_el = 0;
2829dd5cca4SPhilippe Mathieu-Daudé }
2839dd5cca4SPhilippe Mathieu-Daudé } else {
2849dd5cca4SPhilippe Mathieu-Daudé uint64_t pc = is_a64(env) ? env->pc : env->regs[15];
2859dd5cca4SPhilippe Mathieu-Daudé
2869dd5cca4SPhilippe Mathieu-Daudé if (!env->cpu_breakpoint[n] || env->cpu_breakpoint[n]->pc != pc) {
2879dd5cca4SPhilippe Mathieu-Daudé return false;
2889dd5cca4SPhilippe Mathieu-Daudé }
2899dd5cca4SPhilippe Mathieu-Daudé cr = env->cp15.dbgbcr[n];
2909dd5cca4SPhilippe Mathieu-Daudé }
2919dd5cca4SPhilippe Mathieu-Daudé /*
2929dd5cca4SPhilippe Mathieu-Daudé * The WATCHPOINT_HIT flag guarantees us that the watchpoint is
2939dd5cca4SPhilippe Mathieu-Daudé * enabled and that the address and access type match; for breakpoints
2949dd5cca4SPhilippe Mathieu-Daudé * we know the address matched; check the remaining fields, including
2959dd5cca4SPhilippe Mathieu-Daudé * linked breakpoints. We rely on WCR and BCR having the same layout
2969dd5cca4SPhilippe Mathieu-Daudé * for the LBN, SSC, HMC, PAC/PMC and is-linked fields.
2979dd5cca4SPhilippe Mathieu-Daudé * Note that some combinations of {PAC, HMC, SSC} are reserved and
2989dd5cca4SPhilippe Mathieu-Daudé * must act either like some valid combination or as if the watchpoint
2999dd5cca4SPhilippe Mathieu-Daudé * were disabled. We choose the former, and use this together with
3009dd5cca4SPhilippe Mathieu-Daudé * the fact that EL3 must always be Secure and EL2 must always be
3019dd5cca4SPhilippe Mathieu-Daudé * Non-Secure to simplify the code slightly compared to the full
3029dd5cca4SPhilippe Mathieu-Daudé * table in the ARM ARM.
3039dd5cca4SPhilippe Mathieu-Daudé */
3048b7a5bbeSRichard Henderson pac = FIELD_EX64(cr, DBGWCR, PAC);
3058b7a5bbeSRichard Henderson hmc = FIELD_EX64(cr, DBGWCR, HMC);
3068b7a5bbeSRichard Henderson ssc = FIELD_EX64(cr, DBGWCR, SSC);
3079dd5cca4SPhilippe Mathieu-Daudé
3089dd5cca4SPhilippe Mathieu-Daudé switch (ssc) {
3099dd5cca4SPhilippe Mathieu-Daudé case 0:
3109dd5cca4SPhilippe Mathieu-Daudé break;
3119dd5cca4SPhilippe Mathieu-Daudé case 1:
3129dd5cca4SPhilippe Mathieu-Daudé case 3:
3139dd5cca4SPhilippe Mathieu-Daudé if (is_secure) {
3149dd5cca4SPhilippe Mathieu-Daudé return false;
3159dd5cca4SPhilippe Mathieu-Daudé }
3169dd5cca4SPhilippe Mathieu-Daudé break;
3179dd5cca4SPhilippe Mathieu-Daudé case 2:
3189dd5cca4SPhilippe Mathieu-Daudé if (!is_secure) {
3199dd5cca4SPhilippe Mathieu-Daudé return false;
3209dd5cca4SPhilippe Mathieu-Daudé }
3219dd5cca4SPhilippe Mathieu-Daudé break;
3229dd5cca4SPhilippe Mathieu-Daudé }
3239dd5cca4SPhilippe Mathieu-Daudé
3249dd5cca4SPhilippe Mathieu-Daudé switch (access_el) {
3259dd5cca4SPhilippe Mathieu-Daudé case 3:
3269dd5cca4SPhilippe Mathieu-Daudé case 2:
3279dd5cca4SPhilippe Mathieu-Daudé if (!hmc) {
3289dd5cca4SPhilippe Mathieu-Daudé return false;
3299dd5cca4SPhilippe Mathieu-Daudé }
3309dd5cca4SPhilippe Mathieu-Daudé break;
3319dd5cca4SPhilippe Mathieu-Daudé case 1:
3329dd5cca4SPhilippe Mathieu-Daudé if (extract32(pac, 0, 1) == 0) {
3339dd5cca4SPhilippe Mathieu-Daudé return false;
3349dd5cca4SPhilippe Mathieu-Daudé }
3359dd5cca4SPhilippe Mathieu-Daudé break;
3369dd5cca4SPhilippe Mathieu-Daudé case 0:
3379dd5cca4SPhilippe Mathieu-Daudé if (extract32(pac, 1, 1) == 0) {
3389dd5cca4SPhilippe Mathieu-Daudé return false;
3399dd5cca4SPhilippe Mathieu-Daudé }
3409dd5cca4SPhilippe Mathieu-Daudé break;
3419dd5cca4SPhilippe Mathieu-Daudé default:
3429dd5cca4SPhilippe Mathieu-Daudé g_assert_not_reached();
3439dd5cca4SPhilippe Mathieu-Daudé }
3449dd5cca4SPhilippe Mathieu-Daudé
3458b7a5bbeSRichard Henderson wt = FIELD_EX64(cr, DBGWCR, WT);
3468b7a5bbeSRichard Henderson lbn = FIELD_EX64(cr, DBGWCR, LBN);
3479dd5cca4SPhilippe Mathieu-Daudé
3489dd5cca4SPhilippe Mathieu-Daudé if (wt && !linked_bp_matches(cpu, lbn)) {
3499dd5cca4SPhilippe Mathieu-Daudé return false;
3509dd5cca4SPhilippe Mathieu-Daudé }
3519dd5cca4SPhilippe Mathieu-Daudé
3529dd5cca4SPhilippe Mathieu-Daudé return true;
3539dd5cca4SPhilippe Mathieu-Daudé }
3549dd5cca4SPhilippe Mathieu-Daudé
check_watchpoints(ARMCPU * cpu)3559dd5cca4SPhilippe Mathieu-Daudé static bool check_watchpoints(ARMCPU *cpu)
3569dd5cca4SPhilippe Mathieu-Daudé {
3579dd5cca4SPhilippe Mathieu-Daudé CPUARMState *env = &cpu->env;
3589dd5cca4SPhilippe Mathieu-Daudé int n;
3599dd5cca4SPhilippe Mathieu-Daudé
3609dd5cca4SPhilippe Mathieu-Daudé /*
3619dd5cca4SPhilippe Mathieu-Daudé * If watchpoints are disabled globally or we can't take debug
3629dd5cca4SPhilippe Mathieu-Daudé * exceptions here then watchpoint firings are ignored.
3639dd5cca4SPhilippe Mathieu-Daudé */
3649dd5cca4SPhilippe Mathieu-Daudé if (extract32(env->cp15.mdscr_el1, 15, 1) == 0
3659dd5cca4SPhilippe Mathieu-Daudé || !arm_generate_debug_exceptions(env)) {
3669dd5cca4SPhilippe Mathieu-Daudé return false;
3679dd5cca4SPhilippe Mathieu-Daudé }
3689dd5cca4SPhilippe Mathieu-Daudé
3699dd5cca4SPhilippe Mathieu-Daudé for (n = 0; n < ARRAY_SIZE(env->cpu_watchpoint); n++) {
3709dd5cca4SPhilippe Mathieu-Daudé if (bp_wp_matches(cpu, n, true)) {
3719dd5cca4SPhilippe Mathieu-Daudé return true;
3729dd5cca4SPhilippe Mathieu-Daudé }
3739dd5cca4SPhilippe Mathieu-Daudé }
3749dd5cca4SPhilippe Mathieu-Daudé return false;
3759dd5cca4SPhilippe Mathieu-Daudé }
3769dd5cca4SPhilippe Mathieu-Daudé
arm_debug_check_breakpoint(CPUState * cs)377b00d86bcSRichard Henderson bool arm_debug_check_breakpoint(CPUState *cs)
3789dd5cca4SPhilippe Mathieu-Daudé {
379b00d86bcSRichard Henderson ARMCPU *cpu = ARM_CPU(cs);
3809dd5cca4SPhilippe Mathieu-Daudé CPUARMState *env = &cpu->env;
3818dc89f1fSRichard Henderson target_ulong pc;
3829dd5cca4SPhilippe Mathieu-Daudé int n;
3839dd5cca4SPhilippe Mathieu-Daudé
3849dd5cca4SPhilippe Mathieu-Daudé /*
3859dd5cca4SPhilippe Mathieu-Daudé * If breakpoints are disabled globally or we can't take debug
3869dd5cca4SPhilippe Mathieu-Daudé * exceptions here then breakpoint firings are ignored.
3879dd5cca4SPhilippe Mathieu-Daudé */
3889dd5cca4SPhilippe Mathieu-Daudé if (extract32(env->cp15.mdscr_el1, 15, 1) == 0
3899dd5cca4SPhilippe Mathieu-Daudé || !arm_generate_debug_exceptions(env)) {
3909dd5cca4SPhilippe Mathieu-Daudé return false;
3919dd5cca4SPhilippe Mathieu-Daudé }
3929dd5cca4SPhilippe Mathieu-Daudé
3938dc89f1fSRichard Henderson /*
3948dc89f1fSRichard Henderson * Single-step exceptions have priority over breakpoint exceptions.
3958dc89f1fSRichard Henderson * If single-step state is active-pending, suppress the bp.
3968dc89f1fSRichard Henderson */
3978dc89f1fSRichard Henderson if (arm_singlestep_active(env) && !(env->pstate & PSTATE_SS)) {
3988dc89f1fSRichard Henderson return false;
3998dc89f1fSRichard Henderson }
4008dc89f1fSRichard Henderson
4018dc89f1fSRichard Henderson /*
4028dc89f1fSRichard Henderson * PC alignment faults have priority over breakpoint exceptions.
4038dc89f1fSRichard Henderson */
4048dc89f1fSRichard Henderson pc = is_a64(env) ? env->pc : env->regs[15];
4058dc89f1fSRichard Henderson if ((is_a64(env) || !env->thumb) && (pc & 3) != 0) {
4068dc89f1fSRichard Henderson return false;
4078dc89f1fSRichard Henderson }
4088dc89f1fSRichard Henderson
4098dc89f1fSRichard Henderson /*
4108dc89f1fSRichard Henderson * Instruction aborts have priority over breakpoint exceptions.
4118dc89f1fSRichard Henderson * TODO: We would need to look up the page for PC and verify that
4128dc89f1fSRichard Henderson * it is present and executable.
4138dc89f1fSRichard Henderson */
4148dc89f1fSRichard Henderson
4159dd5cca4SPhilippe Mathieu-Daudé for (n = 0; n < ARRAY_SIZE(env->cpu_breakpoint); n++) {
4169dd5cca4SPhilippe Mathieu-Daudé if (bp_wp_matches(cpu, n, false)) {
4179dd5cca4SPhilippe Mathieu-Daudé return true;
4189dd5cca4SPhilippe Mathieu-Daudé }
4199dd5cca4SPhilippe Mathieu-Daudé }
4209dd5cca4SPhilippe Mathieu-Daudé return false;
4219dd5cca4SPhilippe Mathieu-Daudé }
4229dd5cca4SPhilippe Mathieu-Daudé
arm_debug_check_watchpoint(CPUState * cs,CPUWatchpoint * wp)4239dd5cca4SPhilippe Mathieu-Daudé bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
4249dd5cca4SPhilippe Mathieu-Daudé {
4259dd5cca4SPhilippe Mathieu-Daudé /*
4269dd5cca4SPhilippe Mathieu-Daudé * Called by core code when a CPU watchpoint fires; need to check if this
4279dd5cca4SPhilippe Mathieu-Daudé * is also an architectural watchpoint match.
4289dd5cca4SPhilippe Mathieu-Daudé */
4299dd5cca4SPhilippe Mathieu-Daudé ARMCPU *cpu = ARM_CPU(cs);
4309dd5cca4SPhilippe Mathieu-Daudé
4319dd5cca4SPhilippe Mathieu-Daudé return check_watchpoints(cpu);
4329dd5cca4SPhilippe Mathieu-Daudé }
4339dd5cca4SPhilippe Mathieu-Daudé
434a853e3aeSRichard Henderson /*
435a853e3aeSRichard Henderson * Return the FSR value for a debug exception (watchpoint, hardware
436a853e3aeSRichard Henderson * breakpoint or BKPT insn) targeting the specified exception level.
437a853e3aeSRichard Henderson */
arm_debug_exception_fsr(CPUARMState * env)438a853e3aeSRichard Henderson static uint32_t arm_debug_exception_fsr(CPUARMState *env)
439a853e3aeSRichard Henderson {
440a853e3aeSRichard Henderson ARMMMUFaultInfo fi = { .type = ARMFault_Debug };
441a853e3aeSRichard Henderson int target_el = arm_debug_target_el(env);
4425d78893fSPeter Maydell bool using_lpae;
443a853e3aeSRichard Henderson
4445d78893fSPeter Maydell if (arm_feature(env, ARM_FEATURE_M)) {
4455d78893fSPeter Maydell using_lpae = false;
4465d78893fSPeter Maydell } else if (target_el == 2 || arm_el_is_aa64(env, target_el)) {
447a853e3aeSRichard Henderson using_lpae = true;
448452c67a4STobias Röhmel } else if (arm_feature(env, ARM_FEATURE_PMSA) &&
449452c67a4STobias Röhmel arm_feature(env, ARM_FEATURE_V8)) {
450452c67a4STobias Röhmel using_lpae = true;
4515d78893fSPeter Maydell } else if (arm_feature(env, ARM_FEATURE_LPAE) &&
452cb4a0a34SPeter Maydell (env->cp15.tcr_el[target_el] & TTBCR_EAE)) {
453a853e3aeSRichard Henderson using_lpae = true;
4545d78893fSPeter Maydell } else {
4555d78893fSPeter Maydell using_lpae = false;
456a853e3aeSRichard Henderson }
457a853e3aeSRichard Henderson
458a853e3aeSRichard Henderson if (using_lpae) {
459a853e3aeSRichard Henderson return arm_fi_to_lfsc(&fi);
460a853e3aeSRichard Henderson } else {
461a853e3aeSRichard Henderson return arm_fi_to_sfsc(&fi);
462a853e3aeSRichard Henderson }
463a853e3aeSRichard Henderson }
464a853e3aeSRichard Henderson
arm_debug_excp_handler(CPUState * cs)4659dd5cca4SPhilippe Mathieu-Daudé void arm_debug_excp_handler(CPUState *cs)
4669dd5cca4SPhilippe Mathieu-Daudé {
4679dd5cca4SPhilippe Mathieu-Daudé /*
4689dd5cca4SPhilippe Mathieu-Daudé * Called by core code when a watchpoint or breakpoint fires;
4699dd5cca4SPhilippe Mathieu-Daudé * need to check which one and raise the appropriate exception.
4709dd5cca4SPhilippe Mathieu-Daudé */
4719dd5cca4SPhilippe Mathieu-Daudé ARMCPU *cpu = ARM_CPU(cs);
4729dd5cca4SPhilippe Mathieu-Daudé CPUARMState *env = &cpu->env;
4739dd5cca4SPhilippe Mathieu-Daudé CPUWatchpoint *wp_hit = cs->watchpoint_hit;
4749dd5cca4SPhilippe Mathieu-Daudé
4759dd5cca4SPhilippe Mathieu-Daudé if (wp_hit) {
4769dd5cca4SPhilippe Mathieu-Daudé if (wp_hit->flags & BP_CPU) {
4779dd5cca4SPhilippe Mathieu-Daudé bool wnr = (wp_hit->flags & BP_WATCHPOINT_HIT_WRITE) != 0;
4789dd5cca4SPhilippe Mathieu-Daudé
4799dd5cca4SPhilippe Mathieu-Daudé cs->watchpoint_hit = NULL;
4809dd5cca4SPhilippe Mathieu-Daudé
4819dd5cca4SPhilippe Mathieu-Daudé env->exception.fsr = arm_debug_exception_fsr(env);
4829dd5cca4SPhilippe Mathieu-Daudé env->exception.vaddress = wp_hit->hitaddr;
48304eacf6eSRichard Henderson raise_exception_debug(env, EXCP_DATA_ABORT,
48404eacf6eSRichard Henderson syn_watchpoint(0, 0, wnr));
4859dd5cca4SPhilippe Mathieu-Daudé }
4869dd5cca4SPhilippe Mathieu-Daudé } else {
4879dd5cca4SPhilippe Mathieu-Daudé uint64_t pc = is_a64(env) ? env->pc : env->regs[15];
4889dd5cca4SPhilippe Mathieu-Daudé
4899dd5cca4SPhilippe Mathieu-Daudé /*
4909dd5cca4SPhilippe Mathieu-Daudé * (1) GDB breakpoints should be handled first.
4919dd5cca4SPhilippe Mathieu-Daudé * (2) Do not raise a CPU exception if no CPU breakpoint has fired,
4929dd5cca4SPhilippe Mathieu-Daudé * since singlestep is also done by generating a debug internal
4939dd5cca4SPhilippe Mathieu-Daudé * exception.
4949dd5cca4SPhilippe Mathieu-Daudé */
4959dd5cca4SPhilippe Mathieu-Daudé if (cpu_breakpoint_test(cs, pc, BP_GDB)
4969dd5cca4SPhilippe Mathieu-Daudé || !cpu_breakpoint_test(cs, pc, BP_CPU)) {
4979dd5cca4SPhilippe Mathieu-Daudé return;
4989dd5cca4SPhilippe Mathieu-Daudé }
4999dd5cca4SPhilippe Mathieu-Daudé
5009dd5cca4SPhilippe Mathieu-Daudé env->exception.fsr = arm_debug_exception_fsr(env);
5019dd5cca4SPhilippe Mathieu-Daudé /*
5029dd5cca4SPhilippe Mathieu-Daudé * FAR is UNKNOWN: clear vaddress to avoid potentially exposing
5039dd5cca4SPhilippe Mathieu-Daudé * values to the guest that it shouldn't be able to see at its
5049dd5cca4SPhilippe Mathieu-Daudé * exception/security level.
5059dd5cca4SPhilippe Mathieu-Daudé */
5069dd5cca4SPhilippe Mathieu-Daudé env->exception.vaddress = 0;
50704eacf6eSRichard Henderson raise_exception_debug(env, EXCP_PREFETCH_ABORT, syn_breakpoint(0));
5089dd5cca4SPhilippe Mathieu-Daudé }
5099dd5cca4SPhilippe Mathieu-Daudé }
5109dd5cca4SPhilippe Mathieu-Daudé
51116f9d5f6SRichard Henderson /*
51216f9d5f6SRichard Henderson * Raise an EXCP_BKPT with the specified syndrome register value,
51316f9d5f6SRichard Henderson * targeting the correct exception level for debug exceptions.
51416f9d5f6SRichard Henderson */
HELPER(exception_bkpt_insn)51516f9d5f6SRichard Henderson void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome)
51616f9d5f6SRichard Henderson {
51716f9d5f6SRichard Henderson int debug_el = arm_debug_target_el(env);
51816f9d5f6SRichard Henderson int cur_el = arm_current_el(env);
51916f9d5f6SRichard Henderson
52016f9d5f6SRichard Henderson /* FSR will only be used if the debug target EL is AArch32. */
52116f9d5f6SRichard Henderson env->exception.fsr = arm_debug_exception_fsr(env);
52216f9d5f6SRichard Henderson /*
52316f9d5f6SRichard Henderson * FAR is UNKNOWN: clear vaddress to avoid potentially exposing
52416f9d5f6SRichard Henderson * values to the guest that it shouldn't be able to see at its
52516f9d5f6SRichard Henderson * exception/security level.
52616f9d5f6SRichard Henderson */
52716f9d5f6SRichard Henderson env->exception.vaddress = 0;
52816f9d5f6SRichard Henderson /*
52916f9d5f6SRichard Henderson * Other kinds of architectural debug exception are ignored if
53016f9d5f6SRichard Henderson * they target an exception level below the current one (in QEMU
53116f9d5f6SRichard Henderson * this is checked by arm_generate_debug_exceptions()). Breakpoint
53216f9d5f6SRichard Henderson * instructions are special because they always generate an exception
53316f9d5f6SRichard Henderson * to somewhere: if they can't go to the configured debug exception
53416f9d5f6SRichard Henderson * level they are taken to the current exception level.
53516f9d5f6SRichard Henderson */
53616f9d5f6SRichard Henderson if (debug_el < cur_el) {
53716f9d5f6SRichard Henderson debug_el = cur_el;
53816f9d5f6SRichard Henderson }
53916f9d5f6SRichard Henderson raise_exception(env, EXCP_BKPT, syndrome, debug_el);
54016f9d5f6SRichard Henderson }
54116f9d5f6SRichard Henderson
HELPER(exception_swstep)542f0d7c205SRichard Henderson void HELPER(exception_swstep)(CPUARMState *env, uint32_t syndrome)
543f0d7c205SRichard Henderson {
54404eacf6eSRichard Henderson raise_exception_debug(env, EXCP_UDEF, syndrome);
545f0d7c205SRichard Henderson }
546f0d7c205SRichard Henderson
hw_watchpoint_update(ARMCPU * cpu,int n)5472059ec75SFabiano Rosas void hw_watchpoint_update(ARMCPU *cpu, int n)
5482059ec75SFabiano Rosas {
5492059ec75SFabiano Rosas CPUARMState *env = &cpu->env;
5502059ec75SFabiano Rosas vaddr len = 0;
5512059ec75SFabiano Rosas vaddr wvr = env->cp15.dbgwvr[n];
5522059ec75SFabiano Rosas uint64_t wcr = env->cp15.dbgwcr[n];
5532059ec75SFabiano Rosas int mask;
5542059ec75SFabiano Rosas int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
5552059ec75SFabiano Rosas
5562059ec75SFabiano Rosas if (env->cpu_watchpoint[n]) {
5572059ec75SFabiano Rosas cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]);
5582059ec75SFabiano Rosas env->cpu_watchpoint[n] = NULL;
5592059ec75SFabiano Rosas }
5602059ec75SFabiano Rosas
5612059ec75SFabiano Rosas if (!FIELD_EX64(wcr, DBGWCR, E)) {
5622059ec75SFabiano Rosas /* E bit clear : watchpoint disabled */
5632059ec75SFabiano Rosas return;
5642059ec75SFabiano Rosas }
5652059ec75SFabiano Rosas
5662059ec75SFabiano Rosas switch (FIELD_EX64(wcr, DBGWCR, LSC)) {
5672059ec75SFabiano Rosas case 0:
5682059ec75SFabiano Rosas /* LSC 00 is reserved and must behave as if the wp is disabled */
5692059ec75SFabiano Rosas return;
5702059ec75SFabiano Rosas case 1:
5712059ec75SFabiano Rosas flags |= BP_MEM_READ;
5722059ec75SFabiano Rosas break;
5732059ec75SFabiano Rosas case 2:
5742059ec75SFabiano Rosas flags |= BP_MEM_WRITE;
5752059ec75SFabiano Rosas break;
5762059ec75SFabiano Rosas case 3:
5772059ec75SFabiano Rosas flags |= BP_MEM_ACCESS;
5782059ec75SFabiano Rosas break;
5792059ec75SFabiano Rosas }
5802059ec75SFabiano Rosas
5812059ec75SFabiano Rosas /*
5822059ec75SFabiano Rosas * Attempts to use both MASK and BAS fields simultaneously are
5832059ec75SFabiano Rosas * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case,
5842059ec75SFabiano Rosas * thus generating a watchpoint for every byte in the masked region.
5852059ec75SFabiano Rosas */
5862059ec75SFabiano Rosas mask = FIELD_EX64(wcr, DBGWCR, MASK);
5872059ec75SFabiano Rosas if (mask == 1 || mask == 2) {
5882059ec75SFabiano Rosas /*
5892059ec75SFabiano Rosas * Reserved values of MASK; we must act as if the mask value was
5902059ec75SFabiano Rosas * some non-reserved value, or as if the watchpoint were disabled.
5912059ec75SFabiano Rosas * We choose the latter.
5922059ec75SFabiano Rosas */
5932059ec75SFabiano Rosas return;
5942059ec75SFabiano Rosas } else if (mask) {
5952059ec75SFabiano Rosas /* Watchpoint covers an aligned area up to 2GB in size */
5962059ec75SFabiano Rosas len = 1ULL << mask;
5972059ec75SFabiano Rosas /*
5982059ec75SFabiano Rosas * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE
5992059ec75SFabiano Rosas * whether the watchpoint fires when the unmasked bits match; we opt
6002059ec75SFabiano Rosas * to generate the exceptions.
6012059ec75SFabiano Rosas */
6022059ec75SFabiano Rosas wvr &= ~(len - 1);
6032059ec75SFabiano Rosas } else {
6042059ec75SFabiano Rosas /* Watchpoint covers bytes defined by the byte address select bits */
6052059ec75SFabiano Rosas int bas = FIELD_EX64(wcr, DBGWCR, BAS);
6062059ec75SFabiano Rosas int basstart;
6072059ec75SFabiano Rosas
6082059ec75SFabiano Rosas if (extract64(wvr, 2, 1)) {
6092059ec75SFabiano Rosas /*
6102059ec75SFabiano Rosas * Deprecated case of an only 4-aligned address. BAS[7:4] are
6112059ec75SFabiano Rosas * ignored, and BAS[3:0] define which bytes to watch.
6122059ec75SFabiano Rosas */
6132059ec75SFabiano Rosas bas &= 0xf;
6142059ec75SFabiano Rosas }
6152059ec75SFabiano Rosas
6162059ec75SFabiano Rosas if (bas == 0) {
6172059ec75SFabiano Rosas /* This must act as if the watchpoint is disabled */
6182059ec75SFabiano Rosas return;
6192059ec75SFabiano Rosas }
6202059ec75SFabiano Rosas
6212059ec75SFabiano Rosas /*
6222059ec75SFabiano Rosas * The BAS bits are supposed to be programmed to indicate a contiguous
6232059ec75SFabiano Rosas * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether
6242059ec75SFabiano Rosas * we fire for each byte in the word/doubleword addressed by the WVR.
6252059ec75SFabiano Rosas * We choose to ignore any non-zero bits after the first range of 1s.
6262059ec75SFabiano Rosas */
6272059ec75SFabiano Rosas basstart = ctz32(bas);
6282059ec75SFabiano Rosas len = cto32(bas >> basstart);
6292059ec75SFabiano Rosas wvr += basstart;
6302059ec75SFabiano Rosas }
6312059ec75SFabiano Rosas
6322059ec75SFabiano Rosas cpu_watchpoint_insert(CPU(cpu), wvr, len, flags,
6332059ec75SFabiano Rosas &env->cpu_watchpoint[n]);
6342059ec75SFabiano Rosas }
6352059ec75SFabiano Rosas
hw_watchpoint_update_all(ARMCPU * cpu)6362059ec75SFabiano Rosas void hw_watchpoint_update_all(ARMCPU *cpu)
6372059ec75SFabiano Rosas {
6382059ec75SFabiano Rosas int i;
6392059ec75SFabiano Rosas CPUARMState *env = &cpu->env;
6402059ec75SFabiano Rosas
6412059ec75SFabiano Rosas /*
6422059ec75SFabiano Rosas * Completely clear out existing QEMU watchpoints and our array, to
6432059ec75SFabiano Rosas * avoid possible stale entries following migration load.
6442059ec75SFabiano Rosas */
6452059ec75SFabiano Rosas cpu_watchpoint_remove_all(CPU(cpu), BP_CPU);
6462059ec75SFabiano Rosas memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint));
6472059ec75SFabiano Rosas
6482059ec75SFabiano Rosas for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) {
6492059ec75SFabiano Rosas hw_watchpoint_update(cpu, i);
6502059ec75SFabiano Rosas }
6512059ec75SFabiano Rosas }
6522059ec75SFabiano Rosas
hw_breakpoint_update(ARMCPU * cpu,int n)6532059ec75SFabiano Rosas void hw_breakpoint_update(ARMCPU *cpu, int n)
6542059ec75SFabiano Rosas {
6552059ec75SFabiano Rosas CPUARMState *env = &cpu->env;
6562059ec75SFabiano Rosas uint64_t bvr = env->cp15.dbgbvr[n];
6572059ec75SFabiano Rosas uint64_t bcr = env->cp15.dbgbcr[n];
6582059ec75SFabiano Rosas vaddr addr;
6592059ec75SFabiano Rosas int bt;
6602059ec75SFabiano Rosas int flags = BP_CPU;
6612059ec75SFabiano Rosas
6622059ec75SFabiano Rosas if (env->cpu_breakpoint[n]) {
6632059ec75SFabiano Rosas cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]);
6642059ec75SFabiano Rosas env->cpu_breakpoint[n] = NULL;
6652059ec75SFabiano Rosas }
6662059ec75SFabiano Rosas
6672059ec75SFabiano Rosas if (!extract64(bcr, 0, 1)) {
6682059ec75SFabiano Rosas /* E bit clear : watchpoint disabled */
6692059ec75SFabiano Rosas return;
6702059ec75SFabiano Rosas }
6712059ec75SFabiano Rosas
6722059ec75SFabiano Rosas bt = extract64(bcr, 20, 4);
6732059ec75SFabiano Rosas
6742059ec75SFabiano Rosas switch (bt) {
6752059ec75SFabiano Rosas case 4: /* unlinked address mismatch (reserved if AArch64) */
6762059ec75SFabiano Rosas case 5: /* linked address mismatch (reserved if AArch64) */
6772059ec75SFabiano Rosas qemu_log_mask(LOG_UNIMP,
6782059ec75SFabiano Rosas "arm: address mismatch breakpoint types not implemented\n");
6792059ec75SFabiano Rosas return;
6802059ec75SFabiano Rosas case 0: /* unlinked address match */
6812059ec75SFabiano Rosas case 1: /* linked address match */
6822059ec75SFabiano Rosas {
6832059ec75SFabiano Rosas /*
6842059ec75SFabiano Rosas * Bits [1:0] are RES0.
6852059ec75SFabiano Rosas *
6862059ec75SFabiano Rosas * It is IMPLEMENTATION DEFINED whether bits [63:49]
6872059ec75SFabiano Rosas * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit
6882059ec75SFabiano Rosas * of the VA field ([48] or [52] for FEAT_LVA), or whether the
6892059ec75SFabiano Rosas * value is read as written. It is CONSTRAINED UNPREDICTABLE
6902059ec75SFabiano Rosas * whether the RESS bits are ignored when comparing an address.
6912059ec75SFabiano Rosas * Therefore we are allowed to compare the entire register, which
6922059ec75SFabiano Rosas * lets us avoid considering whether FEAT_LVA is actually enabled.
6932059ec75SFabiano Rosas *
6942059ec75SFabiano Rosas * The BAS field is used to allow setting breakpoints on 16-bit
6952059ec75SFabiano Rosas * wide instructions; it is CONSTRAINED UNPREDICTABLE whether
6962059ec75SFabiano Rosas * a bp will fire if the addresses covered by the bp and the addresses
6972059ec75SFabiano Rosas * covered by the insn overlap but the insn doesn't start at the
6982059ec75SFabiano Rosas * start of the bp address range. We choose to require the insn and
6992059ec75SFabiano Rosas * the bp to have the same address. The constraints on writing to
7002059ec75SFabiano Rosas * BAS enforced in dbgbcr_write mean we have only four cases:
7012059ec75SFabiano Rosas * 0b0000 => no breakpoint
7022059ec75SFabiano Rosas * 0b0011 => breakpoint on addr
7032059ec75SFabiano Rosas * 0b1100 => breakpoint on addr + 2
7042059ec75SFabiano Rosas * 0b1111 => breakpoint on addr
7052059ec75SFabiano Rosas * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c).
7062059ec75SFabiano Rosas */
7072059ec75SFabiano Rosas int bas = extract64(bcr, 5, 4);
7082059ec75SFabiano Rosas addr = bvr & ~3ULL;
7092059ec75SFabiano Rosas if (bas == 0) {
7102059ec75SFabiano Rosas return;
7112059ec75SFabiano Rosas }
7122059ec75SFabiano Rosas if (bas == 0xc) {
7132059ec75SFabiano Rosas addr += 2;
7142059ec75SFabiano Rosas }
7152059ec75SFabiano Rosas break;
7162059ec75SFabiano Rosas }
7172059ec75SFabiano Rosas case 2: /* unlinked context ID match */
7182059ec75SFabiano Rosas case 8: /* unlinked VMID match (reserved if no EL2) */
7192059ec75SFabiano Rosas case 10: /* unlinked context ID and VMID match (reserved if no EL2) */
7202059ec75SFabiano Rosas qemu_log_mask(LOG_UNIMP,
7212059ec75SFabiano Rosas "arm: unlinked context breakpoint types not implemented\n");
7222059ec75SFabiano Rosas return;
7232059ec75SFabiano Rosas case 9: /* linked VMID match (reserved if no EL2) */
7242059ec75SFabiano Rosas case 11: /* linked context ID and VMID match (reserved if no EL2) */
7252059ec75SFabiano Rosas case 3: /* linked context ID match */
7262059ec75SFabiano Rosas default:
7272059ec75SFabiano Rosas /*
7282059ec75SFabiano Rosas * We must generate no events for Linked context matches (unless
7292059ec75SFabiano Rosas * they are linked to by some other bp/wp, which is handled in
7302059ec75SFabiano Rosas * updates for the linking bp/wp). We choose to also generate no events
7312059ec75SFabiano Rosas * for reserved values.
7322059ec75SFabiano Rosas */
7332059ec75SFabiano Rosas return;
7342059ec75SFabiano Rosas }
7352059ec75SFabiano Rosas
7362059ec75SFabiano Rosas cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]);
7372059ec75SFabiano Rosas }
7382059ec75SFabiano Rosas
hw_breakpoint_update_all(ARMCPU * cpu)7392059ec75SFabiano Rosas void hw_breakpoint_update_all(ARMCPU *cpu)
7402059ec75SFabiano Rosas {
7412059ec75SFabiano Rosas int i;
7422059ec75SFabiano Rosas CPUARMState *env = &cpu->env;
7432059ec75SFabiano Rosas
7442059ec75SFabiano Rosas /*
7452059ec75SFabiano Rosas * Completely clear out existing QEMU breakpoints and our array, to
7462059ec75SFabiano Rosas * avoid possible stale entries following migration load.
7472059ec75SFabiano Rosas */
7482059ec75SFabiano Rosas cpu_breakpoint_remove_all(CPU(cpu), BP_CPU);
7492059ec75SFabiano Rosas memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint));
7502059ec75SFabiano Rosas
7512059ec75SFabiano Rosas for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) {
7522059ec75SFabiano Rosas hw_breakpoint_update(cpu, i);
7532059ec75SFabiano Rosas }
7542059ec75SFabiano Rosas }
7552059ec75SFabiano Rosas
7562059ec75SFabiano Rosas #if !defined(CONFIG_USER_ONLY)
7572059ec75SFabiano Rosas
arm_adjust_watchpoint_address(CPUState * cs,vaddr addr,int len)7582059ec75SFabiano Rosas vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len)
7592059ec75SFabiano Rosas {
7602059ec75SFabiano Rosas ARMCPU *cpu = ARM_CPU(cs);
7612059ec75SFabiano Rosas CPUARMState *env = &cpu->env;
7622059ec75SFabiano Rosas
7632059ec75SFabiano Rosas /*
7642059ec75SFabiano Rosas * In BE32 system mode, target memory is stored byteswapped (on a
7652059ec75SFabiano Rosas * little-endian host system), and by the time we reach here (via an
7662059ec75SFabiano Rosas * opcode helper) the addresses of subword accesses have been adjusted
7672059ec75SFabiano Rosas * to account for that, which means that watchpoints will not match.
7682059ec75SFabiano Rosas * Undo the adjustment here.
7692059ec75SFabiano Rosas */
7702059ec75SFabiano Rosas if (arm_sctlr_b(env)) {
7712059ec75SFabiano Rosas if (len == 1) {
7722059ec75SFabiano Rosas addr ^= 3;
7732059ec75SFabiano Rosas } else if (len == 2) {
7742059ec75SFabiano Rosas addr ^= 2;
7752059ec75SFabiano Rosas }
7762059ec75SFabiano Rosas }
7772059ec75SFabiano Rosas
7782059ec75SFabiano Rosas return addr;
7792059ec75SFabiano Rosas }
7802059ec75SFabiano Rosas
7812059ec75SFabiano Rosas #endif /* !CONFIG_USER_ONLY */
7822059ec75SFabiano Rosas #endif /* CONFIG_TCG */
7832059ec75SFabiano Rosas
784f43ee493SPeter Maydell /*
785f43ee493SPeter Maydell * Check for traps to "powerdown debug" registers, which are controlled
786f43ee493SPeter Maydell * by MDCR.TDOSA
787f43ee493SPeter Maydell */
access_tdosa(CPUARMState * env,const ARMCPRegInfo * ri,bool isread)788f43ee493SPeter Maydell static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri,
789f43ee493SPeter Maydell bool isread)
790f43ee493SPeter Maydell {
791f43ee493SPeter Maydell int el = arm_current_el(env);
792f43ee493SPeter Maydell uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
793f43ee493SPeter Maydell bool mdcr_el2_tdosa = (mdcr_el2 & MDCR_TDOSA) || (mdcr_el2 & MDCR_TDE) ||
794f43ee493SPeter Maydell (arm_hcr_el2_eff(env) & HCR_TGE);
795f43ee493SPeter Maydell
796f43ee493SPeter Maydell if (el < 2 && mdcr_el2_tdosa) {
797f43ee493SPeter Maydell return CP_ACCESS_TRAP_EL2;
798f43ee493SPeter Maydell }
799f43ee493SPeter Maydell if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDOSA)) {
800f43ee493SPeter Maydell return CP_ACCESS_TRAP_EL3;
801f43ee493SPeter Maydell }
802f43ee493SPeter Maydell return CP_ACCESS_OK;
803f43ee493SPeter Maydell }
804f43ee493SPeter Maydell
805f43ee493SPeter Maydell /*
806f43ee493SPeter Maydell * Check for traps to "debug ROM" registers, which are controlled
807f43ee493SPeter Maydell * by MDCR_EL2.TDRA for EL2 but by the more general MDCR_EL3.TDA for EL3.
808f43ee493SPeter Maydell */
access_tdra(CPUARMState * env,const ARMCPRegInfo * ri,bool isread)809f43ee493SPeter Maydell static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri,
810f43ee493SPeter Maydell bool isread)
811f43ee493SPeter Maydell {
812f43ee493SPeter Maydell int el = arm_current_el(env);
813f43ee493SPeter Maydell uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
814f43ee493SPeter Maydell bool mdcr_el2_tdra = (mdcr_el2 & MDCR_TDRA) || (mdcr_el2 & MDCR_TDE) ||
815f43ee493SPeter Maydell (arm_hcr_el2_eff(env) & HCR_TGE);
816f43ee493SPeter Maydell
817f43ee493SPeter Maydell if (el < 2 && mdcr_el2_tdra) {
818f43ee493SPeter Maydell return CP_ACCESS_TRAP_EL2;
819f43ee493SPeter Maydell }
820f43ee493SPeter Maydell if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
821f43ee493SPeter Maydell return CP_ACCESS_TRAP_EL3;
822f43ee493SPeter Maydell }
823f43ee493SPeter Maydell return CP_ACCESS_OK;
824f43ee493SPeter Maydell }
825f43ee493SPeter Maydell
826f43ee493SPeter Maydell /*
827f43ee493SPeter Maydell * Check for traps to general debug registers, which are controlled
828f43ee493SPeter Maydell * by MDCR_EL2.TDA for EL2 and MDCR_EL3.TDA for EL3.
829f43ee493SPeter Maydell */
access_tda(CPUARMState * env,const ARMCPRegInfo * ri,bool isread)830f43ee493SPeter Maydell static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri,
831f43ee493SPeter Maydell bool isread)
832f43ee493SPeter Maydell {
833f43ee493SPeter Maydell int el = arm_current_el(env);
834f43ee493SPeter Maydell uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
835f43ee493SPeter Maydell bool mdcr_el2_tda = (mdcr_el2 & MDCR_TDA) || (mdcr_el2 & MDCR_TDE) ||
836f43ee493SPeter Maydell (arm_hcr_el2_eff(env) & HCR_TGE);
837f43ee493SPeter Maydell
838f43ee493SPeter Maydell if (el < 2 && mdcr_el2_tda) {
839f43ee493SPeter Maydell return CP_ACCESS_TRAP_EL2;
840f43ee493SPeter Maydell }
841f43ee493SPeter Maydell if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
842f43ee493SPeter Maydell return CP_ACCESS_TRAP_EL3;
843f43ee493SPeter Maydell }
844f43ee493SPeter Maydell return CP_ACCESS_OK;
845f43ee493SPeter Maydell }
846f43ee493SPeter Maydell
access_dbgvcr32(CPUARMState * env,const ARMCPRegInfo * ri,bool isread)84783aea11dSPeter Maydell static CPAccessResult access_dbgvcr32(CPUARMState *env, const ARMCPRegInfo *ri,
84883aea11dSPeter Maydell bool isread)
84983aea11dSPeter Maydell {
85083aea11dSPeter Maydell /* MCDR_EL3.TDMA doesn't apply for FEAT_NV traps */
85183aea11dSPeter Maydell if (arm_current_el(env) == 2 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
85283aea11dSPeter Maydell return CP_ACCESS_TRAP_EL3;
85383aea11dSPeter Maydell }
85483aea11dSPeter Maydell return CP_ACCESS_OK;
85583aea11dSPeter Maydell }
85683aea11dSPeter Maydell
8571748ef03SPeter Maydell /*
8581748ef03SPeter Maydell * Check for traps to Debug Comms Channel registers. If FEAT_FGT
8591748ef03SPeter Maydell * is implemented then these are controlled by MDCR_EL2.TDCC for
8601748ef03SPeter Maydell * EL2 and MDCR_EL3.TDCC for EL3. They are also controlled by
8611748ef03SPeter Maydell * the general debug access trap bits MDCR_EL2.TDA and MDCR_EL3.TDA.
862f9ac7788SZhuojia Shen * For EL0, they are also controlled by MDSCR_EL1.TDCC.
8631748ef03SPeter Maydell */
access_tdcc(CPUARMState * env,const ARMCPRegInfo * ri,bool isread)8641748ef03SPeter Maydell static CPAccessResult access_tdcc(CPUARMState *env, const ARMCPRegInfo *ri,
8651748ef03SPeter Maydell bool isread)
8661748ef03SPeter Maydell {
8671748ef03SPeter Maydell int el = arm_current_el(env);
8681748ef03SPeter Maydell uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
869f9ac7788SZhuojia Shen bool mdscr_el1_tdcc = extract32(env->cp15.mdscr_el1, 12, 1);
8701748ef03SPeter Maydell bool mdcr_el2_tda = (mdcr_el2 & MDCR_TDA) || (mdcr_el2 & MDCR_TDE) ||
8711748ef03SPeter Maydell (arm_hcr_el2_eff(env) & HCR_TGE);
8721748ef03SPeter Maydell bool mdcr_el2_tdcc = cpu_isar_feature(aa64_fgt, env_archcpu(env)) &&
8731748ef03SPeter Maydell (mdcr_el2 & MDCR_TDCC);
8741748ef03SPeter Maydell bool mdcr_el3_tdcc = cpu_isar_feature(aa64_fgt, env_archcpu(env)) &&
8751748ef03SPeter Maydell (env->cp15.mdcr_el3 & MDCR_TDCC);
8761748ef03SPeter Maydell
877f9ac7788SZhuojia Shen if (el < 1 && mdscr_el1_tdcc) {
878f9ac7788SZhuojia Shen return CP_ACCESS_TRAP;
879f9ac7788SZhuojia Shen }
8801748ef03SPeter Maydell if (el < 2 && (mdcr_el2_tda || mdcr_el2_tdcc)) {
8811748ef03SPeter Maydell return CP_ACCESS_TRAP_EL2;
8821748ef03SPeter Maydell }
883*37600704SPeter Maydell if (!arm_is_el3_or_mon(env) &&
884*37600704SPeter Maydell ((env->cp15.mdcr_el3 & MDCR_TDA) || mdcr_el3_tdcc)) {
8851748ef03SPeter Maydell return CP_ACCESS_TRAP_EL3;
8861748ef03SPeter Maydell }
8871748ef03SPeter Maydell return CP_ACCESS_OK;
8881748ef03SPeter Maydell }
oslar_write(CPUARMState * env,const ARMCPRegInfo * ri,uint64_t value)8891748ef03SPeter Maydell
890f43ee493SPeter Maydell static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri,
891f43ee493SPeter Maydell uint64_t value)
892f43ee493SPeter Maydell {
893f43ee493SPeter Maydell /*
894f43ee493SPeter Maydell * Writes to OSLAR_EL1 may update the OS lock status, which can be
895f43ee493SPeter Maydell * read via a bit in OSLSR_EL1.
896f43ee493SPeter Maydell */
897f43ee493SPeter Maydell int oslock;
898f43ee493SPeter Maydell
899f43ee493SPeter Maydell if (ri->state == ARM_CP_STATE_AA32) {
900f43ee493SPeter Maydell oslock = (value == 0xC5ACCE55);
901f43ee493SPeter Maydell } else {
902f43ee493SPeter Maydell oslock = value & 1;
903f43ee493SPeter Maydell }
904f43ee493SPeter Maydell
905f43ee493SPeter Maydell env->cp15.oslsr_el1 = deposit32(env->cp15.oslsr_el1, 1, 1, oslock);
906f43ee493SPeter Maydell }
osdlr_write(CPUARMState * env,const ARMCPRegInfo * ri,uint64_t value)907f43ee493SPeter Maydell
908f94a6df5SPeter Maydell static void osdlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
909f94a6df5SPeter Maydell uint64_t value)
910f94a6df5SPeter Maydell {
911f94a6df5SPeter Maydell ARMCPU *cpu = env_archcpu(env);
912f94a6df5SPeter Maydell /*
913f94a6df5SPeter Maydell * Only defined bit is bit 0 (DLK); if Feat_DoubleLock is not
914f94a6df5SPeter Maydell * implemented this is RAZ/WI.
915f94a6df5SPeter Maydell */
916f94a6df5SPeter Maydell if(arm_feature(env, ARM_FEATURE_AARCH64)
917f94a6df5SPeter Maydell ? cpu_isar_feature(aa64_doublelock, cpu)
918f94a6df5SPeter Maydell : cpu_isar_feature(aa32_doublelock, cpu)) {
919f94a6df5SPeter Maydell env->cp15.osdlr_el1 = value & 1;
920f94a6df5SPeter Maydell }
921f94a6df5SPeter Maydell }
dbgclaimset_write(CPUARMState * env,const ARMCPRegInfo * ri,uint64_t value)922f94a6df5SPeter Maydell
9235fc83f11SEvgeny Iakovlev static void dbgclaimset_write(CPUARMState *env, const ARMCPRegInfo *ri,
9245fc83f11SEvgeny Iakovlev uint64_t value)
9255fc83f11SEvgeny Iakovlev {
9265fc83f11SEvgeny Iakovlev env->cp15.dbgclaim |= (value & 0xFF);
9275fc83f11SEvgeny Iakovlev }
dbgclaimset_read(CPUARMState * env,const ARMCPRegInfo * ri)9285fc83f11SEvgeny Iakovlev
9295fc83f11SEvgeny Iakovlev static uint64_t dbgclaimset_read(CPUARMState *env, const ARMCPRegInfo *ri)
9305fc83f11SEvgeny Iakovlev {
9315fc83f11SEvgeny Iakovlev /* CLAIM bits are RAO */
9325fc83f11SEvgeny Iakovlev return 0xFF;
9335fc83f11SEvgeny Iakovlev }
dbgclaimclr_write(CPUARMState * env,const ARMCPRegInfo * ri,uint64_t value)9345fc83f11SEvgeny Iakovlev
9355fc83f11SEvgeny Iakovlev static void dbgclaimclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
9365fc83f11SEvgeny Iakovlev uint64_t value)
9375fc83f11SEvgeny Iakovlev {
9385fc83f11SEvgeny Iakovlev env->cp15.dbgclaim &= ~(value & 0xFF);
9395fc83f11SEvgeny Iakovlev }
9405fc83f11SEvgeny Iakovlev
941f43ee493SPeter Maydell static const ARMCPRegInfo debug_cp_reginfo[] = {
942f43ee493SPeter Maydell /*
943f43ee493SPeter Maydell * DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped
944f43ee493SPeter Maydell * debug components. The AArch64 version of DBGDRAR is named MDRAR_EL1;
945f43ee493SPeter Maydell * unlike DBGDRAR it is never accessible from EL0.
946f43ee493SPeter Maydell * DBGDSAR is deprecated and must RAZ from v8 anyway, so it has no AArch64
947f43ee493SPeter Maydell * accessor.
948f43ee493SPeter Maydell */
949f43ee493SPeter Maydell { .name = "DBGDRAR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
950f43ee493SPeter Maydell .access = PL0_R, .accessfn = access_tdra,
951f654387bSAlex Bennée .type = ARM_CP_CONST | ARM_CP_NO_GDB, .resetvalue = 0 },
952f43ee493SPeter Maydell { .name = "MDRAR_EL1", .state = ARM_CP_STATE_AA64,
953f43ee493SPeter Maydell .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
954f43ee493SPeter Maydell .access = PL1_R, .accessfn = access_tdra,
955f43ee493SPeter Maydell .type = ARM_CP_CONST, .resetvalue = 0 },
956f43ee493SPeter Maydell { .name = "DBGDSAR", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
957f43ee493SPeter Maydell .access = PL0_R, .accessfn = access_tdra,
958f654387bSAlex Bennée .type = ARM_CP_CONST | ARM_CP_NO_GDB, .resetvalue = 0 },
959f43ee493SPeter Maydell /* Monitor debug system control register; the 32-bit alias is DBGDSCRext. */
960f43ee493SPeter Maydell { .name = "MDSCR_EL1", .state = ARM_CP_STATE_BOTH,
961f43ee493SPeter Maydell .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
962f43ee493SPeter Maydell .access = PL1_RW, .accessfn = access_tda,
963917b1405SPeter Maydell .fgt = FGT_MDSCR_EL1,
964bb7b95b0SPeter Maydell .nv2_redirect_offset = 0x158,
965f43ee493SPeter Maydell .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1),
966f43ee493SPeter Maydell .resetvalue = 0 },
967f43ee493SPeter Maydell /*
968f43ee493SPeter Maydell * MDCCSR_EL0[30:29] map to EDSCR[30:29]. Simply RAZ as the external
969f43ee493SPeter Maydell * Debug Communication Channel is not implemented.
970f43ee493SPeter Maydell */
971f43ee493SPeter Maydell { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_AA64,
972f43ee493SPeter Maydell .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 1, .opc2 = 0,
9731748ef03SPeter Maydell .access = PL0_R, .accessfn = access_tdcc,
974f43ee493SPeter Maydell .type = ARM_CP_CONST, .resetvalue = 0 },
975f43ee493SPeter Maydell /*
97670a670caSAlex Bennée * These registers belong to the Debug Communications Channel,
97770a670caSAlex Bennée * which is not implemented. However we implement RAZ/WI behaviour
97870a670caSAlex Bennée * with trapping to prevent spurious SIGILLs if the guest OS does
97970a670caSAlex Bennée * access them as the support cannot be probed for.
980b3aa2f21SEvgeny Iakovlev */
981b3aa2f21SEvgeny Iakovlev { .name = "OSDTRRX_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
982b3aa2f21SEvgeny Iakovlev .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 2,
9831748ef03SPeter Maydell .access = PL1_RW, .accessfn = access_tdcc,
984b3aa2f21SEvgeny Iakovlev .type = ARM_CP_CONST, .resetvalue = 0 },
985b3aa2f21SEvgeny Iakovlev { .name = "OSDTRTX_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
986b3aa2f21SEvgeny Iakovlev .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
9871748ef03SPeter Maydell .access = PL1_RW, .accessfn = access_tdcc,
988b3aa2f21SEvgeny Iakovlev .type = ARM_CP_CONST, .resetvalue = 0 },
98970a670caSAlex Bennée /* DBGDTRTX_EL0/DBGDTRRX_EL0 depend on direction */
99070a670caSAlex Bennée { .name = "DBGDTR_EL0", .state = ARM_CP_STATE_BOTH, .cp = 14,
99170a670caSAlex Bennée .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 5, .opc2 = 0,
99270a670caSAlex Bennée .access = PL0_RW, .accessfn = access_tdcc,
99370a670caSAlex Bennée .type = ARM_CP_CONST, .resetvalue = 0 },
994b3aa2f21SEvgeny Iakovlev /*
995b3aa2f21SEvgeny Iakovlev * OSECCR_EL1 provides a mechanism for an operating system
996b3aa2f21SEvgeny Iakovlev * to access the contents of EDECCR. EDECCR is not implemented though,
997b3aa2f21SEvgeny Iakovlev * as is the rest of external device mechanism.
998b3aa2f21SEvgeny Iakovlev */
999b3aa2f21SEvgeny Iakovlev { .name = "OSECCR_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
1000b3aa2f21SEvgeny Iakovlev .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
1001b3aa2f21SEvgeny Iakovlev .access = PL1_RW, .accessfn = access_tda,
1002917b1405SPeter Maydell .fgt = FGT_OSECCR_EL1,
1003b3aa2f21SEvgeny Iakovlev .type = ARM_CP_CONST, .resetvalue = 0 },
1004b3aa2f21SEvgeny Iakovlev /*
1005f43ee493SPeter Maydell * DBGDSCRint[15,12,5:2] map to MDSCR_EL1[15,12,5:2]. Map all bits as
1006f43ee493SPeter Maydell * it is unlikely a guest will care.
1007f43ee493SPeter Maydell * We don't implement the configurable EL0 access.
1008f43ee493SPeter Maydell */
1009f43ee493SPeter Maydell { .name = "DBGDSCRint", .state = ARM_CP_STATE_AA32,
1010f43ee493SPeter Maydell .cp = 14, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
1011f43ee493SPeter Maydell .type = ARM_CP_ALIAS,
1012f43ee493SPeter Maydell .access = PL1_R, .accessfn = access_tda,
1013f43ee493SPeter Maydell .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), },
1014f43ee493SPeter Maydell { .name = "OSLAR_EL1", .state = ARM_CP_STATE_BOTH,
1015f43ee493SPeter Maydell .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4,
1016f43ee493SPeter Maydell .access = PL1_W, .type = ARM_CP_NO_RAW,
1017f43ee493SPeter Maydell .accessfn = access_tdosa,
1018917b1405SPeter Maydell .fgt = FGT_OSLAR_EL1,
1019f43ee493SPeter Maydell .writefn = oslar_write },
1020f43ee493SPeter Maydell { .name = "OSLSR_EL1", .state = ARM_CP_STATE_BOTH,
1021f43ee493SPeter Maydell .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 4,
1022f43ee493SPeter Maydell .access = PL1_R, .resetvalue = 10,
1023f43ee493SPeter Maydell .accessfn = access_tdosa,
1024917b1405SPeter Maydell .fgt = FGT_OSLSR_EL1,
1025f43ee493SPeter Maydell .fieldoffset = offsetof(CPUARMState, cp15.oslsr_el1) },
1026f43ee493SPeter Maydell /* Dummy OSDLR_EL1: 32-bit Linux will read this */
1027f43ee493SPeter Maydell { .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH,
1028f43ee493SPeter Maydell .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4,
1029f43ee493SPeter Maydell .access = PL1_RW, .accessfn = access_tdosa,
1030917b1405SPeter Maydell .fgt = FGT_OSDLR_EL1,
1031f94a6df5SPeter Maydell .writefn = osdlr_write,
1032f94a6df5SPeter Maydell .fieldoffset = offsetof(CPUARMState, cp15.osdlr_el1) },
1033f43ee493SPeter Maydell /*
1034f43ee493SPeter Maydell * Dummy DBGVCR: Linux wants to clear this on startup, but we don't
1035f43ee493SPeter Maydell * implement vector catch debug events yet.
1036f43ee493SPeter Maydell */
1037f43ee493SPeter Maydell { .name = "DBGVCR",
1038f43ee493SPeter Maydell .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
1039f43ee493SPeter Maydell .access = PL1_RW, .accessfn = access_tda,
1040f43ee493SPeter Maydell .type = ARM_CP_NOP },
1041f43ee493SPeter Maydell /*
1042f43ee493SPeter Maydell * Dummy MDCCINT_EL1, since we don't implement the Debug Communications
1043f43ee493SPeter Maydell * Channel but Linux may try to access this register. The 32-bit
1044f43ee493SPeter Maydell * alias is DBGDCCINT.
1045f43ee493SPeter Maydell */
1046f43ee493SPeter Maydell { .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH,
1047f43ee493SPeter Maydell .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
10481748ef03SPeter Maydell .access = PL1_RW, .accessfn = access_tdcc,
1049f43ee493SPeter Maydell .type = ARM_CP_NOP },
10505fc83f11SEvgeny Iakovlev /*
10515fc83f11SEvgeny Iakovlev * Dummy DBGCLAIM registers.
10525fc83f11SEvgeny Iakovlev * "The architecture does not define any functionality for the CLAIM tag bits.",
10535fc83f11SEvgeny Iakovlev * so we only keep the raw bits
10545fc83f11SEvgeny Iakovlev */
10555fc83f11SEvgeny Iakovlev { .name = "DBGCLAIMSET_EL1", .state = ARM_CP_STATE_BOTH,
10565fc83f11SEvgeny Iakovlev .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 6,
10575fc83f11SEvgeny Iakovlev .type = ARM_CP_ALIAS,
10585fc83f11SEvgeny Iakovlev .access = PL1_RW, .accessfn = access_tda,
1059917b1405SPeter Maydell .fgt = FGT_DBGCLAIM,
10605fc83f11SEvgeny Iakovlev .writefn = dbgclaimset_write, .readfn = dbgclaimset_read },
10615fc83f11SEvgeny Iakovlev { .name = "DBGCLAIMCLR_EL1", .state = ARM_CP_STATE_BOTH,
10625fc83f11SEvgeny Iakovlev .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 6,
10635fc83f11SEvgeny Iakovlev .access = PL1_RW, .accessfn = access_tda,
1064917b1405SPeter Maydell .fgt = FGT_DBGCLAIM,
10655fc83f11SEvgeny Iakovlev .writefn = dbgclaimclr_write, .raw_writefn = raw_write,
10665fc83f11SEvgeny Iakovlev .fieldoffset = offsetof(CPUARMState, cp15.dbgclaim) },
1067f43ee493SPeter Maydell };
1068f43ee493SPeter Maydell
1069c36a0d57SPeter Maydell /* These are present only when EL1 supports AArch32 */
1070c36a0d57SPeter Maydell static const ARMCPRegInfo debug_aa32_el1_reginfo[] = {
1071c36a0d57SPeter Maydell /*
1072c36a0d57SPeter Maydell * Dummy DBGVCR32_EL2 (which is only for a 64-bit hypervisor
1073c36a0d57SPeter Maydell * to save and restore a 32-bit guest's DBGVCR)
1074c36a0d57SPeter Maydell */
1075c36a0d57SPeter Maydell { .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
1076c36a0d57SPeter Maydell .opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
107783aea11dSPeter Maydell .access = PL2_RW, .accessfn = access_dbgvcr32,
1078c36a0d57SPeter Maydell .type = ARM_CP_NOP | ARM_CP_EL3_NO_EL2_KEEP },
1079c36a0d57SPeter Maydell };
1080c36a0d57SPeter Maydell
1081f43ee493SPeter Maydell static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
1082f43ee493SPeter Maydell /* 64 bit access versions of the (dummy) debug registers */
1083f43ee493SPeter Maydell { .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0,
1084f654387bSAlex Bennée .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT | ARM_CP_NO_GDB,
1085f654387bSAlex Bennée .resetvalue = 0 },
1086f43ee493SPeter Maydell { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0,
1087f654387bSAlex Bennée .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT | ARM_CP_NO_GDB,
1088f654387bSAlex Bennée .resetvalue = 0 },
1089f43ee493SPeter Maydell };
dbgwvr_write(CPUARMState * env,const ARMCPRegInfo * ri,uint64_t value)1090f43ee493SPeter Maydell
1091f43ee493SPeter Maydell static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1092f43ee493SPeter Maydell uint64_t value)
1093f43ee493SPeter Maydell {
1094f43ee493SPeter Maydell ARMCPU *cpu = env_archcpu(env);
1095f43ee493SPeter Maydell int i = ri->crm;
1096f43ee493SPeter Maydell
1097f43ee493SPeter Maydell /*
1098f43ee493SPeter Maydell * Bits [1:0] are RES0.
1099f43ee493SPeter Maydell *
1100f43ee493SPeter Maydell * It is IMPLEMENTATION DEFINED whether [63:49] ([63:53] with FEAT_LVA)
1101f43ee493SPeter Maydell * are hardwired to the value of bit [48] ([52] with FEAT_LVA), or if
1102f43ee493SPeter Maydell * they contain the value written. It is CONSTRAINED UNPREDICTABLE
1103f43ee493SPeter Maydell * whether the RESS bits are ignored when comparing an address.
1104f43ee493SPeter Maydell *
1105f43ee493SPeter Maydell * Therefore we are allowed to compare the entire register, which lets
1106f43ee493SPeter Maydell * us avoid considering whether or not FEAT_LVA is actually enabled.
1107f43ee493SPeter Maydell */
1108f43ee493SPeter Maydell value &= ~3ULL;
1109f43ee493SPeter Maydell
1110f43ee493SPeter Maydell raw_write(env, ri, value);
1111fa05d1abSFabiano Rosas if (tcg_enabled()) {
1112f43ee493SPeter Maydell hw_watchpoint_update(cpu, i);
1113f43ee493SPeter Maydell }
1114fa05d1abSFabiano Rosas }
dbgwcr_write(CPUARMState * env,const ARMCPRegInfo * ri,uint64_t value)1115f43ee493SPeter Maydell
1116f43ee493SPeter Maydell static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1117f43ee493SPeter Maydell uint64_t value)
1118f43ee493SPeter Maydell {
1119f43ee493SPeter Maydell ARMCPU *cpu = env_archcpu(env);
1120f43ee493SPeter Maydell int i = ri->crm;
1121f43ee493SPeter Maydell
1122f43ee493SPeter Maydell raw_write(env, ri, value);
1123fa05d1abSFabiano Rosas if (tcg_enabled()) {
1124f43ee493SPeter Maydell hw_watchpoint_update(cpu, i);
1125f43ee493SPeter Maydell }
1126fa05d1abSFabiano Rosas }
dbgbvr_write(CPUARMState * env,const ARMCPRegInfo * ri,uint64_t value)1127f43ee493SPeter Maydell
1128f43ee493SPeter Maydell static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1129f43ee493SPeter Maydell uint64_t value)
1130f43ee493SPeter Maydell {
1131f43ee493SPeter Maydell ARMCPU *cpu = env_archcpu(env);
1132f43ee493SPeter Maydell int i = ri->crm;
1133f43ee493SPeter Maydell
1134f43ee493SPeter Maydell raw_write(env, ri, value);
1135fa05d1abSFabiano Rosas if (tcg_enabled()) {
1136f43ee493SPeter Maydell hw_breakpoint_update(cpu, i);
1137f43ee493SPeter Maydell }
1138fa05d1abSFabiano Rosas }
dbgbcr_write(CPUARMState * env,const ARMCPRegInfo * ri,uint64_t value)1139f43ee493SPeter Maydell
1140f43ee493SPeter Maydell static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1141f43ee493SPeter Maydell uint64_t value)
1142f43ee493SPeter Maydell {
1143f43ee493SPeter Maydell ARMCPU *cpu = env_archcpu(env);
1144f43ee493SPeter Maydell int i = ri->crm;
1145f43ee493SPeter Maydell
1146f43ee493SPeter Maydell /*
1147f43ee493SPeter Maydell * BAS[3] is a read-only copy of BAS[2], and BAS[1] a read-only
1148f43ee493SPeter Maydell * copy of BAS[0].
1149f43ee493SPeter Maydell */
1150f43ee493SPeter Maydell value = deposit64(value, 6, 1, extract64(value, 5, 1));
1151f43ee493SPeter Maydell value = deposit64(value, 8, 1, extract64(value, 7, 1));
1152f43ee493SPeter Maydell
1153f43ee493SPeter Maydell raw_write(env, ri, value);
1154fa05d1abSFabiano Rosas if (tcg_enabled()) {
1155f43ee493SPeter Maydell hw_breakpoint_update(cpu, i);
1156f43ee493SPeter Maydell }
1157fa05d1abSFabiano Rosas }
define_debug_regs(ARMCPU * cpu)1158f43ee493SPeter Maydell
1159f43ee493SPeter Maydell void define_debug_regs(ARMCPU *cpu)
1160f43ee493SPeter Maydell {
1161f43ee493SPeter Maydell /*
1162f43ee493SPeter Maydell * Define v7 and v8 architectural debug registers.
1163f43ee493SPeter Maydell * These are just dummy implementations for now.
1164f43ee493SPeter Maydell */
1165f43ee493SPeter Maydell int i;
1166f43ee493SPeter Maydell int wrps, brps, ctx_cmps;
1167f43ee493SPeter Maydell
1168f43ee493SPeter Maydell /*
1169f43ee493SPeter Maydell * The Arm ARM says DBGDIDR is optional and deprecated if EL1 cannot
1170f43ee493SPeter Maydell * use AArch32. Given that bit 15 is RES1, if the value is 0 then
1171f43ee493SPeter Maydell * the register must not exist for this cpu.
1172f43ee493SPeter Maydell */
1173f43ee493SPeter Maydell if (cpu->isar.dbgdidr != 0) {
1174f43ee493SPeter Maydell ARMCPRegInfo dbgdidr = {
1175f43ee493SPeter Maydell .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0,
1176f43ee493SPeter Maydell .opc1 = 0, .opc2 = 0,
1177f43ee493SPeter Maydell .access = PL0_R, .accessfn = access_tda,
1178f43ee493SPeter Maydell .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
1179f43ee493SPeter Maydell };
1180f43ee493SPeter Maydell define_one_arm_cp_reg(cpu, &dbgdidr);
1181f43ee493SPeter Maydell }
1182f43ee493SPeter Maydell
118309754ca8SPeter Maydell /*
118409754ca8SPeter Maydell * DBGDEVID is present in the v7 debug architecture if
118509754ca8SPeter Maydell * DBGDIDR.DEVID_imp is 1 (bit 15); from v7.1 and on it is
118609754ca8SPeter Maydell * mandatory (and bit 15 is RES1). DBGDEVID1 and DBGDEVID2 exist
118709754ca8SPeter Maydell * from v7.1 of the debug architecture. Because no fields have yet
118809754ca8SPeter Maydell * been defined in DBGDEVID2 (and quite possibly none will ever
118909754ca8SPeter Maydell * be) we don't define an ARMISARegisters field for it.
119009754ca8SPeter Maydell * These registers exist only if EL1 can use AArch32, but that
119109754ca8SPeter Maydell * happens naturally because they are only PL1 accessible anyway.
119209754ca8SPeter Maydell */
119309754ca8SPeter Maydell if (extract32(cpu->isar.dbgdidr, 15, 1)) {
119409754ca8SPeter Maydell ARMCPRegInfo dbgdevid = {
119509754ca8SPeter Maydell .name = "DBGDEVID",
119609754ca8SPeter Maydell .cp = 14, .opc1 = 0, .crn = 7, .opc2 = 2, .crn = 7,
119709754ca8SPeter Maydell .access = PL1_R, .accessfn = access_tda,
119809754ca8SPeter Maydell .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdevid,
119909754ca8SPeter Maydell };
120009754ca8SPeter Maydell define_one_arm_cp_reg(cpu, &dbgdevid);
120109754ca8SPeter Maydell }
120209754ca8SPeter Maydell if (cpu_isar_feature(aa32_debugv7p1, cpu)) {
120309754ca8SPeter Maydell ARMCPRegInfo dbgdevid12[] = {
120409754ca8SPeter Maydell {
120509754ca8SPeter Maydell .name = "DBGDEVID1",
120609754ca8SPeter Maydell .cp = 14, .opc1 = 0, .crn = 7, .opc2 = 1, .crn = 7,
120709754ca8SPeter Maydell .access = PL1_R, .accessfn = access_tda,
120809754ca8SPeter Maydell .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdevid1,
120909754ca8SPeter Maydell }, {
121009754ca8SPeter Maydell .name = "DBGDEVID2",
121109754ca8SPeter Maydell .cp = 14, .opc1 = 0, .crn = 7, .opc2 = 0, .crn = 7,
121209754ca8SPeter Maydell .access = PL1_R, .accessfn = access_tda,
121309754ca8SPeter Maydell .type = ARM_CP_CONST, .resetvalue = 0,
121409754ca8SPeter Maydell },
121509754ca8SPeter Maydell };
121609754ca8SPeter Maydell define_arm_cp_regs(cpu, dbgdevid12);
121709754ca8SPeter Maydell }
121809754ca8SPeter Maydell
1219f43ee493SPeter Maydell brps = arm_num_brps(cpu);
1220f43ee493SPeter Maydell wrps = arm_num_wrps(cpu);
1221f43ee493SPeter Maydell ctx_cmps = arm_num_ctx_cmps(cpu);
1222f43ee493SPeter Maydell
1223f43ee493SPeter Maydell assert(ctx_cmps <= brps);
1224f43ee493SPeter Maydell
1225f43ee493SPeter Maydell define_arm_cp_regs(cpu, debug_cp_reginfo);
1226c36a0d57SPeter Maydell if (cpu_isar_feature(aa64_aa32_el1, cpu)) {
1227c36a0d57SPeter Maydell define_arm_cp_regs(cpu, debug_aa32_el1_reginfo);
1228c36a0d57SPeter Maydell }
1229f43ee493SPeter Maydell
1230f43ee493SPeter Maydell if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {
1231f43ee493SPeter Maydell define_arm_cp_regs(cpu, debug_lpae_cp_reginfo);
1232f43ee493SPeter Maydell }
1233f43ee493SPeter Maydell
1234f43ee493SPeter Maydell for (i = 0; i < brps; i++) {
1235f43ee493SPeter Maydell char *dbgbvr_el1_name = g_strdup_printf("DBGBVR%d_EL1", i);
1236f43ee493SPeter Maydell char *dbgbcr_el1_name = g_strdup_printf("DBGBCR%d_EL1", i);
1237f43ee493SPeter Maydell ARMCPRegInfo dbgregs[] = {
1238f43ee493SPeter Maydell { .name = dbgbvr_el1_name, .state = ARM_CP_STATE_BOTH,
1239f43ee493SPeter Maydell .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
1240f43ee493SPeter Maydell .access = PL1_RW, .accessfn = access_tda,
1241917b1405SPeter Maydell .fgt = FGT_DBGBVRN_EL1,
1242f43ee493SPeter Maydell .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]),
1243f43ee493SPeter Maydell .writefn = dbgbvr_write, .raw_writefn = raw_write
1244f43ee493SPeter Maydell },
1245f43ee493SPeter Maydell { .name = dbgbcr_el1_name, .state = ARM_CP_STATE_BOTH,
1246f43ee493SPeter Maydell .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
1247f43ee493SPeter Maydell .access = PL1_RW, .accessfn = access_tda,
1248917b1405SPeter Maydell .fgt = FGT_DBGBCRN_EL1,
1249f43ee493SPeter Maydell .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
1250f43ee493SPeter Maydell .writefn = dbgbcr_write, .raw_writefn = raw_write
1251f43ee493SPeter Maydell },
1252f43ee493SPeter Maydell };
1253f43ee493SPeter Maydell define_arm_cp_regs(cpu, dbgregs);
1254f43ee493SPeter Maydell g_free(dbgbvr_el1_name);
1255f43ee493SPeter Maydell g_free(dbgbcr_el1_name);
1256f43ee493SPeter Maydell }
1257f43ee493SPeter Maydell
1258f43ee493SPeter Maydell for (i = 0; i < wrps; i++) {
1259f43ee493SPeter Maydell char *dbgwvr_el1_name = g_strdup_printf("DBGWVR%d_EL1", i);
1260f43ee493SPeter Maydell char *dbgwcr_el1_name = g_strdup_printf("DBGWCR%d_EL1", i);
1261f43ee493SPeter Maydell ARMCPRegInfo dbgregs[] = {
1262f43ee493SPeter Maydell { .name = dbgwvr_el1_name, .state = ARM_CP_STATE_BOTH,
1263f43ee493SPeter Maydell .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
1264f43ee493SPeter Maydell .access = PL1_RW, .accessfn = access_tda,
1265917b1405SPeter Maydell .fgt = FGT_DBGWVRN_EL1,
1266f43ee493SPeter Maydell .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]),
1267f43ee493SPeter Maydell .writefn = dbgwvr_write, .raw_writefn = raw_write
1268f43ee493SPeter Maydell },
1269f43ee493SPeter Maydell { .name = dbgwcr_el1_name, .state = ARM_CP_STATE_BOTH,
1270f43ee493SPeter Maydell .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
1271f43ee493SPeter Maydell .access = PL1_RW, .accessfn = access_tda,
1272917b1405SPeter Maydell .fgt = FGT_DBGWCRN_EL1,
1273f43ee493SPeter Maydell .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
1274f43ee493SPeter Maydell .writefn = dbgwcr_write, .raw_writefn = raw_write
1275f43ee493SPeter Maydell },
1276f43ee493SPeter Maydell };
1277f43ee493SPeter Maydell define_arm_cp_regs(cpu, dbgregs);
1278f43ee493SPeter Maydell g_free(dbgwvr_el1_name);
1279f43ee493SPeter Maydell g_free(dbgwcr_el1_name);
1280f43ee493SPeter Maydell }
1281f43ee493SPeter Maydell }
1282