From ef984784289f8bd4ddedcc4a6ead2c45704cc35b Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Tue, 11 Sep 2018 12:57:36 +0100 Subject: [PATCH] dev-arm: Fix GICv2 cpu interrupt enable flag Read/WriteCpu methods in the GICv2 are accessing the GICC_CTRL register as if writing any non-zero value to the register will enable IRQ signaling to the CPU. Instead, only the 2 least significant bits control group0/group1 enablement. This patch is renaming GICC_CTRL underlying data buffer from cpuEnabled to cpuControl and it is making it an array of uint32_t instead of bool. cpuEnabled now becomes a method and checks if GICC_CTRL.EnableGrp0 or GICC_CTRL.EnableGrp0 are set. Change-Id: I40f0b3c52c40abd482a856f032bf3686f96ef641 Signed-off-by: Giacomo Travaglini Reviewed-on: https://gem5-review.googlesource.com/12945 Reviewed-by: Andreas Sandberg Maintainer: Andreas Sandberg --- src/dev/arm/gic_v2.cc | 34 +++++++++++++++++----------------- src/dev/arm/gic_v2.hh | 16 +++++++++++++++- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/dev/arm/gic_v2.cc b/src/dev/arm/gic_v2.cc index fd846387c..92949a34f 100644 --- a/src/dev/arm/gic_v2.cc +++ b/src/dev/arm/gic_v2.cc @@ -80,7 +80,7 @@ GicV2::GicV2(const Params *p) { for (int x = 0; x < CPU_MAX; x++) { iccrpr[x] = 0xff; - cpuEnabled[x] = false; + cpuControl[x] = 0; cpuPriority[x] = 0xff; cpuBpr[x] = GICC_BPR_MINIMUM; // Initialize cpu highest int @@ -89,8 +89,8 @@ GicV2::GicV2(const Params *p) new EventFunctionWrapper([this, x]{ postDelayedInt(x); }, "Post Interrupt to CPU"); } - DPRINTF(Interrupt, "cpuEnabled[0]=%d cpuEnabled[1]=%d\n", cpuEnabled[0], - cpuEnabled[1]); + DPRINTF(Interrupt, "cpuEnabled[0]=%d cpuEnabled[1]=%d\n", cpuEnabled(0), + cpuEnabled(1)); gem5ExtensionsEnabled = false; } @@ -302,13 +302,13 @@ GicV2::readCpu(ContextID ctx, Addr daddr) case GICC_IIDR: return GICC_400_IIDR_VALUE; case GICC_CTLR: - return cpuEnabled[ctx]; + return cpuControl[ctx]; case GICC_PMR: return cpuPriority[ctx]; case GICC_BPR: return cpuBpr[ctx]; case GICC_IAR: - if (enabled && cpuEnabled[ctx]) { + if (enabled && cpuEnabled(ctx)) { int active_int = cpuHighestInt[ctx]; IAR iar = 0; iar.ack_id = active_int; @@ -564,7 +564,7 @@ GicV2::writeCpu(ContextID ctx, Addr daddr, uint32_t data) { switch(daddr) { case GICC_CTLR: - cpuEnabled[ctx] = data; + cpuControl[ctx] = data; break; case GICC_PMR: cpuPriority[ctx] = data; @@ -616,7 +616,7 @@ GicV2::writeCpu(ContextID ctx, Addr daddr, uint32_t data) panic("Tried to write Gic cpu at offset %#x\n", daddr); break; } - if (cpuEnabled[ctx]) updateIntState(-1); + if (cpuEnabled(ctx)) updateIntState(-1); } GicV2::BankedRegs& @@ -639,7 +639,7 @@ GicV2::softInt(ContextID ctx, SWI swi) int dest = swi.cpu_list; DPRINTF(IPI, "Generating softIRQ from CPU %d for CPU %d\n", ctx, dest); - if (cpuEnabled[dest]) { + if (cpuEnabled(dest)) { cpuSgiPendingExt[dest] |= (1 << swi.sgi_id); DPRINTF(IPI, "SGI[%d]=%#x\n", dest, cpuSgiPendingExt[dest]); @@ -649,7 +649,7 @@ GicV2::softInt(ContextID ctx, SWI swi) // interrupt all for (int i = 0; i < sys->numContexts(); i++) { DPRINTF(IPI, "Processing CPU %d\n", i); - if (!cpuEnabled[i]) + if (!cpuEnabled(i)) continue; cpuSgiPendingExt[i] |= 1 << swi.sgi_id; DPRINTF(IPI, "SGI[%d]=%#x\n", swi.sgi_id, @@ -660,7 +660,7 @@ GicV2::softInt(ContextID ctx, SWI swi) // Interrupt requesting cpu only DPRINTF(IPI, "Generating softIRQ from CPU %d for CPU %d\n", ctx, ctx); - if (cpuEnabled[ctx]) { + if (cpuEnabled(ctx)) { cpuSgiPendingExt[ctx] |= (1 << swi.sgi_id); DPRINTF(IPI, "SGI[%d]=%#x\n", ctx, cpuSgiPendingExt[ctx]); @@ -674,7 +674,7 @@ GicV2::softInt(ContextID ctx, SWI swi) uint8_t cpu_list; cpu_list = 0; for (int x = 0; x < sys->numContexts(); x++) - cpu_list |= cpuEnabled[x] ? 1 << x : 0; + cpu_list |= cpuEnabled(x) ? 1 << x : 0; swi.cpu_list = cpu_list; break; case 2: @@ -688,7 +688,7 @@ GicV2::softInt(ContextID ctx, SWI swi) swi.cpu_list); for (int i = 0; i < sys->numContexts(); i++) { DPRINTF(IPI, "Processing CPU %d\n", i); - if (!cpuEnabled[i]) + if (!cpuEnabled(i)) continue; if (swi.cpu_list & (1 << i)) cpuSgiPending[swi.sgi_id] |= (1 << i) << (8 * ctx); @@ -722,7 +722,7 @@ void GicV2::updateIntState(int hint) { for (int cpu = 0; cpu < sys->numContexts(); cpu++) { - if (!cpuEnabled[cpu]) + if (!cpuEnabled(cpu)) continue; /*@todo use hint to do less work. */ @@ -799,7 +799,7 @@ GicV2::updateIntState(int hint) /* @todo make this work for more than one cpu, need to handle 1:N, N:N * models */ - if (enabled && cpuEnabled[cpu] && + if (enabled && cpuEnabled(cpu) && (highest_pri < getCpuPriority(cpu)) && !(getActiveInt(cpu, intNumToWord(highest_int)) & (1 << intNumToBit(highest_int)))) { @@ -815,7 +815,7 @@ void GicV2::updateRunPri() { for (int cpu = 0; cpu < sys->numContexts(); cpu++) { - if (!cpuEnabled[cpu]) + if (!cpuEnabled(cpu)) continue; uint8_t maxPriority = 0xff; for (int i = 0; i < itLines; i++) { @@ -942,7 +942,7 @@ GicV2::serialize(CheckpointOut &cp) const SERIALIZE_ARRAY(intPriority, GLOBAL_INT_LINES); SERIALIZE_ARRAY(cpuTarget, GLOBAL_INT_LINES); SERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2); - SERIALIZE_ARRAY(cpuEnabled, CPU_MAX); + SERIALIZE_ARRAY(cpuControl, CPU_MAX); SERIALIZE_ARRAY(cpuPriority, CPU_MAX); SERIALIZE_ARRAY(cpuBpr, CPU_MAX); SERIALIZE_ARRAY(cpuHighestInt, CPU_MAX); @@ -984,7 +984,7 @@ GicV2::unserialize(CheckpointIn &cp) UNSERIALIZE_ARRAY(intPriority, GLOBAL_INT_LINES); UNSERIALIZE_ARRAY(cpuTarget, GLOBAL_INT_LINES); UNSERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2); - UNSERIALIZE_ARRAY(cpuEnabled, CPU_MAX); + UNSERIALIZE_ARRAY(cpuControl, CPU_MAX); UNSERIALIZE_ARRAY(cpuPriority, CPU_MAX); UNSERIALIZE_ARRAY(cpuBpr, CPU_MAX); UNSERIALIZE_ARRAY(cpuHighestInt, CPU_MAX); diff --git a/src/dev/arm/gic_v2.hh b/src/dev/arm/gic_v2.hh index 352b108d0..2057e7d5b 100644 --- a/src/dev/arm/gic_v2.hh +++ b/src/dev/arm/gic_v2.hh @@ -142,6 +142,12 @@ class GicV2 : public BaseGic, public BaseGicRegisters Bitfield<12,10> cpu_id; EndBitUnion(IAR) + BitUnion32(CTLR) + Bitfield<3> fiqEn; + Bitfield<1> enableGrp1; + Bitfield<0> enableGrp0; + EndBitUnion(CTLR) + protected: /* Params */ /** Address range for the distributor interface */ const AddrRange distRange; @@ -310,7 +316,15 @@ class GicV2 : public BaseGic, public BaseGicRegisters } /** CPU enabled */ - bool cpuEnabled[CPU_MAX]; + bool cpuEnabled(ContextID ctx) const { + return cpuControl[ctx].enableGrp0 || + cpuControl[ctx].enableGrp1; + } + + /** GICC_CTLR: + * CPU interface control register + */ + CTLR cpuControl[CPU_MAX]; /** CPU priority */ uint8_t cpuPriority[CPU_MAX]; -- 2.30.2