From 2f14baaabca315e078597e3441bf8cf3dc703264 Mon Sep 17 00:00:00 2001 From: Curtis Dunham Date: Tue, 31 Jan 2017 17:11:24 +0000 Subject: arm, dev: refactor GIC Pl390 GICD_ITARGETSRn handling The aforementioned registers (Interrupt Processor Targets Registers) are banked per-CPU, but are read-only. This patch eliminates the per-CPU storage of these values that are simply computed. Change-Id: I52cafc2f58e87dd54239a71326c01f4923544689 Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/2442 Maintainer: Andreas Sandberg Reviewed-by: Weiping Liao --- src/dev/arm/gic_pl390.cc | 63 ++++++++++++++++++------------------------------ src/dev/arm/gic_pl390.hh | 24 +++++++++++------- 2 files changed, 38 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/dev/arm/gic_pl390.cc b/src/dev/arm/gic_pl390.cc index b65014d23..e7f3e32ef 100644 --- a/src/dev/arm/gic_pl390.cc +++ b/src/dev/arm/gic_pl390.cc @@ -217,31 +217,15 @@ Pl390::readDistributor(ContextID ctx, Addr daddr, size_t resp_sz) int_num); assert(int_num < INT_LINES_MAX); - // First 31 interrupts only target single processor (SGI) - if (int_num > 31) { - if (resp_sz == 1) { - return cpuTarget[int_num]; - } else { - assert(resp_sz == 4); - int_num = mbits(int_num, 31, 2); - return (cpuTarget[int_num] | - cpuTarget[int_num+1] << 8 | - cpuTarget[int_num+2] << 16 | - cpuTarget[int_num+3] << 24) ; - } + if (resp_sz == 1) { + return getCpuTarget(ctx, int_num); } else { - assert(ctx < sys->numRunningContexts()); - uint32_t ctx_mask; - if (gem5ExtensionsEnabled) { - ctx_mask = ctx; - } else { - // convert the CPU id number into a bit mask - ctx_mask = power(2, ctx); - } - // replicate the 8-bit mask 4 times in a 32-bit word - ctx_mask |= ctx_mask << 8; - ctx_mask |= ctx_mask << 16; - return ctx_mask; + assert(resp_sz == 4); + int_num = mbits(int_num, 31, 2); + return (getCpuTarget(ctx, int_num) | + getCpuTarget(ctx, int_num+1) << 8 | + getCpuTarget(ctx, int_num+2) << 16 | + getCpuTarget(ctx, int_num+3) << 24) ; } } @@ -477,18 +461,18 @@ Pl390::writeDistributor(ContextID ctx, Addr daddr, uint32_t data, if (GICD_ITARGETSR.contains(daddr)) { Addr int_num = daddr - GICD_ITARGETSR.start(); - // First 31 interrupts only target single processor - if (int_num >= SGI_MAX) { + // Interrupts 0-31 are read only + unsigned offset = SGI_MAX + PPI_MAX; + if (int_num >= offset) { + unsigned ix = int_num - offset; // index into cpuTarget array if (data_sz == 1) { - cpuTarget[int_num] = data & 0xff; + cpuTarget[ix] = data & 0xff; } else { assert (data_sz == 4); - int_num = mbits(int_num, 31, 2); - uint32_t tmp = data; - cpuTarget[int_num] = bits(tmp, 7, 0); - cpuTarget[int_num+1] = bits(tmp, 15, 8); - cpuTarget[int_num+2] = bits(tmp, 23, 16); - cpuTarget[int_num+3] = bits(tmp, 31, 24); + cpuTarget[ix] = bits(data, 7, 0); + cpuTarget[ix+1] = bits(data, 15, 8); + cpuTarget[ix+2] = bits(data, 23, 16); + cpuTarget[ix+3] = bits(data, 31, 24); } updateIntState(int_num >> 2); } @@ -733,8 +717,8 @@ Pl390::updateIntState(int hint) (getIntPriority(cpu, int_nm) < highest_pri)) if ((!mp_sys) || (gem5ExtensionsEnabled - ? (cpuTarget[int_nm] == cpu) - : (cpuTarget[int_nm] & (1 << cpu)))) { + ? (getCpuTarget(cpu, int_nm) == cpu) + : (getCpuTarget(cpu, int_nm) & (1 << cpu)))) { highest_pri = getIntPriority(cpu, int_nm); highest_int = int_nm; } @@ -792,13 +776,14 @@ Pl390::updateRunPri() void Pl390::sendInt(uint32_t num) { + uint8_t target = getCpuTarget(0, num); DPRINTF(Interrupt, "Received Interrupt number %d, cpuTarget %#x: \n", - num, cpuTarget[num]); - if ((cpuTarget[num] & (cpuTarget[num] - 1)) && !gem5ExtensionsEnabled) + num, target); + if ((target & (target - 1)) && !gem5ExtensionsEnabled) panic("Multiple targets for peripheral interrupts is not supported\n"); panic_if(num < SGI_MAX + PPI_MAX, "sentInt() must only be used for interrupts 32 and higher"); - getPendingInt(cpuTarget[num], intNumToWord(num)) |= 1 << intNumToBit(num); + getPendingInt(target, intNumToWord(num)) |= 1 << intNumToBit(num); updateIntState(intNumToWord(num)); } @@ -896,7 +881,6 @@ Pl390::BankedRegs::serialize(CheckpointOut &cp) const SERIALIZE_SCALAR(pendingInt); SERIALIZE_SCALAR(activeInt); SERIALIZE_ARRAY(intPriority, SGI_MAX + PPI_MAX); - SERIALIZE_ARRAY(cpuTarget, SGI_MAX + PPI_MAX); } void @@ -955,7 +939,6 @@ Pl390::BankedRegs::unserialize(CheckpointIn &cp) UNSERIALIZE_SCALAR(pendingInt); UNSERIALIZE_SCALAR(activeInt); UNSERIALIZE_ARRAY(intPriority, SGI_MAX + PPI_MAX); - UNSERIALIZE_ARRAY(cpuTarget, SGI_MAX + PPI_MAX); } Pl390 * diff --git a/src/dev/arm/gic_pl390.hh b/src/dev/arm/gic_pl390.hh index aa3f3c084..210f91cfc 100644 --- a/src/dev/arm/gic_pl390.hh +++ b/src/dev/arm/gic_pl390.hh @@ -172,16 +172,11 @@ class Pl390 : public BaseGic * interrupt priority for SGIs and PPIs */ uint8_t intPriority[SGI_MAX + PPI_MAX]; - /** GICD_ITARGETSR{0..7} - * 8b CPU target ID for each SGI and PPI */ - uint8_t cpuTarget[SGI_MAX + PPI_MAX]; - void serialize(CheckpointOut &cp) const override; void unserialize(CheckpointIn &cp) override; BankedRegs() : - intEnabled(0), pendingInt(0), activeInt(0), - intPriority {0}, cpuTarget {0} + intEnabled(0), pendingInt(0), activeInt(0), intPriority {0} {} }; std::vector bankedRegs; @@ -252,12 +247,23 @@ class Pl390 : public BaseGic */ uint8_t cpuTarget[GLOBAL_INT_LINES]; - uint8_t& getCpuTarget(ContextID ctx, uint32_t ix) { + uint8_t getCpuTarget(ContextID ctx, uint32_t ix) { + assert(ctx < sys->numRunningContexts()); assert(ix < INT_LINES_MAX); if (ix < SGI_MAX + PPI_MAX) { - return getBankedRegs(ctx).cpuTarget[ix]; + // "GICD_ITARGETSR0 to GICD_ITARGETSR7 are read-only, and each + // field returns a value that corresponds only to the processor + // reading the register." + uint32_t ctx_mask; + if (gem5ExtensionsEnabled) { + ctx_mask = ctx; + } else { + // convert the CPU id number into a bit mask + ctx_mask = power(2, ctx); + } + return ctx_mask; } else { - return cpuTarget[ix - (SGI_MAX + PPI_MAX)]; + return cpuTarget[ix - 32]; } } -- cgit v1.2.3