/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * 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 "arch/sparc/interrupts.hh"
#include "arch/sparc/isa.hh"
#include "arch/sparc/regs/misc.hh"
#include "base/bitfield.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "debug/Quiesce.hh"
#include "debug/Timer.hh"
#include "sim/system.hh"

namespace gem5
{

using namespace SparcISA;


void
ISA::checkSoftInt()
{
    BaseCPU *cpu = tc->getCpuPtr();

    // If PIL < 14, copy over the tm and sm bits
    if (pil < 14 && softint & 0x10000)
        cpu->postInterrupt(0, IT_SOFT_INT, 16);
    else
        cpu->clearInterrupt(0, IT_SOFT_INT, 16);
    if (pil < 14 && softint & 0x1)
        cpu->postInterrupt(0, IT_SOFT_INT, 0);
    else
        cpu->clearInterrupt(0, IT_SOFT_INT, 0);

    // Copy over any of the other bits that are set
    for (int bit = 15; bit > 0; --bit) {
        if (1 << bit & softint && bit > pil)
            cpu->postInterrupt(0, IT_SOFT_INT, bit);
        else
            cpu->clearInterrupt(0, IT_SOFT_INT, bit);
    }
}

// These functions map register indices to names
static inline std::string
getMiscRegName(RegIndex index)
{
    static std::string miscRegName[NumMiscRegs] =
        {/*"y", "ccr",*/ "asi", "tick", "fprs", "pcr", "pic",
         "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
         "stick", "stick_cmpr",
         "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
         "pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin",
         "wstate",*/ "gl",
         "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
         "hstick_cmpr",
         "fsr", "prictx", "secctx", "partId", "lsuCtrlReg",
         "scratch0", "scratch1", "scratch2", "scratch3", "scratch4",
         "scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail",
         "devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail",
         "nresErrorHead", "nresErrorTail", "TlbData" };
    return miscRegName[index];
}

void
ISA::setFSReg(int miscReg, RegVal val)
{
    BaseCPU *cpu = tc->getCpuPtr();

    int64_t time;
    switch (miscReg) {
        /* Full system only ASRs */
      case MISCREG_SOFTINT:
        setMiscRegNoEffect(miscReg, val);
        checkSoftInt();
        break;
      case MISCREG_SOFTINT_CLR:
        return setMiscReg(MISCREG_SOFTINT, ~val & softint);
      case MISCREG_SOFTINT_SET:
        return setMiscReg(MISCREG_SOFTINT, val | softint);

      case MISCREG_TICK_CMPR:
        if (tickCompare == NULL)
            tickCompare = new TickCompareEvent(*this);
        setMiscRegNoEffect(miscReg, val);
        if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled())
            cpu->deschedule(tickCompare);
        time = (tick_cmpr & mask(63)) - (tick & mask(63));
        if (!(tick_cmpr & ~mask(63)) && time > 0) {
            if (tickCompare->scheduled())
                cpu->deschedule(tickCompare);
            cpu->schedule(tickCompare, cpu->clockEdge(Cycles(time)));
        }
        DPRINTF(Timer, "writing to TICK compare register value %#X\n", val);
        break;

      case MISCREG_STICK_CMPR:
        if (sTickCompare == NULL)
            sTickCompare = new STickCompareEvent(*this);
        setMiscRegNoEffect(miscReg, val);
        if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
            cpu->deschedule(sTickCompare);
        time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
            cpu->instCount();
        if (!(stick_cmpr & ~mask(63)) && time > 0) {
            if (sTickCompare->scheduled())
                cpu->deschedule(sTickCompare);
            cpu->schedule(sTickCompare, cpu->clockEdge(Cycles(time)));
        }
        DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
        break;

      case MISCREG_PSTATE:
        setMiscRegNoEffect(miscReg, val);
        break;

      case MISCREG_PIL:
        setMiscRegNoEffect(miscReg, val);
        checkSoftInt();
        break;

      case MISCREG_HVER:
        panic("Shouldn't be writing HVER\n");

      case MISCREG_HINTP:
        setMiscRegNoEffect(miscReg, val);
        if (hintp)
            cpu->postInterrupt(0, IT_HINTP, 0);
        else
            cpu->clearInterrupt(0, IT_HINTP, 0);
        break;

      case MISCREG_HTBA:
        // clear lower 7 bits on writes.
        setMiscRegNoEffect(miscReg, val & ~0x7FFFULL);
        break;

      case MISCREG_QUEUE_CPU_MONDO_HEAD:
      case MISCREG_QUEUE_CPU_MONDO_TAIL:
        setMiscRegNoEffect(miscReg, val);
        if (cpu_mondo_head != cpu_mondo_tail)
            cpu->postInterrupt(0, IT_CPU_MONDO, 0);
        else
            cpu->clearInterrupt(0, IT_CPU_MONDO, 0);
        break;
      case MISCREG_QUEUE_DEV_MONDO_HEAD:
      case MISCREG_QUEUE_DEV_MONDO_TAIL:
        setMiscRegNoEffect(miscReg, val);
        if (dev_mondo_head != dev_mondo_tail)
            cpu->postInterrupt(0, IT_DEV_MONDO, 0);
        else
            cpu->clearInterrupt(0, IT_DEV_MONDO, 0);
        break;
      case MISCREG_QUEUE_RES_ERROR_HEAD:
      case MISCREG_QUEUE_RES_ERROR_TAIL:
        setMiscRegNoEffect(miscReg, val);
        if (res_error_head != res_error_tail)
            cpu->postInterrupt(0, IT_RES_ERROR, 0);
        else
            cpu->clearInterrupt(0, IT_RES_ERROR, 0);
        break;
      case MISCREG_QUEUE_NRES_ERROR_HEAD:
      case MISCREG_QUEUE_NRES_ERROR_TAIL:
        setMiscRegNoEffect(miscReg, val);
        // This one doesn't have an interrupt to report to the guest OS
        break;

      case MISCREG_HSTICK_CMPR:
        if (hSTickCompare == NULL)
            hSTickCompare = new HSTickCompareEvent(*this);
        setMiscRegNoEffect(miscReg, val);
        if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
            cpu->deschedule(hSTickCompare);
        time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
            cpu->instCount();
        if (!(hstick_cmpr & ~mask(63)) && time > 0) {
            if (hSTickCompare->scheduled())
                cpu->deschedule(hSTickCompare);
            cpu->schedule(hSTickCompare, cpu->clockEdge(Cycles(time)));
        }
        DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val);
        break;

      case MISCREG_HPSTATE:
        {
            HPSTATE newVal = val;
            newVal.id = 1;
            // T1000 spec says impl. dependent val must always be 1
            setMiscRegNoEffect(miscReg, newVal);
            newVal = hpstate;
            if (newVal.tlz && tl == 0 && !newVal.hpriv)
                cpu->postInterrupt(0, IT_TRAP_LEVEL_ZERO, 0);
            else
                cpu->clearInterrupt(0, IT_TRAP_LEVEL_ZERO, 0);
            break;
        }
      case MISCREG_HTSTATE:
        setMiscRegNoEffect(miscReg, val);
        break;

      case MISCREG_STRAND_STS_REG:
        if (bits(val,2,2))
            panic("No support for setting spec_en bit\n");
        setMiscRegNoEffect(miscReg, bits(val,0,0));
        if (!bits(val,0,0)) {
            DPRINTF(Quiesce, "Cpu executed quiescing instruction\n");
            // Time to go to sleep
            tc->suspend();
            auto *workload = tc->getSystemPtr()->workload;
            if (workload)
                workload->recordQuiesce();
        }
        break;

      default:
        panic("Invalid write to FS misc register %s\n",
              getMiscRegName(miscReg));
    }
}

RegVal
ISA::readFSReg(int miscReg)
{
    uint64_t temp;

    switch (miscReg) {
        /* Privileged registers. */
      case MISCREG_QUEUE_CPU_MONDO_HEAD:
      case MISCREG_QUEUE_CPU_MONDO_TAIL:
      case MISCREG_QUEUE_DEV_MONDO_HEAD:
      case MISCREG_QUEUE_DEV_MONDO_TAIL:
      case MISCREG_QUEUE_RES_ERROR_HEAD:
      case MISCREG_QUEUE_RES_ERROR_TAIL:
      case MISCREG_QUEUE_NRES_ERROR_HEAD:
      case MISCREG_QUEUE_NRES_ERROR_TAIL:
      case MISCREG_SOFTINT:
      case MISCREG_TICK_CMPR:
      case MISCREG_STICK_CMPR:
      case MISCREG_PIL:
      case MISCREG_HPSTATE:
      case MISCREG_HINTP:
      case MISCREG_HTSTATE:
      case MISCREG_HSTICK_CMPR:
        return readMiscRegNoEffect(miscReg) ;

      case MISCREG_HTBA:
        return readMiscRegNoEffect(miscReg) & ~0x7FFFULL;
      case MISCREG_HVER:
        // XXX set to match Legion
        return 0x3eULL << 48 |
               0x23ULL << 32 |
               0x20ULL << 24 |
                   // MaxGL << 16 | XXX For some reason legion doesn't set GL
                   MaxTL << 8  |
           (NWindows -1) << 0;

      case MISCREG_STRAND_STS_REG:
        System *sys;
        int x;
        sys = tc->getSystemPtr();

        temp = readMiscRegNoEffect(miscReg) & (STS::active | STS::speculative);
        // Check that the CPU array is fully populated
        // (by calling getNumCPus())
        assert(sys->threads.size() > tc->contextId());

        temp |= tc->contextId()  << STS::shft_id;

        for (x = tc->contextId() & ~3; x < sys->threads.size(); x++) {
            switch (sys->threads[x]->status()) {
              case ThreadContext::Active:
                temp |= STS::st_run << (STS::shft_fsm0 -
                        ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
                break;
              case ThreadContext::Suspended:
                // should this be idle?
                temp |= STS::st_idle << (STS::shft_fsm0 -
                        ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
                break;
              case ThreadContext::Halted:
                temp |= STS::st_halt << (STS::shft_fsm0 -
                        ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
                break;
              default:
                panic("What state are we in?!\n");
            } // switch
        } // for

        return temp;
      default:
        panic("Invalid read to FS misc register\n");
    }
}

void
ISA::processTickCompare()
{
    panic("tick compare not implemented\n");
}

void
ISA::processSTickCompare()
{
    BaseCPU *cpu = tc->getCpuPtr();

    // since our microcode instructions take two cycles we need to check if
    // we're actually at the correct cycle or we need to wait a little while
    // more
    int delay;
    delay = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
        cpu->instCount();
    assert(delay >= 0 && "stick compare missed interrupt cycle");

    if (delay == 0 || tc->status() == ThreadContext::Suspended) {
        DPRINTF(Timer, "STick compare cycle reached at %#x\n",
                (stick_cmpr & mask(63)));
        if (!(tc->readMiscRegNoEffect(MISCREG_STICK_CMPR) & (1ULL << 63))) {
            setMiscReg(MISCREG_SOFTINT, softint | (1ULL << 16));
        }
    } else {
        cpu->schedule(sTickCompare, cpu->clockEdge(Cycles(delay)));
    }
}

void
ISA::processHSTickCompare()
{
    BaseCPU *cpu = tc->getCpuPtr();

    // since our microcode instructions take two cycles we need to check if
    // we're actually at the correct cycle or we need to wait a little while
    // more
    int delay;
    if ( tc->status() == ThreadContext::Halted)
       return;

    delay = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
        cpu->instCount();
    assert(delay >= 0 && "hstick compare missed interrupt cycle");

    if (delay == 0 || tc->status() == ThreadContext::Suspended) {
        DPRINTF(Timer, "HSTick compare cycle reached at %#x\n",
                (stick_cmpr & mask(63)));
        if (!(tc->readMiscRegNoEffect(MISCREG_HSTICK_CMPR) & (1ULL << 63))) {
            setMiscReg(MISCREG_HINTP, 1);
        }
        // Need to do something to cause interrupt to happen here !!! @todo
    } else {
        cpu->schedule(hSTickCompare, cpu->clockEdge(Cycles(delay)));
    }
}

} // namespace gem5
