arch-arm: Setup TC/ISA at construction time 2nd attempt

This partly reverts commit ec75787aef
by fixing the original problem noted by Bobby (long regressions):

setupThreadContext has to be implemented otherswise the GICv3 cpu interface
will end up holding old references when switching TC/ISAs.

This new implementation is still setting up the cpu interface reference
in the ISA only when it is required, but it is storing the
TC/ISA reference within the interface every time the ISA::setupThreadContext
gets called.

Change-Id: I2f54f95761d63655162c253e887b872f3718c764
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/66291
Maintainer: Bobby Bruce <bbruce@ucdavis.edu>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
This commit is contained in:
Giacomo Travaglini
2022-11-23 08:35:50 +00:00
committed by Bobby Bruce
parent 6f3f6c16f3
commit 23a406e811
5 changed files with 34 additions and 16 deletions

View File

@@ -524,15 +524,10 @@ ISA::setupThreadContext()
selfDebug->init(tc);
Gicv3 *gicv3 = dynamic_cast<Gicv3 *>(system->getGIC());
if (!gicv3)
return;
if (!gicv3CpuInterface)
gicv3CpuInterface.reset(gicv3->getCPUInterface(tc->contextId()));
gicv3CpuInterface->setISA(this);
gicv3CpuInterface->setThreadContext(tc);
if (auto gicv3_ifc = getGICv3CPUInterface(tc); gicv3_ifc) {
gicv3_ifc->setISA(this);
gicv3_ifc->setThreadContext(tc);
}
}
void
@@ -2008,10 +2003,28 @@ ISA::getGenericTimer()
BaseISADevice &
ISA::getGICv3CPUInterface()
{
panic_if(!gicv3CpuInterface, "GICV3 cpu interface is not registered!");
if (gicv3CpuInterface)
return *gicv3CpuInterface.get();
auto gicv3_ifc = getGICv3CPUInterface(tc);
panic_if(!gicv3_ifc, "The system does not have a GICv3 irq controller\n");
gicv3CpuInterface.reset(gicv3_ifc);
return *gicv3CpuInterface.get();
}
BaseISADevice*
ISA::getGICv3CPUInterface(ThreadContext *tc)
{
assert(system);
Gicv3 *gicv3 = dynamic_cast<Gicv3 *>(system->getGIC());
if (gicv3) {
return gicv3->getCPUInterface(tc->contextId());
} else {
return nullptr;
}
}
bool
ISA::inSecureState() const
{

View File

@@ -116,6 +116,7 @@ namespace ArmISA
BaseISADevice &getGenericTimer();
BaseISADevice &getGICv3CPUInterface();
BaseISADevice *getGICv3CPUInterface(ThreadContext *tc);
RegVal miscRegs[NUM_MISCREGS];
const RegId *intRegMap;

View File

@@ -147,7 +147,7 @@ Gicv3::init()
for (int i = 0; i < threads; i++) {
redistributors[i] = new Gicv3Redistributor(this, i);
cpuInterfaces[i] = new Gicv3CPUInterface(this, i);
cpuInterfaces[i] = new Gicv3CPUInterface(this, sys->threads[i]);
}
distRange = RangeSize(params().dist_addr,

View File

@@ -55,15 +55,19 @@ using namespace ArmISA;
const uint8_t Gicv3CPUInterface::GIC_MIN_BPR;
const uint8_t Gicv3CPUInterface::GIC_MIN_BPR_NS;
Gicv3CPUInterface::Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id)
Gicv3CPUInterface::Gicv3CPUInterface(Gicv3 * gic, ThreadContext *_tc)
: BaseISADevice(),
gic(gic),
redistributor(nullptr),
distributor(nullptr),
cpuId(cpu_id)
tc(_tc),
maintenanceInterrupt(gic->params().maint_int->get(tc)),
cpuId(tc->contextId())
{
hppi.prio = 0xff;
hppi.intid = Gicv3::INTID_SPURIOUS;
setISA(static_cast<ISA*>(tc->getIsaPtr()));
}
void

View File

@@ -68,10 +68,10 @@ class Gicv3CPUInterface : public ArmISA::BaseISADevice, public Serializable
Gicv3 * gic;
Gicv3Redistributor * redistributor;
Gicv3Distributor * distributor;
uint32_t cpuId;
ArmInterruptPin *maintenanceInterrupt;
ThreadContext *tc;
ArmInterruptPin *maintenanceInterrupt;
uint32_t cpuId;
BitUnion64(ICC_CTLR_EL1)
Bitfield<63, 20> res0_3;
@@ -359,7 +359,7 @@ class Gicv3CPUInterface : public ArmISA::BaseISADevice, public Serializable
void setBankedMiscReg(ArmISA::MiscRegIndex misc_reg, RegVal val) const;
public:
Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id);
Gicv3CPUInterface(Gicv3 * gic, ThreadContext *tc);
void init();