From a43e3108b4a9bd34cf382588e2e3bc0b81381623 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Tue, 11 Sep 2018 15:18:02 +0100 Subject: [PATCH] dev-arm: Make CpuLocalTimer use standard ArmInterruptPin Change-Id: I8c4eb9389b47df8cdf1eec966bb2c9da85a7a7c8 Signed-off-by: Giacomo Travaglini Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/12744 Maintainer: Andreas Sandberg --- src/dev/arm/RealView.py | 11 +++--- src/dev/arm/timer_cpulocal.cc | 63 ++++++++++++++++++++--------------- src/dev/arm/timer_cpulocal.hh | 24 +++++++------ 3 files changed, 56 insertions(+), 42 deletions(-) diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py index e8a7cd6d4..3f1803037 100644 --- a/src/dev/arm/RealView.py +++ b/src/dev/arm/RealView.py @@ -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, diff --git a/src/dev/arm/timer_cpulocal.cc b/src/dev/arm/timer_cpulocal.cc index 033031547..9e9946b1f 100644 --- a/src/dev/arm/timer_cpulocal.cc +++ b/src/dev/arm/timer_cpulocal.cc @@ -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) { +} + +void +CpuLocalTimer::init() +{ + auto p = params(); // Initialize the timer registers for each per cpu timer - for (int i = 0; i < CPU_MAX; i++) { + for (int i = 0; i < sys->numContexts(); i++) { + ThreadContext* tc = sys->getThreadContext(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; + + localTimer.emplace_back( + new Timer(oss.str(), this, + p->int_timer->get(tc), + p->int_watchdog->get(tc))); } + + BasicPioDevice::init(); } -CpuLocalTimer::Timer::Timer() - : timerControl(0x0), watchdogControl(0x0), rawIntTimer(false), rawIntWatchdog(false), - rawResetWatchdog(false), watchdogDisableReg(0x0), pendingIntTimer(false), pendingIntWatchdog(false), +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 * diff --git a/src/dev/arm/timer_cpulocal.hh b/src/dev/arm/timer_cpulocal.hh index 425f1fd6b..df4aa511a 100644 --- a/src/dev/arm/timer_cpulocal.hh +++ b/src/dev/arm/timer_cpulocal.hh @@ -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> 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. -- 2.30.2