/*
 * Copyright (c) 2010-2013,2018 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: Ali Saidi
 *          Geoffrey Blake
 */

#include "dev/arm/timer_cpulocal.hh"

#include "arch/arm/system.hh"
#include "base/intmath.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"

CpuLocalTimer::CpuLocalTimer(Params *p)
    : BasicPioDevice(p, 0x38)
{
}

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())
{
}

Tick
CpuLocalTimer::read(PacketPtr pkt)
{
    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
    assert(pkt->getSize() == 4);
    Addr daddr = pkt->getAddr() - pioAddr;
    ContextID cpu_id = pkt->req->contextId();
    DPRINTF(Timer, "Reading from CpuLocalTimer at offset: %#x\n", daddr);
    assert(cpu_id >= 0);
    assert(cpu_id < localTimer.size());

    if (daddr < Timer::Size)
        localTimer[cpu_id]->read(pkt, daddr);
    else
        panic("Tried to read CpuLocalTimer at offset %#x that doesn't exist\n", daddr);
    pkt->makeAtomicResponse();
    return pioDelay;
}


void
CpuLocalTimer::Timer::read(PacketPtr pkt, Addr daddr)
{
    DPRINTF(Timer, "Reading from CpuLocalTimer at offset: %#x\n", daddr);
    Tick time;

    switch(daddr) {
      case TimerLoadReg:
        pkt->set<uint32_t>(timerLoadValue);
        break;
      case TimerCounterReg:
        DPRINTF(Timer, "Event schedule for timer %d, clock=%d, prescale=%d\n",
                timerZeroEvent.when(), parent->clockPeriod(),
                timerControl.prescalar);
        time = timerZeroEvent.when() - curTick();
        time = time / parent->clockPeriod() /
            power(16, timerControl.prescalar);
        DPRINTF(Timer, "-- returning counter at %d\n", time);
        pkt->set<uint32_t>(time);
        break;
      case TimerControlReg:
        pkt->set<uint32_t>(timerControl);
        break;
      case TimerIntStatusReg:
        pkt->set<uint32_t>(rawIntTimer);
        break;
      case WatchdogLoadReg:
        pkt->set<uint32_t>(watchdogLoadValue);
        break;
      case WatchdogCounterReg:
        DPRINTF(Timer,
                "Event schedule for watchdog %d, clock=%d, prescale=%d\n",
                watchdogZeroEvent.when(), parent->clockPeriod(),
                watchdogControl.prescalar);
        time = watchdogZeroEvent.when() - curTick();
        time = time / parent->clockPeriod() /
            power(16, watchdogControl.prescalar);
        DPRINTF(Timer, "-- returning counter at %d\n", time);
        pkt->set<uint32_t>(time);
        break;
      case WatchdogControlReg:
        pkt->set<uint32_t>(watchdogControl);
        break;
      case WatchdogIntStatusReg:
        pkt->set<uint32_t>(rawIntWatchdog);
        break;
      case WatchdogResetStatusReg:
        pkt->set<uint32_t>(rawResetWatchdog);
        break;
      case WatchdogDisableReg:
        panic("Tried to read from WatchdogDisableRegister\n");
        break;
      default:
        panic("Tried to read CpuLocalTimer at offset %#x\n", daddr);
        break;
    }
}

Tick
CpuLocalTimer::write(PacketPtr pkt)
{
    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
    assert(pkt->getSize() == 4);
    Addr daddr = pkt->getAddr() - pioAddr;
    ContextID cpu_id = pkt->req->contextId();
    DPRINTF(Timer, "Writing to CpuLocalTimer at offset: %#x\n", daddr);
    assert(cpu_id >= 0);
    assert(cpu_id < localTimer.size());

    if (daddr < Timer::Size)
        localTimer[cpu_id]->write(pkt, daddr);
    else
        panic("Tried to write CpuLocalTimer at offset %#x that doesn't exist\n", daddr);
    pkt->makeAtomicResponse();
    return pioDelay;
}

void
CpuLocalTimer::Timer::write(PacketPtr pkt, Addr daddr)
{
    DPRINTF(Timer, "Writing to CpuLocalTimer at offset: %#x\n", daddr);
    bool old_enable;
    bool old_wd_mode;
    uint32_t old_val;

    switch (daddr) {
      case TimerLoadReg:
        // Writing to this register also resets the counter register and
        // starts decrementing if the counter is enabled.
        timerLoadValue = pkt->get<uint32_t>();
        restartTimerCounter(timerLoadValue);
        break;
      case TimerCounterReg:
        // Can be written, doesn't start counting unless the timer is enabled
        restartTimerCounter(pkt->get<uint32_t>());
        break;
      case TimerControlReg:
        old_enable = timerControl.enable;
        timerControl = pkt->get<uint32_t>();
        if ((old_enable == 0) && timerControl.enable)
            restartTimerCounter(timerLoadValue);
        break;
      case TimerIntStatusReg:
        rawIntTimer = false;
        if (pendingIntTimer) {
            pendingIntTimer = false;
            DPRINTF(Timer, "Clearing interrupt\n");
        }
        break;
      case WatchdogLoadReg:
        watchdogLoadValue = pkt->get<uint32_t>();
        restartWatchdogCounter(watchdogLoadValue);
        break;
      case WatchdogCounterReg:
        // Can't be written when in watchdog mode, but can in timer mode
        if (!watchdogControl.watchdogMode) {
            restartWatchdogCounter(pkt->get<uint32_t>());
        }
        break;
      case WatchdogControlReg:
        old_enable = watchdogControl.enable;
        old_wd_mode = watchdogControl.watchdogMode;
        watchdogControl = pkt->get<uint32_t>();
        if ((old_enable == 0) && watchdogControl.enable)
            restartWatchdogCounter(watchdogLoadValue);
        // cannot disable watchdog using control register
        if ((old_wd_mode == 1) && watchdogControl.watchdogMode == 0)
            watchdogControl.watchdogMode = 1;
        break;
      case WatchdogIntStatusReg:
        rawIntWatchdog = false;
        if (pendingIntWatchdog) {
            pendingIntWatchdog = false;
            DPRINTF(Timer, "Clearing watchdog interrupt\n");
        }
        break;
      case WatchdogResetStatusReg:
        rawResetWatchdog = false;
        DPRINTF(Timer, "Clearing watchdog reset flag\n");
        break;
      case WatchdogDisableReg:
        old_val = watchdogDisableReg;
        watchdogDisableReg = pkt->get<uint32_t>();
        // if this sequence is observed, turn off watchdog mode
        if (old_val == 0x12345678 && watchdogDisableReg == 0x87654321)
            watchdogControl.watchdogMode = 0;
        break;
      default:
        panic("Tried to write CpuLocalTimer timer at offset %#x\n", daddr);
        break;
    }
}

//XXX: Two functions are needed because the control registers are different types
void
CpuLocalTimer::Timer::restartTimerCounter(uint32_t val)
{
    DPRINTF(Timer, "Resetting timer counter with value %#x\n", val);
    if (!timerControl.enable)
        return;

    Tick time = parent->clockPeriod() * power(16, timerControl.prescalar);
    time *= val;

    if (timerZeroEvent.scheduled()) {
        DPRINTF(Timer, "-- Event was already schedule, de-scheduling\n");
        parent->deschedule(timerZeroEvent);
    }
    parent->schedule(timerZeroEvent, curTick() + time);
    DPRINTF(Timer, "-- Scheduling new event for: %d\n", curTick() + time);
}

void
CpuLocalTimer::Timer::restartWatchdogCounter(uint32_t val)
{
    DPRINTF(Timer, "Resetting watchdog counter with value %#x\n", val);
    if (!watchdogControl.enable)
        return;

    Tick time = parent->clockPeriod() * power(16, watchdogControl.prescalar);
    time *= val;

    if (watchdogZeroEvent.scheduled()) {
        DPRINTF(Timer, "-- Event was already schedule, de-scheduling\n");
        parent->deschedule(watchdogZeroEvent);
    }
    parent->schedule(watchdogZeroEvent, curTick() + time);
    DPRINTF(Timer, "-- Scheduling new event for: %d\n", curTick() + time);
}
//////

void
CpuLocalTimer::Timer::timerAtZero()
{
    if (!timerControl.enable)
        return;

    DPRINTF(Timer, "Timer Counter reached zero\n");

    rawIntTimer = true;
    bool old_pending = pendingIntTimer;
    if (timerControl.intEnable)
        pendingIntTimer = true;
    if (pendingIntTimer && !old_pending) {
        DPRINTF(Timer, "-- Causing interrupt\n");
        intTimer->raise();
    }

    if (!timerControl.autoReload)
        return;
    else
        restartTimerCounter(timerLoadValue);
}

void
CpuLocalTimer::Timer::watchdogAtZero()
{
    if (!watchdogControl.enable)
        return;

    DPRINTF(Timer, "Watchdog Counter reached zero\n");

    rawIntWatchdog = true;
    bool old_pending = pendingIntWatchdog;
    // generates an interrupt only if the watchdog is in timer
    // mode.
    if (watchdogControl.intEnable && !watchdogControl.watchdogMode)
        pendingIntWatchdog = true;
    else if (watchdogControl.watchdogMode) {
        rawResetWatchdog = true;
        fatal("gem5 ARM Model does not support true watchdog operation!\n");
        //XXX: Should we ever support a true watchdog reset?
    }

    if (pendingIntWatchdog && !old_pending) {
        DPRINTF(Timer, "-- Causing interrupt\n");
        intWatchdog->raise();
    }

    if (watchdogControl.watchdogMode)
        return;
    else if (watchdogControl.autoReload)
        restartWatchdogCounter(watchdogLoadValue);
}

void
CpuLocalTimer::Timer::serialize(CheckpointOut &cp) const
{
    DPRINTF(Checkpoint, "Serializing Arm CpuLocalTimer\n");

    uint32_t timer_control_serial = timerControl;
    uint32_t watchdog_control_serial = watchdogControl;
    SERIALIZE_SCALAR(timer_control_serial);
    SERIALIZE_SCALAR(watchdog_control_serial);

    SERIALIZE_SCALAR(rawIntTimer);
    SERIALIZE_SCALAR(rawIntWatchdog);
    SERIALIZE_SCALAR(rawResetWatchdog);
    SERIALIZE_SCALAR(watchdogDisableReg);
    SERIALIZE_SCALAR(pendingIntTimer);
    SERIALIZE_SCALAR(pendingIntWatchdog);
    SERIALIZE_SCALAR(timerLoadValue);
    SERIALIZE_SCALAR(watchdogLoadValue);

    bool timer_is_in_event = timerZeroEvent.scheduled();
    SERIALIZE_SCALAR(timer_is_in_event);
    bool watchdog_is_in_event = watchdogZeroEvent.scheduled();
    SERIALIZE_SCALAR(watchdog_is_in_event);

    Tick timer_event_time;
    if (timer_is_in_event){
        timer_event_time = timerZeroEvent.when();
        SERIALIZE_SCALAR(timer_event_time);
    }
    Tick watchdog_event_time;
    if (watchdog_is_in_event){
        watchdog_event_time = watchdogZeroEvent.when();
        SERIALIZE_SCALAR(watchdog_event_time);
    }
}

void
CpuLocalTimer::Timer::unserialize(CheckpointIn &cp)
{
    DPRINTF(Checkpoint, "Unserializing Arm CpuLocalTimer\n");

    uint32_t timer_control_serial;
    UNSERIALIZE_SCALAR(timer_control_serial);
    timerControl = timer_control_serial;
    uint32_t watchdog_control_serial;
    UNSERIALIZE_SCALAR(watchdog_control_serial);
    watchdogControl = watchdog_control_serial;

    UNSERIALIZE_SCALAR(rawIntTimer);
    UNSERIALIZE_SCALAR(rawIntWatchdog);
    UNSERIALIZE_SCALAR(rawResetWatchdog);
    UNSERIALIZE_SCALAR(watchdogDisableReg);
    UNSERIALIZE_SCALAR(pendingIntTimer);
    UNSERIALIZE_SCALAR(pendingIntWatchdog);
    UNSERIALIZE_SCALAR(timerLoadValue);
    UNSERIALIZE_SCALAR(watchdogLoadValue);

    bool timer_is_in_event;
    UNSERIALIZE_SCALAR(timer_is_in_event);
    bool watchdog_is_in_event;
    UNSERIALIZE_SCALAR(watchdog_is_in_event);

    Tick timer_event_time;
    if (timer_is_in_event){
        UNSERIALIZE_SCALAR(timer_event_time);
        parent->schedule(timerZeroEvent, timer_event_time);
    }
    Tick watchdog_event_time;
    if (watchdog_is_in_event) {
        UNSERIALIZE_SCALAR(watchdog_event_time);
        parent->schedule(watchdogZeroEvent, watchdog_event_time);
    }
}



void
CpuLocalTimer::serialize(CheckpointOut &cp) const
{
    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 < sys->numContexts(); i++)
        localTimer[i]->unserializeSection(cp, csprintf("timer%d", i));
}

CpuLocalTimer *
CpuLocalTimerParams::create()
{
    return new CpuLocalTimer(this);
}
