/*
 * Copyright (c) 2002-2005 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.
 *
 * Authors: Steve Reinhardt
 *          Nathan Binkert
 */

#include "arch/alpha/faults.hh"
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/kernel_stats.hh"
#include "arch/alpha/osfpal.hh"
#include "arch/alpha/tlb.hh"
#include "base/cp_annotate.hh"
#include "base/debug.hh"
#include "cpu/base.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#include "sim/sim_exit.hh"

namespace AlphaISA {

////////////////////////////////////////////////////////////////////////
//
//  Machine dependent functions
//
void
initCPU(ThreadContext *tc, int cpuId)
{
    initIPRs(tc, cpuId);

    tc->setIntReg(16, cpuId);
    tc->setIntReg(0, cpuId);

    AlphaFault *reset = new ResetFault;

    tc->pcState(tc->readMiscRegNoEffect(IPR_PAL_BASE) + reset->vect());

    delete reset;
}

template <class CPU>
void
zeroRegisters(CPU *cpu)
{
    // Insure ISA semantics
    // (no longer very clean due to the change in setIntReg() in the
    // cpu model.  Consider changing later.)
    cpu->thread->setIntReg(ZeroReg, 0);
    cpu->thread->setFloatReg(ZeroReg, 0.0);
}

////////////////////////////////////////////////////////////////////////
//
//
//
void
initIPRs(ThreadContext *tc, int cpuId)
{
    for (int i = 0; i < NumInternalProcRegs; ++i) {
        tc->setMiscRegNoEffect(i, 0);
    }

    tc->setMiscRegNoEffect(IPR_PAL_BASE, PalBase);
    tc->setMiscRegNoEffect(IPR_MCSR, 0x6);
    tc->setMiscRegNoEffect(IPR_PALtemp16, cpuId);
}

MiscReg
ISA::readIpr(int idx, ThreadContext *tc)
{
    uint64_t retval = 0;        // return value, default 0

    switch (idx) {
      case IPR_PALtemp0:
      case IPR_PALtemp1:
      case IPR_PALtemp2:
      case IPR_PALtemp3:
      case IPR_PALtemp4:
      case IPR_PALtemp5:
      case IPR_PALtemp6:
      case IPR_PALtemp7:
      case IPR_PALtemp8:
      case IPR_PALtemp9:
      case IPR_PALtemp10:
      case IPR_PALtemp11:
      case IPR_PALtemp12:
      case IPR_PALtemp13:
      case IPR_PALtemp14:
      case IPR_PALtemp15:
      case IPR_PALtemp16:
      case IPR_PALtemp17:
      case IPR_PALtemp18:
      case IPR_PALtemp19:
      case IPR_PALtemp20:
      case IPR_PALtemp21:
      case IPR_PALtemp22:
      case IPR_PALtemp23:
      case IPR_PAL_BASE:

      case IPR_IVPTBR:
      case IPR_DC_MODE:
      case IPR_MAF_MODE:
      case IPR_ISR:
      case IPR_EXC_ADDR:
      case IPR_IC_PERR_STAT:
      case IPR_DC_PERR_STAT:
      case IPR_MCSR:
      case IPR_ASTRR:
      case IPR_ASTER:
      case IPR_SIRR:
      case IPR_ICSR:
      case IPR_ICM:
      case IPR_DTB_CM:
      case IPR_IPLR:
      case IPR_INTID:
      case IPR_PMCTR:
        // no side-effect
        retval = ipr[idx];
        break;

      case IPR_CC:
        retval |= ipr[idx] & ULL(0xffffffff00000000);
        retval |= tc->getCpuPtr()->curCycle()  & ULL(0x00000000ffffffff);
        break;

      case IPR_VA:
        retval = ipr[idx];
        break;

      case IPR_VA_FORM:
      case IPR_MM_STAT:
      case IPR_IFAULT_VA_FORM:
      case IPR_EXC_MASK:
      case IPR_EXC_SUM:
        retval = ipr[idx];
        break;

      case IPR_DTB_PTE:
        {
            TlbEntry &entry = tc->getDTBPtr()->index(1);

            retval |= ((uint64_t)entry.ppn & ULL(0x7ffffff)) << 32;
            retval |= ((uint64_t)entry.xre & ULL(0xf)) << 8;
            retval |= ((uint64_t)entry.xwe & ULL(0xf)) << 12;
            retval |= ((uint64_t)entry.fonr & ULL(0x1)) << 1;
            retval |= ((uint64_t)entry.fonw & ULL(0x1))<< 2;
            retval |= ((uint64_t)entry.asma & ULL(0x1)) << 4;
            retval |= ((uint64_t)entry.asn & ULL(0x7f)) << 57;
        }
        break;

        // write only registers
      case IPR_HWINT_CLR:
      case IPR_SL_XMIT:
      case IPR_DC_FLUSH:
      case IPR_IC_FLUSH:
      case IPR_ALT_MODE:
      case IPR_DTB_IA:
      case IPR_DTB_IAP:
      case IPR_ITB_IA:
      case IPR_ITB_IAP:
        panic("Tried to read write only register %d\n", idx);
        break;

      default:
        // invalid IPR
        panic("Tried to read from invalid ipr %d\n", idx);
        break;
    }

    return retval;
}

// Cause the simulator to break when changing to the following IPL
int break_ipl = -1;

void
ISA::setIpr(int idx, uint64_t val, ThreadContext *tc)
{
    switch (idx) {
      case IPR_PALtemp0:
      case IPR_PALtemp1:
      case IPR_PALtemp2:
      case IPR_PALtemp3:
      case IPR_PALtemp4:
      case IPR_PALtemp5:
      case IPR_PALtemp6:
      case IPR_PALtemp7:
      case IPR_PALtemp8:
      case IPR_PALtemp9:
      case IPR_PALtemp10:
      case IPR_PALtemp11:
      case IPR_PALtemp12:
      case IPR_PALtemp13:
      case IPR_PALtemp14:
      case IPR_PALtemp15:
      case IPR_PALtemp16:
      case IPR_PALtemp17:
      case IPR_PALtemp18:
      case IPR_PALtemp19:
      case IPR_PALtemp20:
      case IPR_PALtemp21:
      case IPR_PALtemp22:
      case IPR_PAL_BASE:
      case IPR_IC_PERR_STAT:
      case IPR_DC_PERR_STAT:
      case IPR_PMCTR:
        // write entire quad w/ no side-effect
        ipr[idx] = val;
        break;

      case IPR_CC_CTL:
        // This IPR resets the cycle counter.  We assume this only
        // happens once... let's verify that.
        assert(ipr[idx] == 0);
        ipr[idx] = 1;
        break;

      case IPR_CC:
        // This IPR only writes the upper 64 bits.  It's ok to write
        // all 64 here since we mask out the lower 32 in rpcc (see
        // isa_desc).
        ipr[idx] = val;
        break;

      case IPR_PALtemp23:
        // write entire quad w/ no side-effect
        if (tc->getKernelStats())
            tc->getKernelStats()->context(ipr[idx], val, tc);
        ipr[idx] = val;
        break;

      case IPR_DTB_PTE:
        // write entire quad w/ no side-effect, tag is forthcoming
        ipr[idx] = val;
        break;

      case IPR_EXC_ADDR:
        // second least significant bit in PC is always zero
        ipr[idx] = val & ~2;
        break;

      case IPR_ASTRR:
      case IPR_ASTER:
        // only write least significant four bits - privilege mask
        ipr[idx] = val & 0xf;
        break;

      case IPR_IPLR:
        // only write least significant five bits - interrupt level
        ipr[idx] = val & 0x1f;
        if (tc->getKernelStats())
            tc->getKernelStats()->swpipl(ipr[idx]);
        break;

      case IPR_DTB_CM:
        if (val & 0x18) {
            if (tc->getKernelStats())
                tc->getKernelStats()->mode(Kernel::user, tc);
        } else {
            if (tc->getKernelStats())
                tc->getKernelStats()->mode(Kernel::kernel, tc);
        }

      case IPR_ICM:
        // only write two mode bits - processor mode
        ipr[idx] = val & 0x18;
        break;

      case IPR_ALT_MODE:
        // only write two mode bits - processor mode
        ipr[idx] = val & 0x18;
        break;

      case IPR_MCSR:
        // more here after optimization...
        ipr[idx] = val;
        break;

      case IPR_SIRR:
        // only write software interrupt mask
        ipr[idx] = val & 0x7fff0;
        break;

      case IPR_ICSR:
        ipr[idx] = val & ULL(0xffffff0300);
        break;

      case IPR_IVPTBR:
      case IPR_MVPTBR:
        ipr[idx] = val & ULL(0xffffffffc0000000);
        break;

      case IPR_DC_TEST_CTL:
        ipr[idx] = val & 0x1ffb;
        break;

      case IPR_DC_MODE:
      case IPR_MAF_MODE:
        ipr[idx] = val & 0x3f;
        break;

      case IPR_ITB_ASN:
        ipr[idx] = val & 0x7f0;
        break;

      case IPR_DTB_ASN:
        ipr[idx] = val & ULL(0xfe00000000000000);
        break;

      case IPR_EXC_SUM:
      case IPR_EXC_MASK:
        // any write to this register clears it
        ipr[idx] = 0;
        break;

      case IPR_INTID:
      case IPR_SL_RCV:
      case IPR_MM_STAT:
      case IPR_ITB_PTE_TEMP:
      case IPR_DTB_PTE_TEMP:
        // read-only registers
        panic("Tried to write read only ipr %d\n", idx);

      case IPR_HWINT_CLR:
      case IPR_SL_XMIT:
      case IPR_DC_FLUSH:
      case IPR_IC_FLUSH:
        // the following are write only
        ipr[idx] = val;
        break;

      case IPR_DTB_IA:
        // really a control write
        ipr[idx] = 0;

        tc->getDTBPtr()->flushAll();
        break;

      case IPR_DTB_IAP:
        // really a control write
        ipr[idx] = 0;

        tc->getDTBPtr()->flushProcesses();
        break;

      case IPR_DTB_IS:
        // really a control write
        ipr[idx] = val;

        tc->getDTBPtr()->flushAddr(val, DTB_ASN_ASN(ipr[IPR_DTB_ASN]));
        break;

      case IPR_DTB_TAG: {
          struct TlbEntry entry;

          // FIXME: granularity hints NYI...
          if (DTB_PTE_GH(ipr[IPR_DTB_PTE]) != 0)
              panic("PTE GH field != 0");

          // write entire quad
          ipr[idx] = val;

          // construct PTE for new entry
          entry.ppn = DTB_PTE_PPN(ipr[IPR_DTB_PTE]);
          entry.xre = DTB_PTE_XRE(ipr[IPR_DTB_PTE]);
          entry.xwe = DTB_PTE_XWE(ipr[IPR_DTB_PTE]);
          entry.fonr = DTB_PTE_FONR(ipr[IPR_DTB_PTE]);
          entry.fonw = DTB_PTE_FONW(ipr[IPR_DTB_PTE]);
          entry.asma = DTB_PTE_ASMA(ipr[IPR_DTB_PTE]);
          entry.asn = DTB_ASN_ASN(ipr[IPR_DTB_ASN]);

          // insert new TAG/PTE value into data TLB
          tc->getDTBPtr()->insert(val, entry);
      }
        break;

      case IPR_ITB_PTE: {
          struct TlbEntry entry;

          // FIXME: granularity hints NYI...
          if (ITB_PTE_GH(val) != 0)
              panic("PTE GH field != 0");

          // write entire quad
          ipr[idx] = val;

          // construct PTE for new entry
          entry.ppn = ITB_PTE_PPN(val);
          entry.xre = ITB_PTE_XRE(val);
          entry.xwe = 0;
          entry.fonr = ITB_PTE_FONR(val);
          entry.fonw = ITB_PTE_FONW(val);
          entry.asma = ITB_PTE_ASMA(val);
          entry.asn = ITB_ASN_ASN(ipr[IPR_ITB_ASN]);

          // insert new TAG/PTE value into data TLB
          tc->getITBPtr()->insert(ipr[IPR_ITB_TAG], entry);
      }
        break;

      case IPR_ITB_IA:
        // really a control write
        ipr[idx] = 0;

        tc->getITBPtr()->flushAll();
        break;

      case IPR_ITB_IAP:
        // really a control write
        ipr[idx] = 0;

        tc->getITBPtr()->flushProcesses();
        break;

      case IPR_ITB_IS:
        // really a control write
        ipr[idx] = val;

        tc->getITBPtr()->flushAddr(val, ITB_ASN_ASN(ipr[IPR_ITB_ASN]));
        break;

      default:
        // invalid IPR
        panic("Tried to write to invalid ipr %d\n", idx);
    }

    // no error...
}

void
copyIprs(ThreadContext *src, ThreadContext *dest)
{
    for (int i = 0; i < NumInternalProcRegs; ++i)
        dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
}

} // namespace AlphaISA

using namespace AlphaISA;

Fault
SimpleThread::hwrei()
{
    PCState pc = pcState();
    if (!(pc.pc() & 0x3))
        return std::make_shared<UnimplementedOpcodeFault>();

    pc.npc(readMiscRegNoEffect(IPR_EXC_ADDR));
    pcState(pc);

    CPA::cpa()->swAutoBegin(tc, pc.npc());

    if (kernelStats)
        kernelStats->hwrei();

    // FIXME: XXX check for interrupts? XXX
    return NoFault;
}

/**
 * Check for special simulator handling of specific PAL calls.
 * If return value is false, actual PAL call will be suppressed.
 */
bool
SimpleThread::simPalCheck(int palFunc)
{
    if (kernelStats)
        kernelStats->callpal(palFunc, tc);

    switch (palFunc) {
      case PAL::halt:
        halt();
        if (--System::numSystemsRunning == 0)
            exitSimLoop("all cpus halted");
        break;

      case PAL::bpt:
      case PAL::bugchk:
        if (system->breakpoint())
            return false;
        break;
    }

    return true;
}
