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

template<typename T>
TLB *
getITBPtr(T *tc)
{
    auto tlb = dynamic_cast<TLB *>(tc->getITBPtr());
    assert(tlb);
    return tlb;
}

template<typename T>
TLB *
getDTBPtr(T *tc)
{
    auto tlb = dynamic_cast<TLB *>(tc->getDTBPtr());
    assert(tlb);
    return tlb;
}

////////////////////////////////////////////////////////////////////////
//
//  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);
}

////////////////////////////////////////////////////////////////////////
//
//
//
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);
}

RegVal
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 = getDTBPtr(tc)->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)
{
    auto *stats = dynamic_cast<AlphaISA::Kernel::Statistics *>(
            tc->getKernelStats());
    assert(stats || !tc->getKernelStats());
    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 (stats)
            stats->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 (stats)
            stats->swpipl(ipr[idx]);
        break;

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

      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;

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

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

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

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

        getDTBPtr(tc)->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
          getDTBPtr(tc)->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
          getITBPtr(tc)->insert(ipr[IPR_ITB_TAG], entry);
      }
        break;

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

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

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

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

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

        getITBPtr(tc)->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
