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 <giacomo.travaglini@arm.com> Reviewed-on: https://gem5-review.googlesource.com/12945 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user