generic_timer.cc revision 10844:8551af601f75
18981Sandreas.hansson@arm.com/*
214208Sandreas.sandberg@arm.com * Copyright (c) 2013, 2015 ARM Limited
311804Srjthakur@google.com * All rights reserved.
411904Spierre-yves.peneau@lirmm.fr *
511804Srjthakur@google.com * The license below extends only to copyright in the software and shall
68981Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
78981Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
88981Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
98981Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
108981Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
118981Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
128981Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
138981Sandreas.hansson@arm.com *
148981Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
158981Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
168981Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
178981Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
188981Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
198981Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
208981Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
218981Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
228981Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
238981Sandreas.hansson@arm.com * this software without specific prior written permission.
248981Sandreas.hansson@arm.com *
258981Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
268981Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
278981Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
288981Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
298981Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
308981Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
318981Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
328981Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
338981Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
348981Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
358981Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
368981Sandreas.hansson@arm.com *
378981Sandreas.hansson@arm.com * Authors: Giacomo Gabrielli
388981Sandreas.hansson@arm.com *          Andreas Sandberg
398981Sandreas.hansson@arm.com */
408981Sandreas.hansson@arm.com
4111804Srjthakur@google.com#include "dev/arm/generic_timer.hh"
4211904Spierre-yves.peneau@lirmm.fr
438981Sandreas.hansson@arm.com#include "arch/arm/system.hh"
448981Sandreas.hansson@arm.com#include "debug/Timer.hh"
458981Sandreas.hansson@arm.com#include "dev/arm/base_gic.hh"
468981Sandreas.hansson@arm.com#include "params/GenericTimer.hh"
478981Sandreas.hansson@arm.com
488981Sandreas.hansson@arm.comSystemCounter::SystemCounter()
4913892Sgabeblack@google.com    : _freq(0), _period(0), _resetTick(0), _regCntkctl(0)
508981Sandreas.hansson@arm.com{
5110994Sandreas.sandberg@arm.com    setFreq(0x01800000);
5213892Sgabeblack@google.com}
538981Sandreas.hansson@arm.com
548981Sandreas.hansson@arm.comvoid
5513892Sgabeblack@google.comSystemCounter::setFreq(uint32_t freq)
568981Sandreas.hansson@arm.com{
578981Sandreas.hansson@arm.com    if (_freq != 0) {
588981Sandreas.hansson@arm.com        // Altering the frequency after boot shouldn't be done in practice.
598981Sandreas.hansson@arm.com        warn_once("The frequency of the system counter has already been set");
608981Sandreas.hansson@arm.com    }
618981Sandreas.hansson@arm.com    _freq = freq;
628981Sandreas.hansson@arm.com    _period = (1.0 / freq) * SimClock::Frequency;
638981Sandreas.hansson@arm.com    _resetTick = curTick();
648981Sandreas.hansson@arm.com}
6513892Sgabeblack@google.com
668981Sandreas.hansson@arm.comvoid
678981Sandreas.hansson@arm.comSystemCounter::serialize(std::ostream &os) const
6810902Sandreas.sandberg@arm.com{
698981Sandreas.hansson@arm.com    SERIALIZE_SCALAR(_regCntkctl);
708981Sandreas.hansson@arm.com    SERIALIZE_SCALAR(_freq);
718981Sandreas.hansson@arm.com    SERIALIZE_SCALAR(_period);
728981Sandreas.hansson@arm.com    SERIALIZE_SCALAR(_resetTick);
738981Sandreas.hansson@arm.com}
748981Sandreas.hansson@arm.com
758981Sandreas.hansson@arm.comvoid
768981Sandreas.hansson@arm.comSystemCounter::unserialize(Checkpoint *cp,
778981Sandreas.hansson@arm.com                           const std::string &section)
788981Sandreas.hansson@arm.com{
798981Sandreas.hansson@arm.com    // We didn't handle CNTKCTL in this class before, assume it's zero
808981Sandreas.hansson@arm.com    // if it isn't present.
818981Sandreas.hansson@arm.com    if (!UNSERIALIZE_OPT_SCALAR(_regCntkctl))
8211168Sandreas.hansson@arm.com        _regCntkctl = 0;
8311168Sandreas.hansson@arm.com    UNSERIALIZE_SCALAR(_freq);
8411168Sandreas.hansson@arm.com    UNSERIALIZE_SCALAR(_period);
858981Sandreas.hansson@arm.com    UNSERIALIZE_SCALAR(_resetTick);
8613892Sgabeblack@google.com}
8713784Sgabeblack@google.com
8813784Sgabeblack@google.com
898981Sandreas.hansson@arm.com
908981Sandreas.hansson@arm.comArchTimer::ArchTimer(const std::string &name,
918981Sandreas.hansson@arm.com                     SimObject &parent,
928981Sandreas.hansson@arm.com                     SystemCounter &sysctr,
938981Sandreas.hansson@arm.com                     const Interrupt &interrupt)
948981Sandreas.hansson@arm.com    : _name(name), _parent(parent), _systemCounter(sysctr),
958981Sandreas.hansson@arm.com      _interrupt(interrupt),
968981Sandreas.hansson@arm.com      _control(0), _counterLimit(0),
978981Sandreas.hansson@arm.com      _counterLimitReachedEvent(this)
988981Sandreas.hansson@arm.com{
998981Sandreas.hansson@arm.com}
1008981Sandreas.hansson@arm.com
1018981Sandreas.hansson@arm.comvoid
1029542Sandreas.hansson@arm.comArchTimer::counterLimitReached()
1039542Sandreas.hansson@arm.com{
1048981Sandreas.hansson@arm.com    _control.istatus = 1;
1058981Sandreas.hansson@arm.com
1068981Sandreas.hansson@arm.com    if (!_control.enable)
1079542Sandreas.hansson@arm.com        return;
1089542Sandreas.hansson@arm.com
1098981Sandreas.hansson@arm.com    DPRINTF(Timer, "Counter limit reached\n");
1108981Sandreas.hansson@arm.com    if (!_control.imask) {
1118981Sandreas.hansson@arm.com        DPRINTF(Timer, "Causing interrupt\n");
1128981Sandreas.hansson@arm.com        _interrupt.send();
1138981Sandreas.hansson@arm.com    }
1148981Sandreas.hansson@arm.com}
1158981Sandreas.hansson@arm.com
1168981Sandreas.hansson@arm.comvoid
1178981Sandreas.hansson@arm.comArchTimer::updateCounter()
1188981Sandreas.hansson@arm.com{
1198981Sandreas.hansson@arm.com    if (_counterLimitReachedEvent.scheduled())
1208981Sandreas.hansson@arm.com        _parent.deschedule(_counterLimitReachedEvent);
1218981Sandreas.hansson@arm.com    if (value() >= _counterLimit) {
1228981Sandreas.hansson@arm.com        counterLimitReached();
1238981Sandreas.hansson@arm.com    } else {
1248981Sandreas.hansson@arm.com        const auto period(_systemCounter.period());
1258981Sandreas.hansson@arm.com        _control.istatus = 0;
1268981Sandreas.hansson@arm.com        _parent.schedule(_counterLimitReachedEvent,
1278981Sandreas.hansson@arm.com             curTick() + (_counterLimit - value()) * period);
1288981Sandreas.hansson@arm.com    }
1298981Sandreas.hansson@arm.com}
1308981Sandreas.hansson@arm.com
1318981Sandreas.hansson@arm.comvoid
1328981Sandreas.hansson@arm.comArchTimer::setCompareValue(uint64_t val)
1338981Sandreas.hansson@arm.com{
1348981Sandreas.hansson@arm.com    _counterLimit = val;
1358981Sandreas.hansson@arm.com    updateCounter();
1368981Sandreas.hansson@arm.com}
1378981Sandreas.hansson@arm.com
1388981Sandreas.hansson@arm.comvoid
1398981Sandreas.hansson@arm.comArchTimer::setTimerValue(uint32_t val)
1408981Sandreas.hansson@arm.com{
1418981Sandreas.hansson@arm.com    setCompareValue(value() + sext<32>(val));
1428981Sandreas.hansson@arm.com}
1438981Sandreas.hansson@arm.com
1448981Sandreas.hansson@arm.comvoid
1458981Sandreas.hansson@arm.comArchTimer::setControl(uint32_t val)
1468981Sandreas.hansson@arm.com{
1478981Sandreas.hansson@arm.com    ArchTimerCtrl new_ctl = val;
1488981Sandreas.hansson@arm.com    if ((new_ctl.enable && !new_ctl.imask) &&
1498981Sandreas.hansson@arm.com        !(_control.enable && !_control.imask)) {
1508981Sandreas.hansson@arm.com        // Re-evalute the timer condition
1518981Sandreas.hansson@arm.com        if (_counterLimit >= value()) {
1528981Sandreas.hansson@arm.com            _control.istatus = 1;
1538981Sandreas.hansson@arm.com
1548981Sandreas.hansson@arm.com            DPRINTF(Timer, "Causing interrupt in control\n");
1558981Sandreas.hansson@arm.com            //_interrupt.send();
1568981Sandreas.hansson@arm.com        }
1578981Sandreas.hansson@arm.com    }
1588981Sandreas.hansson@arm.com    _control.enable = new_ctl.enable;
1598981Sandreas.hansson@arm.com    _control.imask = new_ctl.imask;
1608981Sandreas.hansson@arm.com}
1618981Sandreas.hansson@arm.com
1628981Sandreas.hansson@arm.comuint64_t
1638981Sandreas.hansson@arm.comArchTimer::value() const
1648981Sandreas.hansson@arm.com{
1658981Sandreas.hansson@arm.com    return _systemCounter.value();
16610713Sandreas.hansson@arm.com}
1678981Sandreas.hansson@arm.com
16810713Sandreas.hansson@arm.comvoid
1698981Sandreas.hansson@arm.comArchTimer::serialize(std::ostream &os) const
1708981Sandreas.hansson@arm.com{
17111173Sandreas.hansson@arm.com    paramOut(os, "control_serial", _control);
17211173Sandreas.hansson@arm.com    SERIALIZE_SCALAR(_counterLimit);
17311173Sandreas.hansson@arm.com
17411173Sandreas.hansson@arm.com    const bool event_scheduled(_counterLimitReachedEvent.scheduled());
17511173Sandreas.hansson@arm.com    SERIALIZE_SCALAR(event_scheduled);
1768981Sandreas.hansson@arm.com    if (event_scheduled) {
1778981Sandreas.hansson@arm.com        const Tick event_time(_counterLimitReachedEvent.when());
1788981Sandreas.hansson@arm.com        SERIALIZE_SCALAR(event_time);
1798981Sandreas.hansson@arm.com    }
1808981Sandreas.hansson@arm.com}
1818981Sandreas.hansson@arm.com
1828981Sandreas.hansson@arm.comvoid
1838981Sandreas.hansson@arm.comArchTimer::unserialize(Checkpoint *cp,
1848981Sandreas.hansson@arm.com                                         const std::string &section)
1858981Sandreas.hansson@arm.com{
1868981Sandreas.hansson@arm.com    paramIn(cp, section, "control_serial", _control);
1878981Sandreas.hansson@arm.com    bool event_scheduled;
1888981Sandreas.hansson@arm.com    UNSERIALIZE_SCALAR(event_scheduled);
1898981Sandreas.hansson@arm.com    if (event_scheduled) {
1908981Sandreas.hansson@arm.com        Tick event_time;
1918981Sandreas.hansson@arm.com        UNSERIALIZE_SCALAR(event_time);
1928981Sandreas.hansson@arm.com        _parent.schedule(_counterLimitReachedEvent, event_time);
1938981Sandreas.hansson@arm.com    }
1948981Sandreas.hansson@arm.com}
1958981Sandreas.hansson@arm.com
1968981Sandreas.hansson@arm.comvoid
1978981Sandreas.hansson@arm.comArchTimer::Interrupt::send()
1988981Sandreas.hansson@arm.com{
1998981Sandreas.hansson@arm.com    if (_ppi) {
2008981Sandreas.hansson@arm.com        _gic.sendPPInt(_irq, _cpu);
2018981Sandreas.hansson@arm.com    } else {
2028981Sandreas.hansson@arm.com        _gic.sendInt(_irq);
2038981Sandreas.hansson@arm.com    }
2048981Sandreas.hansson@arm.com}
2058981Sandreas.hansson@arm.com
2068981Sandreas.hansson@arm.com
2078981Sandreas.hansson@arm.comvoid
2088981Sandreas.hansson@arm.comArchTimer::Interrupt::clear()
2098981Sandreas.hansson@arm.com{
2108981Sandreas.hansson@arm.com    if (_ppi) {
2118981Sandreas.hansson@arm.com        _gic.clearPPInt(_irq, _cpu);
2128981Sandreas.hansson@arm.com    } else {
2138981Sandreas.hansson@arm.com        _gic.clearInt(_irq);
2148981Sandreas.hansson@arm.com    }
2158981Sandreas.hansson@arm.com}
2168981Sandreas.hansson@arm.com
2178981Sandreas.hansson@arm.com
2188981Sandreas.hansson@arm.comGenericTimer::GenericTimer(GenericTimerParams *p)
2198981Sandreas.hansson@arm.com    : SimObject(p),
2208981Sandreas.hansson@arm.com      gic(p->gic),
2218981Sandreas.hansson@arm.com      irqPhys(p->int_phys)
2229090Sandreas.hansson@arm.com{
2238981Sandreas.hansson@arm.com    dynamic_cast<ArmSystem &>(*p->system).setGenericTimer(this);
2248981Sandreas.hansson@arm.com}
2258981Sandreas.hansson@arm.com
2268981Sandreas.hansson@arm.comvoid
22710713Sandreas.hansson@arm.comGenericTimer::serialize(std::ostream &os)
2288981Sandreas.hansson@arm.com{
22910713Sandreas.hansson@arm.com    paramOut(os, "cpu_count", timers.size());
2308981Sandreas.hansson@arm.com
2318981Sandreas.hansson@arm.com    nameOut(os, csprintf("%s.sys_counter", name()));
23213573Ssascha.bischoff@arm.com    systemCounter.serialize(os);
23313573Ssascha.bischoff@arm.com
23413573Ssascha.bischoff@arm.com    for (int i = 0; i < timers.size(); ++i) {
23513573Ssascha.bischoff@arm.com        CoreTimers &core(getTimers(i));
23613573Ssascha.bischoff@arm.com
2378981Sandreas.hansson@arm.com        nameOut(os, core.phys.name());
2388981Sandreas.hansson@arm.com        core.phys.serialize(os);
2398981Sandreas.hansson@arm.com    }
2408981Sandreas.hansson@arm.com}
2418981Sandreas.hansson@arm.com
2428981Sandreas.hansson@arm.comvoid
2438981Sandreas.hansson@arm.comGenericTimer::unserialize(Checkpoint *cp, const std::string &section)
2448981Sandreas.hansson@arm.com{
2458981Sandreas.hansson@arm.com    systemCounter.unserialize(cp, csprintf("%s.sys_counter", section));
2468981Sandreas.hansson@arm.com
2478981Sandreas.hansson@arm.com    // Try to unserialize the CPU count. Old versions of the timer
2488981Sandreas.hansson@arm.com    // model assumed a 8 CPUs, so we fall back to that if the field
2498981Sandreas.hansson@arm.com    // isn't present.
2508981Sandreas.hansson@arm.com    static const unsigned OLD_CPU_MAX = 8;
2518981Sandreas.hansson@arm.com    unsigned cpu_count;
2528981Sandreas.hansson@arm.com    if (!UNSERIALIZE_OPT_SCALAR(cpu_count)) {
2538981Sandreas.hansson@arm.com        warn("Checkpoint does not contain CPU count, assuming %i CPUs\n",
2548981Sandreas.hansson@arm.com             OLD_CPU_MAX);
2558981Sandreas.hansson@arm.com        cpu_count = OLD_CPU_MAX;
2568981Sandreas.hansson@arm.com    }
2578981Sandreas.hansson@arm.com
2588981Sandreas.hansson@arm.com    for (int i = 0; i < cpu_count; ++i) {
2598981Sandreas.hansson@arm.com        CoreTimers &core(getTimers(i));
2608981Sandreas.hansson@arm.com        // This should really be phys_timerN, but we are stuck with
2618981Sandreas.hansson@arm.com        // arch_timer for backwards compatibility.
26211173Sandreas.hansson@arm.com        core.phys.unserialize(cp, csprintf("%s.arch_timer%d", section, i));
26311173Sandreas.hansson@arm.com    }
2649090Sandreas.hansson@arm.com}
2658981Sandreas.hansson@arm.com
2668981Sandreas.hansson@arm.com
2678981Sandreas.hansson@arm.comGenericTimer::CoreTimers &
26810713Sandreas.hansson@arm.comGenericTimer::getTimers(int cpu_id)
2698981Sandreas.hansson@arm.com{
27010713Sandreas.hansson@arm.com    if (cpu_id >= timers.size())
2718981Sandreas.hansson@arm.com        createTimers(cpu_id + 1);
2728981Sandreas.hansson@arm.com
2738981Sandreas.hansson@arm.com    return *timers[cpu_id];
27413573Ssascha.bischoff@arm.com}
27513573Ssascha.bischoff@arm.com
2768981Sandreas.hansson@arm.comvoid
27714208Sandreas.sandberg@arm.comGenericTimer::createTimers(unsigned cpus)
2788981Sandreas.hansson@arm.com{
27911848Spierre-yves.peneau@lirmm.fr    assert(timers.size() < cpus);
2808981Sandreas.hansson@arm.com
2818981Sandreas.hansson@arm.com    const unsigned old_cpu_count(timers.size());
2828981Sandreas.hansson@arm.com    timers.resize(cpus);
2838981Sandreas.hansson@arm.com    for (unsigned i = old_cpu_count; i < cpus; ++i) {
2848981Sandreas.hansson@arm.com        timers[i].reset(
2858981Sandreas.hansson@arm.com            new CoreTimers(*this, i, irqPhys));
2868981Sandreas.hansson@arm.com    }
2878981Sandreas.hansson@arm.com}
2888981Sandreas.hansson@arm.com
2898981Sandreas.hansson@arm.com
2908981Sandreas.hansson@arm.comvoid
2918981Sandreas.hansson@arm.comGenericTimer::setMiscReg(int reg, unsigned cpu, MiscReg val)
2928981Sandreas.hansson@arm.com{
2938981Sandreas.hansson@arm.com    CoreTimers &core(getTimers(cpu));
2948981Sandreas.hansson@arm.com
2958981Sandreas.hansson@arm.com    switch (reg) {
2968981Sandreas.hansson@arm.com      case MISCREG_CNTFRQ:
2978981Sandreas.hansson@arm.com      case MISCREG_CNTFRQ_EL0:
29814208Sandreas.sandberg@arm.com        systemCounter.setFreq(val);
2998981Sandreas.hansson@arm.com        return;
3008981Sandreas.hansson@arm.com
3018981Sandreas.hansson@arm.com      case MISCREG_CNTKCTL:
3028981Sandreas.hansson@arm.com      case MISCREG_CNTKCTL_EL1:
3038981Sandreas.hansson@arm.com        systemCounter.setKernelControl(val);
3048981Sandreas.hansson@arm.com        return;
3058981Sandreas.hansson@arm.com
3068981Sandreas.hansson@arm.com      // Physical timer
30714208Sandreas.sandberg@arm.com      case MISCREG_CNTP_CVAL:
3088981Sandreas.hansson@arm.com      case MISCREG_CNTP_CVAL_NS:
3098981Sandreas.hansson@arm.com      case MISCREG_CNTP_CVAL_EL0:
3108981Sandreas.hansson@arm.com        core.phys.setCompareValue(val);
3118981Sandreas.hansson@arm.com        return;
3128981Sandreas.hansson@arm.com
3138981Sandreas.hansson@arm.com      case MISCREG_CNTP_TVAL:
3148981Sandreas.hansson@arm.com      case MISCREG_CNTP_TVAL_NS:
3158981Sandreas.hansson@arm.com      case MISCREG_CNTP_TVAL_EL0:
3168981Sandreas.hansson@arm.com        core.phys.setTimerValue(val);
3178981Sandreas.hansson@arm.com        return;
3188981Sandreas.hansson@arm.com
3198981Sandreas.hansson@arm.com      case MISCREG_CNTP_CTL:
3208981Sandreas.hansson@arm.com      case MISCREG_CNTP_CTL_NS:
3218981Sandreas.hansson@arm.com      case MISCREG_CNTP_CTL_EL0:
3228981Sandreas.hansson@arm.com        core.phys.setControl(val);
3238981Sandreas.hansson@arm.com        return;
3248981Sandreas.hansson@arm.com
3258981Sandreas.hansson@arm.com      // Count registers
3268981Sandreas.hansson@arm.com      case MISCREG_CNTPCT:
3278981Sandreas.hansson@arm.com      case MISCREG_CNTPCT_EL0:
3288981Sandreas.hansson@arm.com      case MISCREG_CNTVCT:
3298981Sandreas.hansson@arm.com      case MISCREG_CNTVCT_EL0:
3308981Sandreas.hansson@arm.com        warn("Ignoring write to read only count register: %s\n",
3318981Sandreas.hansson@arm.com             miscRegName[reg]);
3328981Sandreas.hansson@arm.com        return;
3338981Sandreas.hansson@arm.com
3348981Sandreas.hansson@arm.com      // Virtual timer
3358981Sandreas.hansson@arm.com      case MISCREG_CNTVOFF:
3368981Sandreas.hansson@arm.com      case MISCREG_CNTVOFF_EL2:
3378981Sandreas.hansson@arm.com      case MISCREG_CNTV_CVAL:
3388981Sandreas.hansson@arm.com      case MISCREG_CNTV_CVAL_EL0:
3398981Sandreas.hansson@arm.com      case MISCREG_CNTV_TVAL:
3408981Sandreas.hansson@arm.com      case MISCREG_CNTV_TVAL_EL0:
3418981Sandreas.hansson@arm.com      case MISCREG_CNTV_CTL:
3428981Sandreas.hansson@arm.com      case MISCREG_CNTV_CTL_EL0:
3438981Sandreas.hansson@arm.com        /* FALLTHROUGH */
3448981Sandreas.hansson@arm.com
3458981Sandreas.hansson@arm.com      // PL1 phys. timer, secure
3468981Sandreas.hansson@arm.com      case MISCREG_CNTP_CTL_S:
3478981Sandreas.hansson@arm.com      case MISCREG_CNTPS_CVAL_EL1:
3488981Sandreas.hansson@arm.com      case MISCREG_CNTPS_TVAL_EL1:
3498981Sandreas.hansson@arm.com      case MISCREG_CNTPS_CTL_EL1:
3508981Sandreas.hansson@arm.com        /* FALLTHROUGH */
3518981Sandreas.hansson@arm.com
3528981Sandreas.hansson@arm.com      // PL2 phys. timer, non-secure
3538981Sandreas.hansson@arm.com      case MISCREG_CNTHCTL:
3548981Sandreas.hansson@arm.com      case MISCREG_CNTHCTL_EL2:
3558981Sandreas.hansson@arm.com      case MISCREG_CNTHP_CVAL:
3568981Sandreas.hansson@arm.com      case MISCREG_CNTHP_CVAL_EL2:
3578981Sandreas.hansson@arm.com      case MISCREG_CNTHP_TVAL:
3588981Sandreas.hansson@arm.com      case MISCREG_CNTHP_TVAL_EL2:
3598981Sandreas.hansson@arm.com      case MISCREG_CNTHP_CTL:
3608981Sandreas.hansson@arm.com      case MISCREG_CNTHP_CTL_EL2:
3618981Sandreas.hansson@arm.com        warn("Writing to unimplemented register: %s\n",
3628981Sandreas.hansson@arm.com             miscRegName[reg]);
3638981Sandreas.hansson@arm.com        return;
3648981Sandreas.hansson@arm.com
3658981Sandreas.hansson@arm.com      default:
3668981Sandreas.hansson@arm.com        warn("Writing to unknown register: %s\n", miscRegName[reg]);
36711804Srjthakur@google.com        return;
36811804Srjthakur@google.com    }
36911804Srjthakur@google.com}
37011804Srjthakur@google.com
37111804Srjthakur@google.com
37211804Srjthakur@google.comMiscReg
3738981Sandreas.hansson@arm.comGenericTimer::readMiscReg(int reg, unsigned cpu)
3748981Sandreas.hansson@arm.com{
3758981Sandreas.hansson@arm.com    CoreTimers &core(getTimers(cpu));
3768981Sandreas.hansson@arm.com
3778981Sandreas.hansson@arm.com    switch (reg) {
3788981Sandreas.hansson@arm.com      case MISCREG_CNTFRQ:
3798981Sandreas.hansson@arm.com      case MISCREG_CNTFRQ_EL0:
3808981Sandreas.hansson@arm.com        return systemCounter.freq();
3818981Sandreas.hansson@arm.com
3828981Sandreas.hansson@arm.com      case MISCREG_CNTKCTL:
3838981Sandreas.hansson@arm.com      case MISCREG_CNTKCTL_EL1:
3848981Sandreas.hansson@arm.com        return systemCounter.getKernelControl();
3858981Sandreas.hansson@arm.com
3868981Sandreas.hansson@arm.com      // Physical timer
3878981Sandreas.hansson@arm.com      case MISCREG_CNTP_CVAL:
3888981Sandreas.hansson@arm.com      case MISCREG_CNTP_CVAL_EL0:
3898981Sandreas.hansson@arm.com        return core.phys.compareValue();
39014208Sandreas.sandberg@arm.com
3918981Sandreas.hansson@arm.com      case MISCREG_CNTP_TVAL:
39211804Srjthakur@google.com      case MISCREG_CNTP_TVAL_EL0:
39311804Srjthakur@google.com        return core.phys.timerValue();
39411804Srjthakur@google.com
39511804Srjthakur@google.com      case MISCREG_CNTP_CTL:
3968981Sandreas.hansson@arm.com      case MISCREG_CNTP_CTL_EL0:
3978981Sandreas.hansson@arm.com      case MISCREG_CNTP_CTL_NS:
3988981Sandreas.hansson@arm.com        return core.phys.control();
3998981Sandreas.hansson@arm.com
4008981Sandreas.hansson@arm.com      case MISCREG_CNTPCT:
4018981Sandreas.hansson@arm.com      case MISCREG_CNTPCT_EL0:
40212084Sspwilson2@wisc.edu        return core.phys.value();
4038981Sandreas.hansson@arm.com
40410902Sandreas.sandberg@arm.com
40510902Sandreas.sandberg@arm.com      // Virtual timer
40610902Sandreas.sandberg@arm.com      case MISCREG_CNTVCT:
40710902Sandreas.sandberg@arm.com      case MISCREG_CNTVCT_EL0:
40810902Sandreas.sandberg@arm.com        warn_once("Virtual timer not implemented, "
4098981Sandreas.hansson@arm.com                  "returning physical timer value\n");
41010902Sandreas.sandberg@arm.com        return core.phys.value();
41110902Sandreas.sandberg@arm.com
41210902Sandreas.sandberg@arm.com      case MISCREG_CNTVOFF:
4138981Sandreas.hansson@arm.com      case MISCREG_CNTVOFF_EL2:
41410902Sandreas.sandberg@arm.com      case MISCREG_CNTV_CVAL:
41510902Sandreas.sandberg@arm.com      case MISCREG_CNTV_CVAL_EL0:
4168981Sandreas.hansson@arm.com      case MISCREG_CNTV_TVAL:
4178981Sandreas.hansson@arm.com      case MISCREG_CNTV_TVAL_EL0:
41810994Sandreas.sandberg@arm.com      case MISCREG_CNTV_CTL:
41910994Sandreas.sandberg@arm.com      case MISCREG_CNTV_CTL_EL0:
42010994Sandreas.sandberg@arm.com        /* FALLTHROUGH */
42110994Sandreas.sandberg@arm.com
42210994Sandreas.sandberg@arm.com      // PL1 phys. timer, secure
42310994Sandreas.sandberg@arm.com      case MISCREG_CNTP_CTL_S:
42410994Sandreas.sandberg@arm.com      case MISCREG_CNTPS_CVAL_EL1:
42510994Sandreas.sandberg@arm.com      case MISCREG_CNTPS_TVAL_EL1:
42610994Sandreas.sandberg@arm.com      case MISCREG_CNTPS_CTL_EL1:
42710994Sandreas.sandberg@arm.com        /* FALLTHROUGH */
42810994Sandreas.sandberg@arm.com
42910994Sandreas.sandberg@arm.com      // PL2 phys. timer, non-secure
43010994Sandreas.sandberg@arm.com      case MISCREG_CNTHCTL:
43110994Sandreas.sandberg@arm.com      case MISCREG_CNTHCTL_EL2:
4328981Sandreas.hansson@arm.com      case MISCREG_CNTHP_CVAL:
4338981Sandreas.hansson@arm.com      case MISCREG_CNTHP_CVAL_EL2:
4348981Sandreas.hansson@arm.com      case MISCREG_CNTHP_TVAL:
435      case MISCREG_CNTHP_TVAL_EL2:
436      case MISCREG_CNTHP_CTL:
437      case MISCREG_CNTHP_CTL_EL2:
438        warn("Reading from unimplemented register: %s\n",
439             miscRegName[reg]);
440        return 0;
441
442
443      default:
444        warn("Reading from unknown register: %s\n", miscRegName[reg]);
445        return 0;
446    }
447}
448
449
450GenericTimer *
451GenericTimerParams::create()
452{
453    return new GenericTimer(this);
454}
455