From patchwork Tue Nov 7 15:01:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 118178 Delivered-To: patches@linaro.org Received: by 10.80.245.45 with SMTP id t42csp624885edm; Tue, 7 Nov 2017 07:01:04 -0800 (PST) X-Google-Smtp-Source: ABhQp+Sfxi82hMXjAjgTsfBQ3v4wuDPHrmLvSNtfpj8ehIO66WO2SPm6OAxgsrWCsBHmO4FCD0qI X-Received: by 10.223.197.201 with SMTP id v9mr14674470wrg.82.1510066864646; Tue, 07 Nov 2017 07:01:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510066864; cv=none; d=google.com; s=arc-20160816; b=XLm0oo6HqMTyFUI1MDumst0IGCtLSTIuhGYfp6SS3+AiRjwn/ZB+QU383HZV+5+QSm trabfV+us2OeVI39lAiDu1skIaurq+9RrwUbyDf1m8VA7lTzGkLqZ42butRZw3EbyT5H RVV+XJtkEcdB9QJ5aKtoIKivlFmHyAjzj9iOILnydEa5vNc6XsfkwcTUXQj4hqYW7qQB gAkd6X9jQ05Zxk9IrRH8UCj7jcifH9i7BtA/4IsAsM5g6DXAyxTkSpwEEI4gkjKiS37A FKoTOcjtYp4gX3pNIDT7vPnqBkz6vtqgRAeqRBvOj0pJLhaJh1H8rBaMeYMLdYPT8jU8 9YnA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=message-id:date:subject:cc:to:from:arc-authentication-results; bh=HGquXareDZFji+QC1Q4/ffzK3e5pbgCXbUZroBJiAXw=; b=uplWdNBEeGJCLp6REGDL3GYR62L0JQ9NC+liLqSd3JLhpFUdLusyfgYJpe8rtSi+FO adzY3AQCfxCkEkB5u7hfL6Bfl5FPgSGYJLS3TqHsLakBwB1c6nsQF0lZFZcsMEJX+4N6 PnEOhQiBwbWigYlrMBP4lTFUdJiT290nktP0R9/++/Nrir0TugocYzlFsRuAzFTpbXXy Xf6dzKI0p0kacPCqSRCpvP+BH8sMLoCdlv1ciM0eNm85fO//Wd/JJeNOM4iKckTFA+px zReC1s6ZVFQBvtGNBH3YVF2X1xbAafv6OWSOYFlPEv0Zb2u6UGyhgNcsUlLLOp7G+4ne 8pkQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id u203si1211602wmb.268.2017.11.07.07.01.04 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 07 Nov 2017 07:01:04 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eC5N9-0004fo-ME; Tue, 07 Nov 2017 15:01:03 +0000 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org, Stefano Stabellini Subject: [PATCH for-2.11] target/arm: Report GICv3 sysregs present in ID registers if needed Date: Tue, 7 Nov 2017 15:01:38 +0000 Message-Id: <1510066898-3725-1-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 The CPU ID registers ID_AA64PFR0_EL1, ID_PFR1_EL1 and ID_PFR1 have a field for reporting presence of GICv3 system registers. We need to report this field correctly in order for Xen to work as a guest inside QEMU emulation. We mustn't incorrectly claim the sysregs exist when they don't, though, or Linux will crash. Unfortunately the way we've designed the GICv3 emulation in QEMU puts the system registers as part of the GICv3 device, which may be created after the CPU proper has been realized. This means that we don't know at the point when we define the ID registers what the correct value is. Handle this by switching them to calling a function at runtime to read the value, where we can fill in the GIC field appropriately. Signed-off-by: Peter Maydell --- In retrospect I think having the sysregs emulation in the GIC device was a bit of a design error -- we should have split it like the hardware does, with a defined protocol between the GIC and the CPU interface. (In real hardware the CPU can have the GIC system registers even though it's not connected to an actual GICv3, and we don't/can't emulate that with our current design.) --- target/arm/helper.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) -- 2.7.4 Tested-by: Stefano Stabellini Reviewed-by: Richard Henderson diff --git a/target/arm/helper.c b/target/arm/helper.c index f61fb3e..35c5bd6 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -4549,6 +4549,33 @@ static void define_debug_regs(ARMCPU *cpu) } } +/* We don't know until after realize whether there's a GICv3 + * attached, and that is what registers the gicv3 sysregs. + * So we have to fill in the GIC fields in ID_PFR/ID_PFR1_EL1/ID_AA64PFR0_EL1 + * at runtime. + */ +static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + uint64_t pfr1 = cpu->id_pfr1; + + if (env->gicv3state) { + pfr1 |= 1 << 28; + } + return pfr1; +} + +static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + uint64_t pfr0 = cpu->id_aa64pfr0; + + if (env->gicv3state) { + pfr0 |= 1 << 24; + } + return pfr0; +} + void register_cp_regs_for_features(ARMCPU *cpu) { /* Register all the coprocessor registers based on feature bits */ @@ -4573,10 +4600,14 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->id_pfr0 }, + /* ID_PFR1 is not a plain ARM_CP_CONST because we don't know + * the value of the GIC field until after we define these regs. + */ { .name = "ID_PFR1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_pfr1 }, + .access = PL1_R, .type = ARM_CP_NO_RAW, + .readfn = id_pfr1_read, + .writefn = arm_cp_write_ignore }, { .name = "ID_DFR0", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, @@ -4692,10 +4723,15 @@ void register_cp_regs_for_features(ARMCPU *cpu) * define new registers here. */ ARMCPRegInfo v8_idregs[] = { + /* ID_AA64PFR0_EL1 is not a plain ARM_CP_CONST because we don't + * know the right value for the GIC field until after we + * define these regs. + */ { .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_aa64pfr0 }, + .access = PL1_R, .type = ARM_CP_NO_RAW, + .readfn = id_aa64pfr0_read, + .writefn = arm_cp_write_ignore }, { .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST,