/*
 * 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
