get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2196934/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2196934,
    "url": "http://patchwork.ozlabs.org/api/patches/2196934/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260216160349.3079657-2-peter.maydell@linaro.org/",
    "project": {
        "id": 14,
        "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api",
        "name": "QEMU Development",
        "link_name": "qemu-devel",
        "list_id": "qemu-devel.nongnu.org",
        "list_email": "qemu-devel@nongnu.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260216160349.3079657-2-peter.maydell@linaro.org>",
    "list_archive_url": null,
    "date": "2026-02-16T16:03:48",
    "name": "[1/2] target/arm: Move TCG-specific code out of debug_helper.c",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "3b2eb3472e24dc4e6770030d314d7b96eb7e75b5",
    "submitter": {
        "id": 5111,
        "url": "http://patchwork.ozlabs.org/api/people/5111/?format=api",
        "name": "Peter Maydell",
        "email": "peter.maydell@linaro.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260216160349.3079657-2-peter.maydell@linaro.org/mbox/",
    "series": [
        {
            "id": 492324,
            "url": "http://patchwork.ozlabs.org/api/series/492324/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=492324",
            "date": "2026-02-16T16:03:48",
            "name": "target/arm: Don't use HELPER_H in non-tcg files",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/492324/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2196934/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2196934/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256\n header.s=google header.b=CaQB0WN0;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"
        ],
        "Received": [
            "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fF6z55TR9z1xtN\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 17 Feb 2026 03:04:17 +1100 (AEDT)",
            "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1vs150-00029e-6A; Mon, 16 Feb 2026 11:04:10 -0500",
            "from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <peter.maydell@linaro.org>)\n id 1vs14p-000287-GM\n for qemu-devel@nongnu.org; Mon, 16 Feb 2026 11:04:00 -0500",
            "from mail-wm1-x32c.google.com ([2a00:1450:4864:20::32c])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <peter.maydell@linaro.org>)\n id 1vs14k-0005nE-JY\n for qemu-devel@nongnu.org; Mon, 16 Feb 2026 11:03:59 -0500",
            "by mail-wm1-x32c.google.com with SMTP id\n 5b1f17b1804b1-483487335c2so31597945e9.2\n for <qemu-devel@nongnu.org>; Mon, 16 Feb 2026 08:03:54 -0800 (PST)",
            "from lanath.. (wildly.archaic.org.uk. [81.2.115.145])\n by smtp.gmail.com with ESMTPSA id\n 5b1f17b1804b1-4835d92267bsm661713185e9.0.2026.02.16.08.03.51\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Mon, 16 Feb 2026 08:03:51 -0800 (PST)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=linaro.org; s=google; t=1771257833; x=1771862633; darn=nongnu.org;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=9hAfYiBKs2xPmH/RRmNpRM+W3+7eJf2RUtEtIWW8ULA=;\n b=CaQB0WN0bExZICoaoXyUaGWkqZlV/8iFB2+ikfsQsHDOUgFou+aoHKZmmkFAfAUY2Y\n xEWvAANQ1nD4TOp8cCGEil/6dOVNfFWjKev8FzdJAkT4rugfjL+IRU9ZfeGwCqY5UEpI\n UffCZO8LL+Kptn0LD+oJKMUI8pxPzFQoXkn+Z/UM95LufkFshgajy6ONDQoKE/LIgPqp\n FzV5ALYSc5QEhaEiKpdh1rjuoSRmq57afOs7NTZHKT/O2mZPTUOL1ojQAsktVHlbmycA\n qQQkPh5Jlqnq/BXWUT7RRD2NVgrbo7aiuILZbFX9lP4GJJdJmxSfhGfPbdj5i88C4B+j\n kY/g==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1771257833; x=1771862633;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=9hAfYiBKs2xPmH/RRmNpRM+W3+7eJf2RUtEtIWW8ULA=;\n b=saTjBWPG1zqx8HFD2+wGF7s+B3qk6CA5UyeJjpQpT4Zd6cC1L4zN+ChG8ZGn+nPhIV\n 4B8cG3a/EdzwQluPD0K1V/AKDcP4KZZEfPK/f/KdGQd1LWwjcomm7o3jtj9QV29vcdT6\n OCjIS/YLXOnuSx+Dq3Ga/2pPv/qCrLfAzgo59VqfVFkUJhomH6qKLYyi1SMh1bzxl28d\n IEI7bTFxAfHBBkeWngklroRf2Rb4o85KPd77a0UfBwVaW+QndtpPhhuE8axD8Pc/nQCV\n /0EuTK94iR6u3oqyJ/Spon8mgoOQlWZESS3YIO+WV0Kqwu/U9IXssnSMLN29hQ2PyKnp\n PjkQ==",
        "X-Forwarded-Encrypted": "i=1;\n AJvYcCUyWlDiDqkpVdfvW/IzljzOtFichvVK+RClDu1Z7+FgkC0PI77fdhBz1xXu3hWLbtARDOqWhxFRwUY/@nongnu.org",
        "X-Gm-Message-State": "AOJu0YxPfMlocWt8MY0agnJwWym7hJa6DZfvuKMeAF81QFl2iZxQGfnK\n yRr4bpJ6BBZ4zERwx32j1B39K6anI+13mKXBdvodW7ZWJknMLDTFxlR8PxZxuZBvIPYNWvm3P+p\n 4uSBL",
        "X-Gm-Gg": "AZuq6aKh9gT86VDxChjJqzfqw0QeP248158DewTfubKs+PCG1/GgpIBrVJkI751nzvw\n 530yHrBdyokQEu99uC/V+nmKEQThV+dnbn6AfO1v9VJKsEUeHp7lTIMO4i45DcW1X3SsFjBDy9i\n B820kkHZ5yoasb9kzh4Vy2GQU087kSZkiph2OtYu9vZhCp4uIv6xyGq5FRcmTYFMysN6VJFqLuD\n 1fuIDUxAxHbmtkPSl2y1J0V2oB++fwx5iM87K8YrKlJEykwB2bscqSpMWAeyEa2SUo6RJqPoB86\n icWNKpeTm1hZIfYtfyNLvnlNk8yC7w4KJwHmVJM/HrTHfHE5Z0G9tHstmvmqpH6tPDDgyNKNeBX\n dNb+V6NLTt6kvwL9WJNirQzFbJn6Hr/2sKtv8oR+49SQF5z6Sl7fYlfgiUdaU7rZG+ScIcn3ZmI\n om71+YA0yC2B5BVFxR+rdMxqUKQQhb6M601i/1SpS1KrHTHRPC4XiG5jLhZrfgXV4XnmEMIv7kN\n GVZwIQXB532UfDwmAP6D7Jb3qIncJ4=",
        "X-Received": "by 2002:a05:600c:6096:b0:483:612d:7a9a with SMTP id\n 5b1f17b1804b1-483737b89a4mr155698545e9.0.1771257832437;\n Mon, 16 Feb 2026 08:03:52 -0800 (PST)",
        "From": "Peter Maydell <peter.maydell@linaro.org>",
        "To": "qemu-arm@nongnu.org,\n\tqemu-devel@nongnu.org",
        "Cc": "Pierrick Bouvier <pierrick.bouvier@linaro.org>",
        "Subject": "[PATCH 1/2] target/arm: Move TCG-specific code out of debug_helper.c",
        "Date": "Mon, 16 Feb 2026 16:03:48 +0000",
        "Message-ID": "<20260216160349.3079657-2-peter.maydell@linaro.org>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<20260216160349.3079657-1-peter.maydell@linaro.org>",
        "References": "<20260216160349.3079657-1-peter.maydell@linaro.org>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Received-SPF": "pass client-ip=2a00:1450:4864:20::32c;\n envelope-from=peter.maydell@linaro.org; helo=mail-wm1-x32c.google.com",
        "X-Spam_score_int": "-20",
        "X-Spam_score": "-2.1",
        "X-Spam_bar": "--",
        "X-Spam_report": "(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,\n SPF_PASS=-0.001 autolearn=ham autolearn_force=no",
        "X-Spam_action": "no action",
        "X-BeenThere": "qemu-devel@nongnu.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "qemu development <qemu-devel.nongnu.org>",
        "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>",
        "List-Post": "<mailto:qemu-devel@nongnu.org>",
        "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>",
        "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>",
        "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org",
        "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"
    },
    "content": "The target/arm/debug_helper.c file has some code which we need\nfor non-TCG accelerators, but quite a lot which is guarded by\na CONFIG_TCG ifdef. Move all this TCG-only code out to a\nnew file target/arm/tcg/debug.c.\n\nIn particular all the code requiring access to the TCG\nhelper function prototypes is in the moved code, so we can\ndrop the use of tcg/helper.h from debug_helper.c.\n\nSigned-off-by: Peter Maydell <peter.maydell@linaro.org>\n---\n target/arm/debug_helper.c                  | 769 ---------------------\n target/arm/{debug_helper.c => tcg/debug.c} | 542 +--------------\n target/arm/tcg/meson.build                 |   2 +\n 3 files changed, 3 insertions(+), 1310 deletions(-)\n copy target/arm/{debug_helper.c => tcg/debug.c} (53%)",
    "diff": "diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c\nindex 579516e154..352c8e5c8e 100644\n--- a/target/arm/debug_helper.c\n+++ b/target/arm/debug_helper.c\n@@ -14,775 +14,6 @@\n #include \"exec/watchpoint.h\"\n #include \"system/tcg.h\"\n \n-#define HELPER_H \"tcg/helper.h\"\n-#include \"exec/helper-proto.h.inc\"\n-\n-#ifdef CONFIG_TCG\n-/* Return the Exception Level targeted by debug exceptions. */\n-static int arm_debug_target_el(CPUARMState *env)\n-{\n-    bool secure = arm_is_secure(env);\n-    bool route_to_el2 = false;\n-\n-    if (arm_feature(env, ARM_FEATURE_M)) {\n-        return 1;\n-    }\n-\n-    if (arm_is_el2_enabled(env)) {\n-        route_to_el2 = env->cp15.hcr_el2 & HCR_TGE ||\n-                       env->cp15.mdcr_el2 & MDCR_TDE;\n-    }\n-\n-    if (route_to_el2) {\n-        return 2;\n-    } else if (arm_feature(env, ARM_FEATURE_EL3) &&\n-               !arm_el_is_aa64(env, 3) && secure) {\n-        return 3;\n-    } else {\n-        return 1;\n-    }\n-}\n-\n-/*\n- * Raise an exception to the debug target el.\n- * Modify syndrome to indicate when origin and target EL are the same.\n- */\n-G_NORETURN static void\n-raise_exception_debug(CPUARMState *env, uint32_t excp, uint32_t syndrome)\n-{\n-    int debug_el = arm_debug_target_el(env);\n-    int cur_el = arm_current_el(env);\n-\n-    /*\n-     * If singlestep is targeting a lower EL than the current one, then\n-     * DisasContext.ss_active must be false and we can never get here.\n-     * Similarly for watchpoint and breakpoint matches.\n-     */\n-    assert(debug_el >= cur_el);\n-    syndrome |= (debug_el == cur_el) << ARM_EL_EC_SHIFT;\n-    raise_exception(env, excp, syndrome, debug_el);\n-}\n-\n-/* See AArch64.GenerateDebugExceptionsFrom() in ARM ARM pseudocode */\n-static bool aa64_generate_debug_exceptions(CPUARMState *env)\n-{\n-    int cur_el = arm_current_el(env);\n-    int debug_el;\n-\n-    if (cur_el == 3) {\n-        return false;\n-    }\n-\n-    /* MDCR_EL3.SDD disables debug events from Secure state */\n-    if (arm_is_secure_below_el3(env)\n-        && extract32(env->cp15.mdcr_el3, 16, 1)) {\n-        return false;\n-    }\n-\n-    /*\n-     * Same EL to same EL debug exceptions need MDSCR_KDE enabled\n-     * while not masking the (D)ebug bit in DAIF.\n-     */\n-    debug_el = arm_debug_target_el(env);\n-\n-    if (cur_el == debug_el) {\n-        return extract32(env->cp15.mdscr_el1, 13, 1)\n-            && !(env->daif & PSTATE_D);\n-    }\n-\n-    /* Otherwise the debug target needs to be a higher EL */\n-    return debug_el > cur_el;\n-}\n-\n-static bool aa32_generate_debug_exceptions(CPUARMState *env)\n-{\n-    int el = arm_current_el(env);\n-\n-    if (el == 0 && arm_el_is_aa64(env, 1)) {\n-        return aa64_generate_debug_exceptions(env);\n-    }\n-\n-    if (arm_is_secure(env)) {\n-        int spd;\n-\n-        if (el == 0 && (env->cp15.sder & 1)) {\n-            /*\n-             * SDER.SUIDEN means debug exceptions from Secure EL0\n-             * are always enabled. Otherwise they are controlled by\n-             * SDCR.SPD like those from other Secure ELs.\n-             */\n-            return true;\n-        }\n-\n-        spd = extract32(env->cp15.mdcr_el3, 14, 2);\n-        switch (spd) {\n-        case 1:\n-            /* SPD == 0b01 is reserved, but behaves as 0b00. */\n-        case 0:\n-            /*\n-             * For 0b00 we return true if external secure invasive debug\n-             * is enabled. On real hardware this is controlled by external\n-             * signals to the core. QEMU always permits debug, and behaves\n-             * as if DBGEN, SPIDEN, NIDEN and SPNIDEN are all tied high.\n-             */\n-            return true;\n-        case 2:\n-            return false;\n-        case 3:\n-            return true;\n-        }\n-    }\n-\n-    return el != 2;\n-}\n-\n-/*\n- * Return true if debugging exceptions are currently enabled.\n- * This corresponds to what in ARM ARM pseudocode would be\n- *    if UsingAArch32() then\n- *        return AArch32.GenerateDebugExceptions()\n- *    else\n- *        return AArch64.GenerateDebugExceptions()\n- * We choose to push the if() down into this function for clarity,\n- * since the pseudocode has it at all callsites except for the one in\n- * CheckSoftwareStep(), where it is elided because both branches would\n- * always return the same value.\n- */\n-bool arm_generate_debug_exceptions(CPUARMState *env)\n-{\n-    if ((env->cp15.oslsr_el1 & 1) || (env->cp15.osdlr_el1 & 1)) {\n-        return false;\n-    }\n-    if (is_a64(env)) {\n-        return aa64_generate_debug_exceptions(env);\n-    } else {\n-        return aa32_generate_debug_exceptions(env);\n-    }\n-}\n-\n-/*\n- * Is single-stepping active? (Note that the \"is EL_D AArch64?\" check\n- * implicitly means this always returns false in pre-v8 CPUs.)\n- */\n-bool arm_singlestep_active(CPUARMState *env)\n-{\n-    return extract32(env->cp15.mdscr_el1, 0, 1)\n-        && arm_el_is_aa64(env, arm_debug_target_el(env))\n-        && arm_generate_debug_exceptions(env);\n-}\n-\n-/* Return true if the linked breakpoint entry lbn passes its checks */\n-static bool linked_bp_matches(ARMCPU *cpu, int lbn)\n-{\n-    CPUARMState *env = &cpu->env;\n-    uint64_t bcr = env->cp15.dbgbcr[lbn];\n-    int brps = arm_num_brps(cpu);\n-    int ctx_cmps = arm_num_ctx_cmps(cpu);\n-    int bt;\n-    uint32_t contextidr;\n-    uint64_t hcr_el2;\n-\n-    /*\n-     * Links to unimplemented or non-context aware breakpoints are\n-     * CONSTRAINED UNPREDICTABLE: either behave as if disabled, or\n-     * as if linked to an UNKNOWN context-aware breakpoint (in which\n-     * case DBGWCR<n>_EL1.LBN must indicate that breakpoint).\n-     * We choose the former.\n-     */\n-    if (lbn >= brps || lbn < (brps - ctx_cmps)) {\n-        return false;\n-    }\n-\n-    bcr = env->cp15.dbgbcr[lbn];\n-\n-    if (extract64(bcr, 0, 1) == 0) {\n-        /* Linked breakpoint disabled : generate no events */\n-        return false;\n-    }\n-\n-    bt = extract64(bcr, 20, 4);\n-    hcr_el2 = arm_hcr_el2_eff(env);\n-\n-    switch (bt) {\n-    case 3: /* linked context ID match */\n-        switch (arm_current_el(env)) {\n-        default:\n-            /* Context matches never fire in AArch64 EL3 */\n-            return false;\n-        case 2:\n-            if (!(hcr_el2 & HCR_E2H)) {\n-                /* Context matches never fire in EL2 without E2H enabled. */\n-                return false;\n-            }\n-            contextidr = env->cp15.contextidr_el[2];\n-            break;\n-        case 1:\n-            contextidr = env->cp15.contextidr_el[1];\n-            break;\n-        case 0:\n-            if ((hcr_el2 & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {\n-                contextidr = env->cp15.contextidr_el[2];\n-            } else {\n-                contextidr = env->cp15.contextidr_el[1];\n-            }\n-            break;\n-        }\n-        break;\n-\n-    case 7:  /* linked contextidr_el1 match */\n-        contextidr = env->cp15.contextidr_el[1];\n-        break;\n-    case 13: /* linked contextidr_el2 match */\n-        contextidr = env->cp15.contextidr_el[2];\n-        break;\n-\n-    case 9: /* linked VMID match (reserved if no EL2) */\n-    case 11: /* linked context ID and VMID match (reserved if no EL2) */\n-    case 15: /* linked full context ID match */\n-    default:\n-        /*\n-         * Links to Unlinked context breakpoints must generate no\n-         * events; we choose to do the same for reserved values too.\n-         */\n-        return false;\n-    }\n-\n-    /*\n-     * We match the whole register even if this is AArch32 using the\n-     * short descriptor format (in which case it holds both PROCID and ASID),\n-     * since we don't implement the optional v7 context ID masking.\n-     */\n-    return contextidr == (uint32_t)env->cp15.dbgbvr[lbn];\n-}\n-\n-static bool bp_wp_matches(ARMCPU *cpu, int n, bool is_wp)\n-{\n-    CPUARMState *env = &cpu->env;\n-    uint64_t cr;\n-    int pac, hmc, ssc, wt, lbn;\n-    /*\n-     * Note that for watchpoints the check is against the CPU security\n-     * state, not the S/NS attribute on the offending data access.\n-     */\n-    bool is_secure = arm_is_secure(env);\n-    int access_el = arm_current_el(env);\n-\n-    if (is_wp) {\n-        CPUWatchpoint *wp = env->cpu_watchpoint[n];\n-\n-        if (!wp || !(wp->flags & BP_WATCHPOINT_HIT)) {\n-            return false;\n-        }\n-        cr = env->cp15.dbgwcr[n];\n-        if (wp->hitattrs.user) {\n-            /*\n-             * The LDRT/STRT/LDT/STT \"unprivileged access\" instructions should\n-             * match watchpoints as if they were accesses done at EL0, even if\n-             * the CPU is at EL1 or higher.\n-             */\n-            access_el = 0;\n-        }\n-    } else {\n-        uint64_t pc = is_a64(env) ? env->pc : env->regs[15];\n-\n-        if (!env->cpu_breakpoint[n] || env->cpu_breakpoint[n]->pc != pc) {\n-            return false;\n-        }\n-        cr = env->cp15.dbgbcr[n];\n-    }\n-    /*\n-     * The WATCHPOINT_HIT flag guarantees us that the watchpoint is\n-     * enabled and that the address and access type match; for breakpoints\n-     * we know the address matched; check the remaining fields, including\n-     * linked breakpoints. We rely on WCR and BCR having the same layout\n-     * for the LBN, SSC, HMC, PAC/PMC and is-linked fields.\n-     * Note that some combinations of {PAC, HMC, SSC} are reserved and\n-     * must act either like some valid combination or as if the watchpoint\n-     * were disabled. We choose the former, and use this together with\n-     * the fact that EL3 must always be Secure and EL2 must always be\n-     * Non-Secure to simplify the code slightly compared to the full\n-     * table in the ARM ARM.\n-     */\n-    pac = FIELD_EX64(cr, DBGWCR, PAC);\n-    hmc = FIELD_EX64(cr, DBGWCR, HMC);\n-    ssc = FIELD_EX64(cr, DBGWCR, SSC);\n-\n-    switch (ssc) {\n-    case 0:\n-        break;\n-    case 1:\n-    case 3:\n-        if (is_secure) {\n-            return false;\n-        }\n-        break;\n-    case 2:\n-        if (!is_secure) {\n-            return false;\n-        }\n-        break;\n-    }\n-\n-    switch (access_el) {\n-    case 3:\n-    case 2:\n-        if (!hmc) {\n-            return false;\n-        }\n-        break;\n-    case 1:\n-        if (extract32(pac, 0, 1) == 0) {\n-            return false;\n-        }\n-        break;\n-    case 0:\n-        if (extract32(pac, 1, 1) == 0) {\n-            return false;\n-        }\n-        break;\n-    default:\n-        g_assert_not_reached();\n-    }\n-\n-    wt = FIELD_EX64(cr, DBGWCR, WT);\n-    lbn = FIELD_EX64(cr, DBGWCR, LBN);\n-\n-    if (wt && !linked_bp_matches(cpu, lbn)) {\n-        return false;\n-    }\n-\n-    return true;\n-}\n-\n-static bool check_watchpoints(ARMCPU *cpu)\n-{\n-    CPUARMState *env = &cpu->env;\n-    int n;\n-\n-    /*\n-     * If watchpoints are disabled globally or we can't take debug\n-     * exceptions here then watchpoint firings are ignored.\n-     */\n-    if (extract32(env->cp15.mdscr_el1, 15, 1) == 0\n-        || !arm_generate_debug_exceptions(env)) {\n-        return false;\n-    }\n-\n-    for (n = 0; n < ARRAY_SIZE(env->cpu_watchpoint); n++) {\n-        if (bp_wp_matches(cpu, n, true)) {\n-            return true;\n-        }\n-    }\n-    return false;\n-}\n-\n-bool arm_debug_check_breakpoint(CPUState *cs)\n-{\n-    ARMCPU *cpu = ARM_CPU(cs);\n-    CPUARMState *env = &cpu->env;\n-    vaddr pc;\n-    int n;\n-\n-    /*\n-     * If breakpoints are disabled globally or we can't take debug\n-     * exceptions here then breakpoint firings are ignored.\n-     */\n-    if (extract32(env->cp15.mdscr_el1, 15, 1) == 0\n-        || !arm_generate_debug_exceptions(env)) {\n-        return false;\n-    }\n-\n-    /*\n-     * Single-step exceptions have priority over breakpoint exceptions.\n-     * If single-step state is active-pending, suppress the bp.\n-     */\n-    if (arm_singlestep_active(env) && !(env->pstate & PSTATE_SS)) {\n-        return false;\n-    }\n-\n-    /*\n-     * PC alignment faults have priority over breakpoint exceptions.\n-     */\n-    pc = is_a64(env) ? env->pc : env->regs[15];\n-    if ((is_a64(env) || !env->thumb) && (pc & 3) != 0) {\n-        return false;\n-    }\n-\n-    /*\n-     * Instruction aborts have priority over breakpoint exceptions.\n-     * TODO: We would need to look up the page for PC and verify that\n-     * it is present and executable.\n-     */\n-\n-    for (n = 0; n < ARRAY_SIZE(env->cpu_breakpoint); n++) {\n-        if (bp_wp_matches(cpu, n, false)) {\n-            return true;\n-        }\n-    }\n-    return false;\n-}\n-\n-bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)\n-{\n-    /*\n-     * Called by core code when a CPU watchpoint fires; need to check if this\n-     * is also an architectural watchpoint match.\n-     */\n-    ARMCPU *cpu = ARM_CPU(cs);\n-\n-    return check_watchpoints(cpu);\n-}\n-\n-/*\n- * Return the FSR value for a debug exception (watchpoint, hardware\n- * breakpoint or BKPT insn) targeting the specified exception level.\n- */\n-static uint32_t arm_debug_exception_fsr(CPUARMState *env)\n-{\n-    ARMMMUFaultInfo fi = { .type = ARMFault_Debug };\n-    int target_el = arm_debug_target_el(env);\n-    bool using_lpae;\n-\n-    if (arm_feature(env, ARM_FEATURE_M)) {\n-        using_lpae = false;\n-    } else if (target_el == 2 || arm_el_is_aa64(env, target_el)) {\n-        using_lpae = true;\n-    } else if (arm_feature(env, ARM_FEATURE_PMSA) &&\n-               arm_feature(env, ARM_FEATURE_V8)) {\n-        using_lpae = true;\n-    } else if (arm_feature(env, ARM_FEATURE_LPAE) &&\n-               (env->cp15.tcr_el[target_el] & TTBCR_EAE)) {\n-        using_lpae = true;\n-    } else {\n-        using_lpae = false;\n-    }\n-\n-    if (using_lpae) {\n-        return arm_fi_to_lfsc(&fi);\n-    } else {\n-        return arm_fi_to_sfsc(&fi);\n-    }\n-}\n-\n-void arm_debug_excp_handler(CPUState *cs)\n-{\n-    /*\n-     * Called by core code when a watchpoint or breakpoint fires;\n-     * need to check which one and raise the appropriate exception.\n-     */\n-    ARMCPU *cpu = ARM_CPU(cs);\n-    CPUARMState *env = &cpu->env;\n-    CPUWatchpoint *wp_hit = cs->watchpoint_hit;\n-\n-    if (wp_hit) {\n-        if (wp_hit->flags & BP_CPU) {\n-            bool wnr = (wp_hit->flags & BP_WATCHPOINT_HIT_WRITE) != 0;\n-\n-            cs->watchpoint_hit = NULL;\n-\n-            env->exception.fsr = arm_debug_exception_fsr(env);\n-            env->exception.vaddress = wp_hit->hitaddr;\n-            raise_exception_debug(env, EXCP_DATA_ABORT,\n-                                  syn_watchpoint(0, 0, wnr));\n-        }\n-    } else {\n-        uint64_t pc = is_a64(env) ? env->pc : env->regs[15];\n-\n-        /*\n-         * (1) GDB breakpoints should be handled first.\n-         * (2) Do not raise a CPU exception if no CPU breakpoint has fired,\n-         * since singlestep is also done by generating a debug internal\n-         * exception.\n-         */\n-        if (cpu_breakpoint_test(cs, pc, BP_GDB)\n-            || !cpu_breakpoint_test(cs, pc, BP_CPU)) {\n-            return;\n-        }\n-\n-        env->exception.fsr = arm_debug_exception_fsr(env);\n-        /*\n-         * FAR is UNKNOWN: clear vaddress to avoid potentially exposing\n-         * values to the guest that it shouldn't be able to see at its\n-         * exception/security level.\n-         */\n-        env->exception.vaddress = 0;\n-        raise_exception_debug(env, EXCP_PREFETCH_ABORT, syn_breakpoint(0));\n-    }\n-}\n-\n-/*\n- * Raise an EXCP_BKPT with the specified syndrome register value,\n- * targeting the correct exception level for debug exceptions.\n- */\n-void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome)\n-{\n-    int debug_el = arm_debug_target_el(env);\n-    int cur_el = arm_current_el(env);\n-\n-    /* FSR will only be used if the debug target EL is AArch32. */\n-    env->exception.fsr = arm_debug_exception_fsr(env);\n-    /*\n-     * FAR is UNKNOWN: clear vaddress to avoid potentially exposing\n-     * values to the guest that it shouldn't be able to see at its\n-     * exception/security level.\n-     */\n-    env->exception.vaddress = 0;\n-    /*\n-     * Other kinds of architectural debug exception are ignored if\n-     * they target an exception level below the current one (in QEMU\n-     * this is checked by arm_generate_debug_exceptions()). Breakpoint\n-     * instructions are special because they always generate an exception\n-     * to somewhere: if they can't go to the configured debug exception\n-     * level they are taken to the current exception level.\n-     */\n-    if (debug_el < cur_el) {\n-        debug_el = cur_el;\n-    }\n-    raise_exception(env, EXCP_BKPT, syndrome, debug_el);\n-}\n-\n-void HELPER(exception_swstep)(CPUARMState *env, uint32_t syndrome)\n-{\n-    raise_exception_debug(env, EXCP_UDEF, syndrome);\n-}\n-\n-void hw_watchpoint_update(ARMCPU *cpu, int n)\n-{\n-    CPUARMState *env = &cpu->env;\n-    vaddr len = 0;\n-    vaddr wvr = env->cp15.dbgwvr[n];\n-    uint64_t wcr = env->cp15.dbgwcr[n];\n-    int mask;\n-    int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;\n-\n-    if (env->cpu_watchpoint[n]) {\n-        cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]);\n-        env->cpu_watchpoint[n] = NULL;\n-    }\n-\n-    if (!FIELD_EX64(wcr, DBGWCR, E)) {\n-        /* E bit clear : watchpoint disabled */\n-        return;\n-    }\n-\n-    switch (FIELD_EX64(wcr, DBGWCR, LSC)) {\n-    case 0:\n-        /* LSC 00 is reserved and must behave as if the wp is disabled */\n-        return;\n-    case 1:\n-        flags |= BP_MEM_READ;\n-        break;\n-    case 2:\n-        flags |= BP_MEM_WRITE;\n-        break;\n-    case 3:\n-        flags |= BP_MEM_ACCESS;\n-        break;\n-    }\n-\n-    /*\n-     * Attempts to use both MASK and BAS fields simultaneously are\n-     * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case,\n-     * thus generating a watchpoint for every byte in the masked region.\n-     */\n-    mask = FIELD_EX64(wcr, DBGWCR, MASK);\n-    if (mask == 1 || mask == 2) {\n-        /*\n-         * Reserved values of MASK; we must act as if the mask value was\n-         * some non-reserved value, or as if the watchpoint were disabled.\n-         * We choose the latter.\n-         */\n-        return;\n-    } else if (mask) {\n-        /* Watchpoint covers an aligned area up to 2GB in size */\n-        len = 1ULL << mask;\n-        /*\n-         * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE\n-         * whether the watchpoint fires when the unmasked bits match; we opt\n-         * to generate the exceptions.\n-         */\n-        wvr &= ~(len - 1);\n-    } else {\n-        /* Watchpoint covers bytes defined by the byte address select bits */\n-        int bas = FIELD_EX64(wcr, DBGWCR, BAS);\n-        int basstart;\n-\n-        if (extract64(wvr, 2, 1)) {\n-            /*\n-             * Deprecated case of an only 4-aligned address. BAS[7:4] are\n-             * ignored, and BAS[3:0] define which bytes to watch.\n-             */\n-            bas &= 0xf;\n-        }\n-\n-        if (bas == 0) {\n-            /* This must act as if the watchpoint is disabled */\n-            return;\n-        }\n-\n-        /*\n-         * The BAS bits are supposed to be programmed to indicate a contiguous\n-         * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether\n-         * we fire for each byte in the word/doubleword addressed by the WVR.\n-         * We choose to ignore any non-zero bits after the first range of 1s.\n-         */\n-        basstart = ctz32(bas);\n-        len = cto32(bas >> basstart);\n-        wvr += basstart;\n-    }\n-\n-    cpu_watchpoint_insert(CPU(cpu), wvr, len, flags,\n-                          &env->cpu_watchpoint[n]);\n-}\n-\n-void hw_watchpoint_update_all(ARMCPU *cpu)\n-{\n-    int i;\n-    CPUARMState *env = &cpu->env;\n-\n-    /*\n-     * Completely clear out existing QEMU watchpoints and our array, to\n-     * avoid possible stale entries following migration load.\n-     */\n-    cpu_watchpoint_remove_all(CPU(cpu), BP_CPU);\n-    memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint));\n-\n-    for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) {\n-        hw_watchpoint_update(cpu, i);\n-    }\n-}\n-\n-void hw_breakpoint_update(ARMCPU *cpu, int n)\n-{\n-    CPUARMState *env = &cpu->env;\n-    uint64_t bvr = env->cp15.dbgbvr[n];\n-    uint64_t bcr = env->cp15.dbgbcr[n];\n-    vaddr addr;\n-    int bt;\n-    int flags = BP_CPU;\n-\n-    if (env->cpu_breakpoint[n]) {\n-        cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]);\n-        env->cpu_breakpoint[n] = NULL;\n-    }\n-\n-    if (!extract64(bcr, 0, 1)) {\n-        /* E bit clear : watchpoint disabled */\n-        return;\n-    }\n-\n-    bt = extract64(bcr, 20, 4);\n-\n-    switch (bt) {\n-    case 4: /* unlinked address mismatch (reserved if AArch64) */\n-    case 5: /* linked address mismatch (reserved if AArch64) */\n-        qemu_log_mask(LOG_UNIMP,\n-                      \"arm: address mismatch breakpoint types not implemented\\n\");\n-        return;\n-    case 0: /* unlinked address match */\n-    case 1: /* linked address match */\n-    {\n-        /*\n-         * Bits [1:0] are RES0.\n-         *\n-         * It is IMPLEMENTATION DEFINED whether bits [63:49]\n-         * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit\n-         * of the VA field ([48] or [52] for FEAT_LVA), or whether the\n-         * value is read as written.  It is CONSTRAINED UNPREDICTABLE\n-         * whether the RESS bits are ignored when comparing an address.\n-         * Therefore we are allowed to compare the entire register, which\n-         * lets us avoid considering whether FEAT_LVA is actually enabled.\n-         *\n-         * The BAS field is used to allow setting breakpoints on 16-bit\n-         * wide instructions; it is CONSTRAINED UNPREDICTABLE whether\n-         * a bp will fire if the addresses covered by the bp and the addresses\n-         * covered by the insn overlap but the insn doesn't start at the\n-         * start of the bp address range. We choose to require the insn and\n-         * the bp to have the same address. The constraints on writing to\n-         * BAS enforced in dbgbcr_write mean we have only four cases:\n-         *  0b0000  => no breakpoint\n-         *  0b0011  => breakpoint on addr\n-         *  0b1100  => breakpoint on addr + 2\n-         *  0b1111  => breakpoint on addr\n-         * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c).\n-         */\n-        int bas = extract64(bcr, 5, 4);\n-        addr = bvr & ~3ULL;\n-        if (bas == 0) {\n-            return;\n-        }\n-        if (bas == 0xc) {\n-            addr += 2;\n-        }\n-        break;\n-    }\n-    case 2: /* unlinked context ID match */\n-    case 8: /* unlinked VMID match (reserved if no EL2) */\n-    case 10: /* unlinked context ID and VMID match (reserved if no EL2) */\n-        qemu_log_mask(LOG_UNIMP,\n-                      \"arm: unlinked context breakpoint types not implemented\\n\");\n-        return;\n-    case 9: /* linked VMID match (reserved if no EL2) */\n-    case 11: /* linked context ID and VMID match (reserved if no EL2) */\n-    case 3: /* linked context ID match */\n-    default:\n-        /*\n-         * We must generate no events for Linked context matches (unless\n-         * they are linked to by some other bp/wp, which is handled in\n-         * updates for the linking bp/wp). We choose to also generate no events\n-         * for reserved values.\n-         */\n-        return;\n-    }\n-\n-    cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]);\n-}\n-\n-void hw_breakpoint_update_all(ARMCPU *cpu)\n-{\n-    int i;\n-    CPUARMState *env = &cpu->env;\n-\n-    /*\n-     * Completely clear out existing QEMU breakpoints and our array, to\n-     * avoid possible stale entries following migration load.\n-     */\n-    cpu_breakpoint_remove_all(CPU(cpu), BP_CPU);\n-    memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint));\n-\n-    for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) {\n-        hw_breakpoint_update(cpu, i);\n-    }\n-}\n-\n-#if !defined(CONFIG_USER_ONLY)\n-\n-vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len)\n-{\n-    ARMCPU *cpu = ARM_CPU(cs);\n-    CPUARMState *env = &cpu->env;\n-\n-    /*\n-     * In BE32 system mode, target memory is stored byteswapped (on a\n-     * little-endian host system), and by the time we reach here (via an\n-     * opcode helper) the addresses of subword accesses have been adjusted\n-     * to account for that, which means that watchpoints will not match.\n-     * Undo the adjustment here.\n-     */\n-    if (arm_sctlr_b(env)) {\n-        if (len == 1) {\n-            addr ^= 3;\n-        } else if (len == 2) {\n-            addr ^= 2;\n-        }\n-    }\n-\n-    return addr;\n-}\n-\n-#endif /* !CONFIG_USER_ONLY */\n-#endif /* CONFIG_TCG */\n-\n /*\n  * Check for traps to \"powerdown debug\" registers, which are controlled\n  * by MDCR.TDOSA\ndiff --git a/target/arm/debug_helper.c b/target/arm/tcg/debug.c\nsimilarity index 53%\ncopy from target/arm/debug_helper.c\ncopy to target/arm/tcg/debug.c\nindex 579516e154..8edaeebd8a 100644\n--- a/target/arm/debug_helper.c\n+++ b/target/arm/tcg/debug.c\n@@ -1,5 +1,5 @@\n /*\n- * ARM debug helpers.\n+ * ARM debug helpers used by TCG\n  *\n  * This code is licensed under the GNU GPL v2 or later.\n  *\n@@ -17,7 +17,6 @@\n #define HELPER_H \"tcg/helper.h\"\n #include \"exec/helper-proto.h.inc\"\n \n-#ifdef CONFIG_TCG\n /* Return the Exception Level targeted by debug exceptions. */\n static int arm_debug_target_el(CPUARMState *env)\n {\n@@ -781,542 +780,3 @@ vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len)\n }\n \n #endif /* !CONFIG_USER_ONLY */\n-#endif /* CONFIG_TCG */\n-\n-/*\n- * Check for traps to \"powerdown debug\" registers, which are controlled\n- * by MDCR.TDOSA\n- */\n-static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri,\n-                                   bool isread)\n-{\n-    int el = arm_current_el(env);\n-    uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);\n-    bool mdcr_el2_tdosa = (mdcr_el2 & MDCR_TDOSA) || (mdcr_el2 & MDCR_TDE) ||\n-        (arm_hcr_el2_eff(env) & HCR_TGE);\n-\n-    if (el < 2 && mdcr_el2_tdosa) {\n-        return CP_ACCESS_TRAP_EL2;\n-    }\n-    if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDOSA)) {\n-        return CP_ACCESS_TRAP_EL3;\n-    }\n-    return CP_ACCESS_OK;\n-}\n-\n-/*\n- * Check for traps to \"debug ROM\" registers, which are controlled\n- * by MDCR_EL2.TDRA for EL2 but by the more general MDCR_EL3.TDA for EL3.\n- */\n-static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri,\n-                                  bool isread)\n-{\n-    int el = arm_current_el(env);\n-    uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);\n-    bool mdcr_el2_tdra = (mdcr_el2 & MDCR_TDRA) || (mdcr_el2 & MDCR_TDE) ||\n-        (arm_hcr_el2_eff(env) & HCR_TGE);\n-\n-    if (el < 2 && mdcr_el2_tdra) {\n-        return CP_ACCESS_TRAP_EL2;\n-    }\n-    if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {\n-        return CP_ACCESS_TRAP_EL3;\n-    }\n-    return CP_ACCESS_OK;\n-}\n-\n-/*\n- * Check for traps to general debug registers, which are controlled\n- * by MDCR_EL2.TDA for EL2 and MDCR_EL3.TDA for EL3.\n- */\n-static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri,\n-                                  bool isread)\n-{\n-    int el = arm_current_el(env);\n-    uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);\n-    bool mdcr_el2_tda = (mdcr_el2 & MDCR_TDA) || (mdcr_el2 & MDCR_TDE) ||\n-        (arm_hcr_el2_eff(env) & HCR_TGE);\n-\n-    if (el < 2 && mdcr_el2_tda) {\n-        return CP_ACCESS_TRAP_EL2;\n-    }\n-    if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {\n-        return CP_ACCESS_TRAP_EL3;\n-    }\n-    return CP_ACCESS_OK;\n-}\n-\n-static CPAccessResult access_dbgvcr32(CPUARMState *env, const ARMCPRegInfo *ri,\n-                                      bool isread)\n-{\n-    /* MCDR_EL3.TDMA doesn't apply for FEAT_NV traps */\n-    if (arm_current_el(env) == 2 && (env->cp15.mdcr_el3 & MDCR_TDA)) {\n-        return CP_ACCESS_TRAP_EL3;\n-    }\n-    return CP_ACCESS_OK;\n-}\n-\n-/*\n- * Check for traps to Debug Comms Channel registers. If FEAT_FGT\n- * is implemented then these are controlled by MDCR_EL2.TDCC for\n- * EL2 and MDCR_EL3.TDCC for EL3. They are also controlled by\n- * the general debug access trap bits MDCR_EL2.TDA and MDCR_EL3.TDA.\n- * For EL0, they are also controlled by MDSCR_EL1.TDCC.\n- */\n-static CPAccessResult access_tdcc(CPUARMState *env, const ARMCPRegInfo *ri,\n-                                  bool isread)\n-{\n-    int el = arm_current_el(env);\n-    uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);\n-    bool mdscr_el1_tdcc = extract32(env->cp15.mdscr_el1, 12, 1);\n-    bool mdcr_el2_tda = (mdcr_el2 & MDCR_TDA) || (mdcr_el2 & MDCR_TDE) ||\n-        (arm_hcr_el2_eff(env) & HCR_TGE);\n-    bool mdcr_el2_tdcc = cpu_isar_feature(aa64_fgt, env_archcpu(env)) &&\n-                                          (mdcr_el2 & MDCR_TDCC);\n-    bool mdcr_el3_tdcc = cpu_isar_feature(aa64_fgt, env_archcpu(env)) &&\n-                                          (env->cp15.mdcr_el3 & MDCR_TDCC);\n-\n-    if (el < 1 && mdscr_el1_tdcc) {\n-        return CP_ACCESS_TRAP_EL1;\n-    }\n-    if (el < 2 && (mdcr_el2_tda || mdcr_el2_tdcc)) {\n-        return CP_ACCESS_TRAP_EL2;\n-    }\n-    if (!arm_is_el3_or_mon(env) &&\n-        ((env->cp15.mdcr_el3 & MDCR_TDA) || mdcr_el3_tdcc)) {\n-        return CP_ACCESS_TRAP_EL3;\n-    }\n-    return CP_ACCESS_OK;\n-}\n-\n-static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri,\n-                        uint64_t value)\n-{\n-    /*\n-     * Writes to OSLAR_EL1 may update the OS lock status, which can be\n-     * read via a bit in OSLSR_EL1.\n-     */\n-    int oslock;\n-\n-    if (ri->state == ARM_CP_STATE_AA32) {\n-        oslock = (value == 0xC5ACCE55);\n-    } else {\n-        oslock = value & 1;\n-    }\n-\n-    env->cp15.oslsr_el1 = deposit32(env->cp15.oslsr_el1, 1, 1, oslock);\n-}\n-\n-static void osdlr_write(CPUARMState *env, const ARMCPRegInfo *ri,\n-                        uint64_t value)\n-{\n-    ARMCPU *cpu = env_archcpu(env);\n-    /*\n-     * Only defined bit is bit 0 (DLK); if Feat_DoubleLock is not\n-     * implemented this is RAZ/WI.\n-     */\n-    if(arm_feature(env, ARM_FEATURE_AARCH64)\n-       ? cpu_isar_feature(aa64_doublelock, cpu)\n-       : cpu_isar_feature(aa32_doublelock, cpu)) {\n-        env->cp15.osdlr_el1 = value & 1;\n-    }\n-}\n-\n-static void dbgclaimset_write(CPUARMState *env, const ARMCPRegInfo *ri,\n-                              uint64_t value)\n-{\n-    env->cp15.dbgclaim |= (value & 0xFF);\n-}\n-\n-static uint64_t dbgclaimset_read(CPUARMState *env, const ARMCPRegInfo *ri)\n-{\n-    /* CLAIM bits are RAO */\n-    return 0xFF;\n-}\n-\n-static void dbgclaimclr_write(CPUARMState *env, const ARMCPRegInfo *ri,\n-                              uint64_t value)\n-{\n-    env->cp15.dbgclaim &= ~(value & 0xFF);\n-}\n-\n-static CPAccessResult access_bogus(CPUARMState *env, const ARMCPRegInfo *ri,\n-                                   bool isread)\n-{\n-    /* Always UNDEF, as if this cpreg didn't exist */\n-    return CP_ACCESS_UNDEFINED;\n-}\n-\n-static const ARMCPRegInfo debug_cp_reginfo[] = {\n-    /*\n-     * DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped\n-     * debug components. The AArch64 version of DBGDRAR is named MDRAR_EL1;\n-     * unlike DBGDRAR it is never accessible from EL0.\n-     * DBGDSAR is deprecated and must RAZ from v8 anyway, so it has no AArch64\n-     * accessor.\n-     */\n-    { .name = \"DBGDRAR\", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,\n-      .access = PL0_R, .accessfn = access_tdra,\n-      .type = ARM_CP_CONST | ARM_CP_NO_GDB, .resetvalue = 0 },\n-    { .name = \"MDRAR_EL1\", .state = ARM_CP_STATE_AA64,\n-      .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,\n-      .access = PL1_R, .accessfn = access_tdra,\n-      .type = ARM_CP_CONST, .resetvalue = 0 },\n-    { .name = \"DBGDSAR\", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,\n-      .access = PL0_R, .accessfn = access_tdra,\n-      .type = ARM_CP_CONST | ARM_CP_NO_GDB, .resetvalue = 0 },\n-    /* Monitor debug system control register; the 32-bit alias is DBGDSCRext. */\n-    { .name = \"MDSCR_EL1\", .state = ARM_CP_STATE_BOTH,\n-      .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,\n-      .access = PL1_RW, .accessfn = access_tda,\n-      .fgt = FGT_MDSCR_EL1,\n-      .nv2_redirect_offset = 0x158,\n-      .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1),\n-      .resetvalue = 0 },\n-    /*\n-     * MDCCSR_EL0[30:29] map to EDSCR[30:29].  Simply RAZ as the external\n-     * Debug Communication Channel is not implemented.\n-     */\n-    { .name = \"MDCCSR_EL0\", .state = ARM_CP_STATE_AA64,\n-      .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 1, .opc2 = 0,\n-      .access = PL0_R, .accessfn = access_tdcc,\n-      .type = ARM_CP_CONST, .resetvalue = 0 },\n-    /*\n-     * These registers belong to the Debug Communications Channel,\n-     * which is not implemented. However we implement RAZ/WI behaviour\n-     * with trapping to prevent spurious SIGILLs if the guest OS does\n-     * access them as the support cannot be probed for.\n-     */\n-    { .name = \"OSDTRRX_EL1\", .state = ARM_CP_STATE_BOTH, .cp = 14,\n-      .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 2,\n-      .access = PL1_RW, .accessfn = access_tdcc,\n-      .type = ARM_CP_CONST, .resetvalue = 0 },\n-    { .name = \"OSDTRTX_EL1\", .state = ARM_CP_STATE_BOTH, .cp = 14,\n-      .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,\n-      .access = PL1_RW, .accessfn = access_tdcc,\n-      .type = ARM_CP_CONST, .resetvalue = 0 },\n-    /* Architecturally DBGDTRTX is named DBGDTRRX when used for reads */\n-    { .name = \"DBGDTRTX_EL0\", .state = ARM_CP_STATE_AA64,\n-      .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 5, .opc2 = 0,\n-      .access = PL0_RW, .accessfn = access_tdcc,\n-      .type = ARM_CP_CONST, .resetvalue = 0 },\n-    { .name = \"DBGDTRTX\", .state = ARM_CP_STATE_AA32, .cp = 14,\n-      .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,\n-      .access = PL0_RW, .accessfn = access_tdcc,\n-      .type = ARM_CP_CONST, .resetvalue = 0 },\n-    /* This is AArch64-only and is a combination of DBGDTRTX and DBGDTRRX */\n-    { .name = \"DBGDTR_EL0\", .state = ARM_CP_STATE_AA64,\n-      .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 4, .opc2 = 0,\n-      .access = PL0_RW, .accessfn = access_tdcc,\n-      .type = ARM_CP_CONST, .resetvalue = 0 },\n-    /*\n-     * This is not a real AArch32 register. We used to incorrectly expose\n-     * this due to a QEMU bug; to avoid breaking migration compatibility we\n-     * need to continue to provide it so that we don't fail the inbound\n-     * migration when it tells us about a sysreg that we don't have.\n-     * We set an always-fails .accessfn, which means that the guest doesn't\n-     * actually see this register (it will always UNDEF, identically to if\n-     * there were no cpreg definition for it other than that we won't print\n-     * a LOG_UNIMP message about it), and we set the ARM_CP_NO_GDB flag so the\n-     * gdbstub won't see it either.\n-     * (We can't just set .access = 0, because add_cpreg_to_hashtable()\n-     * helpfully ignores cpregs which aren't accessible to the highest\n-     * implemented EL.)\n-     *\n-     * TODO: implement a system for being able to describe \"this register\n-     * can be ignored if it appears in the inbound stream\"; then we can\n-     * remove this temporary hack.\n-     */\n-    { .name = \"BOGUS_DBGDTR_EL0\", .state = ARM_CP_STATE_AA32,\n-      .cp = 14, .opc1 = 3, .crn = 0, .crm = 5, .opc2 = 0,\n-      .access = PL0_RW, .accessfn = access_bogus,\n-      .type = ARM_CP_CONST | ARM_CP_NO_GDB, .resetvalue = 0 },\n-    /*\n-     * OSECCR_EL1 provides a mechanism for an operating system\n-     * to access the contents of EDECCR. EDECCR is not implemented though,\n-     * as is the rest of external device mechanism.\n-     */\n-    { .name = \"OSECCR_EL1\", .state = ARM_CP_STATE_BOTH, .cp = 14,\n-      .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,\n-      .access = PL1_RW, .accessfn = access_tda,\n-      .fgt = FGT_OSECCR_EL1,\n-      .type = ARM_CP_CONST, .resetvalue = 0 },\n-    /*\n-     * DBGDSCRint[15,12,5:2] map to MDSCR_EL1[15,12,5:2].  Map all bits as\n-     * it is unlikely a guest will care.\n-     * We don't implement the configurable EL0 access.\n-     */\n-    { .name = \"DBGDSCRint\", .state = ARM_CP_STATE_AA32,\n-      .cp = 14, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,\n-      .type = ARM_CP_ALIAS,\n-      .access = PL1_R, .accessfn = access_tda,\n-      .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), },\n-    { .name = \"OSLAR_EL1\", .state = ARM_CP_STATE_BOTH,\n-      .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4,\n-      .access = PL1_W, .type = ARM_CP_NO_RAW,\n-      .accessfn = access_tdosa,\n-      .fgt = FGT_OSLAR_EL1,\n-      .writefn = oslar_write },\n-    { .name = \"OSLSR_EL1\", .state = ARM_CP_STATE_BOTH,\n-      .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 4,\n-      .access = PL1_R, .resetvalue = 10,\n-      .accessfn = access_tdosa,\n-      .fgt = FGT_OSLSR_EL1,\n-      .fieldoffset = offsetof(CPUARMState, cp15.oslsr_el1) },\n-    /* Dummy OSDLR_EL1: 32-bit Linux will read this */\n-    { .name = \"OSDLR_EL1\", .state = ARM_CP_STATE_BOTH,\n-      .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4,\n-      .access = PL1_RW, .accessfn = access_tdosa,\n-      .fgt = FGT_OSDLR_EL1,\n-      .writefn = osdlr_write,\n-      .fieldoffset = offsetof(CPUARMState, cp15.osdlr_el1) },\n-    /*\n-     * Dummy DBGVCR: Linux wants to clear this on startup, but we don't\n-     * implement vector catch debug events yet.\n-     */\n-    { .name = \"DBGVCR\",\n-      .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,\n-      .access = PL1_RW, .accessfn = access_tda,\n-      .type = ARM_CP_CONST, .resetvalue = 0 },\n-    /*\n-     * Dummy MDCCINT_EL1, since we don't implement the Debug Communications\n-     * Channel but Linux may try to access this register. The 32-bit\n-     * alias is DBGDCCINT.\n-     */\n-    { .name = \"MDCCINT_EL1\", .state = ARM_CP_STATE_BOTH,\n-      .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,\n-      .access = PL1_RW, .accessfn = access_tdcc,\n-      .type = ARM_CP_CONST, .resetvalue = 0 },\n-    /*\n-     * Dummy DBGCLAIM registers.\n-     * \"The architecture does not define any functionality for the CLAIM tag bits.\",\n-     * so we only keep the raw bits\n-     */\n-    { .name = \"DBGCLAIMSET_EL1\", .state = ARM_CP_STATE_BOTH,\n-      .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 6,\n-      .type = ARM_CP_ALIAS,\n-      .access = PL1_RW, .accessfn = access_tda,\n-      .fgt = FGT_DBGCLAIM,\n-      .writefn = dbgclaimset_write, .readfn = dbgclaimset_read },\n-    { .name = \"DBGCLAIMCLR_EL1\", .state = ARM_CP_STATE_BOTH,\n-      .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 6,\n-      .access = PL1_RW, .accessfn = access_tda,\n-      .fgt = FGT_DBGCLAIM,\n-      .writefn = dbgclaimclr_write, .raw_writefn = raw_write,\n-      .fieldoffset = offsetof(CPUARMState, cp15.dbgclaim) },\n-};\n-\n-/* These are present only when EL1 supports AArch32 */\n-static const ARMCPRegInfo debug_aa32_el1_reginfo[] = {\n-    /*\n-     * Dummy DBGVCR32_EL2 (which is only for a 64-bit hypervisor\n-     * to save and restore a 32-bit guest's DBGVCR)\n-     */\n-    { .name = \"DBGVCR32_EL2\", .state = ARM_CP_STATE_AA64,\n-      .opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,\n-      .access = PL2_RW, .accessfn = access_dbgvcr32,\n-      .type = ARM_CP_CONST | ARM_CP_EL3_NO_EL2_KEEP,\n-      .resetvalue = 0 },\n-};\n-\n-static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {\n-    /* 64 bit access versions of the (dummy) debug registers */\n-    { .name = \"DBGDRAR\", .cp = 14, .crm = 1, .opc1 = 0,\n-      .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT | ARM_CP_NO_GDB,\n-      .resetvalue = 0 },\n-    { .name = \"DBGDSAR\", .cp = 14, .crm = 2, .opc1 = 0,\n-      .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT | ARM_CP_NO_GDB,\n-      .resetvalue = 0 },\n-};\n-\n-static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,\n-                         uint64_t value)\n-{\n-    ARMCPU *cpu = env_archcpu(env);\n-    int i = ri->crm;\n-\n-    /*\n-     * Bits [1:0] are RES0.\n-     *\n-     * It is IMPLEMENTATION DEFINED whether [63:49] ([63:53] with FEAT_LVA)\n-     * are hardwired to the value of bit [48] ([52] with FEAT_LVA), or if\n-     * they contain the value written.  It is CONSTRAINED UNPREDICTABLE\n-     * whether the RESS bits are ignored when comparing an address.\n-     *\n-     * Therefore we are allowed to compare the entire register, which lets\n-     * us avoid considering whether or not FEAT_LVA is actually enabled.\n-     */\n-    value &= ~3ULL;\n-\n-    raw_write(env, ri, value);\n-    if (tcg_enabled()) {\n-        hw_watchpoint_update(cpu, i);\n-    }\n-}\n-\n-static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri,\n-                         uint64_t value)\n-{\n-    ARMCPU *cpu = env_archcpu(env);\n-    int i = ri->crm;\n-\n-    raw_write(env, ri, value);\n-    if (tcg_enabled()) {\n-        hw_watchpoint_update(cpu, i);\n-    }\n-}\n-\n-static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri,\n-                         uint64_t value)\n-{\n-    ARMCPU *cpu = env_archcpu(env);\n-    int i = ri->crm;\n-\n-    raw_write(env, ri, value);\n-    if (tcg_enabled()) {\n-        hw_breakpoint_update(cpu, i);\n-    }\n-}\n-\n-static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,\n-                         uint64_t value)\n-{\n-    ARMCPU *cpu = env_archcpu(env);\n-    int i = ri->crm;\n-\n-    /*\n-     * BAS[3] is a read-only copy of BAS[2], and BAS[1] a read-only\n-     * copy of BAS[0].\n-     */\n-    value = deposit64(value, 6, 1, extract64(value, 5, 1));\n-    value = deposit64(value, 8, 1, extract64(value, 7, 1));\n-\n-    raw_write(env, ri, value);\n-    if (tcg_enabled()) {\n-        hw_breakpoint_update(cpu, i);\n-    }\n-}\n-\n-void define_debug_regs(ARMCPU *cpu)\n-{\n-    /*\n-     * Define v7 and v8 architectural debug registers.\n-     * These are just dummy implementations for now.\n-     */\n-    int i;\n-    int wrps, brps, ctx_cmps;\n-\n-    /*\n-     * The Arm ARM says DBGDIDR is optional and deprecated if EL1 cannot\n-     * use AArch32.  Given that bit 15 is RES1, if the value is 0 then\n-     * the register must not exist for this cpu.\n-     */\n-    if (cpu->isar.dbgdidr != 0) {\n-        ARMCPRegInfo dbgdidr = {\n-            .name = \"DBGDIDR\", .cp = 14, .crn = 0, .crm = 0,\n-            .opc1 = 0, .opc2 = 0,\n-            .access = PL0_R, .accessfn = access_tda,\n-            .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,\n-        };\n-        define_one_arm_cp_reg(cpu, &dbgdidr);\n-    }\n-\n-    /*\n-     * DBGDEVID is present in the v7 debug architecture if\n-     * DBGDIDR.DEVID_imp is 1 (bit 15); from v7.1 and on it is\n-     * mandatory (and bit 15 is RES1). DBGDEVID1 and DBGDEVID2 exist\n-     * from v7.1 of the debug architecture. Because no fields have yet\n-     * been defined in DBGDEVID2 (and quite possibly none will ever\n-     * be) we don't define an ARMISARegisters field for it.\n-     * These registers exist only if EL1 can use AArch32, but that\n-     * happens naturally because they are only PL1 accessible anyway.\n-     */\n-    if (extract32(cpu->isar.dbgdidr, 15, 1)) {\n-        ARMCPRegInfo dbgdevid = {\n-            .name = \"DBGDEVID\",\n-            .cp = 14, .opc1 = 0, .crn = 7, .opc2 = 2, .crn = 7,\n-            .access = PL1_R, .accessfn = access_tda,\n-            .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdevid,\n-        };\n-        define_one_arm_cp_reg(cpu, &dbgdevid);\n-    }\n-    if (cpu_isar_feature(aa32_debugv7p1, cpu)) {\n-        ARMCPRegInfo dbgdevid12[] = {\n-            {\n-                .name = \"DBGDEVID1\",\n-                .cp = 14, .opc1 = 0, .crn = 7, .opc2 = 1, .crn = 7,\n-                .access = PL1_R, .accessfn = access_tda,\n-                .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdevid1,\n-            }, {\n-                .name = \"DBGDEVID2\",\n-                .cp = 14, .opc1 = 0, .crn = 7, .opc2 = 0, .crn = 7,\n-                .access = PL1_R, .accessfn = access_tda,\n-                .type = ARM_CP_CONST, .resetvalue = 0,\n-            },\n-        };\n-        define_arm_cp_regs(cpu, dbgdevid12);\n-    }\n-\n-    brps = arm_num_brps(cpu);\n-    wrps = arm_num_wrps(cpu);\n-    ctx_cmps = arm_num_ctx_cmps(cpu);\n-\n-    assert(ctx_cmps <= brps);\n-\n-    define_arm_cp_regs(cpu, debug_cp_reginfo);\n-    if (cpu_isar_feature(aa64_aa32_el1, cpu)) {\n-        define_arm_cp_regs(cpu, debug_aa32_el1_reginfo);\n-    }\n-\n-    if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {\n-        define_arm_cp_regs(cpu, debug_lpae_cp_reginfo);\n-    }\n-\n-    for (i = 0; i < brps; i++) {\n-        char *dbgbvr_el1_name = g_strdup_printf(\"DBGBVR%d_EL1\", i);\n-        char *dbgbcr_el1_name = g_strdup_printf(\"DBGBCR%d_EL1\", i);\n-        ARMCPRegInfo dbgregs[] = {\n-            { .name = dbgbvr_el1_name, .state = ARM_CP_STATE_BOTH,\n-              .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,\n-              .access = PL1_RW, .accessfn = access_tda,\n-              .fgt = FGT_DBGBVRN_EL1,\n-              .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]),\n-              .writefn = dbgbvr_write, .raw_writefn = raw_write\n-            },\n-            { .name = dbgbcr_el1_name, .state = ARM_CP_STATE_BOTH,\n-              .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,\n-              .access = PL1_RW, .accessfn = access_tda,\n-              .fgt = FGT_DBGBCRN_EL1,\n-              .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),\n-              .writefn = dbgbcr_write, .raw_writefn = raw_write\n-            },\n-        };\n-        define_arm_cp_regs(cpu, dbgregs);\n-        g_free(dbgbvr_el1_name);\n-        g_free(dbgbcr_el1_name);\n-    }\n-\n-    for (i = 0; i < wrps; i++) {\n-        char *dbgwvr_el1_name = g_strdup_printf(\"DBGWVR%d_EL1\", i);\n-        char *dbgwcr_el1_name = g_strdup_printf(\"DBGWCR%d_EL1\", i);\n-        ARMCPRegInfo dbgregs[] = {\n-            { .name = dbgwvr_el1_name, .state = ARM_CP_STATE_BOTH,\n-              .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,\n-              .access = PL1_RW, .accessfn = access_tda,\n-              .fgt = FGT_DBGWVRN_EL1,\n-              .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]),\n-              .writefn = dbgwvr_write, .raw_writefn = raw_write\n-            },\n-            { .name = dbgwcr_el1_name, .state = ARM_CP_STATE_BOTH,\n-              .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,\n-              .access = PL1_RW, .accessfn = access_tda,\n-              .fgt = FGT_DBGWCRN_EL1,\n-              .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),\n-              .writefn = dbgwcr_write, .raw_writefn = raw_write\n-            },\n-        };\n-        define_arm_cp_regs(cpu, dbgregs);\n-        g_free(dbgwvr_el1_name);\n-        g_free(dbgwcr_el1_name);\n-    }\n-}\ndiff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build\nindex 1b115656c4..6e9aed3e5d 100644\n--- a/target/arm/tcg/meson.build\n+++ b/target/arm/tcg/meson.build\n@@ -65,6 +65,7 @@ arm_common_ss.add(files(\n \n arm_common_system_ss.add(files(\n   'cpregs-at.c',\n+  'debug.c',\n   'hflags.c',\n   'neon_helper.c',\n   'tlb_helper.c',\n@@ -72,6 +73,7 @@ arm_common_system_ss.add(files(\n   'vfp_helper.c',\n ))\n arm_user_ss.add(files(\n+  'debug.c',\n   'hflags.c',\n   'neon_helper.c',\n   'tlb_helper.c',\n",
    "prefixes": [
        "1/2"
    ]
}