/*
 * Copyright (c) 2013, 2015, 2017 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.
 *
 * Authors: Giacomo Gabrielli
 *          Andreas Sandberg
 */

#include "dev/arm/generic_timer.hh"

#include "arch/arm/system.hh"
#include "debug/Timer.hh"
#include "dev/arm/base_gic.hh"
#include "mem/packet_access.hh"
#include "params/GenericTimer.hh"
#include "params/GenericTimerMem.hh"

SystemCounter::SystemCounter()
    : _freq(0), _period(0), _resetTick(0), _regCntkctl(0)
{
    setFreq(0x01800000);
}

void
SystemCounter::setFreq(uint32_t freq)
{
    if (_freq != 0) {
        // Altering the frequency after boot shouldn't be done in practice.
        warn_once("The frequency of the system counter has already been set");
    }
    _freq = freq;
    _period = (1.0 / freq) * SimClock::Frequency;
    _resetTick = curTick();
}

void
SystemCounter::serialize(CheckpointOut &cp) const
{
    SERIALIZE_SCALAR(_regCntkctl);
    SERIALIZE_SCALAR(_freq);
    SERIALIZE_SCALAR(_period);
    SERIALIZE_SCALAR(_resetTick);
}

void
SystemCounter::unserialize(CheckpointIn &cp)
{
    // We didn't handle CNTKCTL in this class before, assume it's zero
    // if it isn't present.
    if (!UNSERIALIZE_OPT_SCALAR(_regCntkctl))
        _regCntkctl = 0;
    UNSERIALIZE_SCALAR(_freq);
    UNSERIALIZE_SCALAR(_period);
    UNSERIALIZE_SCALAR(_resetTick);
}



ArchTimer::ArchTimer(const std::string &name,
                     SimObject &parent,
                     SystemCounter &sysctr,
                     const Interrupt &interrupt)
    : _name(name), _parent(parent), _systemCounter(sysctr),
      _interrupt(interrupt),
      _control(0), _counterLimit(0), _offset(0),
      _counterLimitReachedEvent([this]{ counterLimitReached(); }, name)
{
}

void
ArchTimer::counterLimitReached()
{
    _control.istatus = 1;

    if (!_control.enable)
        return;

    DPRINTF(Timer, "Counter limit reached\n");
    if (!_control.imask) {
        if (scheduleEvents()) {
            DPRINTF(Timer, "Causing interrupt\n");
            _interrupt.send();
        } else {
            DPRINTF(Timer, "Kvm mode; skipping simulated interrupt\n");
        }
    }
}

void
ArchTimer::updateCounter()
{
    if (_counterLimitReachedEvent.scheduled())
        _parent.deschedule(_counterLimitReachedEvent);
    if (value() >= _counterLimit) {
        counterLimitReached();
    } else {
        _control.istatus = 0;
        if (scheduleEvents()) {
            const auto period(_systemCounter.period());
            _parent.schedule(_counterLimitReachedEvent,
                 curTick() + (_counterLimit - value()) * period);
        }
    }
}

void
ArchTimer::setCompareValue(uint64_t val)
{
    _counterLimit = val;
    updateCounter();
}

void
ArchTimer::setTimerValue(uint32_t val)
{
    setCompareValue(value() + sext<32>(val));
}

void
ArchTimer::setControl(uint32_t val)
{
    ArchTimerCtrl new_ctl = val;
    if ((new_ctl.enable && !new_ctl.imask) &&
        !(_control.enable && !_control.imask)) {
        // Re-evalute the timer condition
        if (_counterLimit >= value()) {
            _control.istatus = 1;

            DPRINTF(Timer, "Causing interrupt in control\n");
            //_interrupt.send();
        }
    }
    _control.enable = new_ctl.enable;
    _control.imask = new_ctl.imask;
}

void
ArchTimer::setOffset(uint64_t val)
{
    _offset = val;
    updateCounter();
}

uint64_t
ArchTimer::value() const
{
    return _systemCounter.value() - _offset;
}

void
ArchTimer::serialize(CheckpointOut &cp) const
{
    paramOut(cp, "control_serial", _control);
    SERIALIZE_SCALAR(_counterLimit);
    SERIALIZE_SCALAR(_offset);
}

void
ArchTimer::unserialize(CheckpointIn &cp)
{
    paramIn(cp, "control_serial", _control);
    // We didn't serialize an offset before we added support for the
    // virtual timer. Consider it optional to maintain backwards
    // compatibility.
    if (!UNSERIALIZE_OPT_SCALAR(_offset))
        _offset = 0;

    // We no longer schedule an event here because we may enter KVM
    // emulation.  The event creation is delayed until drainResume().
}

DrainState
ArchTimer::drain()
{
    if (_counterLimitReachedEvent.scheduled())
        _parent.deschedule(_counterLimitReachedEvent);

    return DrainState::Drained;
}

void
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),
      irqPhys(p->int_phys),
      irqVirt(p->int_virt)
{
    fatal_if(!p->system, "No system specified, can't instantiate timer.\n");
    system.setGenericTimer(this);
}

void
GenericTimer::serialize(CheckpointOut &cp) const
{
    paramOut(cp, "cpu_count", timers.size());

    systemCounter.serializeSection(cp, "sys_counter");

    for (int i = 0; i < timers.size(); ++i) {
        const CoreTimers &core(*timers[i]);

        // This should really be phys_timerN, but we are stuck with
        // arch_timer for backwards compatibility.
        core.phys.serializeSection(cp, csprintf("arch_timer%d", i));
        core.virt.serializeSection(cp, csprintf("virt_timer%d", i));
    }
}

void
GenericTimer::unserialize(CheckpointIn &cp)
{
    systemCounter.unserializeSection(cp, "sys_counter");

    // Try to unserialize the CPU count. Old versions of the timer
    // model assumed a 8 CPUs, so we fall back to that if the field
    // isn't present.
    static const unsigned OLD_CPU_MAX = 8;
    unsigned cpu_count;
    if (!UNSERIALIZE_OPT_SCALAR(cpu_count)) {
        warn("Checkpoint does not contain CPU count, assuming %i CPUs\n",
             OLD_CPU_MAX);
        cpu_count = OLD_CPU_MAX;
    }

    for (int i = 0; i < cpu_count; ++i) {
        CoreTimers &core(getTimers(i));
        // This should really be phys_timerN, but we are stuck with
        // arch_timer for backwards compatibility.
        core.phys.unserializeSection(cp, csprintf("arch_timer%d", i));
        core.virt.unserializeSection(cp, csprintf("virt_timer%d", i));
    }
}


GenericTimer::CoreTimers &
GenericTimer::getTimers(int cpu_id)
{
    if (cpu_id >= timers.size())
        createTimers(cpu_id + 1);

    return *timers[cpu_id];
}

void
GenericTimer::createTimers(unsigned cpus)
{
    assert(timers.size() < cpus);

    const unsigned old_cpu_count(timers.size());
    timers.resize(cpus);
    for (unsigned i = old_cpu_count; i < cpus; ++i) {
        timers[i].reset(
            new CoreTimers(*this, system, i, irqPhys, irqVirt));
    }
}


void
GenericTimer::setMiscReg(int reg, unsigned cpu, MiscReg val)
{
    CoreTimers &core(getTimers(cpu));

    switch (reg) {
      case MISCREG_CNTFRQ:
      case MISCREG_CNTFRQ_EL0:
        systemCounter.setFreq(val);
        return;

      case MISCREG_CNTKCTL:
      case MISCREG_CNTKCTL_EL1:
        systemCounter.setKernelControl(val);
        return;

      // Physical timer
      case MISCREG_CNTP_CVAL:
      case MISCREG_CNTP_CVAL_NS:
      case MISCREG_CNTP_CVAL_EL0:
        core.phys.setCompareValue(val);
        return;

      case MISCREG_CNTP_TVAL:
      case MISCREG_CNTP_TVAL_NS:
      case MISCREG_CNTP_TVAL_EL0:
        core.phys.setTimerValue(val);
        return;

      case MISCREG_CNTP_CTL:
      case MISCREG_CNTP_CTL_NS:
      case MISCREG_CNTP_CTL_EL0:
        core.phys.setControl(val);
        return;

      // Count registers
      case MISCREG_CNTPCT:
      case MISCREG_CNTPCT_EL0:
      case MISCREG_CNTVCT:
      case MISCREG_CNTVCT_EL0:
        warn("Ignoring write to read only count register: %s\n",
             miscRegName[reg]);
        return;

      // Virtual timer
      case MISCREG_CNTVOFF:
      case MISCREG_CNTVOFF_EL2:
        core.virt.setOffset(val);
        return;

      case MISCREG_CNTV_CVAL:
      case MISCREG_CNTV_CVAL_EL0:
        core.virt.setCompareValue(val);
        return;

      case MISCREG_CNTV_TVAL:
      case MISCREG_CNTV_TVAL_EL0:
        core.virt.setTimerValue(val);
        return;

      case MISCREG_CNTV_CTL:
      case MISCREG_CNTV_CTL_EL0:
        core.virt.setControl(val);
        return;

      // PL1 phys. timer, secure
      case MISCREG_CNTP_CTL_S:
      case MISCREG_CNTPS_CVAL_EL1:
      case MISCREG_CNTPS_TVAL_EL1:
      case MISCREG_CNTPS_CTL_EL1:
        M5_FALLTHROUGH;

      // PL2 phys. timer, non-secure
      case MISCREG_CNTHCTL:
      case MISCREG_CNTHCTL_EL2:
      case MISCREG_CNTHP_CVAL:
      case MISCREG_CNTHP_CVAL_EL2:
      case MISCREG_CNTHP_TVAL:
      case MISCREG_CNTHP_TVAL_EL2:
      case MISCREG_CNTHP_CTL:
      case MISCREG_CNTHP_CTL_EL2:
        warn("Writing to unimplemented register: %s\n",
             miscRegName[reg]);
        return;

      default:
        warn("Writing to unknown register: %s\n", miscRegName[reg]);
        return;
    }
}


MiscReg
GenericTimer::readMiscReg(int reg, unsigned cpu)
{
    CoreTimers &core(getTimers(cpu));

    switch (reg) {
      case MISCREG_CNTFRQ:
      case MISCREG_CNTFRQ_EL0:
        return systemCounter.freq();

      case MISCREG_CNTKCTL:
      case MISCREG_CNTKCTL_EL1:
        return systemCounter.getKernelControl();

      // Physical timer
      case MISCREG_CNTP_CVAL:
      case MISCREG_CNTP_CVAL_EL0:
        return core.phys.compareValue();

      case MISCREG_CNTP_TVAL:
      case MISCREG_CNTP_TVAL_EL0:
        return core.phys.timerValue();

      case MISCREG_CNTP_CTL:
      case MISCREG_CNTP_CTL_EL0:
      case MISCREG_CNTP_CTL_NS:
        return core.phys.control();

      case MISCREG_CNTPCT:
      case MISCREG_CNTPCT_EL0:
        return core.phys.value();


      // Virtual timer
      case MISCREG_CNTVCT:
      case MISCREG_CNTVCT_EL0:
        return core.virt.value();

      case MISCREG_CNTVOFF:
      case MISCREG_CNTVOFF_EL2:
        return core.virt.offset();

      case MISCREG_CNTV_CVAL:
      case MISCREG_CNTV_CVAL_EL0:
        return core.virt.compareValue();

      case MISCREG_CNTV_TVAL:
      case MISCREG_CNTV_TVAL_EL0:
        return core.virt.timerValue();

      case MISCREG_CNTV_CTL:
      case MISCREG_CNTV_CTL_EL0:
        return core.virt.control();

      // PL1 phys. timer, secure
      case MISCREG_CNTP_CTL_S:
      case MISCREG_CNTPS_CVAL_EL1:
      case MISCREG_CNTPS_TVAL_EL1:
      case MISCREG_CNTPS_CTL_EL1:
        M5_FALLTHROUGH;

      // PL2 phys. timer, non-secure
      case MISCREG_CNTHCTL:
      case MISCREG_CNTHCTL_EL2:
      case MISCREG_CNTHP_CVAL:
      case MISCREG_CNTHP_CVAL_EL2:
      case MISCREG_CNTHP_TVAL:
      case MISCREG_CNTHP_TVAL_EL2:
      case MISCREG_CNTHP_CTL:
      case MISCREG_CNTHP_CTL_EL2:
        warn("Reading from unimplemented register: %s\n",
             miscRegName[reg]);
        return 0;


      default:
        warn("Reading from unknown register: %s\n", miscRegName[reg]);
        return 0;
    }
}



GenericTimerMem::GenericTimerMem(GenericTimerMemParams *p)
    : PioDevice(p),
      ctrlRange(RangeSize(p->base, TheISA::PageBytes)),
      timerRange(RangeSize(p->base + TheISA::PageBytes, TheISA::PageBytes)),
      addrRanges{ctrlRange, timerRange},
      systemCounter(),
      physTimer(csprintf("%s.phys_timer0", name()),
                *this, systemCounter,
                ArchTimer::Interrupt(*p->gic, p->int_phys)),
      virtTimer(csprintf("%s.virt_timer0", name()),
                *this, systemCounter,
                ArchTimer::Interrupt(*p->gic, p->int_virt))
{
}

void
GenericTimerMem::serialize(CheckpointOut &cp) const
{
    paramOut(cp, "timer_count", 1);

    systemCounter.serializeSection(cp, "sys_counter");

    physTimer.serializeSection(cp, "phys_timer0");
    virtTimer.serializeSection(cp, "virt_timer0");
}

void
GenericTimerMem::unserialize(CheckpointIn &cp)
{
    systemCounter.unserializeSection(cp, "sys_counter");

    unsigned timer_count;
    UNSERIALIZE_SCALAR(timer_count);
    // The timer count variable is just here for future versions where
    // we support more than one set of timers.
    if (timer_count != 1)
        panic("Incompatible checkpoint: Only one set of timers supported");

    physTimer.unserializeSection(cp, "phys_timer0");
    virtTimer.unserializeSection(cp, "virt_timer0");
}

Tick
GenericTimerMem::read(PacketPtr pkt)
{
    const unsigned size(pkt->getSize());
    const Addr addr(pkt->getAddr());
    uint64_t value;

    pkt->makeResponse();
    if (ctrlRange.contains(addr)) {
        value = ctrlRead(addr - ctrlRange.start(), size);
    } else if (timerRange.contains(addr)) {
        value = timerRead(addr - timerRange.start(), size);
    } else {
        panic("Invalid address: 0x%x\n", addr);
    }

    DPRINTF(Timer, "Read 0x%x <- 0x%x(%i)\n", value, addr, size);

    if (size == 8) {
        pkt->set<uint64_t>(value);
    } else if (size == 4) {
        pkt->set<uint32_t>(value);
    } else {
        panic("Unexpected access size: %i\n", size);
    }

    return 0;
}

Tick
GenericTimerMem::write(PacketPtr pkt)
{
    const unsigned size(pkt->getSize());
    if (size != 8 && size != 4)
        panic("Unexpected access size\n");

    const Addr addr(pkt->getAddr());
    const uint64_t value(size == 8 ?
                         pkt->get<uint64_t>() : pkt->get<uint32_t>());

    DPRINTF(Timer, "Write 0x%x -> 0x%x(%i)\n", value, addr, size);
    if (ctrlRange.contains(addr)) {
        ctrlWrite(addr - ctrlRange.start(), size, value);
    } else if (timerRange.contains(addr)) {
        timerWrite(addr - timerRange.start(), size, value);
    } else {
        panic("Invalid address: 0x%x\n", addr);
    }

    pkt->makeResponse();
    return 0;
}

uint64_t
GenericTimerMem::ctrlRead(Addr addr, size_t size) const
{
    if (size == 4) {
        switch (addr) {
          case CTRL_CNTFRQ:
            return systemCounter.freq();

          case CTRL_CNTTIDR:
            return 0x3; // Frame 0 implemented with virtual timers

          case CTRL_CNTNSAR:
          case CTRL_CNTACR_BASE:
            warn("Reading from unimplemented control register (0x%x)\n", addr);
            return 0;

          case CTRL_CNTVOFF_LO_BASE:
            return virtTimer.offset();

          case CTRL_CNTVOFF_HI_BASE:
            return virtTimer.offset() >> 32;

          default:
            warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size);
            return 0;
        }
    } else if (size == 8) {
        switch (addr) {
          case CTRL_CNTVOFF_LO_BASE:
            return virtTimer.offset();

          default:
            warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size);
            return 0;
        }
    } else {
        panic("Invalid access size: %i\n", size);
    }
}

void
GenericTimerMem::ctrlWrite(Addr addr, size_t size, uint64_t value)
{
    if (size == 4) {
        switch (addr) {
          case CTRL_CNTFRQ:
          case CTRL_CNTNSAR:
          case CTRL_CNTTIDR:
          case CTRL_CNTACR_BASE:
            warn("Write to unimplemented control register (0x%x)\n", addr);
            return;

          case CTRL_CNTVOFF_LO_BASE:
            virtTimer.setOffset(
                insertBits(virtTimer.offset(), 31, 0, value));
            return;

          case CTRL_CNTVOFF_HI_BASE:
            virtTimer.setOffset(
                insertBits(virtTimer.offset(), 63, 32, value));
            return;

          default:
            warn("Ignoring write to unexpected address (0x%x:%i)\n",
                 addr, size);
            return;
        }
    } else if (size == 8) {
        switch (addr) {
          case CTRL_CNTVOFF_LO_BASE:
            virtTimer.setOffset(value);
            return;

          default:
            warn("Ignoring write to unexpected address (0x%x:%i)\n",
                 addr, size);
            return;
        }
    } else {
        panic("Invalid access size: %i\n", size);
    }
}

uint64_t
GenericTimerMem::timerRead(Addr addr, size_t size) const
{
    if (size == 4) {
        switch (addr) {
          case TIMER_CNTPCT_LO:
            return physTimer.value();

          case TIMER_CNTPCT_HI:
            return physTimer.value() >> 32;

          case TIMER_CNTVCT_LO:
            return virtTimer.value();

          case TIMER_CNTVCT_HI:
            return virtTimer.value() >> 32;

          case TIMER_CNTFRQ:
            return systemCounter.freq();

          case TIMER_CNTEL0ACR:
            warn("Read from unimplemented timer register (0x%x)\n", addr);
            return 0;

          case CTRL_CNTVOFF_LO_BASE:
            return virtTimer.offset();

          case CTRL_CNTVOFF_HI_BASE:
            return virtTimer.offset() >> 32;

          case TIMER_CNTP_CVAL_LO:
            return physTimer.compareValue();

          case TIMER_CNTP_CVAL_HI:
            return physTimer.compareValue() >> 32;

          case TIMER_CNTP_TVAL:
            return physTimer.timerValue();

          case TIMER_CNTP_CTL:
            return physTimer.control();

          case TIMER_CNTV_CVAL_LO:
            return virtTimer.compareValue();

          case TIMER_CNTV_CVAL_HI:
            return virtTimer.compareValue() >> 32;

          case TIMER_CNTV_TVAL:
            return virtTimer.timerValue();

          case TIMER_CNTV_CTL:
            return virtTimer.control();

          default:
            warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size);
            return 0;
        }
    } else if (size == 8) {
        switch (addr) {
          case TIMER_CNTPCT_LO:
            return physTimer.value();

          case TIMER_CNTVCT_LO:
            return virtTimer.value();

          case CTRL_CNTVOFF_LO_BASE:
            return virtTimer.offset();

          case TIMER_CNTP_CVAL_LO:
            return physTimer.compareValue();

          case TIMER_CNTV_CVAL_LO:
            return virtTimer.compareValue();

          default:
            warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size);
            return 0;
        }
    } else {
        panic("Invalid access size: %i\n", size);
    }
}

void
GenericTimerMem::timerWrite(Addr addr, size_t size, uint64_t value)
{
    if (size == 4) {
        switch (addr) {
          case TIMER_CNTEL0ACR:
            warn("Unimplemented timer register (0x%x)\n", addr);
            return;

          case TIMER_CNTP_CVAL_LO:
            physTimer.setCompareValue(
                insertBits(physTimer.compareValue(), 31, 0, value));
            return;

          case TIMER_CNTP_CVAL_HI:
            physTimer.setCompareValue(
                insertBits(physTimer.compareValue(), 63, 32, value));
            return;

          case TIMER_CNTP_TVAL:
            physTimer.setTimerValue(value);
            return;

          case TIMER_CNTP_CTL:
            physTimer.setControl(value);
            return;

          case TIMER_CNTV_CVAL_LO:
            virtTimer.setCompareValue(
                insertBits(virtTimer.compareValue(), 31, 0, value));
            return;

          case TIMER_CNTV_CVAL_HI:
            virtTimer.setCompareValue(
                insertBits(virtTimer.compareValue(), 63, 32, value));
            return;

          case TIMER_CNTV_TVAL:
            virtTimer.setTimerValue(value);
            return;

          case TIMER_CNTV_CTL:
            virtTimer.setControl(value);
            return;

          default:
            warn("Unexpected address (0x%x:%i), ignoring write\n", addr, size);
            return;
        }
    } else if (size == 8) {
        switch (addr) {
          case TIMER_CNTP_CVAL_LO:
            return physTimer.setCompareValue(value);

          case TIMER_CNTV_CVAL_LO:
            return virtTimer.setCompareValue(value);

          default:
            warn("Unexpected address (0x%x:%i), ignoring write\n", addr, size);
            return;
        }
    } else {
        panic("Invalid access size: %i\n", size);
    }
}

GenericTimer *
GenericTimerParams::create()
{
    return new GenericTimer(this);
}

GenericTimerMem *
GenericTimerMemParams::create()
{
    return new GenericTimerMem(this);
}
