diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py index 7caa203eb8..e3558e3b27 100644 --- a/src/dev/arm/RealView.py +++ b/src/dev/arm/RealView.py @@ -456,12 +456,6 @@ class GenericWatchdog(PioDevice): "The Watchdog uses the Generic Timer system counter as the timebase " "against which the decision to trigger an interrupt is made.") -class A9GlobalTimer(BasicPioDevice): - type = 'A9GlobalTimer' - cxx_header = "dev/arm/timer_a9global.hh" - gic = Param.BaseGic(Parent.any, "Gic to use for interrupting") - int_num = Param.UInt32("Interrrupt number that connects to GIC") - class CpuLocalTimer(BasicPioDevice): type = 'CpuLocalTimer' cxx_header = "dev/arm/timer_cpulocal.hh" diff --git a/src/dev/arm/SConscript b/src/dev/arm/SConscript index c78483f2c6..a33b37d483 100644 --- a/src/dev/arm/SConscript +++ b/src/dev/arm/SConscript @@ -89,7 +89,6 @@ if env['TARGET_ISA'] == 'arm': Source('realview.cc') Source('rtc_pl031.cc') Source('timer_cpulocal.cc') - Source('timer_a9global.cc') Source('vgic.cc') Source('vio_mmio.cc') Source('ufs_device.cc') diff --git a/src/dev/arm/timer_a9global.cc b/src/dev/arm/timer_a9global.cc deleted file mode 100644 index e1b1910687..0000000000 --- a/src/dev/arm/timer_a9global.cc +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (c) 2017 Gedare Bloom - * Copyright (c) 2010 ARM Limited - * All rights reserved - * - * The license below extends only to copyright in the software and shall - * not be construed as granting a license to any other intellectual - * property including but not limited to intellectual property relating - * to a hardware implementation of the functionality of the software - * licensed hereunder. You may use the software subject to the license - * terms below provided that you ensure that this notice is replicated - * unmodified and in its entirety in all distributions of the software, - * modified or unmodified, in source code or in binary form. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "dev/arm/timer_a9global.hh" - -#include - -#include "base/intmath.hh" -#include "base/logging.hh" -#include "base/trace.hh" -#include "debug/Checkpoint.hh" -#include "debug/Timer.hh" -#include "dev/arm/base_gic.hh" -#include "mem/packet.hh" -#include "mem/packet_access.hh" - -A9GlobalTimer::A9GlobalTimer(const Params &p) - : BasicPioDevice(p, 0x1C), gic(p.gic), - global_timer(name() + ".globaltimer", this, p.int_num) -{ -} - -A9GlobalTimer::Timer::Timer(std::string __name, A9GlobalTimer *_parent, - int int_num) - : _name(__name), parent(_parent), intNum(int_num), control(0x0), - rawInt(false), pendingInt(false), autoIncValue(0x0), cmpValEvent(this) -{ -} - -Tick -A9GlobalTimer::read(PacketPtr pkt) -{ - assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - assert(pkt->getSize() == 4); - Addr daddr = pkt->getAddr() - pioAddr; - - if (daddr < Timer::Size) - global_timer.read(pkt, daddr); - else - panic("Tried to read A9GlobalTimer at offset %#x that doesn't exist\n", - daddr); - pkt->makeAtomicResponse(); - return pioDelay; -} - -uint64_t -A9GlobalTimer::Timer::getTimeCounterFromTicks(Tick ticks) -{ - return ticks / parent->clockPeriod() / (control.prescalar + 1) - 1; -} - -void -A9GlobalTimer::Timer::read(PacketPtr pkt, Addr daddr) -{ - DPRINTF(Timer, "Reading from A9GlobalTimer at offset: %#x\n", daddr); - uint64_t time; - - switch(daddr) { - case CounterRegLow32: - time = getTimeCounterFromTicks(curTick()); - DPRINTF(Timer, "-- returning lower 32-bits of counter: %u\n", time); - pkt->setLE(time); - break; - case CounterRegHigh32: - time = getTimeCounterFromTicks(curTick()); - time >>= 32; - DPRINTF(Timer, "-- returning upper 32-bits of counter: %u\n", time); - pkt->setLE(time); - break; - case ControlReg: - pkt->setLE(control); - break; - case IntStatusReg: - pkt->setLE(rawInt); - break; - case CmpValRegLow32: - DPRINTF(Timer, "Event schedule for %d, clock=%d, prescale=%d\n", - cmpValEvent.when(), parent->clockPeriod(), control.prescalar); - if (cmpValEvent.scheduled()) { - time = getTimeCounterFromTicks(cmpValEvent.when() - curTick()); - } else { - time = 0; - } - DPRINTF(Timer, "-- returning lower 32-bits of comparator: %u\n", time); - pkt->setLE(time); - break; - case CmpValRegHigh32: - DPRINTF(Timer, "Event schedule for %d, clock=%d, prescale=%d\n", - cmpValEvent.when(), parent->clockPeriod(), control.prescalar); - if (cmpValEvent.scheduled()) { - time = getTimeCounterFromTicks(cmpValEvent.when() - curTick()); - time >>= 32; - } else { - time = 0; - } - DPRINTF(Timer, "-- returning upper 32-bits of comparator: %u\n", time); - pkt->setLE(time); - break; - case AutoIncrementReg: - pkt->setLE(autoIncValue); - break; - default: - panic("Tried to read A9GlobalTimer at offset %#x\n", daddr); - break; - } - DPRINTF(Timer, "Reading %#x from A9GlobalTimer at offset: %#x\n", - pkt->getLE(), daddr); -} - -Tick -A9GlobalTimer::write(PacketPtr pkt) -{ - assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - assert(pkt->getSize() == 4); - Addr daddr = pkt->getAddr() - pioAddr; - DPRINTF(Timer, "Writing to A9GlobalTimer at offset: %#x\n", daddr); - - warn_once("A9 Global Timer doesn't support banked per-cpu registers\n"); - - if (daddr < Timer::Size) - global_timer.write(pkt, daddr); - else - panic("Tried to write A9GlobalTimer at offset %#x doesn't exist\n", - daddr); - pkt->makeAtomicResponse(); - return pioDelay; -} - -void -A9GlobalTimer::Timer::write(PacketPtr pkt, Addr daddr) -{ - DPRINTF(Timer, "Writing %#x to A9GlobalTimer at offset: %#x\n", - pkt->getLE(), daddr); - switch (daddr) { - case CounterRegLow32: - case CounterRegHigh32: - DPRINTF(Timer, "Ignoring unsupported write to Global Timer Counter\n"); - break; - case ControlReg: - bool old_enable; - bool old_cmpEnable; - old_enable = control.enable; - old_cmpEnable = control.cmpEnable; - control = pkt->getLE(); - if ((old_enable == 0) && control.enable) - restartCounter(); - if ((old_cmpEnable == 0) && control.cmpEnable) - restartCounter(); - break; - case IntStatusReg: - /* TODO: should check that '1' was written. */ - rawInt = false; - if (pendingInt) { - pendingInt = false; - DPRINTF(Timer, "Clearing interrupt\n"); - parent->gic->clearInt(intNum); - } - break; - case CmpValRegLow32: - cmpVal &= 0xFFFFFFFF00000000ULL; - cmpVal |= (uint64_t)pkt->getLE(); - break; - case CmpValRegHigh32: - cmpVal &= 0x00000000FFFFFFFFULL; - cmpVal |= ((uint64_t)pkt->getLE() << 32); - break; - case AutoIncrementReg: - autoIncValue = pkt->getLE(); - break; - default: - panic("Tried to write A9GlobalTimer at offset %#x\n", daddr); - break; - } -} - -void -A9GlobalTimer::Timer::restartCounter() -{ - if (!control.enable) - return; - DPRINTF(Timer, "Restarting counter with value %#x\n", cmpVal); - - Tick time = parent->clockPeriod() * (control.prescalar + 1) * (cmpVal + 1); - - if (time < curTick()) { - DPRINTF(Timer, "-- Event time %#x < curTick %#x\n", time, curTick()); - return; - } - if (cmpValEvent.scheduled()) { - DPRINTF(Timer, "-- Event was already schedule, de-scheduling\n"); - parent->deschedule(cmpValEvent); - } - parent->schedule(cmpValEvent, time); - DPRINTF(Timer, "-- Scheduling new event for: %d\n", time); -} - -void -A9GlobalTimer::Timer::counterAtCmpVal() -{ - if (!control.enable) - return; - - DPRINTF(Timer, "Counter reached cmpVal\n"); - - rawInt = true; - bool old_pending = pendingInt; - if (control.intEnable) - pendingInt = true; - if (pendingInt && !old_pending) { - DPRINTF(Timer, "-- Causing interrupt\n"); - parent->gic->sendPPInt(intNum, 0); /* FIXME: cpuNum */ - } - - if (control.autoIncrement == 0) // one-shot - return; - - cmpVal += (uint64_t)autoIncValue; - restartCounter(); -} - -void -A9GlobalTimer::Timer::serialize(CheckpointOut &cp) const -{ - DPRINTF(Checkpoint, "Serializing Arm A9GlobalTimer\n"); - - uint32_t control_serial = control; - SERIALIZE_SCALAR(control_serial); - - SERIALIZE_SCALAR(rawInt); - SERIALIZE_SCALAR(pendingInt); - SERIALIZE_SCALAR(cmpVal); - SERIALIZE_SCALAR(autoIncValue); - - bool is_in_event = cmpValEvent.scheduled(); - SERIALIZE_SCALAR(is_in_event); - - Tick event_time; - if (is_in_event){ - event_time = cmpValEvent.when(); - SERIALIZE_SCALAR(event_time); - } -} - -void -A9GlobalTimer::Timer::unserialize(CheckpointIn &cp) -{ - DPRINTF(Checkpoint, "Unserializing Arm A9GlobalTimer\n"); - - uint32_t control_serial; - UNSERIALIZE_SCALAR(control_serial); - control = control_serial; - - UNSERIALIZE_SCALAR(rawInt); - UNSERIALIZE_SCALAR(pendingInt); - UNSERIALIZE_SCALAR(cmpVal); - UNSERIALIZE_SCALAR(autoIncValue); - - bool is_in_event; - UNSERIALIZE_SCALAR(is_in_event); - - Tick event_time; - if (is_in_event){ - UNSERIALIZE_SCALAR(event_time); - parent->schedule(cmpValEvent, event_time); - } -} - -void -A9GlobalTimer::serialize(CheckpointOut &cp) const -{ - global_timer.serialize(cp); -} - -void -A9GlobalTimer::unserialize(CheckpointIn &cp) -{ - global_timer.unserialize(cp); -} diff --git a/src/dev/arm/timer_a9global.hh b/src/dev/arm/timer_a9global.hh deleted file mode 100644 index c56a291b35..0000000000 --- a/src/dev/arm/timer_a9global.hh +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2017 Gedare Bloom - * Copyright (c) 2010 ARM Limited - * All rights reserved - * - * The license below extends only to copyright in the software and shall - * not be construed as granting a license to any other intellectual - * property including but not limited to intellectual property relating - * to a hardware implementation of the functionality of the software - * licensed hereunder. You may use the software subject to the license - * terms below provided that you ensure that this notice is replicated - * unmodified and in its entirety in all distributions of the software, - * modified or unmodified, in source code or in binary form. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __DEV_ARM_GLOBAL_TIMER_HH__ -#define __DEV_ARM_GLOBAL_TIMER_HH__ - -#include - -#include "base/types.hh" -#include "base/bitunion.hh" -#include "base/types.hh" -#include "dev/io_device.hh" -#include "params/A9GlobalTimer.hh" -#include "sim/eventq.hh" -#include "sim/serialize.hh" - -/** @file - * This implements the Cortex A9-MPCore global timer from TRM rev r4p1. - * The global timer is an incrementing timer. - */ - -class BaseGic; - -class A9GlobalTimer : public BasicPioDevice -{ - protected: - class Timer : public Serializable - { - - public: - /* TODO: IntStatusReg, CmpValRegLow32, CmpValRegHigh32, - * and AutoIncrementReg are banked per-cpu. Some bits of - * ControlReg are also banked per-cpu, see below. */ - enum { - CounterRegLow32 = 0x00, - CounterRegHigh32 = 0x04, - ControlReg = 0x08, - IntStatusReg = 0x0C, - CmpValRegLow32 = 0x10, - CmpValRegHigh32 = 0x14, - AutoIncrementReg = 0x18, - Size = 0x1C - }; - - /* TODO: bits 1--3 are banked per-cpu */ - BitUnion32(CTRL) - Bitfield<0> enable; - Bitfield<1> cmpEnable; - Bitfield<2> intEnable; - Bitfield<3> autoIncrement; - Bitfield<7,4> reserved; - Bitfield<15,8> prescalar; - EndBitUnion(CTRL) - - protected: - std::string _name; - - /** Pointer to parent class */ - A9GlobalTimer *parent; - - /** Number of interrupt to cause/clear */ - const uint32_t intNum; - - /** Control register as specified above */ - /* TODO: one per-cpu? */ - CTRL control; - - /** If timer has caused an interrupt. This is irrespective of - * interrupt enable */ - /* TODO: one per-cpu */ - bool rawInt; - - /** If an interrupt is currently pending. Logical and of CTRL.intEnable - * and rawInt */ - bool pendingInt; - - /** Value of the comparator */ - uint64_t cmpVal; - - /** Value to add to comparator when counter reaches comparator */ - /* TODO: one per-cpu */ - uint32_t autoIncValue; - - /** Called when the counter reaches the comparator */ - void counterAtCmpVal(); - EventWrapper cmpValEvent; - - public: - /** Restart the counter ticking */ - void restartCounter(); - /** - * Convert a number of ticks into the time counter format - * @param ticks number of ticks - */ - uint64_t getTimeCounterFromTicks(Tick ticks); - Timer(std::string __name, A9GlobalTimer *parent, int int_num); - - std::string name() const { return _name; } - - /** Handle read for a single timer */ - void read(PacketPtr pkt, Addr daddr); - - /** Handle write for a single timer */ - void write(PacketPtr pkt, Addr daddr); - - void serialize(CheckpointOut &cp) const override; - void unserialize(CheckpointIn &cp) override; - }; - - /** Pointer to the GIC for causing an interrupt */ - BaseGic *gic; - - /** Timer that does the actual work */ - Timer global_timer; - - public: - using Params = A9GlobalTimerParams; - - /** - * The constructor for RealView just registers itself with the MMU. - * @param p params structure - */ - A9GlobalTimer(const Params &p); - - /** - * Handle a read to the device - * @param pkt The memory request. - * @return Returns latency of device read - */ - Tick read(PacketPtr pkt) override; - - /** - * Handle a write to the device. - * @param pkt The memory request. - * @return Returns latency of device write - */ - Tick write(PacketPtr pkt) override; - - void serialize(CheckpointOut &cp) const override; - void unserialize(CheckpointIn &cp) override; -}; - -#endif // __DEV_ARM_GLOBAL_TIMER_HH__