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 <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/2442 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-by: Weiping Liao <weipingliao@google.com>
This commit is contained in:
parent
bbdd34d628
commit
2f14baaabc
3 changed files with 38 additions and 51 deletions
|
@ -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];
|
||||
return getCpuTarget(ctx, 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) ;
|
||||
}
|
||||
} 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;
|
||||
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 *
|
||||
|
|
|
@ -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*> 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 {
|
||||
return cpuTarget[ix - (SGI_MAX + PPI_MAX)];
|
||||
// convert the CPU id number into a bit mask
|
||||
ctx_mask = power(2, ctx);
|
||||
}
|
||||
return ctx_mask;
|
||||
} else {
|
||||
return cpuTarget[ix - 32];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ def upgrader(cpt):
|
|||
b_intEnabled = intEnabled[0]
|
||||
b_pendingInt = pendingInt[0]
|
||||
b_activeInt = activeInt[0]
|
||||
b_cpuTarget = cpuTarget[0:32]
|
||||
|
||||
del intEnabled[0]
|
||||
del pendingInt[0]
|
||||
|
@ -78,4 +77,3 @@ def upgrader(cpt):
|
|||
cpt.set(new_sec, 'pendingInt', b_pendingInt)
|
||||
cpt.set(new_sec, 'activeInt', b_activeInt)
|
||||
cpt.set(new_sec, 'intPriority',' '.join(intPriority))
|
||||
cpt.set(new_sec, 'cpuTarget', ' '.join(b_cpuTarget))
|
||||
|
|
Loading…
Reference in a new issue