dev-arm: Make GenericTimer use standard ArmInterruptPin
This patch is deleting the custom ArchTimer::Interrupt implementation in favour of the standard ArmInterruptPin. Change-Id: I5aa5661e48834398bd7aae15df9578b8db5c8da3 Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/12402 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
@@ -418,11 +418,10 @@ class GenericTimer(ClockedObject):
|
||||
type = 'GenericTimer'
|
||||
cxx_header = "dev/arm/generic_timer.hh"
|
||||
system = Param.ArmSystem(Parent.any, "system")
|
||||
gic = Param.BaseGic(Parent.any, "GIC to use for interrupting")
|
||||
int_phys_s = Param.UInt32("Physical (S) timer interrupt number")
|
||||
int_phys_ns = Param.UInt32("Physical (NS) timer interrupt number")
|
||||
int_virt = Param.UInt32("Virtual timer interrupt number")
|
||||
int_hyp = Param.UInt32("Hypervisor timer interrupt number")
|
||||
int_phys_s = Param.ArmPPI("Physical (S) timer interrupt")
|
||||
int_phys_ns = Param.ArmPPI("Physical (NS) timer interrupt")
|
||||
int_virt = Param.ArmPPI("Virtual timer interrupt")
|
||||
int_hyp = Param.ArmPPI("Hypervisor timer interrupt")
|
||||
|
||||
def generateDeviceTree(self, state):
|
||||
node = FdtNode("timer")
|
||||
@@ -431,10 +430,10 @@ class GenericTimer(ClockedObject):
|
||||
"arm,armv7-timer",
|
||||
"arm,armv8-timer"])
|
||||
node.append(FdtPropertyWords("interrupts", [
|
||||
1, int(self.int_phys_s) - 16, 0xf08,
|
||||
1, int(self.int_phys_ns) - 16, 0xf08,
|
||||
1, int(self.int_virt) - 16, 0xf08,
|
||||
1, int(self.int_hyp) - 16, 0xf08,
|
||||
1, int(self.int_phys_s.num) - 16, 0xf08,
|
||||
1, int(self.int_phys_ns.num) - 16, 0xf08,
|
||||
1, int(self.int_virt.num) - 16, 0xf08,
|
||||
1, int(self.int_hyp.num) - 16, 0xf08,
|
||||
]))
|
||||
clock = state.phandle(self.clk_domain.unproxy(self))
|
||||
node.append(FdtPropertyWords("clocks", clock))
|
||||
@@ -444,12 +443,11 @@ class GenericTimer(ClockedObject):
|
||||
class GenericTimerMem(PioDevice):
|
||||
type = 'GenericTimerMem'
|
||||
cxx_header = "dev/arm/generic_timer.hh"
|
||||
gic = Param.BaseGic(Parent.any, "GIC to use for interrupting")
|
||||
|
||||
base = Param.Addr(0, "Base address")
|
||||
|
||||
int_phys = Param.UInt32("Interrupt number")
|
||||
int_virt = Param.UInt32("Interrupt number")
|
||||
int_phys = Param.ArmSPI("Physical Interrupt")
|
||||
int_virt = Param.ArmSPI("Virtual Interrupt")
|
||||
|
||||
class PL031(AmbaIntDevice):
|
||||
type = 'PL031'
|
||||
@@ -902,8 +900,11 @@ class VExpress_EMM(RealView):
|
||||
conf_base=0x30000000, conf_size='256MB', conf_device_bits=16,
|
||||
pci_pio_base=0)
|
||||
|
||||
generic_timer = GenericTimer(int_phys_s=29, int_phys_ns=30,
|
||||
int_virt=27, int_hyp=26)
|
||||
generic_timer = GenericTimer(int_phys_s=ArmPPI(num=29),
|
||||
int_phys_ns=ArmPPI(num=30),
|
||||
int_virt=ArmPPI(num=27),
|
||||
int_hyp=ArmPPI(num=26))
|
||||
|
||||
timer0 = Sp804(int_num0=34, int_num1=34, pio_addr=0x1C110000, clock0='1MHz', clock1='1MHz')
|
||||
timer1 = Sp804(int_num0=35, int_num1=35, pio_addr=0x1C120000, clock0='1MHz', clock1='1MHz')
|
||||
clcd = Pl111(pio_addr=0x1c1f0000, int_num=46)
|
||||
@@ -1125,8 +1126,10 @@ Interrupts:
|
||||
Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2c1c0000),
|
||||
]
|
||||
|
||||
generic_timer = GenericTimer(int_phys_s=29, int_phys_ns=30,
|
||||
int_virt=27, int_hyp=26)
|
||||
generic_timer = GenericTimer(int_phys_s=ArmPPI(num=29),
|
||||
int_phys_ns=ArmPPI(num=30),
|
||||
int_virt=ArmPPI(num=27),
|
||||
int_hyp=ArmPPI(num=26))
|
||||
|
||||
def _on_chip_devices(self):
|
||||
return [
|
||||
|
||||
@@ -94,7 +94,7 @@ SystemCounter::unserialize(CheckpointIn &cp)
|
||||
ArchTimer::ArchTimer(const std::string &name,
|
||||
SimObject &parent,
|
||||
SystemCounter &sysctr,
|
||||
const Interrupt &interrupt)
|
||||
ArmInterruptPin *interrupt)
|
||||
: _name(name), _parent(parent), _systemCounter(sysctr),
|
||||
_interrupt(interrupt),
|
||||
_control(0), _counterLimit(0), _offset(0),
|
||||
@@ -114,7 +114,7 @@ ArchTimer::counterLimitReached()
|
||||
if (!_control.imask) {
|
||||
if (scheduleEvents()) {
|
||||
DPRINTF(Timer, "Causing interrupt\n");
|
||||
_interrupt.send();
|
||||
_interrupt->raise();
|
||||
} else {
|
||||
DPRINTF(Timer, "Kvm mode; skipping simulated interrupt\n");
|
||||
}
|
||||
@@ -219,41 +219,20 @@ ArchTimer::drainResume()
|
||||
updateCounter();
|
||||
}
|
||||
|
||||
void
|
||||
ArchTimer::Interrupt::send()
|
||||
{
|
||||
if (_ppi) {
|
||||
_gic.sendPPInt(_irq, _cpu);
|
||||
} else {
|
||||
_gic.sendInt(_irq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ArchTimer::Interrupt::clear()
|
||||
{
|
||||
if (_ppi) {
|
||||
_gic.clearPPInt(_irq, _cpu);
|
||||
} else {
|
||||
_gic.clearInt(_irq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GenericTimer::GenericTimer(GenericTimerParams *p)
|
||||
: ClockedObject(p),
|
||||
system(*p->system),
|
||||
gic(p->gic),
|
||||
irqPhysS(p->int_phys_s),
|
||||
irqPhysNS(p->int_phys_ns),
|
||||
irqVirt(p->int_virt),
|
||||
irqHyp(p->int_hyp)
|
||||
system(*p->system)
|
||||
{
|
||||
fatal_if(!p->system, "No system specified, can't instantiate timer.\n");
|
||||
system.setGenericTimer(this);
|
||||
}
|
||||
|
||||
const GenericTimerParams *
|
||||
GenericTimer::params() const
|
||||
{
|
||||
return dynamic_cast<const GenericTimerParams *>(_params);
|
||||
}
|
||||
|
||||
void
|
||||
GenericTimer::serialize(CheckpointOut &cp) const
|
||||
{
|
||||
@@ -314,13 +293,20 @@ void
|
||||
GenericTimer::createTimers(unsigned cpus)
|
||||
{
|
||||
assert(timers.size() < cpus);
|
||||
auto p = static_cast<const GenericTimerParams *>(_params);
|
||||
|
||||
const unsigned old_cpu_count(timers.size());
|
||||
timers.resize(cpus);
|
||||
for (unsigned i = old_cpu_count; i < cpus; ++i) {
|
||||
|
||||
ThreadContext *tc = system.getThreadContext(i);
|
||||
|
||||
timers[i].reset(
|
||||
new CoreTimers(*this, system, i,
|
||||
irqPhysS, irqPhysNS, irqVirt, irqHyp));
|
||||
p->int_phys_s->get(tc),
|
||||
p->int_phys_ns->get(tc),
|
||||
p->int_virt->get(tc),
|
||||
p->int_hyp->get(tc)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,10 +530,10 @@ GenericTimerMem::GenericTimerMem(GenericTimerMemParams *p)
|
||||
systemCounter(),
|
||||
physTimer(csprintf("%s.phys_timer0", name()),
|
||||
*this, systemCounter,
|
||||
ArchTimer::Interrupt(*p->gic, p->int_phys)),
|
||||
p->int_phys->get()),
|
||||
virtTimer(csprintf("%s.virt_timer0", name()),
|
||||
*this, systemCounter,
|
||||
ArchTimer::Interrupt(*p->gic, p->int_virt))
|
||||
p->int_virt->get())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -111,26 +111,6 @@ class SystemCounter : public Serializable
|
||||
/// Per-CPU architected timer.
|
||||
class ArchTimer : public Serializable, public Drainable
|
||||
{
|
||||
public:
|
||||
class Interrupt
|
||||
{
|
||||
public:
|
||||
Interrupt(BaseGic &gic, unsigned irq)
|
||||
: _gic(gic), _ppi(false), _irq(irq), _cpu(0) {}
|
||||
|
||||
Interrupt(BaseGic &gic, unsigned irq, unsigned cpu)
|
||||
: _gic(gic), _ppi(true), _irq(irq), _cpu(cpu) {}
|
||||
|
||||
void send();
|
||||
void clear();
|
||||
|
||||
private:
|
||||
BaseGic &_gic;
|
||||
const bool _ppi;
|
||||
const unsigned _irq;
|
||||
const unsigned _cpu;
|
||||
};
|
||||
|
||||
protected:
|
||||
/// Control register.
|
||||
BitUnion32(ArchTimerCtrl)
|
||||
@@ -147,7 +127,7 @@ class ArchTimer : public Serializable, public Drainable
|
||||
|
||||
SystemCounter &_systemCounter;
|
||||
|
||||
Interrupt _interrupt;
|
||||
ArmInterruptPin * const _interrupt;
|
||||
|
||||
/// Value of the control register ({CNTP/CNTHP/CNTV}_CTL).
|
||||
ArchTimerCtrl _control;
|
||||
@@ -172,7 +152,7 @@ class ArchTimer : public Serializable, public Drainable
|
||||
ArchTimer(const std::string &name,
|
||||
SimObject &parent,
|
||||
SystemCounter &sysctr,
|
||||
const Interrupt &interrupt);
|
||||
ArmInterruptPin *interrupt);
|
||||
|
||||
/// Returns the timer name.
|
||||
std::string name() const { return _name; }
|
||||
@@ -220,7 +200,7 @@ class ArchTimerKvm : public ArchTimer
|
||||
ArmSystem &system,
|
||||
SimObject &parent,
|
||||
SystemCounter &sysctr,
|
||||
const Interrupt &interrupt)
|
||||
ArmInterruptPin *interrupt)
|
||||
: ArchTimer(name, parent, sysctr, interrupt), system(system) {}
|
||||
|
||||
protected:
|
||||
@@ -235,6 +215,8 @@ class ArchTimerKvm : public ArchTimer
|
||||
class GenericTimer : public ClockedObject
|
||||
{
|
||||
public:
|
||||
const GenericTimerParams * params() const;
|
||||
|
||||
GenericTimer(GenericTimerParams *p);
|
||||
|
||||
void serialize(CheckpointOut &cp) const override;
|
||||
@@ -247,32 +229,32 @@ class GenericTimer : public ClockedObject
|
||||
protected:
|
||||
struct CoreTimers {
|
||||
CoreTimers(GenericTimer &parent, ArmSystem &system, unsigned cpu,
|
||||
unsigned _irqPhysS, unsigned _irqPhysNS,
|
||||
unsigned _irqVirt, unsigned _irqHyp)
|
||||
: irqPhysS(*parent.gic, _irqPhysS, cpu),
|
||||
irqPhysNS(*parent.gic, _irqPhysNS, cpu),
|
||||
irqVirt(*parent.gic, _irqVirt, cpu),
|
||||
irqHyp(*parent.gic, _irqHyp, cpu),
|
||||
ArmInterruptPin *_irqPhysS, ArmInterruptPin *_irqPhysNS,
|
||||
ArmInterruptPin *_irqVirt, ArmInterruptPin *_irqHyp)
|
||||
: irqPhysS(_irqPhysS),
|
||||
irqPhysNS(_irqPhysNS),
|
||||
irqVirt(_irqVirt),
|
||||
irqHyp(_irqHyp),
|
||||
physS(csprintf("%s.phys_s_timer%d", parent.name(), cpu),
|
||||
system, parent, parent.systemCounter,
|
||||
irqPhysS),
|
||||
_irqPhysS),
|
||||
// This should really be phys_timerN, but we are stuck with
|
||||
// arch_timer for backwards compatibility.
|
||||
physNS(csprintf("%s.arch_timer%d", parent.name(), cpu),
|
||||
system, parent, parent.systemCounter,
|
||||
irqPhysNS),
|
||||
_irqPhysNS),
|
||||
virt(csprintf("%s.virt_timer%d", parent.name(), cpu),
|
||||
system, parent, parent.systemCounter,
|
||||
irqVirt),
|
||||
_irqVirt),
|
||||
hyp(csprintf("%s.hyp_timer%d", parent.name(), cpu),
|
||||
system, parent, parent.systemCounter,
|
||||
irqHyp)
|
||||
_irqHyp)
|
||||
{}
|
||||
|
||||
ArchTimer::Interrupt irqPhysS;
|
||||
ArchTimer::Interrupt irqPhysNS;
|
||||
ArchTimer::Interrupt irqVirt;
|
||||
ArchTimer::Interrupt irqHyp;
|
||||
ArmInterruptPin const *irqPhysS;
|
||||
ArmInterruptPin const *irqPhysNS;
|
||||
ArmInterruptPin const *irqVirt;
|
||||
ArmInterruptPin const *irqHyp;
|
||||
|
||||
ArchTimerKvm physS;
|
||||
ArchTimerKvm physNS;
|
||||
@@ -296,20 +278,6 @@ class GenericTimer : public ClockedObject
|
||||
protected: // Configuration
|
||||
/// ARM system containing this timer
|
||||
ArmSystem &system;
|
||||
|
||||
/// Pointer to the GIC, needed to trigger timer interrupts.
|
||||
BaseGic *const gic;
|
||||
|
||||
/// Physical timer interrupt (S)
|
||||
const unsigned irqPhysS;
|
||||
/// Physical timer interrupt (NS)
|
||||
const unsigned irqPhysNS;
|
||||
|
||||
/// Virtual timer interrupt
|
||||
const unsigned irqVirt;
|
||||
|
||||
/// Hypervisor timer interrupt
|
||||
const unsigned irqHyp;
|
||||
};
|
||||
|
||||
class GenericTimerISA : public ArmISA::BaseISADevice
|
||||
|
||||
Reference in New Issue
Block a user