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);
|
int_num);
|
||||||
assert(int_num < INT_LINES_MAX);
|
assert(int_num < INT_LINES_MAX);
|
||||||
|
|
||||||
// First 31 interrupts only target single processor (SGI)
|
if (resp_sz == 1) {
|
||||||
if (int_num > 31) {
|
return getCpuTarget(ctx, int_num);
|
||||||
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) ;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
assert(ctx < sys->numRunningContexts());
|
assert(resp_sz == 4);
|
||||||
uint32_t ctx_mask;
|
int_num = mbits(int_num, 31, 2);
|
||||||
if (gem5ExtensionsEnabled) {
|
return (getCpuTarget(ctx, int_num) |
|
||||||
ctx_mask = ctx;
|
getCpuTarget(ctx, int_num+1) << 8 |
|
||||||
} else {
|
getCpuTarget(ctx, int_num+2) << 16 |
|
||||||
// convert the CPU id number into a bit mask
|
getCpuTarget(ctx, int_num+3) << 24) ;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,18 +461,18 @@ Pl390::writeDistributor(ContextID ctx, Addr daddr, uint32_t data,
|
||||||
|
|
||||||
if (GICD_ITARGETSR.contains(daddr)) {
|
if (GICD_ITARGETSR.contains(daddr)) {
|
||||||
Addr int_num = daddr - GICD_ITARGETSR.start();
|
Addr int_num = daddr - GICD_ITARGETSR.start();
|
||||||
// First 31 interrupts only target single processor
|
// Interrupts 0-31 are read only
|
||||||
if (int_num >= SGI_MAX) {
|
unsigned offset = SGI_MAX + PPI_MAX;
|
||||||
|
if (int_num >= offset) {
|
||||||
|
unsigned ix = int_num - offset; // index into cpuTarget array
|
||||||
if (data_sz == 1) {
|
if (data_sz == 1) {
|
||||||
cpuTarget[int_num] = data & 0xff;
|
cpuTarget[ix] = data & 0xff;
|
||||||
} else {
|
} else {
|
||||||
assert (data_sz == 4);
|
assert (data_sz == 4);
|
||||||
int_num = mbits(int_num, 31, 2);
|
cpuTarget[ix] = bits(data, 7, 0);
|
||||||
uint32_t tmp = data;
|
cpuTarget[ix+1] = bits(data, 15, 8);
|
||||||
cpuTarget[int_num] = bits(tmp, 7, 0);
|
cpuTarget[ix+2] = bits(data, 23, 16);
|
||||||
cpuTarget[int_num+1] = bits(tmp, 15, 8);
|
cpuTarget[ix+3] = bits(data, 31, 24);
|
||||||
cpuTarget[int_num+2] = bits(tmp, 23, 16);
|
|
||||||
cpuTarget[int_num+3] = bits(tmp, 31, 24);
|
|
||||||
}
|
}
|
||||||
updateIntState(int_num >> 2);
|
updateIntState(int_num >> 2);
|
||||||
}
|
}
|
||||||
|
@ -733,8 +717,8 @@ Pl390::updateIntState(int hint)
|
||||||
(getIntPriority(cpu, int_nm) < highest_pri))
|
(getIntPriority(cpu, int_nm) < highest_pri))
|
||||||
if ((!mp_sys) ||
|
if ((!mp_sys) ||
|
||||||
(gem5ExtensionsEnabled
|
(gem5ExtensionsEnabled
|
||||||
? (cpuTarget[int_nm] == cpu)
|
? (getCpuTarget(cpu, int_nm) == cpu)
|
||||||
: (cpuTarget[int_nm] & (1 << cpu)))) {
|
: (getCpuTarget(cpu, int_nm) & (1 << cpu)))) {
|
||||||
highest_pri = getIntPriority(cpu, int_nm);
|
highest_pri = getIntPriority(cpu, int_nm);
|
||||||
highest_int = int_nm;
|
highest_int = int_nm;
|
||||||
}
|
}
|
||||||
|
@ -792,13 +776,14 @@ Pl390::updateRunPri()
|
||||||
void
|
void
|
||||||
Pl390::sendInt(uint32_t num)
|
Pl390::sendInt(uint32_t num)
|
||||||
{
|
{
|
||||||
|
uint8_t target = getCpuTarget(0, num);
|
||||||
DPRINTF(Interrupt, "Received Interrupt number %d, cpuTarget %#x: \n",
|
DPRINTF(Interrupt, "Received Interrupt number %d, cpuTarget %#x: \n",
|
||||||
num, cpuTarget[num]);
|
num, target);
|
||||||
if ((cpuTarget[num] & (cpuTarget[num] - 1)) && !gem5ExtensionsEnabled)
|
if ((target & (target - 1)) && !gem5ExtensionsEnabled)
|
||||||
panic("Multiple targets for peripheral interrupts is not supported\n");
|
panic("Multiple targets for peripheral interrupts is not supported\n");
|
||||||
panic_if(num < SGI_MAX + PPI_MAX,
|
panic_if(num < SGI_MAX + PPI_MAX,
|
||||||
"sentInt() must only be used for interrupts 32 and higher");
|
"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));
|
updateIntState(intNumToWord(num));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -896,7 +881,6 @@ Pl390::BankedRegs::serialize(CheckpointOut &cp) const
|
||||||
SERIALIZE_SCALAR(pendingInt);
|
SERIALIZE_SCALAR(pendingInt);
|
||||||
SERIALIZE_SCALAR(activeInt);
|
SERIALIZE_SCALAR(activeInt);
|
||||||
SERIALIZE_ARRAY(intPriority, SGI_MAX + PPI_MAX);
|
SERIALIZE_ARRAY(intPriority, SGI_MAX + PPI_MAX);
|
||||||
SERIALIZE_ARRAY(cpuTarget, SGI_MAX + PPI_MAX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -955,7 +939,6 @@ Pl390::BankedRegs::unserialize(CheckpointIn &cp)
|
||||||
UNSERIALIZE_SCALAR(pendingInt);
|
UNSERIALIZE_SCALAR(pendingInt);
|
||||||
UNSERIALIZE_SCALAR(activeInt);
|
UNSERIALIZE_SCALAR(activeInt);
|
||||||
UNSERIALIZE_ARRAY(intPriority, SGI_MAX + PPI_MAX);
|
UNSERIALIZE_ARRAY(intPriority, SGI_MAX + PPI_MAX);
|
||||||
UNSERIALIZE_ARRAY(cpuTarget, SGI_MAX + PPI_MAX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pl390 *
|
Pl390 *
|
||||||
|
|
|
@ -172,16 +172,11 @@ class Pl390 : public BaseGic
|
||||||
* interrupt priority for SGIs and PPIs */
|
* interrupt priority for SGIs and PPIs */
|
||||||
uint8_t intPriority[SGI_MAX + PPI_MAX];
|
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 serialize(CheckpointOut &cp) const override;
|
||||||
void unserialize(CheckpointIn &cp) override;
|
void unserialize(CheckpointIn &cp) override;
|
||||||
|
|
||||||
BankedRegs() :
|
BankedRegs() :
|
||||||
intEnabled(0), pendingInt(0), activeInt(0),
|
intEnabled(0), pendingInt(0), activeInt(0), intPriority {0}
|
||||||
intPriority {0}, cpuTarget {0}
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
std::vector<BankedRegs*> bankedRegs;
|
std::vector<BankedRegs*> bankedRegs;
|
||||||
|
@ -252,12 +247,23 @@ class Pl390 : public BaseGic
|
||||||
*/
|
*/
|
||||||
uint8_t cpuTarget[GLOBAL_INT_LINES];
|
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);
|
assert(ix < INT_LINES_MAX);
|
||||||
if (ix < SGI_MAX + PPI_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 {
|
} else {
|
||||||
return cpuTarget[ix - (SGI_MAX + PPI_MAX)];
|
return cpuTarget[ix - 32];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,6 @@ def upgrader(cpt):
|
||||||
b_intEnabled = intEnabled[0]
|
b_intEnabled = intEnabled[0]
|
||||||
b_pendingInt = pendingInt[0]
|
b_pendingInt = pendingInt[0]
|
||||||
b_activeInt = activeInt[0]
|
b_activeInt = activeInt[0]
|
||||||
b_cpuTarget = cpuTarget[0:32]
|
|
||||||
|
|
||||||
del intEnabled[0]
|
del intEnabled[0]
|
||||||
del pendingInt[0]
|
del pendingInt[0]
|
||||||
|
@ -78,4 +77,3 @@ def upgrader(cpt):
|
||||||
cpt.set(new_sec, 'pendingInt', b_pendingInt)
|
cpt.set(new_sec, 'pendingInt', b_pendingInt)
|
||||||
cpt.set(new_sec, 'activeInt', b_activeInt)
|
cpt.set(new_sec, 'activeInt', b_activeInt)
|
||||||
cpt.set(new_sec, 'intPriority',' '.join(intPriority))
|
cpt.set(new_sec, 'intPriority',' '.join(intPriority))
|
||||||
cpt.set(new_sec, 'cpuTarget', ' '.join(b_cpuTarget))
|
|
||||||
|
|
Loading…
Reference in a new issue