From patchwork Thu Jun 30 19:41:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 586095 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:5036:0:0:0:0 with SMTP id e22csp704309mab; Thu, 30 Jun 2022 12:44:35 -0700 (PDT) X-Google-Smtp-Source: AGRyM1vLCGpcSSGDLvO02B6KpbLFYpolVbdl4OFdBONK7KsfZcC1UZZmg7pJdYhjawYCucZmhQkN X-Received: by 2002:a05:622a:1302:b0:305:1e02:4fee with SMTP id v2-20020a05622a130200b003051e024feemr9272457qtk.242.1656618275253; Thu, 30 Jun 2022 12:44:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656618275; cv=none; d=google.com; s=arc-20160816; b=AAh9RAYFR4nU2qLt9PrDBkxlQohxdskdQuA8rEHvUuLIcPHthl+5Fl8T43OyMZl2jt ZnXk9IYCY+d9PahVsFdGUrWiGEGHoyHdknjmbC/Baz1qUstN1iIj5EWxC6wiDOt7kEyx P4o/85xbBZAuF5qFS41VY/rsP/HmUnjb0g/C+n7nbS4yI+XwQglGI7QIz4j5vLT0rX2A 1PecI9smkNHe0vdXB/T2E4fxHz4VjKOOIpjRm8fqcjF/xeryHuhbIC+YKOPh+opF+jCR UBOFORg4Jwp0/sVfpwoPukDSqWhAmO83H77xCbj/9c//OchTeR9sN+00NkfMQr+STq7Z rzsw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=VgPb1Tkc0n0TFxZ2n6JlaR4U9pn5OgDJfIFcTGqpVVU=; b=f+nJohKzeqYSu36U/4rrtgm05RIBqaC3uecocijZTrWreyTFUQ9p1VKfgUTSdhy76L SV6+AlpBPVERCMbSfa48UpVF9mskvPsTx7amRVKJ1LqO0MgKQPqO4IE2+CKAyusBsILJ ZLN9bX/2p3Uj7kQcxuukWWJkmjdIxtOgoQ7HCHc4Ibr2GPhSv+Ve1tfjYetZUaltulb3 I23iaWhEnYVQV4CTwOFgBpgRKpdGnTykshkZxVj2LOnNCn+YC32z7n6vrC32VEMyw/K7 UQMlydbf59FN+gRZbD6V+//qTsrj2oJWpkLvmr4XWT6cwAGKbHMMR7p9VT5dCK5IQBNL SWAg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=iiZPMUCf; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id v15-20020a05622a130f00b00303effc6339si10921831qtk.717.2022.06.30.12.44.35 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 30 Jun 2022 12:44:35 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=iiZPMUCf; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:43010 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o705Y-00035z-Mf for patch@linaro.org; Thu, 30 Jun 2022 15:44:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:55154) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o702f-00031r-63 for qemu-devel@nongnu.org; Thu, 30 Jun 2022 15:41:33 -0400 Received: from mail-wr1-x432.google.com ([2a00:1450:4864:20::432]:40507) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1o702W-0005ao-Fw for qemu-devel@nongnu.org; Thu, 30 Jun 2022 15:41:30 -0400 Received: by mail-wr1-x432.google.com with SMTP id v9so61571wrp.7 for ; Thu, 30 Jun 2022 12:41:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=VgPb1Tkc0n0TFxZ2n6JlaR4U9pn5OgDJfIFcTGqpVVU=; b=iiZPMUCfuULaPfn5Gj0GdlAZd76N2XAtBuqBflMrIHyY9ljoJsNEVJw3MQtiyBFjdv 7tvQ5yXgx1vjvjRSm38tGu4CgRjZVx0gld7zdV1sL7P0+MRrFI0MYrU2cAv8bi86mBdk uyMaoovd5z7yzwIgWIlTypUyhbH5HxObngAJc7fiMn6pD4EslCrjHoWWUnQzZIucSKTg HQtz+7vzIjXx/x/FwJVTGRyTLO8fkKZbjjO1dmGXPD+GcXomJTmNS4X84giH8MUWJ0Bj xq0CRb2jPNk5cdGvommC/xqg2ADMjHVEmYcPXddmZgfvUp48NaalugDwXBCPPlshDRSf nuzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=VgPb1Tkc0n0TFxZ2n6JlaR4U9pn5OgDJfIFcTGqpVVU=; b=1C5fOp+WzEvpFVSGcWlbC1kDHvK81Dm4kCsEdSNctQoiN+34Ia6cQ9wXuKaNYiR/0z lvRSC1m6aodbXYs0qAyodpmYd6zCeZUsiN/6tP1duF3cq3Q+gQ2nyAVxjwDl4Ld7dH0H L+D9xqE02ZTDWYL7hewRN23igEIlFlfgQ8K02Pr46K4mkyTLC0uE5ljys6PBnyOBvAnJ 4J0emCMOyVJezpogQNM/3z8qrpQWPP4ML0KdWw5ZHJUuZZV+z+VepYJFKCMd1pXJ/yRN eW4j4YztmYNVUHeNijACRllnu/aMiXZALZEAIERbTi16s8nWq43rzubT3fjcbCZiUkhg bg3g== X-Gm-Message-State: AJIora9A3p7F/9Grvwibu2flKWKxMD6qTt4WsOeg9Etp1vVfS6v+BM4L JyQrjubN7Mrpv6UCxCaaxE4K8w== X-Received: by 2002:a05:6000:1705:b0:21b:bcff:39d3 with SMTP id n5-20020a056000170500b0021bbcff39d3mr10032630wrc.502.1656618081340; Thu, 30 Jun 2022 12:41:21 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by smtp.gmail.com with ESMTPSA id m2-20020adffa02000000b0021d163daeb0sm13200228wrr.108.2022.06.30.12.41.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Jun 2022 12:41:20 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 1/5] target/arm: Fix code style issues in debug helper functions Date: Thu, 30 Jun 2022 20:41:12 +0100 Message-Id: <20220630194116.3438513-2-peter.maydell@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220630194116.3438513-1-peter.maydell@linaro.org> References: <20220630194116.3438513-1-peter.maydell@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::432; envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x432.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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01, T_SPF_HELO_TEMPERROR=0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Before moving debug system register helper functions to a different file, fix the code style issues (mostly block comment syntax) so checkpatch doesn't complain about the code-motion patch. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/helper.c | 58 +++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index f6dcb1a1152..1c7ec2f8678 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -307,7 +307,8 @@ static uint64_t arm_mdcr_el2_eff(CPUARMState *env) return arm_is_el2_enabled(env) ? env->cp15.mdcr_el2 : 0; } -/* Check for traps to "powerdown debug" registers, which are controlled +/* + * Check for traps to "powerdown debug" registers, which are controlled * by MDCR.TDOSA */ static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri, @@ -327,7 +328,8 @@ static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri, return CP_ACCESS_OK; } -/* Check for traps to "debug ROM" registers, which are controlled +/* + * Check for traps to "debug ROM" registers, which are controlled * by MDCR_EL2.TDRA for EL2 but by the more general MDCR_EL3.TDA for EL3. */ static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri, @@ -347,7 +349,8 @@ static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri, return CP_ACCESS_OK; } -/* Check for traps to general debug registers, which are controlled +/* + * Check for traps to general debug registers, which are controlled * by MDCR_EL2.TDA for EL2 and MDCR_EL3.TDA for EL3. */ static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri, @@ -5982,7 +5985,8 @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri, static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { - /* Writes to OSLAR_EL1 may update the OS lock status, which can be + /* + * Writes to OSLAR_EL1 may update the OS lock status, which can be * read via a bit in OSLSR_EL1. */ int oslock; @@ -5997,7 +6001,8 @@ static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri, } static const ARMCPRegInfo debug_cp_reginfo[] = { - /* DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped + /* + * DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped * debug components. The AArch64 version of DBGDRAR is named MDRAR_EL1; * unlike DBGDRAR it is never accessible from EL0. * DBGDSAR is deprecated and must RAZ from v8 anyway, so it has no AArch64 @@ -6052,21 +6057,24 @@ static const ARMCPRegInfo debug_cp_reginfo[] = { .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4, .access = PL1_RW, .accessfn = access_tdosa, .type = ARM_CP_NOP }, - /* Dummy DBGVCR: Linux wants to clear this on startup, but we don't + /* + * Dummy DBGVCR: Linux wants to clear this on startup, but we don't * implement vector catch debug events yet. */ { .name = "DBGVCR", .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, .access = PL1_RW, .accessfn = access_tda, .type = ARM_CP_NOP }, - /* Dummy DBGVCR32_EL2 (which is only for a 64-bit hypervisor + /* + * Dummy DBGVCR32_EL2 (which is only for a 64-bit hypervisor * to save and restore a 32-bit guest's DBGVCR) */ { .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64, .opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0, .access = PL2_RW, .accessfn = access_tda, .type = ARM_CP_NOP | ARM_CP_EL3_NO_EL2_KEEP }, - /* Dummy MDCCINT_EL1, since we don't implement the Debug Communications + /* + * Dummy MDCCINT_EL1, since we don't implement the Debug Communications * Channel but Linux may try to access this register. The 32-bit * alias is DBGDCCINT. */ @@ -6079,9 +6087,9 @@ static const ARMCPRegInfo debug_cp_reginfo[] = { static const ARMCPRegInfo debug_lpae_cp_reginfo[] = { /* 64 bit access versions of the (dummy) debug registers */ { .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0, - .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 }, + .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0, - .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 }, + .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, }; /* @@ -6496,13 +6504,15 @@ void hw_watchpoint_update(ARMCPU *cpu, int n) break; } - /* Attempts to use both MASK and BAS fields simultaneously are + /* + * Attempts to use both MASK and BAS fields simultaneously are * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case, * thus generating a watchpoint for every byte in the masked region. */ mask = FIELD_EX64(wcr, DBGWCR, MASK); if (mask == 1 || mask == 2) { - /* Reserved values of MASK; we must act as if the mask value was + /* + * Reserved values of MASK; we must act as if the mask value was * some non-reserved value, or as if the watchpoint were disabled. * We choose the latter. */ @@ -6510,7 +6520,8 @@ void hw_watchpoint_update(ARMCPU *cpu, int n) } else if (mask) { /* Watchpoint covers an aligned area up to 2GB in size */ len = 1ULL << mask; - /* If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE + /* + * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE * whether the watchpoint fires when the unmasked bits match; we opt * to generate the exceptions. */ @@ -6521,7 +6532,8 @@ void hw_watchpoint_update(ARMCPU *cpu, int n) int basstart; if (extract64(wvr, 2, 1)) { - /* Deprecated case of an only 4-aligned address. BAS[7:4] are + /* + * Deprecated case of an only 4-aligned address. BAS[7:4] are * ignored, and BAS[3:0] define which bytes to watch. */ bas &= 0xf; @@ -6532,7 +6544,8 @@ void hw_watchpoint_update(ARMCPU *cpu, int n) return; } - /* The BAS bits are supposed to be programmed to indicate a contiguous + /* + * The BAS bits are supposed to be programmed to indicate a contiguous * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether * we fire for each byte in the word/doubleword addressed by the WVR. * We choose to ignore any non-zero bits after the first range of 1s. @@ -6551,7 +6564,8 @@ void hw_watchpoint_update_all(ARMCPU *cpu) int i; CPUARMState *env = &cpu->env; - /* Completely clear out existing QEMU watchpoints and our array, to + /* + * Completely clear out existing QEMU watchpoints and our array, to * avoid possible stale entries following migration load. */ cpu_watchpoint_remove_all(CPU(cpu), BP_CPU); @@ -6669,7 +6683,8 @@ void hw_breakpoint_update(ARMCPU *cpu, int n) case 11: /* linked context ID and VMID match (reserved if no EL2) */ case 3: /* linked context ID match */ default: - /* We must generate no events for Linked context matches (unless + /* + * We must generate no events for Linked context matches (unless * they are linked to by some other bp/wp, which is handled in * updates for the linking bp/wp). We choose to also generate no events * for reserved values. @@ -6685,7 +6700,8 @@ void hw_breakpoint_update_all(ARMCPU *cpu) int i; CPUARMState *env = &cpu->env; - /* Completely clear out existing QEMU breakpoints and our array, to + /* + * Completely clear out existing QEMU breakpoints and our array, to * avoid possible stale entries following migration load. */ cpu_breakpoint_remove_all(CPU(cpu), BP_CPU); @@ -6712,7 +6728,8 @@ static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, ARMCPU *cpu = env_archcpu(env); int i = ri->crm; - /* BAS[3] is a read-only copy of BAS[2], and BAS[1] a read-only + /* + * BAS[3] is a read-only copy of BAS[2], and BAS[1] a read-only * copy of BAS[0]. */ value = deposit64(value, 6, 1, extract64(value, 5, 1)); @@ -6724,7 +6741,8 @@ static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, static void define_debug_regs(ARMCPU *cpu) { - /* Define v7 and v8 architectural debug registers. + /* + * Define v7 and v8 architectural debug registers. * These are just dummy implementations for now. */ int i; From patchwork Thu Jun 30 19:41:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 586099 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:5036:0:0:0:0 with SMTP id e22csp709173mab; Thu, 30 Jun 2022 12:50:55 -0700 (PDT) X-Google-Smtp-Source: AGRyM1vIZ7ig6U44ABGrp/2DZGDPsplTR1REEC++zbvWFFwUqP45Xo6mGoTMPq7/OR+c23pInbJQ X-Received: by 2002:ad4:5aee:0:b0:470:69fd:3242 with SMTP id c14-20020ad45aee000000b0047069fd3242mr13096488qvh.34.1656618655527; Thu, 30 Jun 2022 12:50:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656618655; cv=none; d=google.com; s=arc-20160816; b=GfM5sRcoW4A33kQ63hrm9/ALQUwy0VZMASJskzR2PrctixPX4t6OCzoYcFvVwlqxle OTB15CJ9ID5ZKiQ845MgJ5Udk3vKZm1WqjnT/727wkgD7P5IhDEgNMs+7TigaNkNQDQK rrNEnfo/1B9KZQmJlX3yxpgmoX1xQESD9G4XyJVQ77TwYnpZshWf7jXwI8ynfW2l08q0 vz4ByBCZqu9oYj7uUoMMjxMJPv0ai0Ro+IQpMGvzvakOpFC+3AVpnqh60sVrVtbQIi+j cIWax72+sQ2IeYmKTuQIEiDwe8AQBRW9BGO5yCIV8gY9z7sMOjMlQy4LdAZseqHVp/gg bslA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=/juksNgapaVlXXSffqq5SkkdJPD+6+akb8qmi9Z5g0Y=; b=anC1ULJ6N6Gw9ZB/Jpwve3S5prODEwfExJWB39x+Oh5VlgixhYQwNoMwE6MPPjwq+3 y9tYdE20lAkXKNEa8s97ReH7AxwVKsq8n4DdExkv/6mYl1aQKQTpQjibDQqxJGJiyXdv 0Rz4v7BxdLCFA+4zUV+ogOMopXeCpfyRrfL5x2sN4R3VZKyT/kuCsrh00oEzzCuqH1bx klt0JCDlqnKPnAHdPvhuaIi493OIZPL9uiFGKaCuyUnr88Bw2uLZ0ZqElJZYIatntFCK Y7o1iaOYoHbNDL4EQgu8adb/MmSbZ9bq0pDBdTcpFLIskvEjf22vo84Da6/ZzfQEgf/w zJTw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=yyDv02uN; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id e19-20020ac84e53000000b0031d2a6f6ab3si2341665qtw.145.2022.06.30.12.50.55 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 30 Jun 2022 12:50:55 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=yyDv02uN; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:54044 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o70Bi-0002Nk-SU for patch@linaro.org; Thu, 30 Jun 2022 15:50:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:55194) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o702k-00035Y-Fp for qemu-devel@nongnu.org; Thu, 30 Jun 2022 15:41:39 -0400 Received: from mail-wr1-x42f.google.com ([2a00:1450:4864:20::42f]:43828) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1o702X-0005hB-QF for qemu-devel@nongnu.org; Thu, 30 Jun 2022 15:41:38 -0400 Received: by mail-wr1-x42f.google.com with SMTP id d17so45545wrc.10 for ; Thu, 30 Jun 2022 12:41:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=/juksNgapaVlXXSffqq5SkkdJPD+6+akb8qmi9Z5g0Y=; b=yyDv02uN530oY6wdeqFEViVCdPayq8269ftQq3tKCVJcYwgtYaKZ7fHLfTBwHiI+oB IkodeDjAEhGJesYfK9vkCsoIM85WLRRMTYDkhF4Pg6K4IVxnTDp8jcS6ORrhfD9bqmyx 4Us7rtvz0qsrh1dunwWn+KtqtxBo2fC5LRlvGthl2MU5W6FKgSlji58vT9n6XnFCDtOP tx0dJQ/7necQoMYTPx+EspT4uTKo1VVjgvmZaJRB0NyL1D3kNbl7dg/ySP5x2ZgtdTK8 NOhHefmDmq1K7EOHPhqj2abLnYPYM0/ZyrfhYdnkV6REZQf/wq581JbaRf3QuDr8TfHk 0DWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/juksNgapaVlXXSffqq5SkkdJPD+6+akb8qmi9Z5g0Y=; b=YBUDNMAgMwmXN0IflcxSyIcDp1n6vdMuoPga9bwJHANbP5a+hLm3lQKyr3oxrQNyhe y8YodtNfemEq/ql5nFDjczBFV8tKX+87M5lf1hHEalj6l+XViC/6hpKDE4sNE/cWJrKZ uCKXMIpWOwsvG/1eG2aSb4Eveo2UgN4Dd9H6axDM8MJHO14nQi+P3sKuJH3c0EWul49P T2D4nO7Hnor81LWx+P+YqL91lxnNrL9OwvedF5bgB7/NLUVRgUrZI8Z4OlxIKHJFjN+Y gZ9vgdzZo9MhICRFGyKFZ87MjmdonfQ/bVpMt0V2qjk9HCIB+QCfEhRwarZg3D42I7TF n20g== X-Gm-Message-State: AJIora+7mUzL5iYUXj7h66XQfQTWd1QoVmdzXAZX1AgCwReLIRO9xPp5 ThuTuO2VCsG/kxJrr3uWp6NxFzBXW4vO7A== X-Received: by 2002:a5d:584e:0:b0:21c:ea0c:3734 with SMTP id i14-20020a5d584e000000b0021cea0c3734mr10087815wrf.420.1656618083468; Thu, 30 Jun 2022 12:41:23 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by smtp.gmail.com with ESMTPSA id m2-20020adffa02000000b0021d163daeb0sm13200228wrr.108.2022.06.30.12.41.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Jun 2022 12:41:22 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 2/5] target/arm: Move define_debug_regs() to debug_helper.c Date: Thu, 30 Jun 2022 20:41:13 +0100 Message-Id: <20220630194116.3438513-3-peter.maydell@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220630194116.3438513-1-peter.maydell@linaro.org> References: <20220630194116.3438513-1-peter.maydell@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42f; envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x42f.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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" The target/arm/helper.c file is very long and is a grabbag of all kinds of functionality. We have already a debug_helper.c which has code for implementing architectural debug. Move the code which defines the debug-related system registers out to this file also. This affects the define_debug_regs() function and the various functions and arrays which are used only by it. The functions raw_write() and arm_mdcr_el2_eff() and define_debug_regs() now need to be global rather than local to helper.c; everything else is pure code movement. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/cpregs.h | 3 + target/arm/internals.h | 9 + target/arm/debug_helper.c | 525 +++++++++++++++++++++++++++++++++++++ target/arm/helper.c | 531 +------------------------------------- 4 files changed, 538 insertions(+), 530 deletions(-) diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h index d30758ee713..7e78c2c05c6 100644 --- a/target/arm/cpregs.h +++ b/target/arm/cpregs.h @@ -442,6 +442,9 @@ void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri, /* CPReadFn that can be used for read-as-zero behaviour */ uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri); +/* CPWriteFn that just writes the value to ri->fieldoffset */ +void raw_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value); + /* * CPResetFn that does nothing, for use if no reset is required even * if fieldoffset is non zero. diff --git a/target/arm/internals.h b/target/arm/internals.h index c66f74a0db1..00e2e710f6c 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1307,6 +1307,15 @@ int exception_target_el(CPUARMState *env); bool arm_singlestep_active(CPUARMState *env); bool arm_generate_debug_exceptions(CPUARMState *env); +/* Add the cpreg definitions for debug related system registers */ +void define_debug_regs(ARMCPU *cpu); + +/* Effective value of MDCR_EL2 */ +static inline uint64_t arm_mdcr_el2_eff(CPUARMState *env) +{ + return arm_is_el2_enabled(env) ? env->cp15.mdcr_el2 : 0; +} + /* Powers of 2 for sve_vq_map et al. */ #define SVE_VQ_POW2_MAP \ ((1 << (1 - 1)) | (1 << (2 - 1)) | \ diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c index b18a6bd3a23..9a78c1db966 100644 --- a/target/arm/debug_helper.c +++ b/target/arm/debug_helper.c @@ -6,8 +6,10 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ #include "qemu/osdep.h" +#include "qemu/log.h" #include "cpu.h" #include "internals.h" +#include "cpregs.h" #include "exec/exec-all.h" #include "exec/helper-proto.h" @@ -528,6 +530,529 @@ void HELPER(exception_swstep)(CPUARMState *env, uint32_t syndrome) raise_exception_debug(env, EXCP_UDEF, syndrome); } +/* + * Check for traps to "powerdown debug" registers, which are controlled + * by MDCR.TDOSA + */ +static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri, + bool isread) +{ + int el = arm_current_el(env); + uint64_t mdcr_el2 = arm_mdcr_el2_eff(env); + bool mdcr_el2_tdosa = (mdcr_el2 & MDCR_TDOSA) || (mdcr_el2 & MDCR_TDE) || + (arm_hcr_el2_eff(env) & HCR_TGE); + + if (el < 2 && mdcr_el2_tdosa) { + return CP_ACCESS_TRAP_EL2; + } + if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDOSA)) { + return CP_ACCESS_TRAP_EL3; + } + return CP_ACCESS_OK; +} + +/* + * Check for traps to "debug ROM" registers, which are controlled + * by MDCR_EL2.TDRA for EL2 but by the more general MDCR_EL3.TDA for EL3. + */ +static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri, + bool isread) +{ + int el = arm_current_el(env); + uint64_t mdcr_el2 = arm_mdcr_el2_eff(env); + bool mdcr_el2_tdra = (mdcr_el2 & MDCR_TDRA) || (mdcr_el2 & MDCR_TDE) || + (arm_hcr_el2_eff(env) & HCR_TGE); + + if (el < 2 && mdcr_el2_tdra) { + return CP_ACCESS_TRAP_EL2; + } + if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) { + return CP_ACCESS_TRAP_EL3; + } + return CP_ACCESS_OK; +} + +/* + * Check for traps to general debug registers, which are controlled + * by MDCR_EL2.TDA for EL2 and MDCR_EL3.TDA for EL3. + */ +static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri, + bool isread) +{ + int el = arm_current_el(env); + uint64_t mdcr_el2 = arm_mdcr_el2_eff(env); + bool mdcr_el2_tda = (mdcr_el2 & MDCR_TDA) || (mdcr_el2 & MDCR_TDE) || + (arm_hcr_el2_eff(env) & HCR_TGE); + + if (el < 2 && mdcr_el2_tda) { + return CP_ACCESS_TRAP_EL2; + } + if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) { + return CP_ACCESS_TRAP_EL3; + } + return CP_ACCESS_OK; +} + +static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* + * Writes to OSLAR_EL1 may update the OS lock status, which can be + * read via a bit in OSLSR_EL1. + */ + int oslock; + + if (ri->state == ARM_CP_STATE_AA32) { + oslock = (value == 0xC5ACCE55); + } else { + oslock = value & 1; + } + + env->cp15.oslsr_el1 = deposit32(env->cp15.oslsr_el1, 1, 1, oslock); +} + +static const ARMCPRegInfo debug_cp_reginfo[] = { + /* + * DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped + * debug components. The AArch64 version of DBGDRAR is named MDRAR_EL1; + * unlike DBGDRAR it is never accessible from EL0. + * DBGDSAR is deprecated and must RAZ from v8 anyway, so it has no AArch64 + * accessor. + */ + { .name = "DBGDRAR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL0_R, .accessfn = access_tdra, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "MDRAR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0, + .access = PL1_R, .accessfn = access_tdra, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "DBGDSAR", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL0_R, .accessfn = access_tdra, + .type = ARM_CP_CONST, .resetvalue = 0 }, + /* Monitor debug system control register; the 32-bit alias is DBGDSCRext. */ + { .name = "MDSCR_EL1", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2, + .access = PL1_RW, .accessfn = access_tda, + .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), + .resetvalue = 0 }, + /* + * MDCCSR_EL0[30:29] map to EDSCR[30:29]. Simply RAZ as the external + * Debug Communication Channel is not implemented. + */ + { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 1, .opc2 = 0, + .access = PL0_R, .accessfn = access_tda, + .type = ARM_CP_CONST, .resetvalue = 0 }, + /* + * DBGDSCRint[15,12,5:2] map to MDSCR_EL1[15,12,5:2]. Map all bits as + * it is unlikely a guest will care. + * We don't implement the configurable EL0 access. + */ + { .name = "DBGDSCRint", .state = ARM_CP_STATE_AA32, + .cp = 14, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, + .type = ARM_CP_ALIAS, + .access = PL1_R, .accessfn = access_tda, + .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), }, + { .name = "OSLAR_EL1", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .accessfn = access_tdosa, + .writefn = oslar_write }, + { .name = "OSLSR_EL1", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 4, + .access = PL1_R, .resetvalue = 10, + .accessfn = access_tdosa, + .fieldoffset = offsetof(CPUARMState, cp15.oslsr_el1) }, + /* Dummy OSDLR_EL1: 32-bit Linux will read this */ + { .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4, + .access = PL1_RW, .accessfn = access_tdosa, + .type = ARM_CP_NOP }, + /* + * Dummy DBGVCR: Linux wants to clear this on startup, but we don't + * implement vector catch debug events yet. + */ + { .name = "DBGVCR", + .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, + .access = PL1_RW, .accessfn = access_tda, + .type = ARM_CP_NOP }, + /* + * Dummy DBGVCR32_EL2 (which is only for a 64-bit hypervisor + * to save and restore a 32-bit guest's DBGVCR) + */ + { .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0, + .access = PL2_RW, .accessfn = access_tda, + .type = ARM_CP_NOP | ARM_CP_EL3_NO_EL2_KEEP }, + /* + * Dummy MDCCINT_EL1, since we don't implement the Debug Communications + * Channel but Linux may try to access this register. The 32-bit + * alias is DBGDCCINT. + */ + { .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0, + .access = PL1_RW, .accessfn = access_tda, + .type = ARM_CP_NOP }, +}; + +static const ARMCPRegInfo debug_lpae_cp_reginfo[] = { + /* 64 bit access versions of the (dummy) debug registers */ + { .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0, + .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, + { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0, + .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, +}; + +void hw_watchpoint_update(ARMCPU *cpu, int n) +{ + CPUARMState *env = &cpu->env; + vaddr len = 0; + vaddr wvr = env->cp15.dbgwvr[n]; + uint64_t wcr = env->cp15.dbgwcr[n]; + int mask; + int flags = BP_CPU | BP_STOP_BEFORE_ACCESS; + + if (env->cpu_watchpoint[n]) { + cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]); + env->cpu_watchpoint[n] = NULL; + } + + if (!FIELD_EX64(wcr, DBGWCR, E)) { + /* E bit clear : watchpoint disabled */ + return; + } + + switch (FIELD_EX64(wcr, DBGWCR, LSC)) { + case 0: + /* LSC 00 is reserved and must behave as if the wp is disabled */ + return; + case 1: + flags |= BP_MEM_READ; + break; + case 2: + flags |= BP_MEM_WRITE; + break; + case 3: + flags |= BP_MEM_ACCESS; + break; + } + + /* + * Attempts to use both MASK and BAS fields simultaneously are + * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case, + * thus generating a watchpoint for every byte in the masked region. + */ + mask = FIELD_EX64(wcr, DBGWCR, MASK); + if (mask == 1 || mask == 2) { + /* + * Reserved values of MASK; we must act as if the mask value was + * some non-reserved value, or as if the watchpoint were disabled. + * We choose the latter. + */ + return; + } else if (mask) { + /* Watchpoint covers an aligned area up to 2GB in size */ + len = 1ULL << mask; + /* + * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE + * whether the watchpoint fires when the unmasked bits match; we opt + * to generate the exceptions. + */ + wvr &= ~(len - 1); + } else { + /* Watchpoint covers bytes defined by the byte address select bits */ + int bas = FIELD_EX64(wcr, DBGWCR, BAS); + int basstart; + + if (extract64(wvr, 2, 1)) { + /* + * Deprecated case of an only 4-aligned address. BAS[7:4] are + * ignored, and BAS[3:0] define which bytes to watch. + */ + bas &= 0xf; + } + + if (bas == 0) { + /* This must act as if the watchpoint is disabled */ + return; + } + + /* + * The BAS bits are supposed to be programmed to indicate a contiguous + * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether + * we fire for each byte in the word/doubleword addressed by the WVR. + * We choose to ignore any non-zero bits after the first range of 1s. + */ + basstart = ctz32(bas); + len = cto32(bas >> basstart); + wvr += basstart; + } + + cpu_watchpoint_insert(CPU(cpu), wvr, len, flags, + &env->cpu_watchpoint[n]); +} + +void hw_watchpoint_update_all(ARMCPU *cpu) +{ + int i; + CPUARMState *env = &cpu->env; + + /* + * Completely clear out existing QEMU watchpoints and our array, to + * avoid possible stale entries following migration load. + */ + cpu_watchpoint_remove_all(CPU(cpu), BP_CPU); + memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint)); + + for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) { + hw_watchpoint_update(cpu, i); + } +} + +static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = env_archcpu(env); + int i = ri->crm; + + /* + * Bits [1:0] are RES0. + * + * It is IMPLEMENTATION DEFINED whether [63:49] ([63:53] with FEAT_LVA) + * are hardwired to the value of bit [48] ([52] with FEAT_LVA), or if + * they contain the value written. It is CONSTRAINED UNPREDICTABLE + * whether the RESS bits are ignored when comparing an address. + * + * Therefore we are allowed to compare the entire register, which lets + * us avoid considering whether or not FEAT_LVA is actually enabled. + */ + value &= ~3ULL; + + raw_write(env, ri, value); + hw_watchpoint_update(cpu, i); +} + +static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = env_archcpu(env); + int i = ri->crm; + + raw_write(env, ri, value); + hw_watchpoint_update(cpu, i); +} + +void hw_breakpoint_update(ARMCPU *cpu, int n) +{ + CPUARMState *env = &cpu->env; + uint64_t bvr = env->cp15.dbgbvr[n]; + uint64_t bcr = env->cp15.dbgbcr[n]; + vaddr addr; + int bt; + int flags = BP_CPU; + + if (env->cpu_breakpoint[n]) { + cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]); + env->cpu_breakpoint[n] = NULL; + } + + if (!extract64(bcr, 0, 1)) { + /* E bit clear : watchpoint disabled */ + return; + } + + bt = extract64(bcr, 20, 4); + + switch (bt) { + case 4: /* unlinked address mismatch (reserved if AArch64) */ + case 5: /* linked address mismatch (reserved if AArch64) */ + qemu_log_mask(LOG_UNIMP, + "arm: address mismatch breakpoint types not implemented\n"); + return; + case 0: /* unlinked address match */ + case 1: /* linked address match */ + { + /* + * Bits [1:0] are RES0. + * + * It is IMPLEMENTATION DEFINED whether bits [63:49] + * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit + * of the VA field ([48] or [52] for FEAT_LVA), or whether the + * value is read as written. It is CONSTRAINED UNPREDICTABLE + * whether the RESS bits are ignored when comparing an address. + * Therefore we are allowed to compare the entire register, which + * lets us avoid considering whether FEAT_LVA is actually enabled. + * + * The BAS field is used to allow setting breakpoints on 16-bit + * wide instructions; it is CONSTRAINED UNPREDICTABLE whether + * a bp will fire if the addresses covered by the bp and the addresses + * covered by the insn overlap but the insn doesn't start at the + * start of the bp address range. We choose to require the insn and + * the bp to have the same address. The constraints on writing to + * BAS enforced in dbgbcr_write mean we have only four cases: + * 0b0000 => no breakpoint + * 0b0011 => breakpoint on addr + * 0b1100 => breakpoint on addr + 2 + * 0b1111 => breakpoint on addr + * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c). + */ + int bas = extract64(bcr, 5, 4); + addr = bvr & ~3ULL; + if (bas == 0) { + return; + } + if (bas == 0xc) { + addr += 2; + } + break; + } + case 2: /* unlinked context ID match */ + case 8: /* unlinked VMID match (reserved if no EL2) */ + case 10: /* unlinked context ID and VMID match (reserved if no EL2) */ + qemu_log_mask(LOG_UNIMP, + "arm: unlinked context breakpoint types not implemented\n"); + return; + case 9: /* linked VMID match (reserved if no EL2) */ + case 11: /* linked context ID and VMID match (reserved if no EL2) */ + case 3: /* linked context ID match */ + default: + /* + * We must generate no events for Linked context matches (unless + * they are linked to by some other bp/wp, which is handled in + * updates for the linking bp/wp). We choose to also generate no events + * for reserved values. + */ + return; + } + + cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]); +} + +void hw_breakpoint_update_all(ARMCPU *cpu) +{ + int i; + CPUARMState *env = &cpu->env; + + /* + * Completely clear out existing QEMU breakpoints and our array, to + * avoid possible stale entries following migration load. + */ + cpu_breakpoint_remove_all(CPU(cpu), BP_CPU); + memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint)); + + for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) { + hw_breakpoint_update(cpu, i); + } +} + +static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = env_archcpu(env); + int i = ri->crm; + + raw_write(env, ri, value); + hw_breakpoint_update(cpu, i); +} + +static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = env_archcpu(env); + int i = ri->crm; + + /* + * BAS[3] is a read-only copy of BAS[2], and BAS[1] a read-only + * copy of BAS[0]. + */ + value = deposit64(value, 6, 1, extract64(value, 5, 1)); + value = deposit64(value, 8, 1, extract64(value, 7, 1)); + + raw_write(env, ri, value); + hw_breakpoint_update(cpu, i); +} + +void define_debug_regs(ARMCPU *cpu) +{ + /* + * Define v7 and v8 architectural debug registers. + * These are just dummy implementations for now. + */ + int i; + int wrps, brps, ctx_cmps; + + /* + * The Arm ARM says DBGDIDR is optional and deprecated if EL1 cannot + * use AArch32. Given that bit 15 is RES1, if the value is 0 then + * the register must not exist for this cpu. + */ + if (cpu->isar.dbgdidr != 0) { + ARMCPRegInfo dbgdidr = { + .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, + .opc1 = 0, .opc2 = 0, + .access = PL0_R, .accessfn = access_tda, + .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr, + }; + define_one_arm_cp_reg(cpu, &dbgdidr); + } + + brps = arm_num_brps(cpu); + wrps = arm_num_wrps(cpu); + ctx_cmps = arm_num_ctx_cmps(cpu); + + assert(ctx_cmps <= brps); + + define_arm_cp_regs(cpu, debug_cp_reginfo); + + if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) { + define_arm_cp_regs(cpu, debug_lpae_cp_reginfo); + } + + for (i = 0; i < brps; i++) { + char *dbgbvr_el1_name = g_strdup_printf("DBGBVR%d_EL1", i); + char *dbgbcr_el1_name = g_strdup_printf("DBGBCR%d_EL1", i); + ARMCPRegInfo dbgregs[] = { + { .name = dbgbvr_el1_name, .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4, + .access = PL1_RW, .accessfn = access_tda, + .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]), + .writefn = dbgbvr_write, .raw_writefn = raw_write + }, + { .name = dbgbcr_el1_name, .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5, + .access = PL1_RW, .accessfn = access_tda, + .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]), + .writefn = dbgbcr_write, .raw_writefn = raw_write + }, + }; + define_arm_cp_regs(cpu, dbgregs); + g_free(dbgbvr_el1_name); + g_free(dbgbcr_el1_name); + } + + for (i = 0; i < wrps; i++) { + char *dbgwvr_el1_name = g_strdup_printf("DBGWVR%d_EL1", i); + char *dbgwcr_el1_name = g_strdup_printf("DBGWCR%d_EL1", i); + ARMCPRegInfo dbgregs[] = { + { .name = dbgwvr_el1_name, .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6, + .access = PL1_RW, .accessfn = access_tda, + .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]), + .writefn = dbgwvr_write, .raw_writefn = raw_write + }, + { .name = dbgwcr_el1_name, .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7, + .access = PL1_RW, .accessfn = access_tda, + .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]), + .writefn = dbgwcr_write, .raw_writefn = raw_write + }, + }; + define_arm_cp_regs(cpu, dbgregs); + g_free(dbgwvr_el1_name); + g_free(dbgwcr_el1_name); + } +} + #if !defined(CONFIG_USER_ONLY) vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len) diff --git a/target/arm/helper.c b/target/arm/helper.c index 1c7ec2f8678..e6f37e160f8 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -51,8 +51,7 @@ static uint64_t raw_read(CPUARMState *env, const ARMCPRegInfo *ri) } } -static void raw_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) +void raw_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { assert(ri->fieldoffset); if (cpreg_field_is_64bit(ri)) { @@ -302,74 +301,6 @@ static CPAccessResult access_trap_aa32s_el1(CPUARMState *env, return CP_ACCESS_TRAP_UNCATEGORIZED; } -static uint64_t arm_mdcr_el2_eff(CPUARMState *env) -{ - return arm_is_el2_enabled(env) ? env->cp15.mdcr_el2 : 0; -} - -/* - * Check for traps to "powerdown debug" registers, which are controlled - * by MDCR.TDOSA - */ -static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri, - bool isread) -{ - int el = arm_current_el(env); - uint64_t mdcr_el2 = arm_mdcr_el2_eff(env); - bool mdcr_el2_tdosa = (mdcr_el2 & MDCR_TDOSA) || (mdcr_el2 & MDCR_TDE) || - (arm_hcr_el2_eff(env) & HCR_TGE); - - if (el < 2 && mdcr_el2_tdosa) { - return CP_ACCESS_TRAP_EL2; - } - if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDOSA)) { - return CP_ACCESS_TRAP_EL3; - } - return CP_ACCESS_OK; -} - -/* - * Check for traps to "debug ROM" registers, which are controlled - * by MDCR_EL2.TDRA for EL2 but by the more general MDCR_EL3.TDA for EL3. - */ -static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri, - bool isread) -{ - int el = arm_current_el(env); - uint64_t mdcr_el2 = arm_mdcr_el2_eff(env); - bool mdcr_el2_tdra = (mdcr_el2 & MDCR_TDRA) || (mdcr_el2 & MDCR_TDE) || - (arm_hcr_el2_eff(env) & HCR_TGE); - - if (el < 2 && mdcr_el2_tdra) { - return CP_ACCESS_TRAP_EL2; - } - if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) { - return CP_ACCESS_TRAP_EL3; - } - return CP_ACCESS_OK; -} - -/* - * Check for traps to general debug registers, which are controlled - * by MDCR_EL2.TDA for EL2 and MDCR_EL3.TDA for EL3. - */ -static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri, - bool isread) -{ - int el = arm_current_el(env); - uint64_t mdcr_el2 = arm_mdcr_el2_eff(env); - bool mdcr_el2_tda = (mdcr_el2 & MDCR_TDA) || (mdcr_el2 & MDCR_TDE) || - (arm_hcr_el2_eff(env) & HCR_TGE); - - if (el < 2 && mdcr_el2_tda) { - return CP_ACCESS_TRAP_EL2; - } - if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) { - return CP_ACCESS_TRAP_EL3; - } - return CP_ACCESS_OK; -} - /* Check for traps to performance monitor registers, which are controlled * by MDCR_EL2.TPM for EL2 and MDCR_EL3.TPM for EL3. */ @@ -5982,116 +5913,6 @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri, return CP_ACCESS_OK; } -static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* - * Writes to OSLAR_EL1 may update the OS lock status, which can be - * read via a bit in OSLSR_EL1. - */ - int oslock; - - if (ri->state == ARM_CP_STATE_AA32) { - oslock = (value == 0xC5ACCE55); - } else { - oslock = value & 1; - } - - env->cp15.oslsr_el1 = deposit32(env->cp15.oslsr_el1, 1, 1, oslock); -} - -static const ARMCPRegInfo debug_cp_reginfo[] = { - /* - * DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped - * debug components. The AArch64 version of DBGDRAR is named MDRAR_EL1; - * unlike DBGDRAR it is never accessible from EL0. - * DBGDSAR is deprecated and must RAZ from v8 anyway, so it has no AArch64 - * accessor. - */ - { .name = "DBGDRAR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL0_R, .accessfn = access_tdra, - .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "MDRAR_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0, - .access = PL1_R, .accessfn = access_tdra, - .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "DBGDSAR", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL0_R, .accessfn = access_tdra, - .type = ARM_CP_CONST, .resetvalue = 0 }, - /* Monitor debug system control register; the 32-bit alias is DBGDSCRext. */ - { .name = "MDSCR_EL1", .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2, - .access = PL1_RW, .accessfn = access_tda, - .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), - .resetvalue = 0 }, - /* - * MDCCSR_EL0[30:29] map to EDSCR[30:29]. Simply RAZ as the external - * Debug Communication Channel is not implemented. - */ - { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 1, .opc2 = 0, - .access = PL0_R, .accessfn = access_tda, - .type = ARM_CP_CONST, .resetvalue = 0 }, - /* - * DBGDSCRint[15,12,5:2] map to MDSCR_EL1[15,12,5:2]. Map all bits as - * it is unlikely a guest will care. - * We don't implement the configurable EL0 access. - */ - { .name = "DBGDSCRint", .state = ARM_CP_STATE_AA32, - .cp = 14, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, - .type = ARM_CP_ALIAS, - .access = PL1_R, .accessfn = access_tda, - .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), }, - { .name = "OSLAR_EL1", .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .accessfn = access_tdosa, - .writefn = oslar_write }, - { .name = "OSLSR_EL1", .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 4, - .access = PL1_R, .resetvalue = 10, - .accessfn = access_tdosa, - .fieldoffset = offsetof(CPUARMState, cp15.oslsr_el1) }, - /* Dummy OSDLR_EL1: 32-bit Linux will read this */ - { .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4, - .access = PL1_RW, .accessfn = access_tdosa, - .type = ARM_CP_NOP }, - /* - * Dummy DBGVCR: Linux wants to clear this on startup, but we don't - * implement vector catch debug events yet. - */ - { .name = "DBGVCR", - .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, - .access = PL1_RW, .accessfn = access_tda, - .type = ARM_CP_NOP }, - /* - * Dummy DBGVCR32_EL2 (which is only for a 64-bit hypervisor - * to save and restore a 32-bit guest's DBGVCR) - */ - { .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0, - .access = PL2_RW, .accessfn = access_tda, - .type = ARM_CP_NOP | ARM_CP_EL3_NO_EL2_KEEP }, - /* - * Dummy MDCCINT_EL1, since we don't implement the Debug Communications - * Channel but Linux may try to access this register. The 32-bit - * alias is DBGDCCINT. - */ - { .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0, - .access = PL1_RW, .accessfn = access_tda, - .type = ARM_CP_NOP }, -}; - -static const ARMCPRegInfo debug_lpae_cp_reginfo[] = { - /* 64 bit access versions of the (dummy) debug registers */ - { .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0, - .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, - { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0, - .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, -}; - /* * Check for traps to RAS registers, which are controlled * by HCR_EL2.TERR and SCR_EL3.TERR. @@ -6470,356 +6291,6 @@ static const ARMCPRegInfo sme_reginfo[] = { }; #endif /* TARGET_AARCH64 */ -void hw_watchpoint_update(ARMCPU *cpu, int n) -{ - CPUARMState *env = &cpu->env; - vaddr len = 0; - vaddr wvr = env->cp15.dbgwvr[n]; - uint64_t wcr = env->cp15.dbgwcr[n]; - int mask; - int flags = BP_CPU | BP_STOP_BEFORE_ACCESS; - - if (env->cpu_watchpoint[n]) { - cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]); - env->cpu_watchpoint[n] = NULL; - } - - if (!FIELD_EX64(wcr, DBGWCR, E)) { - /* E bit clear : watchpoint disabled */ - return; - } - - switch (FIELD_EX64(wcr, DBGWCR, LSC)) { - case 0: - /* LSC 00 is reserved and must behave as if the wp is disabled */ - return; - case 1: - flags |= BP_MEM_READ; - break; - case 2: - flags |= BP_MEM_WRITE; - break; - case 3: - flags |= BP_MEM_ACCESS; - break; - } - - /* - * Attempts to use both MASK and BAS fields simultaneously are - * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case, - * thus generating a watchpoint for every byte in the masked region. - */ - mask = FIELD_EX64(wcr, DBGWCR, MASK); - if (mask == 1 || mask == 2) { - /* - * Reserved values of MASK; we must act as if the mask value was - * some non-reserved value, or as if the watchpoint were disabled. - * We choose the latter. - */ - return; - } else if (mask) { - /* Watchpoint covers an aligned area up to 2GB in size */ - len = 1ULL << mask; - /* - * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE - * whether the watchpoint fires when the unmasked bits match; we opt - * to generate the exceptions. - */ - wvr &= ~(len - 1); - } else { - /* Watchpoint covers bytes defined by the byte address select bits */ - int bas = FIELD_EX64(wcr, DBGWCR, BAS); - int basstart; - - if (extract64(wvr, 2, 1)) { - /* - * Deprecated case of an only 4-aligned address. BAS[7:4] are - * ignored, and BAS[3:0] define which bytes to watch. - */ - bas &= 0xf; - } - - if (bas == 0) { - /* This must act as if the watchpoint is disabled */ - return; - } - - /* - * The BAS bits are supposed to be programmed to indicate a contiguous - * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether - * we fire for each byte in the word/doubleword addressed by the WVR. - * We choose to ignore any non-zero bits after the first range of 1s. - */ - basstart = ctz32(bas); - len = cto32(bas >> basstart); - wvr += basstart; - } - - cpu_watchpoint_insert(CPU(cpu), wvr, len, flags, - &env->cpu_watchpoint[n]); -} - -void hw_watchpoint_update_all(ARMCPU *cpu) -{ - int i; - CPUARMState *env = &cpu->env; - - /* - * Completely clear out existing QEMU watchpoints and our array, to - * avoid possible stale entries following migration load. - */ - cpu_watchpoint_remove_all(CPU(cpu), BP_CPU); - memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint)); - - for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) { - hw_watchpoint_update(cpu, i); - } -} - -static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = env_archcpu(env); - int i = ri->crm; - - /* - * Bits [1:0] are RES0. - * - * It is IMPLEMENTATION DEFINED whether [63:49] ([63:53] with FEAT_LVA) - * are hardwired to the value of bit [48] ([52] with FEAT_LVA), or if - * they contain the value written. It is CONSTRAINED UNPREDICTABLE - * whether the RESS bits are ignored when comparing an address. - * - * Therefore we are allowed to compare the entire register, which lets - * us avoid considering whether or not FEAT_LVA is actually enabled. - */ - value &= ~3ULL; - - raw_write(env, ri, value); - hw_watchpoint_update(cpu, i); -} - -static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = env_archcpu(env); - int i = ri->crm; - - raw_write(env, ri, value); - hw_watchpoint_update(cpu, i); -} - -void hw_breakpoint_update(ARMCPU *cpu, int n) -{ - CPUARMState *env = &cpu->env; - uint64_t bvr = env->cp15.dbgbvr[n]; - uint64_t bcr = env->cp15.dbgbcr[n]; - vaddr addr; - int bt; - int flags = BP_CPU; - - if (env->cpu_breakpoint[n]) { - cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]); - env->cpu_breakpoint[n] = NULL; - } - - if (!extract64(bcr, 0, 1)) { - /* E bit clear : watchpoint disabled */ - return; - } - - bt = extract64(bcr, 20, 4); - - switch (bt) { - case 4: /* unlinked address mismatch (reserved if AArch64) */ - case 5: /* linked address mismatch (reserved if AArch64) */ - qemu_log_mask(LOG_UNIMP, - "arm: address mismatch breakpoint types not implemented\n"); - return; - case 0: /* unlinked address match */ - case 1: /* linked address match */ - { - /* - * Bits [1:0] are RES0. - * - * It is IMPLEMENTATION DEFINED whether bits [63:49] - * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit - * of the VA field ([48] or [52] for FEAT_LVA), or whether the - * value is read as written. It is CONSTRAINED UNPREDICTABLE - * whether the RESS bits are ignored when comparing an address. - * Therefore we are allowed to compare the entire register, which - * lets us avoid considering whether FEAT_LVA is actually enabled. - * - * The BAS field is used to allow setting breakpoints on 16-bit - * wide instructions; it is CONSTRAINED UNPREDICTABLE whether - * a bp will fire if the addresses covered by the bp and the addresses - * covered by the insn overlap but the insn doesn't start at the - * start of the bp address range. We choose to require the insn and - * the bp to have the same address. The constraints on writing to - * BAS enforced in dbgbcr_write mean we have only four cases: - * 0b0000 => no breakpoint - * 0b0011 => breakpoint on addr - * 0b1100 => breakpoint on addr + 2 - * 0b1111 => breakpoint on addr - * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c). - */ - int bas = extract64(bcr, 5, 4); - addr = bvr & ~3ULL; - if (bas == 0) { - return; - } - if (bas == 0xc) { - addr += 2; - } - break; - } - case 2: /* unlinked context ID match */ - case 8: /* unlinked VMID match (reserved if no EL2) */ - case 10: /* unlinked context ID and VMID match (reserved if no EL2) */ - qemu_log_mask(LOG_UNIMP, - "arm: unlinked context breakpoint types not implemented\n"); - return; - case 9: /* linked VMID match (reserved if no EL2) */ - case 11: /* linked context ID and VMID match (reserved if no EL2) */ - case 3: /* linked context ID match */ - default: - /* - * We must generate no events for Linked context matches (unless - * they are linked to by some other bp/wp, which is handled in - * updates for the linking bp/wp). We choose to also generate no events - * for reserved values. - */ - return; - } - - cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]); -} - -void hw_breakpoint_update_all(ARMCPU *cpu) -{ - int i; - CPUARMState *env = &cpu->env; - - /* - * Completely clear out existing QEMU breakpoints and our array, to - * avoid possible stale entries following migration load. - */ - cpu_breakpoint_remove_all(CPU(cpu), BP_CPU); - memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint)); - - for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) { - hw_breakpoint_update(cpu, i); - } -} - -static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = env_archcpu(env); - int i = ri->crm; - - raw_write(env, ri, value); - hw_breakpoint_update(cpu, i); -} - -static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = env_archcpu(env); - int i = ri->crm; - - /* - * BAS[3] is a read-only copy of BAS[2], and BAS[1] a read-only - * copy of BAS[0]. - */ - value = deposit64(value, 6, 1, extract64(value, 5, 1)); - value = deposit64(value, 8, 1, extract64(value, 7, 1)); - - raw_write(env, ri, value); - hw_breakpoint_update(cpu, i); -} - -static void define_debug_regs(ARMCPU *cpu) -{ - /* - * Define v7 and v8 architectural debug registers. - * These are just dummy implementations for now. - */ - int i; - int wrps, brps, ctx_cmps; - - /* - * The Arm ARM says DBGDIDR is optional and deprecated if EL1 cannot - * use AArch32. Given that bit 15 is RES1, if the value is 0 then - * the register must not exist for this cpu. - */ - if (cpu->isar.dbgdidr != 0) { - ARMCPRegInfo dbgdidr = { - .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, - .opc1 = 0, .opc2 = 0, - .access = PL0_R, .accessfn = access_tda, - .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr, - }; - define_one_arm_cp_reg(cpu, &dbgdidr); - } - - brps = arm_num_brps(cpu); - wrps = arm_num_wrps(cpu); - ctx_cmps = arm_num_ctx_cmps(cpu); - - assert(ctx_cmps <= brps); - - define_arm_cp_regs(cpu, debug_cp_reginfo); - - if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) { - define_arm_cp_regs(cpu, debug_lpae_cp_reginfo); - } - - for (i = 0; i < brps; i++) { - char *dbgbvr_el1_name = g_strdup_printf("DBGBVR%d_EL1", i); - char *dbgbcr_el1_name = g_strdup_printf("DBGBCR%d_EL1", i); - ARMCPRegInfo dbgregs[] = { - { .name = dbgbvr_el1_name, .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4, - .access = PL1_RW, .accessfn = access_tda, - .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]), - .writefn = dbgbvr_write, .raw_writefn = raw_write - }, - { .name = dbgbcr_el1_name, .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5, - .access = PL1_RW, .accessfn = access_tda, - .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]), - .writefn = dbgbcr_write, .raw_writefn = raw_write - }, - }; - define_arm_cp_regs(cpu, dbgregs); - g_free(dbgbvr_el1_name); - g_free(dbgbcr_el1_name); - } - - for (i = 0; i < wrps; i++) { - char *dbgwvr_el1_name = g_strdup_printf("DBGWVR%d_EL1", i); - char *dbgwcr_el1_name = g_strdup_printf("DBGWCR%d_EL1", i); - ARMCPRegInfo dbgregs[] = { - { .name = dbgwvr_el1_name, .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6, - .access = PL1_RW, .accessfn = access_tda, - .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]), - .writefn = dbgwvr_write, .raw_writefn = raw_write - }, - { .name = dbgwcr_el1_name, .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7, - .access = PL1_RW, .accessfn = access_tda, - .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]), - .writefn = dbgwcr_write, .raw_writefn = raw_write - }, - }; - define_arm_cp_regs(cpu, dbgregs); - g_free(dbgwvr_el1_name); - g_free(dbgwcr_el1_name); - } -} - static void define_pmu_regs(ARMCPU *cpu) { /* From patchwork Thu Jun 30 19:41:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 586096 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:5036:0:0:0:0 with SMTP id e22csp704370mab; Thu, 30 Jun 2022 12:44:41 -0700 (PDT) X-Google-Smtp-Source: AGRyM1s8zyM0sV1cUGif/lTfefwAE6FJllexxUXAwac5uhlF8SfBcUPWNozH3LA7mXEhS5OguyFc X-Received: by 2002:ad4:5949:0:b0:470:b658:98ab with SMTP id eo9-20020ad45949000000b00470b65898abmr12672078qvb.118.1656618280939; Thu, 30 Jun 2022 12:44:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656618280; cv=none; d=google.com; s=arc-20160816; b=rKXAUGqRdITxOODyBMjHnMBlc7wGXVQAfy7jReAYjl/aAIc0eOFoCYkVt6hcvhZrar TZYkdPmA+mTEYl0LXqvZi7CPUlpeIoReOoKKerRauENmYcQgOLE2XG3KbfW6i2LgDjVH /vkJwewBmb8NHIQAVbL5pIHcnCFEkO5+h+/whNdjNvCBaS/CU8BMZH/N4PTgglENdxSa sTgfWM+T0bqmw+2U7byqrxvVYs0IB9nSBehm0ylOrgmCGF4KXx8RccGV/q6ZvypsWm4s tiKeSNtABV6ab/sKhjBguTWQFc4A4/ALrRaFpj2NlbQOOW5fvNOOxXbjabR2PMCLLPoJ um/Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=NJ/AhFBVNeKie2SLbn7FmgaDpmNEtGrcl/kxe6zssvA=; b=rpADhGqBOMsTlQbPjesWx3nU2gOuw/e3x//gsgLQYE3pe6mEarly1lSeHIjIOarNsv kJ3Ptlrh4mYSbi1Wf5K56Q/FvIuhGitOAQv+RL4S9eVHGwchRex4WWM2ELsvNK55YG4c ZGWLa6yoRPwumWZfRhXCEAW4PBdVSN9XO+P9PUQ9oJMH+wV4/InuLzQVhkKsVlC8f8wM qgyiw1UJRYepBa4UetM7Pe4ka3z51axrkum95UBzOFBnj4aYC77A3uz6kYNhrvJyq5/I J0d0UJLXqOeY5SerY1FqPA5WG7yacU9u+VedWcmEoehSU8niwH5/6W7nofPmSdBoMPPm IU9w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="wOlu/j7L"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id w9-20020a05622a134900b00304c1e094bdsi11683177qtk.666.2022.06.30.12.44.40 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 30 Jun 2022 12:44:40 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="wOlu/j7L"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:43054 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o705g-00038s-J2 for patch@linaro.org; Thu, 30 Jun 2022 15:44:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:55156) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o702f-00031s-6K for qemu-devel@nongnu.org; Thu, 30 Jun 2022 15:41:33 -0400 Received: from mail-wm1-x333.google.com ([2a00:1450:4864:20::333]:41607) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1o702X-0005hI-Rl for qemu-devel@nongnu.org; Thu, 30 Jun 2022 15:41:30 -0400 Received: by mail-wm1-x333.google.com with SMTP id t17-20020a1c7711000000b003a0434b0af7so250897wmi.0 for ; Thu, 30 Jun 2022 12:41:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=NJ/AhFBVNeKie2SLbn7FmgaDpmNEtGrcl/kxe6zssvA=; b=wOlu/j7LCwBjJhUVYAwscycupj2WyrMC1iLuHQupuN1in9zolJ51yj0XeOBzScV2Rt pD/cJcx4n2tEfUv8ZQxtOXW93zp53z+PG7iMU2pQTY4oakmOvTDoGncT16RN7EDFz6Hz p8nHO4YqFWYn9+MFiaN1BmLydZS2VhfS/d+yGnSjUf5lqlTeH7TwV4XXdaDH3GB6643v OzaDumip/e+cRG0wepEKrQLJQWLn7RQk0C3smFVPMFL///Pen6l5zQJucapBsEbCmYjk L+muIspoJY1dL0LdnUkESfGlblzvbY5LCy0VQtsgcSNaEOHyBi0P2Fpu+6PK5IbiuKEU RQZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NJ/AhFBVNeKie2SLbn7FmgaDpmNEtGrcl/kxe6zssvA=; b=kiqHim9grDk8UZiCtdJqDkGfGUcQqoxRxB2/2beWxwcc1BiFUYgZyfYg6NohVDzGVq p2M0ezyw2xdw9AaB9XYIlzX8NFp7Bh7Th49rkSoJYOQr7mVo0fq1WdSCebm2AOpyTNfW D5F8wuviopmUh0icEclHqTbafsgDaOOP+xdDBzJfQJEDLOPwzOYxk/rO2YcRuRu8TsU+ R10ytR+lsB9AtZSHvX+HhWylNM1dVronmfyRhVQdmYOSXpBTV2+vtjhZSUzOaDcVEkwB l5CQmX4TgfrEeDvpJpEOp5NAMWYcYL+CuhzojAoleklu++nrUHaR+X6T4EPUhNAYVw1U 4qMg== X-Gm-Message-State: AJIora/7qMCO+63qwKD5FqyZuXNki3obK3SEO6S4TJXWZjF+bv2bJNqz iRT0MNczuErLxP1wTvs1jmoHSA== X-Received: by 2002:a05:600c:601c:b0:3a0:4cd9:ed46 with SMTP id az28-20020a05600c601c00b003a04cd9ed46mr14023558wmb.139.1656618084502; Thu, 30 Jun 2022 12:41:24 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by smtp.gmail.com with ESMTPSA id m2-20020adffa02000000b0021d163daeb0sm13200228wrr.108.2022.06.30.12.41.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Jun 2022 12:41:24 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 3/5] target/arm: Suppress debug exceptions when OS Lock set Date: Thu, 30 Jun 2022 20:41:14 +0100 Message-Id: <20220630194116.3438513-4-peter.maydell@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220630194116.3438513-1-peter.maydell@linaro.org> References: <20220630194116.3438513-1-peter.maydell@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::333; envelope-from=peter.maydell@linaro.org; helo=mail-wm1-x333.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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" The "OS Lock" in the Arm debug architecture is a way for software to suppress debug exceptions while it is trying to power down a CPU and save the state of the breakpoint and watchpoint registers. In QEMU we implemented the support for writing the OS Lock bit via OSLAR_EL1 and reading it via OSLSR_EL1, but didn't implement the actual behaviour. The required behaviour with the OS Lock set is: * debug exceptions (apart from BKPT insns) are suppressed * some MDSCR_EL1 bits allow write access to the corresponding EDSCR external debug status register that they shadow (we can ignore this because we don't implement external debug) * similarly with the OSECCR_EL1 which shadows the EDECCR (but we don't implement OSECCR_EL1 anyway) Implement the missing behaviour of suppressing debug exceptions. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/debug_helper.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c index 9a78c1db966..691b9b74c4a 100644 --- a/target/arm/debug_helper.c +++ b/target/arm/debug_helper.c @@ -142,6 +142,9 @@ static bool aa32_generate_debug_exceptions(CPUARMState *env) */ bool arm_generate_debug_exceptions(CPUARMState *env) { + if (env->cp15.oslsr_el1 & 1) { + return false; + } if (is_a64(env)) { return aa64_generate_debug_exceptions(env); } else { From patchwork Thu Jun 30 19:41:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 586097 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:5036:0:0:0:0 with SMTP id e22csp705356mab; Thu, 30 Jun 2022 12:45:45 -0700 (PDT) X-Google-Smtp-Source: AGRyM1sJPUiE8OvulTWlx6PDBUWZh/wVlpSYRXmNiGAyK2A6mgWtg4ZFlinTTS/RIbtpdfl/iPIi X-Received: by 2002:a05:620a:110e:b0:6af:2780:8241 with SMTP id o14-20020a05620a110e00b006af27808241mr7699388qkk.552.1656618345346; Thu, 30 Jun 2022 12:45:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656618345; cv=none; d=google.com; s=arc-20160816; b=wEulbOnmTEaNBDVqYJwIDuwhoicpRSq9NVMfA5Uj4oQ/gWK39Q0nZ1topey9IPwzxN +MpYszOAMSsnurjdascVok5Mul3nczDTDhSzXeFlfgczi7vZ4l81pXRX2Ux47czltYxN iL8KeJdf4RybhyydsNYAlb61OCJJ6PO8gfx6onDSFX7HC1RqL8tP+uK9YqQMxE7zP0kw TEMJAcvWP1CMZWKiwxKDB/nc4Gsg32wUT+jkJqZjmyIJ7imUNLceNpmIcW5wEAvedX3R W3PRn46Tn7mwokDgLxHBrLmZQvxN2xflqJhPm69Vu3Ru6SLZu9312+Hpf0SheG1tzRmg MQPQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=ahC5lT6iTXSDW+ViPehdtBvZE2IkaR7EsRwDpZjYPrA=; b=lYzI5rrX5A+DHt38iRIht0fSOd+4nmz+VaRmnJmZgZOHdf+C/u4RGiJWL1m2zqArRg +BXtjyB2hNymp0j+8jGq4IwLnf6LSXMgdl+yYlUK6Wxo0Ve+YoFKnlyCbYt5C8I7T2Gf RXCgeo/bo9UUq8OSPWZk97ET4JYf4vZo06naKUm0m5fWjohm2WeCkY50fuHLfHkVSd2F LempsMJaSUFxbcmniYfsSxOewe3KTG9ua2hte5xNVDI4I870dbOxtG9AXkAG+YQUMl+0 YLweTHw3ojt3TewwN4/ke/iFL2A/dD0nNBIGJ1anxwuhUvFQMX+SIGS3dN97eUXXiqck Rc6A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FFtBUT7K; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id 17-20020a05620a071100b006af21744d9bsi7126454qkc.333.2022.06.30.12.45.45 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 30 Jun 2022 12:45:45 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FFtBUT7K; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:44082 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o706i-0003qw-5r for patch@linaro.org; Thu, 30 Jun 2022 15:45:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:55158) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o702f-00031t-61 for qemu-devel@nongnu.org; Thu, 30 Jun 2022 15:41:33 -0400 Received: from mail-wr1-x431.google.com ([2a00:1450:4864:20::431]:44611) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1o702Y-0005ht-Tx for qemu-devel@nongnu.org; Thu, 30 Jun 2022 15:41:32 -0400 Received: by mail-wr1-x431.google.com with SMTP id i1so39185wrb.11 for ; Thu, 30 Jun 2022 12:41:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=ahC5lT6iTXSDW+ViPehdtBvZE2IkaR7EsRwDpZjYPrA=; b=FFtBUT7KcLSVGVTFx3yqfW55pZKUltEo1KM/XlYBNKUEqLWy2QRFIAUWcv+bRjxGFc sBJa13FB11zKIkrh2TXA+WVryDhpCoN9AXljKnz654G9GPsdvH1Djqtl0mZ0ebUifL0e OoTqzrju8ox+4CPbCEE+ZHph7xPK+S+kAOq4YVnl8IAZVcDqTofNimVhhXFkaUIBuRRt NjY5P4P2iB6+d3RJj32/AW5+5jqAnrM0WXietW+QIFE8prQB8LUsNxLdBFdR4ijPpezP gkFpX+FcqHriS1aKc+X32W1H7xlhjchM3+ZOOzSDg1zITCrEneydZfgQZh3z4TNaFsHS Xf3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ahC5lT6iTXSDW+ViPehdtBvZE2IkaR7EsRwDpZjYPrA=; b=cO+roZ/Sgt/P23tErTHiV0SuitNLsCAnFqrnde0Me6CROArAG4ITVXg7N35v/FUtrd DOszS+1sANphcPEZ+B90Ep34/K8hsto5W2MQE9EiOdA3+L3cE8lGY2h1gT0GqCIIipE2 cE0IHuFjC0w/BqyDvCXc2u75R4U9lDl1/mPFYnUilB+RTlTXEuf5FgqSIKxIo/a2QnKo K/rggTcFbNTiViSxMmli918HE+dUjh8/H3D3/isWa6V9YykZkabSgNZXGce3Jx3dDEC5 W72Aj8SQS7Ya4gMmf98Lc4Q0iyW+t9ZqAV6IsUHkzzs1drjGp2S7jrwvouUY17pkEImR WLPQ== X-Gm-Message-State: AJIora/NDc0VrPSGf0z0VVSwKrszL69+P/Txdwp05J9huojnJ7o+oszd SjmX+tfxNRhD3VyB5go8j02lWQ== X-Received: by 2002:adf:decc:0:b0:21b:8915:36da with SMTP id i12-20020adfdecc000000b0021b891536damr9949665wrn.261.1656618085516; Thu, 30 Jun 2022 12:41:25 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by smtp.gmail.com with ESMTPSA id m2-20020adffa02000000b0021d163daeb0sm13200228wrr.108.2022.06.30.12.41.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Jun 2022 12:41:25 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 4/5] target/arm: Implement AArch32 DBGDEVID, DBGDEVID1, DBGDEVID2 Date: Thu, 30 Jun 2022 20:41:15 +0100 Message-Id: <20220630194116.3438513-5-peter.maydell@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220630194116.3438513-1-peter.maydell@linaro.org> References: <20220630194116.3438513-1-peter.maydell@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::431; envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x431.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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Starting with v7 of the debug architecture, there are three extra ID registers that add information on top of that provided in DBGDIDR. These are DBGDEVID, DBGDEVID1 and DBGDEVID2. In the v7 debug architecture, DBGDEVID is optional, present only of DBGDIDR.DEVID_imp is set. In v7.1 all three must be present. Implement the missing registers. Note that we only need to set the values in the ARMISARegisters struct for the CPUs Cortex-A7, A15, A53, A57 and A72 (plus the 32-bit 'max' which uses the Cortex-A53 values): earlier CPUs didn't implement v7 of the architecture, and our other 64-bit CPUs (Cortex-A76, Neoverse-N1 and A64fx) don't have AArch32 support at EL1. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- Clearly no guest code users care about is trying to read these registers, or they'd have noticed the UNDEFs. But the AArch32 indicator that Feat_DoubleLock is present is in DBGDEVID, so I want it in ARMISARegisters so I can test against it. --- target/arm/cpu.h | 7 +++++++ target/arm/cpu64.c | 6 ++++++ target/arm/cpu_tcg.c | 6 ++++++ target/arm/debug_helper.c | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 4a4342f2622..c533ad0b64d 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -988,6 +988,8 @@ struct ArchCPU { uint32_t mvfr2; uint32_t id_dfr0; uint32_t dbgdidr; + uint32_t dbgdevid; + uint32_t dbgdevid1; uint64_t id_aa64isar0; uint64_t id_aa64isar1; uint64_t id_aa64pfr0; @@ -3719,6 +3721,11 @@ static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id) return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0; } +static inline bool isar_feature_aa32_debugv7p1(const ARMISARegisters *id) +{ + return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 5; +} + static inline bool isar_feature_aa32_debugv8p2(const ARMISARegisters *id) { return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 8; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 19188d6cc2a..b4fd4b7ec87 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -79,6 +79,8 @@ static void aarch64_a57_initfn(Object *obj) cpu->isar.id_aa64isar0 = 0x00011120; cpu->isar.id_aa64mmfr0 = 0x00001124; cpu->isar.dbgdidr = 0x3516d000; + cpu->isar.dbgdevid = 0x01110f13; + cpu->isar.dbgdevid1 = 0x2; cpu->isar.reset_pmcr_el0 = 0x41013000; cpu->clidr = 0x0a200023; cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */ @@ -134,6 +136,8 @@ static void aarch64_a53_initfn(Object *obj) cpu->isar.id_aa64isar0 = 0x00011120; cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */ cpu->isar.dbgdidr = 0x3516d000; + cpu->isar.dbgdevid = 0x00110f13; + cpu->isar.dbgdevid1 = 0x1; cpu->isar.reset_pmcr_el0 = 0x41033000; cpu->clidr = 0x0a200023; cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */ @@ -187,6 +191,8 @@ static void aarch64_a72_initfn(Object *obj) cpu->isar.id_aa64isar0 = 0x00011120; cpu->isar.id_aa64mmfr0 = 0x00001124; cpu->isar.dbgdidr = 0x3516d000; + cpu->isar.dbgdevid = 0x01110f13; + cpu->isar.dbgdevid1 = 0x2; cpu->isar.reset_pmcr_el0 = 0x41023000; cpu->clidr = 0x0a200023; cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */ diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c index b751a19c8a7..3099b38e32b 100644 --- a/target/arm/cpu_tcg.c +++ b/target/arm/cpu_tcg.c @@ -563,6 +563,8 @@ static void cortex_a7_initfn(Object *obj) cpu->isar.id_isar3 = 0x11112131; cpu->isar.id_isar4 = 0x10011142; cpu->isar.dbgdidr = 0x3515f005; + cpu->isar.dbgdevid = 0x01110f13; + cpu->isar.dbgdevid1 = 0x1; cpu->clidr = 0x0a200023; cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */ cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */ @@ -606,6 +608,8 @@ static void cortex_a15_initfn(Object *obj) cpu->isar.id_isar3 = 0x11112131; cpu->isar.id_isar4 = 0x10011142; cpu->isar.dbgdidr = 0x3515f021; + cpu->isar.dbgdevid = 0x01110f13; + cpu->isar.dbgdevid1 = 0x0; cpu->clidr = 0x0a200023; cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */ cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */ @@ -1098,6 +1102,8 @@ static void arm_max_initfn(Object *obj) cpu->isar.id_isar5 = 0x00011121; cpu->isar.id_isar6 = 0; cpu->isar.dbgdidr = 0x3516d000; + cpu->isar.dbgdevid = 0x00110f13; + cpu->isar.dbgdevid1 = 0x2; cpu->isar.reset_pmcr_el0 = 0x41013000; cpu->clidr = 0x0a200023; cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */ diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c index 691b9b74c4a..e96a4ffd28d 100644 --- a/target/arm/debug_helper.c +++ b/target/arm/debug_helper.c @@ -999,6 +999,42 @@ void define_debug_regs(ARMCPU *cpu) define_one_arm_cp_reg(cpu, &dbgdidr); } + /* + * DBGDEVID is present in the v7 debug architecture if + * DBGDIDR.DEVID_imp is 1 (bit 15); from v7.1 and on it is + * mandatory (and bit 15 is RES1). DBGDEVID1 and DBGDEVID2 exist + * from v7.1 of the debug architecture. Because no fields have yet + * been defined in DBGDEVID2 (and quite possibly none will ever + * be) we don't define an ARMISARegisters field for it. + * These registers exist only if EL1 can use AArch32, but that + * happens naturally because they are only PL1 accessible anyway. + */ + if (extract32(cpu->isar.dbgdidr, 15, 1)) { + ARMCPRegInfo dbgdevid = { + .name = "DBGDEVID", + .cp = 14, .opc1 = 0, .crn = 7, .opc2 = 2, .crn = 7, + .access = PL1_R, .accessfn = access_tda, + .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdevid, + }; + define_one_arm_cp_reg(cpu, &dbgdevid); + } + if (cpu_isar_feature(aa32_debugv7p1, cpu)) { + ARMCPRegInfo dbgdevid12[] = { + { + .name = "DBGDEVID1", + .cp = 14, .opc1 = 0, .crn = 7, .opc2 = 1, .crn = 7, + .access = PL1_R, .accessfn = access_tda, + .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdevid1, + }, { + .name = "DBGDEVID2", + .cp = 14, .opc1 = 0, .crn = 7, .opc2 = 0, .crn = 7, + .access = PL1_R, .accessfn = access_tda, + .type = ARM_CP_CONST, .resetvalue = 0, + }, + }; + define_arm_cp_regs(cpu, dbgdevid12); + } + brps = arm_num_brps(cpu); wrps = arm_num_wrps(cpu); ctx_cmps = arm_num_ctx_cmps(cpu); From patchwork Thu Jun 30 19:41:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 586098 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:5036:0:0:0:0 with SMTP id e22csp708461mab; Thu, 30 Jun 2022 12:49:55 -0700 (PDT) X-Google-Smtp-Source: AGRyM1vvFZd1WNMJ8t1i7ZemMKo2PxXPHsdp669RgxNKFYmaCtF9AEGs0xB63CTY+apcRdomU7fz X-Received: by 2002:a0c:efc6:0:b0:470:45a3:7986 with SMTP id a6-20020a0cefc6000000b0047045a37986mr14324573qvt.62.1656618595843; Thu, 30 Jun 2022 12:49:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656618595; cv=none; d=google.com; s=arc-20160816; b=Q1GjtrrzwbmzBUZLsS0JmT9KB98KI577DBZoW+fumJOCy+umUKaNvhiPw6eG2WOwKi lJdzaXV4jwb3oQbeZwQ4WVESFcKARA5MILyp7SJ6z1e8G6sEUC5KE294L+fEnnmsZuar 1a0ZgIrRxLzODsTpJw2zbHkBj28AP3UYkP8m7Gk6skcWKz49Rx1M0M45N5t+ztIBP9q0 BTgQWf7ZqjqVJfM6rJjdJ2P7K5jxFh8J346MbEEpClmj0o6QNF4VJoRCVO2Ts2FWW+JB JYE9WPtQ4QAtwCzVv6gc23xFg2Q7vHpzGOU80ZmYls/EBOut39W10UY/GJETTw5h9RIf Vu4Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=gxCySAGYvgbHeMWk/bvkJgi22PGqoAxpMgQUYLIF/6g=; b=oI4zfMtnHvdV2gWhIOdc1qR3X0rF4mQhFl95Gxg4m4E1Z7r3jsexNbApKhgzlRl3xB NgzSfIQ6KNgefnOK+I9J03TLkJAFn7JPH9g3umMF3wM6wKkJQ2y6R76ci4ilSnJkj7sw Y4xxYeiXIlIJ8m/2Z7kyavimA7+5g9KYl3TjwPzBTkYd8mcdeoUKUPD1Zr0cfEHap70t 36CpqvLxT2punGrE8iOjVWuPz0RsGjaFcJL3ng5e81hP96QCvEA5kQx9DjREvD9tn5Bg HlI47msXTCaMJvYzN1UhWdP1FLgTmIoJ2xZLpNYJ+8jLgH3Q+/HDzzLeFkCr1jF5fE22 wHOw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ocqGm0NZ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id d19-20020ac85d93000000b00304fea08485si12383006qtx.747.2022.06.30.12.49.55 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 30 Jun 2022 12:49:55 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ocqGm0NZ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52750 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o70Al-0001Vq-7E for patch@linaro.org; Thu, 30 Jun 2022 15:49:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:55164) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o702f-00031w-6N for qemu-devel@nongnu.org; Thu, 30 Jun 2022 15:41:33 -0400 Received: from mail-wr1-x435.google.com ([2a00:1450:4864:20::435]:46787) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1o702a-0005i8-2P for qemu-devel@nongnu.org; Thu, 30 Jun 2022 15:41:32 -0400 Received: by mail-wr1-x435.google.com with SMTP id i25so26348wrc.13 for ; Thu, 30 Jun 2022 12:41:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=gxCySAGYvgbHeMWk/bvkJgi22PGqoAxpMgQUYLIF/6g=; b=ocqGm0NZ2DXvR4jb2upcAUNmcCEiQmP5WnEP3+LsH21sdvvupj7uKb9BUIs03ty54D i4neekB+8NbIDytWdqUpSIJm8YzeXWQ+ajOLuNG7C5c3wMOlUDF2FrZaF3tUq/YjZPAu gRoKf9dTEouUBSlbV0tD8TZ6wI483lIa3Zh9xkym+hXeNw9sO5S4VMYNK3RUJdBGooOM +B3SqMR8dHy5FBE60c6exDT+I6lzrL9g+RgNYQ2Y1MurUHFBDwEJSoaufe7eOzskDcIL 4uX36SPwALgfT7RVGgJs165f7v5omdphvBQj2G6tfVXeoE0oX2/UtUPWKWjNVXRm7elW HTMw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gxCySAGYvgbHeMWk/bvkJgi22PGqoAxpMgQUYLIF/6g=; b=SsWXnsVBc1avJJ9qJZ6oQKsgbVwZkgaD4xmLnOJR4aSs4LSJqXu6QgR3oN2DOvTuwm gYYPCmYw7VRvkqccWopwsJG/FjWyg+hkUp8Kg6alD0fV66PNwlcPW7fuPbu4mkUDTm0/ b39QxYBTOcp9lvrZLyOUU173Nf1SpRJOSx73lcC7LN+bvi+0gvl8KLpydDSMc1jZWn0X QualDyyXuOFDf6470R3Lv6Yx5TCs1raJpyfW4oSRMaj2XwWZHYOPQ5dbnUBipHQqqEbN pjaBX5j2ty3UNjgsMZYlnxuRqJh2CCjz83OHmtEH/U1IilfwzUNkPrMTIlzmuhhjvcj9 xSzQ== X-Gm-Message-State: AJIora8woDKL82+hGYUhDWdUM8wnBINSW9aTBHqJfgQ3cb768HbmlHg6 liPHICCAIkat+qkzs/24xqy3jA== X-Received: by 2002:a5d:4e12:0:b0:21b:ae89:73e7 with SMTP id p18-20020a5d4e12000000b0021bae8973e7mr9825784wrt.386.1656618086809; Thu, 30 Jun 2022 12:41:26 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by smtp.gmail.com with ESMTPSA id m2-20020adffa02000000b0021d163daeb0sm13200228wrr.108.2022.06.30.12.41.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Jun 2022 12:41:26 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 5/5] target/arm: Correctly implement Feat_DoubleLock Date: Thu, 30 Jun 2022 20:41:16 +0100 Message-Id: <20220630194116.3438513-6-peter.maydell@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220630194116.3438513-1-peter.maydell@linaro.org> References: <20220630194116.3438513-1-peter.maydell@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::435; envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x435.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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" The architecture defines the OS DoubleLock as a register which (similarly to the OS Lock) suppresses debug events for use in CPU powerdown sequences. This functionality is required in Arm v7 and v8.0; from v8.2 it becomes optional and in v9 it must not be implemented. Currently in QEMU we implement the OSDLR_EL1 register as a NOP. This is wrong both for the "feature implemented" and the "feature not implemented" cases: if the feature is implemented then the DLK bit should read as written and cause suppression of debug exceptions, and if it is not implemented then the bit must be RAZ/WI. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- Is there a nicer way to implement the isar_any feature test ? What I have here is correct but a bit ad-hoc. --- target/arm/cpu.h | 36 ++++++++++++++++++++++++++++++++++++ target/arm/debug_helper.c | 17 +++++++++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index c533ad0b64d..069dfe1d308 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -500,6 +500,7 @@ typedef struct CPUArchState { uint64_t dbgwcr[16]; /* watchpoint control registers */ uint64_t mdscr_el1; uint64_t oslsr_el1; /* OS Lock Status */ + uint64_t osdlr_el1; /* OS DoubleLock status */ uint64_t mdcr_el2; uint64_t mdcr_el3; /* Stores the architectural value of the counter *the last time it was @@ -2253,6 +2254,15 @@ FIELD(DBGDIDR, CTX_CMPS, 20, 4) FIELD(DBGDIDR, BRPS, 24, 4) FIELD(DBGDIDR, WRPS, 28, 4) +FIELD(DBGDEVID, PCSAMPLE, 0, 4) +FIELD(DBGDEVID, WPADDRMASK, 4, 4) +FIELD(DBGDEVID, BPADDRMASK, 8, 4) +FIELD(DBGDEVID, VECTORCATCH, 12, 4) +FIELD(DBGDEVID, VIRTEXTNS, 16, 4) +FIELD(DBGDEVID, DOUBLELOCK, 20, 4) +FIELD(DBGDEVID, AUXREGS, 24, 4) +FIELD(DBGDEVID, CIDMASK, 28, 4) + FIELD(MVFR0, SIMDREG, 0, 4) FIELD(MVFR0, FPSP, 4, 4) FIELD(MVFR0, FPDP, 8, 4) @@ -3731,6 +3741,11 @@ static inline bool isar_feature_aa32_debugv8p2(const ARMISARegisters *id) return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 8; } +static inline bool isar_feature_aa32_doublelock(const ARMISARegisters *id) +{ + return FIELD_EX32(id->dbgdevid, DBGDEVID, DOUBLELOCK) > 0; +} + /* * 64-bit feature tests via id registers. */ @@ -4155,6 +4170,11 @@ static inline bool isar_feature_aa64_sme_fa64(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, FA64); } +static inline bool isar_feature_aa64_doublelock(const ARMISARegisters *id) +{ + return FIELD_SEX64(id->id_aa64dfr0, ID_AA64DFR0, DOUBLELOCK) >= 0; +} + /* * Feature tests for "does this exist in either 32-bit or 64-bit?" */ @@ -4198,6 +4218,22 @@ static inline bool isar_feature_any_ras(const ARMISARegisters *id) return isar_feature_aa64_ras(id) || isar_feature_aa32_ras(id); } +static inline bool isar_feature_any_doublelock(const ARMISARegisters *id) +{ + /* + * We can't just OR together the aa32 and aa64 checks, because + * if there is no AArch64 support the aa64 function will default + * to returning true for a zero id_aa64dfr0. + * We use "is id_aa64pfr0 non-zero" as a proxy for "do we have + * the AArch64 ID register values in id", because it's always the + * case that ID_AA64PFR0_EL1.EL0 at least will be non-zero. + */ + if (id->id_aa64pfr0) { + return isar_feature_aa64_doublelock(id); + } + return isar_feature_aa32_doublelock(id); +} + /* * Forward to the above feature tests given an ARMCPU pointer. */ diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c index e96a4ffd28d..62bd8f85383 100644 --- a/target/arm/debug_helper.c +++ b/target/arm/debug_helper.c @@ -142,7 +142,7 @@ static bool aa32_generate_debug_exceptions(CPUARMState *env) */ bool arm_generate_debug_exceptions(CPUARMState *env) { - if (env->cp15.oslsr_el1 & 1) { + if ((env->cp15.oslsr_el1 & 1) || (env->cp15.osdlr_el1 & 1)) { return false; } if (is_a64(env)) { @@ -614,6 +614,18 @@ static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri, env->cp15.oslsr_el1 = deposit32(env->cp15.oslsr_el1, 1, 1, oslock); } +static void osdlr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* + * Only defined bit is bit 0 (DLK); if Feat_DoubleLock is not + * implemented this is RAZ/WI. + */ + if (cpu_isar_feature(any_doublelock, env_archcpu(env))) { + env->cp15.osdlr_el1 = value & 1; + } +} + static const ARMCPRegInfo debug_cp_reginfo[] = { /* * DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped @@ -670,7 +682,8 @@ static const ARMCPRegInfo debug_cp_reginfo[] = { { .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4, .access = PL1_RW, .accessfn = access_tdosa, - .type = ARM_CP_NOP }, + .writefn = osdlr_write, + .fieldoffset = offsetof(CPUARMState, cp15.osdlr_el1) }, /* * Dummy DBGVCR: Linux wants to clear this on startup, but we don't * implement vector catch debug events yet.