dev-arm: Make CpuLocalTimer use standard ArmInterruptPin
Change-Id: I8c4eb9389b47df8cdf1eec966bb2c9da85a7a7c8 Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/12744 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
@@ -410,9 +410,8 @@ class A9GlobalTimer(BasicPioDevice):
|
||||
class CpuLocalTimer(BasicPioDevice):
|
||||
type = 'CpuLocalTimer'
|
||||
cxx_header = "dev/arm/timer_cpulocal.hh"
|
||||
gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
|
||||
int_num_timer = Param.UInt32("Interrrupt number used per-cpu to GIC")
|
||||
int_num_watchdog = Param.UInt32("Interrupt number for per-cpu watchdog to GIC")
|
||||
int_timer = Param.ArmPPI("Interrrupt used per-cpu to GIC")
|
||||
int_watchdog = Param.ArmPPI("Interrupt for per-cpu watchdog to GIC")
|
||||
|
||||
class GenericTimer(ClockedObject):
|
||||
type = 'GenericTimer'
|
||||
@@ -621,7 +620,8 @@ class RealViewPBX(RealView):
|
||||
timer0 = Sp804(int_num0=36, int_num1=36, pio_addr=0x10011000)
|
||||
timer1 = Sp804(int_num0=37, int_num1=37, pio_addr=0x10012000)
|
||||
global_timer = A9GlobalTimer(int_num=27, pio_addr=0x1f000200)
|
||||
local_cpu_timer = CpuLocalTimer(int_num_timer=29, int_num_watchdog=30,
|
||||
local_cpu_timer = CpuLocalTimer(int_timer=ArmPPI(num=29),
|
||||
int_watchdog=ArmPPI(num=30),
|
||||
pio_addr=0x1f000600)
|
||||
clcd = Pl111(pio_addr=0x10020000, int_num=55)
|
||||
kmi0 = Pl050(pio_addr=0x10006000, int_num=52, ps2=PS2Keyboard())
|
||||
@@ -877,7 +877,8 @@ class VExpress_EMM(RealView):
|
||||
gic = GicV2(dist_addr=0x2C001000, cpu_addr=0x2C002000)
|
||||
vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, ppint=25)
|
||||
|
||||
local_cpu_timer = CpuLocalTimer(int_num_timer=29, int_num_watchdog=30,
|
||||
local_cpu_timer = CpuLocalTimer(int_timer=ArmPPI(num=29),
|
||||
int_watchdog=ArmPPI(num=30),
|
||||
pio_addr=0x2C080000)
|
||||
|
||||
hdlcd = HDLcd(pxl_clk=dcc.osc_pxl,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2013 ARM Limited
|
||||
* Copyright (c) 2010-2013,2018 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
#include "dev/arm/timer_cpulocal.hh"
|
||||
|
||||
#include "arch/arm/system.hh"
|
||||
#include "base/intmath.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "debug/Checkpoint.hh"
|
||||
@@ -49,23 +50,38 @@
|
||||
#include "mem/packet_access.hh"
|
||||
|
||||
CpuLocalTimer::CpuLocalTimer(Params *p)
|
||||
: BasicPioDevice(p, 0x38), gic(p->gic)
|
||||
: BasicPioDevice(p, 0x38)
|
||||
{
|
||||
// Initialize the timer registers for each per cpu timer
|
||||
for (int i = 0; i < CPU_MAX; i++) {
|
||||
std::stringstream oss;
|
||||
oss << name() << ".timer" << i;
|
||||
localTimer[i]._name = oss.str();
|
||||
localTimer[i].parent = this;
|
||||
localTimer[i].intNumTimer = p->int_num_timer;
|
||||
localTimer[i].intNumWatchdog = p->int_num_watchdog;
|
||||
localTimer[i].cpuNum = i;
|
||||
}
|
||||
}
|
||||
|
||||
CpuLocalTimer::Timer::Timer()
|
||||
: timerControl(0x0), watchdogControl(0x0), rawIntTimer(false), rawIntWatchdog(false),
|
||||
rawResetWatchdog(false), watchdogDisableReg(0x0), pendingIntTimer(false), pendingIntWatchdog(false),
|
||||
void
|
||||
CpuLocalTimer::init()
|
||||
{
|
||||
auto p = params();
|
||||
// Initialize the timer registers for each per cpu timer
|
||||
for (int i = 0; i < sys->numContexts(); i++) {
|
||||
ThreadContext* tc = sys->getThreadContext(i);
|
||||
std::stringstream oss;
|
||||
oss << name() << ".timer" << i;
|
||||
|
||||
localTimer.emplace_back(
|
||||
new Timer(oss.str(), this,
|
||||
p->int_timer->get(tc),
|
||||
p->int_watchdog->get(tc)));
|
||||
}
|
||||
|
||||
BasicPioDevice::init();
|
||||
}
|
||||
|
||||
CpuLocalTimer::Timer::Timer(const std::string &timer_name,
|
||||
CpuLocalTimer* _parent,
|
||||
ArmInterruptPin* int_timer,
|
||||
ArmInterruptPin* int_watchdog)
|
||||
: _name(timer_name), parent(_parent), intTimer(int_timer),
|
||||
intWatchdog(int_watchdog), timerControl(0x0), watchdogControl(0x0),
|
||||
rawIntTimer(false), rawIntWatchdog(false),
|
||||
rawResetWatchdog(false), watchdogDisableReg(0x0),
|
||||
pendingIntTimer(false), pendingIntWatchdog(false),
|
||||
timerLoadValue(0x0), watchdogLoadValue(0x0),
|
||||
timerZeroEvent([this]{ timerAtZero(); }, name()),
|
||||
watchdogZeroEvent([this]{ watchdogAtZero(); }, name())
|
||||
@@ -81,10 +97,10 @@ CpuLocalTimer::read(PacketPtr pkt)
|
||||
ContextID cpu_id = pkt->req->contextId();
|
||||
DPRINTF(Timer, "Reading from CpuLocalTimer at offset: %#x\n", daddr);
|
||||
assert(cpu_id >= 0);
|
||||
assert(cpu_id < CPU_MAX);
|
||||
assert(cpu_id < localTimer.size());
|
||||
|
||||
if (daddr < Timer::Size)
|
||||
localTimer[cpu_id].read(pkt, daddr);
|
||||
localTimer[cpu_id]->read(pkt, daddr);
|
||||
else
|
||||
panic("Tried to read CpuLocalTimer at offset %#x that doesn't exist\n", daddr);
|
||||
pkt->makeAtomicResponse();
|
||||
@@ -159,10 +175,10 @@ CpuLocalTimer::write(PacketPtr pkt)
|
||||
ContextID cpu_id = pkt->req->contextId();
|
||||
DPRINTF(Timer, "Writing to CpuLocalTimer at offset: %#x\n", daddr);
|
||||
assert(cpu_id >= 0);
|
||||
assert(cpu_id < CPU_MAX);
|
||||
assert(cpu_id < localTimer.size());
|
||||
|
||||
if (daddr < Timer::Size)
|
||||
localTimer[cpu_id].write(pkt, daddr);
|
||||
localTimer[cpu_id]->write(pkt, daddr);
|
||||
else
|
||||
panic("Tried to write CpuLocalTimer at offset %#x that doesn't exist\n", daddr);
|
||||
pkt->makeAtomicResponse();
|
||||
@@ -297,7 +313,7 @@ CpuLocalTimer::Timer::timerAtZero()
|
||||
pendingIntTimer = true;
|
||||
if (pendingIntTimer && !old_pending) {
|
||||
DPRINTF(Timer, "-- Causing interrupt\n");
|
||||
parent->gic->sendPPInt(intNumTimer, cpuNum);
|
||||
intTimer->raise();
|
||||
}
|
||||
|
||||
if (!timerControl.autoReload)
|
||||
@@ -328,7 +344,7 @@ CpuLocalTimer::Timer::watchdogAtZero()
|
||||
|
||||
if (pendingIntWatchdog && !old_pending) {
|
||||
DPRINTF(Timer, "-- Causing interrupt\n");
|
||||
parent->gic->sendPPInt(intNumWatchdog, cpuNum);
|
||||
intWatchdog->raise();
|
||||
}
|
||||
|
||||
if (watchdogControl.watchdogMode)
|
||||
@@ -341,8 +357,6 @@ void
|
||||
CpuLocalTimer::Timer::serialize(CheckpointOut &cp) const
|
||||
{
|
||||
DPRINTF(Checkpoint, "Serializing Arm CpuLocalTimer\n");
|
||||
SERIALIZE_SCALAR(intNumTimer);
|
||||
SERIALIZE_SCALAR(intNumWatchdog);
|
||||
|
||||
uint32_t timer_control_serial = timerControl;
|
||||
uint32_t watchdog_control_serial = watchdogControl;
|
||||
@@ -380,9 +394,6 @@ CpuLocalTimer::Timer::unserialize(CheckpointIn &cp)
|
||||
{
|
||||
DPRINTF(Checkpoint, "Unserializing Arm CpuLocalTimer\n");
|
||||
|
||||
UNSERIALIZE_SCALAR(intNumTimer);
|
||||
UNSERIALIZE_SCALAR(intNumWatchdog);
|
||||
|
||||
uint32_t timer_control_serial;
|
||||
UNSERIALIZE_SCALAR(timer_control_serial);
|
||||
timerControl = timer_control_serial;
|
||||
@@ -421,15 +432,15 @@ CpuLocalTimer::Timer::unserialize(CheckpointIn &cp)
|
||||
void
|
||||
CpuLocalTimer::serialize(CheckpointOut &cp) const
|
||||
{
|
||||
for (int i = 0; i < CPU_MAX; i++)
|
||||
localTimer[i].serializeSection(cp, csprintf("timer%d", i));
|
||||
for (int i = 0; i < sys->numContexts(); i++)
|
||||
localTimer[i]->serializeSection(cp, csprintf("timer%d", i));
|
||||
}
|
||||
|
||||
void
|
||||
CpuLocalTimer::unserialize(CheckpointIn &cp)
|
||||
{
|
||||
for (int i = 0; i < CPU_MAX; i++)
|
||||
localTimer[i].unserializeSection(cp, csprintf("timer%d", i));
|
||||
for (int i = 0; i < sys->numContexts(); i++)
|
||||
localTimer[i]->unserializeSection(cp, csprintf("timer%d", i));
|
||||
}
|
||||
|
||||
CpuLocalTimer *
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2011 ARM Limited
|
||||
* Copyright (c) 2010-2011,2018 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -51,6 +51,7 @@
|
||||
*/
|
||||
|
||||
class BaseGic;
|
||||
class ArmInterruptPin;
|
||||
|
||||
class CpuLocalTimer : public BasicPioDevice
|
||||
{
|
||||
@@ -96,12 +97,9 @@ class CpuLocalTimer : public BasicPioDevice
|
||||
/** Pointer to parent class */
|
||||
CpuLocalTimer *parent;
|
||||
|
||||
/** Number of interrupt to cause/clear */
|
||||
uint32_t intNumTimer;
|
||||
uint32_t intNumWatchdog;
|
||||
|
||||
/** Cpu this timer is attached to */
|
||||
uint32_t cpuNum;
|
||||
/** Interrupt to cause/clear */
|
||||
ArmInterruptPin *intTimer;
|
||||
ArmInterruptPin *intWatchdog;
|
||||
|
||||
/** Control register as specified above */
|
||||
TimerCtrl timerControl;
|
||||
@@ -135,7 +133,10 @@ class CpuLocalTimer : public BasicPioDevice
|
||||
void restartTimerCounter(uint32_t val);
|
||||
void restartWatchdogCounter(uint32_t val);
|
||||
|
||||
Timer();
|
||||
Timer(const std::string &name,
|
||||
CpuLocalTimer* _parent,
|
||||
ArmInterruptPin* int_timer,
|
||||
ArmInterruptPin* int_watchdog);
|
||||
|
||||
std::string name() const { return _name; }
|
||||
|
||||
@@ -151,13 +152,11 @@ class CpuLocalTimer : public BasicPioDevice
|
||||
friend class CpuLocalTimer;
|
||||
};
|
||||
|
||||
static const int CPU_MAX = 8;
|
||||
|
||||
/** Pointer to the GIC for causing an interrupt */
|
||||
BaseGic *gic;
|
||||
|
||||
/** Timers that do the actual work */
|
||||
Timer localTimer[CPU_MAX];
|
||||
std::vector<std::unique_ptr<Timer>> localTimer;
|
||||
|
||||
public:
|
||||
typedef CpuLocalTimerParams Params;
|
||||
@@ -172,6 +171,9 @@ class CpuLocalTimer : public BasicPioDevice
|
||||
*/
|
||||
CpuLocalTimer(Params *p);
|
||||
|
||||
/** Inits the local timers */
|
||||
void init() override;
|
||||
|
||||
/**
|
||||
* Handle a read to the device
|
||||
* @param pkt The memory request.
|
||||
|
||||
Reference in New Issue
Block a user