ev5.cc revision 13611:c8b7847b4171
113610Sgiacomo.gabrielli@arm.com/*
213610Sgiacomo.gabrielli@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
313610Sgiacomo.gabrielli@arm.com * All rights reserved.
413610Sgiacomo.gabrielli@arm.com *
513610Sgiacomo.gabrielli@arm.com * Redistribution and use in source and binary forms, with or without
613610Sgiacomo.gabrielli@arm.com * modification, are permitted provided that the following conditions are
713610Sgiacomo.gabrielli@arm.com * met: redistributions of source code must retain the above copyright
813610Sgiacomo.gabrielli@arm.com * notice, this list of conditions and the following disclaimer;
913610Sgiacomo.gabrielli@arm.com * redistributions in binary form must reproduce the above copyright
1013610Sgiacomo.gabrielli@arm.com * notice, this list of conditions and the following disclaimer in the
1113610Sgiacomo.gabrielli@arm.com * documentation and/or other materials provided with the distribution;
1213610Sgiacomo.gabrielli@arm.com * neither the name of the copyright holders nor the names of its
1313610Sgiacomo.gabrielli@arm.com * contributors may be used to endorse or promote products derived from
1413610Sgiacomo.gabrielli@arm.com * this software without specific prior written permission.
1513610Sgiacomo.gabrielli@arm.com *
1613610Sgiacomo.gabrielli@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1713610Sgiacomo.gabrielli@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1813610Sgiacomo.gabrielli@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1913610Sgiacomo.gabrielli@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2013610Sgiacomo.gabrielli@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2113610Sgiacomo.gabrielli@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2213610Sgiacomo.gabrielli@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2313610Sgiacomo.gabrielli@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2413610Sgiacomo.gabrielli@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2513610Sgiacomo.gabrielli@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2613610Sgiacomo.gabrielli@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2713610Sgiacomo.gabrielli@arm.com *
2813610Sgiacomo.gabrielli@arm.com * Authors: Steve Reinhardt
2913610Sgiacomo.gabrielli@arm.com *          Nathan Binkert
3013610Sgiacomo.gabrielli@arm.com */
3113610Sgiacomo.gabrielli@arm.com
3213610Sgiacomo.gabrielli@arm.com#include "arch/alpha/faults.hh"
3313610Sgiacomo.gabrielli@arm.com#include "arch/alpha/isa_traits.hh"
3413610Sgiacomo.gabrielli@arm.com#include "arch/alpha/kernel_stats.hh"
3513610Sgiacomo.gabrielli@arm.com#include "arch/alpha/osfpal.hh"
3613610Sgiacomo.gabrielli@arm.com#include "arch/alpha/tlb.hh"
3713610Sgiacomo.gabrielli@arm.com#include "base/cp_annotate.hh"
3813610Sgiacomo.gabrielli@arm.com#include "base/debug.hh"
3913610Sgiacomo.gabrielli@arm.com#include "cpu/base.hh"
4013610Sgiacomo.gabrielli@arm.com#include "cpu/simple_thread.hh"
4113610Sgiacomo.gabrielli@arm.com#include "cpu/thread_context.hh"
4213610Sgiacomo.gabrielli@arm.com#include "sim/sim_exit.hh"
4313610Sgiacomo.gabrielli@arm.com
4413610Sgiacomo.gabrielli@arm.comnamespace AlphaISA {
4513610Sgiacomo.gabrielli@arm.com
4613610Sgiacomo.gabrielli@arm.comtemplate<typename T>
4713610Sgiacomo.gabrielli@arm.comTLB *
4813610Sgiacomo.gabrielli@arm.comgetITBPtr(T *tc)
4913610Sgiacomo.gabrielli@arm.com{
5013610Sgiacomo.gabrielli@arm.com    auto tlb = dynamic_cast<TLB *>(tc->getITBPtr());
5113610Sgiacomo.gabrielli@arm.com    assert(tlb);
5213610Sgiacomo.gabrielli@arm.com    return tlb;
5313610Sgiacomo.gabrielli@arm.com}
5413610Sgiacomo.gabrielli@arm.com
5513610Sgiacomo.gabrielli@arm.comtemplate<typename T>
5613610Sgiacomo.gabrielli@arm.comTLB *
5713610Sgiacomo.gabrielli@arm.comgetDTBPtr(T *tc)
5813610Sgiacomo.gabrielli@arm.com{
5913610Sgiacomo.gabrielli@arm.com    auto tlb = dynamic_cast<TLB *>(tc->getDTBPtr());
6013610Sgiacomo.gabrielli@arm.com    assert(tlb);
6113610Sgiacomo.gabrielli@arm.com    return tlb;
6213610Sgiacomo.gabrielli@arm.com}
6313610Sgiacomo.gabrielli@arm.com
6413610Sgiacomo.gabrielli@arm.com////////////////////////////////////////////////////////////////////////
6513610Sgiacomo.gabrielli@arm.com//
6613610Sgiacomo.gabrielli@arm.com//  Machine dependent functions
6713610Sgiacomo.gabrielli@arm.com//
6813610Sgiacomo.gabrielli@arm.comvoid
6913610Sgiacomo.gabrielli@arm.cominitCPU(ThreadContext *tc, int cpuId)
7013610Sgiacomo.gabrielli@arm.com{
7113610Sgiacomo.gabrielli@arm.com    initIPRs(tc, cpuId);
7213610Sgiacomo.gabrielli@arm.com
7313610Sgiacomo.gabrielli@arm.com    tc->setIntReg(16, cpuId);
7413610Sgiacomo.gabrielli@arm.com    tc->setIntReg(0, cpuId);
7513610Sgiacomo.gabrielli@arm.com
7613610Sgiacomo.gabrielli@arm.com    AlphaFault *reset = new ResetFault;
7713610Sgiacomo.gabrielli@arm.com
7813610Sgiacomo.gabrielli@arm.com    tc->pcState(tc->readMiscRegNoEffect(IPR_PAL_BASE) + reset->vect());
7913610Sgiacomo.gabrielli@arm.com
8013610Sgiacomo.gabrielli@arm.com    delete reset;
8113610Sgiacomo.gabrielli@arm.com}
8213610Sgiacomo.gabrielli@arm.com
8313610Sgiacomo.gabrielli@arm.comtemplate <class CPU>
8413610Sgiacomo.gabrielli@arm.comvoid
8513610Sgiacomo.gabrielli@arm.comzeroRegisters(CPU *cpu)
8613610Sgiacomo.gabrielli@arm.com{
8713610Sgiacomo.gabrielli@arm.com    // Insure ISA semantics
8813610Sgiacomo.gabrielli@arm.com    // (no longer very clean due to the change in setIntReg() in the
8913610Sgiacomo.gabrielli@arm.com    // cpu model.  Consider changing later.)
9013610Sgiacomo.gabrielli@arm.com    cpu->thread->setIntReg(ZeroReg, 0);
9113610Sgiacomo.gabrielli@arm.com    cpu->thread->setFloatReg(ZeroReg, 0);
9213610Sgiacomo.gabrielli@arm.com}
9313610Sgiacomo.gabrielli@arm.com
9413610Sgiacomo.gabrielli@arm.com////////////////////////////////////////////////////////////////////////
9513610Sgiacomo.gabrielli@arm.com//
9613610Sgiacomo.gabrielli@arm.com//
9713610Sgiacomo.gabrielli@arm.com//
9813610Sgiacomo.gabrielli@arm.comvoid
9913610Sgiacomo.gabrielli@arm.cominitIPRs(ThreadContext *tc, int cpuId)
10013610Sgiacomo.gabrielli@arm.com{
10113610Sgiacomo.gabrielli@arm.com    for (int i = 0; i < NumInternalProcRegs; ++i) {
10213610Sgiacomo.gabrielli@arm.com        tc->setMiscRegNoEffect(i, 0);
10313610Sgiacomo.gabrielli@arm.com    }
10413610Sgiacomo.gabrielli@arm.com
10513610Sgiacomo.gabrielli@arm.com    tc->setMiscRegNoEffect(IPR_PAL_BASE, PalBase);
10613610Sgiacomo.gabrielli@arm.com    tc->setMiscRegNoEffect(IPR_MCSR, 0x6);
10713610Sgiacomo.gabrielli@arm.com    tc->setMiscRegNoEffect(IPR_PALtemp16, cpuId);
10813610Sgiacomo.gabrielli@arm.com}
10913610Sgiacomo.gabrielli@arm.com
11013610Sgiacomo.gabrielli@arm.comMiscReg
11113610Sgiacomo.gabrielli@arm.comISA::readIpr(int idx, ThreadContext *tc)
11213610Sgiacomo.gabrielli@arm.com{
11313610Sgiacomo.gabrielli@arm.com    uint64_t retval = 0;        // return value, default 0
11413610Sgiacomo.gabrielli@arm.com
11513610Sgiacomo.gabrielli@arm.com    switch (idx) {
11613610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp0:
11713610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp1:
11813610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp2:
11913610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp3:
12013610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp4:
12113610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp5:
12213610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp6:
12313610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp7:
12413610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp8:
12513610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp9:
12613610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp10:
12713610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp11:
12813610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp12:
12913610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp13:
13013610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp14:
13113610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp15:
13213610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp16:
13313610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp17:
13413610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp18:
13513610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp19:
13613610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp20:
13713610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp21:
13813610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp22:
13913610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp23:
14013610Sgiacomo.gabrielli@arm.com      case IPR_PAL_BASE:
14113610Sgiacomo.gabrielli@arm.com
14213610Sgiacomo.gabrielli@arm.com      case IPR_IVPTBR:
14313610Sgiacomo.gabrielli@arm.com      case IPR_DC_MODE:
14413610Sgiacomo.gabrielli@arm.com      case IPR_MAF_MODE:
14513610Sgiacomo.gabrielli@arm.com      case IPR_ISR:
14613610Sgiacomo.gabrielli@arm.com      case IPR_EXC_ADDR:
14713610Sgiacomo.gabrielli@arm.com      case IPR_IC_PERR_STAT:
14813610Sgiacomo.gabrielli@arm.com      case IPR_DC_PERR_STAT:
14913610Sgiacomo.gabrielli@arm.com      case IPR_MCSR:
15013610Sgiacomo.gabrielli@arm.com      case IPR_ASTRR:
15113610Sgiacomo.gabrielli@arm.com      case IPR_ASTER:
15213610Sgiacomo.gabrielli@arm.com      case IPR_SIRR:
15313610Sgiacomo.gabrielli@arm.com      case IPR_ICSR:
15413610Sgiacomo.gabrielli@arm.com      case IPR_ICM:
15513610Sgiacomo.gabrielli@arm.com      case IPR_DTB_CM:
15613610Sgiacomo.gabrielli@arm.com      case IPR_IPLR:
15713610Sgiacomo.gabrielli@arm.com      case IPR_INTID:
15813610Sgiacomo.gabrielli@arm.com      case IPR_PMCTR:
15913610Sgiacomo.gabrielli@arm.com        // no side-effect
16013610Sgiacomo.gabrielli@arm.com        retval = ipr[idx];
16113610Sgiacomo.gabrielli@arm.com        break;
16213610Sgiacomo.gabrielli@arm.com
16313610Sgiacomo.gabrielli@arm.com      case IPR_CC:
16413610Sgiacomo.gabrielli@arm.com        retval |= ipr[idx] & ULL(0xffffffff00000000);
16513610Sgiacomo.gabrielli@arm.com        retval |= tc->getCpuPtr()->curCycle()  & ULL(0x00000000ffffffff);
16613610Sgiacomo.gabrielli@arm.com        break;
16713610Sgiacomo.gabrielli@arm.com
16813610Sgiacomo.gabrielli@arm.com      case IPR_VA:
16913610Sgiacomo.gabrielli@arm.com        retval = ipr[idx];
17013610Sgiacomo.gabrielli@arm.com        break;
17113610Sgiacomo.gabrielli@arm.com
17213610Sgiacomo.gabrielli@arm.com      case IPR_VA_FORM:
17313610Sgiacomo.gabrielli@arm.com      case IPR_MM_STAT:
17413610Sgiacomo.gabrielli@arm.com      case IPR_IFAULT_VA_FORM:
17513610Sgiacomo.gabrielli@arm.com      case IPR_EXC_MASK:
17613610Sgiacomo.gabrielli@arm.com      case IPR_EXC_SUM:
17713610Sgiacomo.gabrielli@arm.com        retval = ipr[idx];
17813610Sgiacomo.gabrielli@arm.com        break;
17913610Sgiacomo.gabrielli@arm.com
18013610Sgiacomo.gabrielli@arm.com      case IPR_DTB_PTE:
18113610Sgiacomo.gabrielli@arm.com        {
18213610Sgiacomo.gabrielli@arm.com            TlbEntry &entry = getDTBPtr(tc)->index(1);
18313610Sgiacomo.gabrielli@arm.com
18413610Sgiacomo.gabrielli@arm.com            retval |= ((uint64_t)entry.ppn & ULL(0x7ffffff)) << 32;
18513610Sgiacomo.gabrielli@arm.com            retval |= ((uint64_t)entry.xre & ULL(0xf)) << 8;
18613610Sgiacomo.gabrielli@arm.com            retval |= ((uint64_t)entry.xwe & ULL(0xf)) << 12;
18713610Sgiacomo.gabrielli@arm.com            retval |= ((uint64_t)entry.fonr & ULL(0x1)) << 1;
18813610Sgiacomo.gabrielli@arm.com            retval |= ((uint64_t)entry.fonw & ULL(0x1))<< 2;
18913610Sgiacomo.gabrielli@arm.com            retval |= ((uint64_t)entry.asma & ULL(0x1)) << 4;
19013610Sgiacomo.gabrielli@arm.com            retval |= ((uint64_t)entry.asn & ULL(0x7f)) << 57;
19113610Sgiacomo.gabrielli@arm.com        }
19213610Sgiacomo.gabrielli@arm.com        break;
19313610Sgiacomo.gabrielli@arm.com
19413610Sgiacomo.gabrielli@arm.com        // write only registers
19513610Sgiacomo.gabrielli@arm.com      case IPR_HWINT_CLR:
19613610Sgiacomo.gabrielli@arm.com      case IPR_SL_XMIT:
19713610Sgiacomo.gabrielli@arm.com      case IPR_DC_FLUSH:
19813610Sgiacomo.gabrielli@arm.com      case IPR_IC_FLUSH:
19913610Sgiacomo.gabrielli@arm.com      case IPR_ALT_MODE:
20013610Sgiacomo.gabrielli@arm.com      case IPR_DTB_IA:
20113610Sgiacomo.gabrielli@arm.com      case IPR_DTB_IAP:
20213610Sgiacomo.gabrielli@arm.com      case IPR_ITB_IA:
20313610Sgiacomo.gabrielli@arm.com      case IPR_ITB_IAP:
20413610Sgiacomo.gabrielli@arm.com        panic("Tried to read write only register %d\n", idx);
20513610Sgiacomo.gabrielli@arm.com        break;
20613610Sgiacomo.gabrielli@arm.com
20713610Sgiacomo.gabrielli@arm.com      default:
20813610Sgiacomo.gabrielli@arm.com        // invalid IPR
20913610Sgiacomo.gabrielli@arm.com        panic("Tried to read from invalid ipr %d\n", idx);
21013610Sgiacomo.gabrielli@arm.com        break;
21113610Sgiacomo.gabrielli@arm.com    }
21213610Sgiacomo.gabrielli@arm.com
21313610Sgiacomo.gabrielli@arm.com    return retval;
21413610Sgiacomo.gabrielli@arm.com}
21513610Sgiacomo.gabrielli@arm.com
21613610Sgiacomo.gabrielli@arm.com// Cause the simulator to break when changing to the following IPL
21713610Sgiacomo.gabrielli@arm.comint break_ipl = -1;
21813610Sgiacomo.gabrielli@arm.com
21913610Sgiacomo.gabrielli@arm.comvoid
22013610Sgiacomo.gabrielli@arm.comISA::setIpr(int idx, uint64_t val, ThreadContext *tc)
22113610Sgiacomo.gabrielli@arm.com{
22213610Sgiacomo.gabrielli@arm.com    switch (idx) {
22313610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp0:
22413610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp1:
22513610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp2:
22613610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp3:
22713610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp4:
22813610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp5:
22913610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp6:
23013610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp7:
23113610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp8:
23213610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp9:
23313610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp10:
23413610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp11:
23513610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp12:
23613610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp13:
23713610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp14:
23813610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp15:
23913610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp16:
24013610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp17:
24113610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp18:
24213610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp19:
24313610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp20:
24413610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp21:
24513610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp22:
24613610Sgiacomo.gabrielli@arm.com      case IPR_PAL_BASE:
24713610Sgiacomo.gabrielli@arm.com      case IPR_IC_PERR_STAT:
24813610Sgiacomo.gabrielli@arm.com      case IPR_DC_PERR_STAT:
24913610Sgiacomo.gabrielli@arm.com      case IPR_PMCTR:
25013610Sgiacomo.gabrielli@arm.com        // write entire quad w/ no side-effect
25113610Sgiacomo.gabrielli@arm.com        ipr[idx] = val;
25213610Sgiacomo.gabrielli@arm.com        break;
25313610Sgiacomo.gabrielli@arm.com
25413610Sgiacomo.gabrielli@arm.com      case IPR_CC_CTL:
25513610Sgiacomo.gabrielli@arm.com        // This IPR resets the cycle counter.  We assume this only
25613610Sgiacomo.gabrielli@arm.com        // happens once... let's verify that.
25713610Sgiacomo.gabrielli@arm.com        assert(ipr[idx] == 0);
25813610Sgiacomo.gabrielli@arm.com        ipr[idx] = 1;
25913610Sgiacomo.gabrielli@arm.com        break;
26013610Sgiacomo.gabrielli@arm.com
26113610Sgiacomo.gabrielli@arm.com      case IPR_CC:
26213610Sgiacomo.gabrielli@arm.com        // This IPR only writes the upper 64 bits.  It's ok to write
26313610Sgiacomo.gabrielli@arm.com        // all 64 here since we mask out the lower 32 in rpcc (see
26413610Sgiacomo.gabrielli@arm.com        // isa_desc).
26513610Sgiacomo.gabrielli@arm.com        ipr[idx] = val;
26613610Sgiacomo.gabrielli@arm.com        break;
26713610Sgiacomo.gabrielli@arm.com
26813610Sgiacomo.gabrielli@arm.com      case IPR_PALtemp23:
26913610Sgiacomo.gabrielli@arm.com        // write entire quad w/ no side-effect
27013610Sgiacomo.gabrielli@arm.com        if (tc->getKernelStats())
27113610Sgiacomo.gabrielli@arm.com            tc->getKernelStats()->context(ipr[idx], val, tc);
27213610Sgiacomo.gabrielli@arm.com        ipr[idx] = val;
27313610Sgiacomo.gabrielli@arm.com        break;
27413610Sgiacomo.gabrielli@arm.com
27513610Sgiacomo.gabrielli@arm.com      case IPR_DTB_PTE:
27613610Sgiacomo.gabrielli@arm.com        // write entire quad w/ no side-effect, tag is forthcoming
27713610Sgiacomo.gabrielli@arm.com        ipr[idx] = val;
27813610Sgiacomo.gabrielli@arm.com        break;
27913610Sgiacomo.gabrielli@arm.com
28013610Sgiacomo.gabrielli@arm.com      case IPR_EXC_ADDR:
28113610Sgiacomo.gabrielli@arm.com        // second least significant bit in PC is always zero
28213610Sgiacomo.gabrielli@arm.com        ipr[idx] = val & ~2;
28313610Sgiacomo.gabrielli@arm.com        break;
28413610Sgiacomo.gabrielli@arm.com
28513610Sgiacomo.gabrielli@arm.com      case IPR_ASTRR:
28613610Sgiacomo.gabrielli@arm.com      case IPR_ASTER:
28713610Sgiacomo.gabrielli@arm.com        // only write least significant four bits - privilege mask
28813610Sgiacomo.gabrielli@arm.com        ipr[idx] = val & 0xf;
28913610Sgiacomo.gabrielli@arm.com        break;
29013610Sgiacomo.gabrielli@arm.com
29113610Sgiacomo.gabrielli@arm.com      case IPR_IPLR:
29213610Sgiacomo.gabrielli@arm.com        // only write least significant five bits - interrupt level
29313610Sgiacomo.gabrielli@arm.com        ipr[idx] = val & 0x1f;
29413610Sgiacomo.gabrielli@arm.com        if (tc->getKernelStats())
29513610Sgiacomo.gabrielli@arm.com            tc->getKernelStats()->swpipl(ipr[idx]);
29613610Sgiacomo.gabrielli@arm.com        break;
29713610Sgiacomo.gabrielli@arm.com
29813610Sgiacomo.gabrielli@arm.com      case IPR_DTB_CM:
29913610Sgiacomo.gabrielli@arm.com        if (val & 0x18) {
30013610Sgiacomo.gabrielli@arm.com            if (tc->getKernelStats())
30113610Sgiacomo.gabrielli@arm.com                tc->getKernelStats()->mode(Kernel::user, tc);
30213610Sgiacomo.gabrielli@arm.com        } else {
30313610Sgiacomo.gabrielli@arm.com            if (tc->getKernelStats())
30413610Sgiacomo.gabrielli@arm.com                tc->getKernelStats()->mode(Kernel::kernel, tc);
30513610Sgiacomo.gabrielli@arm.com        }
30613610Sgiacomo.gabrielli@arm.com        M5_FALLTHROUGH;
30713610Sgiacomo.gabrielli@arm.com
30813610Sgiacomo.gabrielli@arm.com      case IPR_ICM:
30913610Sgiacomo.gabrielli@arm.com        // only write two mode bits - processor mode
31013610Sgiacomo.gabrielli@arm.com        ipr[idx] = val & 0x18;
31113610Sgiacomo.gabrielli@arm.com        break;
31213610Sgiacomo.gabrielli@arm.com
31313610Sgiacomo.gabrielli@arm.com      case IPR_ALT_MODE:
31413610Sgiacomo.gabrielli@arm.com        // only write two mode bits - processor mode
31513610Sgiacomo.gabrielli@arm.com        ipr[idx] = val & 0x18;
31613610Sgiacomo.gabrielli@arm.com        break;
31713610Sgiacomo.gabrielli@arm.com
31813610Sgiacomo.gabrielli@arm.com      case IPR_MCSR:
31913610Sgiacomo.gabrielli@arm.com        // more here after optimization...
32013610Sgiacomo.gabrielli@arm.com        ipr[idx] = val;
32113610Sgiacomo.gabrielli@arm.com        break;
32213610Sgiacomo.gabrielli@arm.com
32313610Sgiacomo.gabrielli@arm.com      case IPR_SIRR:
32413610Sgiacomo.gabrielli@arm.com        // only write software interrupt mask
32513610Sgiacomo.gabrielli@arm.com        ipr[idx] = val & 0x7fff0;
32613610Sgiacomo.gabrielli@arm.com        break;
32713610Sgiacomo.gabrielli@arm.com
32813610Sgiacomo.gabrielli@arm.com      case IPR_ICSR:
32913610Sgiacomo.gabrielli@arm.com        ipr[idx] = val & ULL(0xffffff0300);
33013610Sgiacomo.gabrielli@arm.com        break;
33113610Sgiacomo.gabrielli@arm.com
33213610Sgiacomo.gabrielli@arm.com      case IPR_IVPTBR:
33313610Sgiacomo.gabrielli@arm.com      case IPR_MVPTBR:
33413610Sgiacomo.gabrielli@arm.com        ipr[idx] = val & ULL(0xffffffffc0000000);
33513610Sgiacomo.gabrielli@arm.com        break;
33613610Sgiacomo.gabrielli@arm.com
33713610Sgiacomo.gabrielli@arm.com      case IPR_DC_TEST_CTL:
33813610Sgiacomo.gabrielli@arm.com        ipr[idx] = val & 0x1ffb;
33913610Sgiacomo.gabrielli@arm.com        break;
34013610Sgiacomo.gabrielli@arm.com
34113610Sgiacomo.gabrielli@arm.com      case IPR_DC_MODE:
34213610Sgiacomo.gabrielli@arm.com      case IPR_MAF_MODE:
34313610Sgiacomo.gabrielli@arm.com        ipr[idx] = val & 0x3f;
34413610Sgiacomo.gabrielli@arm.com        break;
34513610Sgiacomo.gabrielli@arm.com
34613610Sgiacomo.gabrielli@arm.com      case IPR_ITB_ASN:
34713610Sgiacomo.gabrielli@arm.com        ipr[idx] = val & 0x7f0;
34813610Sgiacomo.gabrielli@arm.com        break;
34913610Sgiacomo.gabrielli@arm.com
35013610Sgiacomo.gabrielli@arm.com      case IPR_DTB_ASN:
35113610Sgiacomo.gabrielli@arm.com        ipr[idx] = val & ULL(0xfe00000000000000);
35213610Sgiacomo.gabrielli@arm.com        break;
35313610Sgiacomo.gabrielli@arm.com
35413610Sgiacomo.gabrielli@arm.com      case IPR_EXC_SUM:
35513610Sgiacomo.gabrielli@arm.com      case IPR_EXC_MASK:
35613610Sgiacomo.gabrielli@arm.com        // any write to this register clears it
35713610Sgiacomo.gabrielli@arm.com        ipr[idx] = 0;
35813610Sgiacomo.gabrielli@arm.com        break;
35913610Sgiacomo.gabrielli@arm.com
36013610Sgiacomo.gabrielli@arm.com      case IPR_INTID:
36113610Sgiacomo.gabrielli@arm.com      case IPR_SL_RCV:
36213610Sgiacomo.gabrielli@arm.com      case IPR_MM_STAT:
36313610Sgiacomo.gabrielli@arm.com      case IPR_ITB_PTE_TEMP:
36413610Sgiacomo.gabrielli@arm.com      case IPR_DTB_PTE_TEMP:
36513610Sgiacomo.gabrielli@arm.com        // read-only registers
36613610Sgiacomo.gabrielli@arm.com        panic("Tried to write read only ipr %d\n", idx);
36713610Sgiacomo.gabrielli@arm.com
36813610Sgiacomo.gabrielli@arm.com      case IPR_HWINT_CLR:
36913610Sgiacomo.gabrielli@arm.com      case IPR_SL_XMIT:
37013610Sgiacomo.gabrielli@arm.com      case IPR_DC_FLUSH:
37113610Sgiacomo.gabrielli@arm.com      case IPR_IC_FLUSH:
37213610Sgiacomo.gabrielli@arm.com        // the following are write only
37313610Sgiacomo.gabrielli@arm.com        ipr[idx] = val;
37413610Sgiacomo.gabrielli@arm.com        break;
37513610Sgiacomo.gabrielli@arm.com
37613610Sgiacomo.gabrielli@arm.com      case IPR_DTB_IA:
37713610Sgiacomo.gabrielli@arm.com        // really a control write
37813610Sgiacomo.gabrielli@arm.com        ipr[idx] = 0;
37913610Sgiacomo.gabrielli@arm.com
38013610Sgiacomo.gabrielli@arm.com        getDTBPtr(tc)->flushAll();
38113610Sgiacomo.gabrielli@arm.com        break;
38213610Sgiacomo.gabrielli@arm.com
38313610Sgiacomo.gabrielli@arm.com      case IPR_DTB_IAP:
38413610Sgiacomo.gabrielli@arm.com        // really a control write
38513610Sgiacomo.gabrielli@arm.com        ipr[idx] = 0;
38613610Sgiacomo.gabrielli@arm.com
38713610Sgiacomo.gabrielli@arm.com        getDTBPtr(tc)->flushProcesses();
38813610Sgiacomo.gabrielli@arm.com        break;
38913610Sgiacomo.gabrielli@arm.com
39013610Sgiacomo.gabrielli@arm.com      case IPR_DTB_IS:
39113610Sgiacomo.gabrielli@arm.com        // really a control write
39213610Sgiacomo.gabrielli@arm.com        ipr[idx] = val;
39313610Sgiacomo.gabrielli@arm.com
39413610Sgiacomo.gabrielli@arm.com        getDTBPtr(tc)->flushAddr(val, DTB_ASN_ASN(ipr[IPR_DTB_ASN]));
39513610Sgiacomo.gabrielli@arm.com        break;
39613610Sgiacomo.gabrielli@arm.com
39713610Sgiacomo.gabrielli@arm.com      case IPR_DTB_TAG: {
39813610Sgiacomo.gabrielli@arm.com          struct TlbEntry entry;
39913610Sgiacomo.gabrielli@arm.com
40013610Sgiacomo.gabrielli@arm.com          // FIXME: granularity hints NYI...
40113610Sgiacomo.gabrielli@arm.com          if (DTB_PTE_GH(ipr[IPR_DTB_PTE]) != 0)
40213610Sgiacomo.gabrielli@arm.com              panic("PTE GH field != 0");
40313610Sgiacomo.gabrielli@arm.com
40413610Sgiacomo.gabrielli@arm.com          // write entire quad
405          ipr[idx] = val;
406
407          // construct PTE for new entry
408          entry.ppn = DTB_PTE_PPN(ipr[IPR_DTB_PTE]);
409          entry.xre = DTB_PTE_XRE(ipr[IPR_DTB_PTE]);
410          entry.xwe = DTB_PTE_XWE(ipr[IPR_DTB_PTE]);
411          entry.fonr = DTB_PTE_FONR(ipr[IPR_DTB_PTE]);
412          entry.fonw = DTB_PTE_FONW(ipr[IPR_DTB_PTE]);
413          entry.asma = DTB_PTE_ASMA(ipr[IPR_DTB_PTE]);
414          entry.asn = DTB_ASN_ASN(ipr[IPR_DTB_ASN]);
415
416          // insert new TAG/PTE value into data TLB
417          getDTBPtr(tc)->insert(val, entry);
418      }
419        break;
420
421      case IPR_ITB_PTE: {
422          struct TlbEntry entry;
423
424          // FIXME: granularity hints NYI...
425          if (ITB_PTE_GH(val) != 0)
426              panic("PTE GH field != 0");
427
428          // write entire quad
429          ipr[idx] = val;
430
431          // construct PTE for new entry
432          entry.ppn = ITB_PTE_PPN(val);
433          entry.xre = ITB_PTE_XRE(val);
434          entry.xwe = 0;
435          entry.fonr = ITB_PTE_FONR(val);
436          entry.fonw = ITB_PTE_FONW(val);
437          entry.asma = ITB_PTE_ASMA(val);
438          entry.asn = ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
439
440          // insert new TAG/PTE value into data TLB
441          getITBPtr(tc)->insert(ipr[IPR_ITB_TAG], entry);
442      }
443        break;
444
445      case IPR_ITB_IA:
446        // really a control write
447        ipr[idx] = 0;
448
449        getITBPtr(tc)->flushAll();
450        break;
451
452      case IPR_ITB_IAP:
453        // really a control write
454        ipr[idx] = 0;
455
456        getITBPtr(tc)->flushProcesses();
457        break;
458
459      case IPR_ITB_IS:
460        // really a control write
461        ipr[idx] = val;
462
463        getITBPtr(tc)->flushAddr(val, ITB_ASN_ASN(ipr[IPR_ITB_ASN]));
464        break;
465
466      default:
467        // invalid IPR
468        panic("Tried to write to invalid ipr %d\n", idx);
469    }
470
471    // no error...
472}
473
474void
475copyIprs(ThreadContext *src, ThreadContext *dest)
476{
477    for (int i = 0; i < NumInternalProcRegs; ++i)
478        dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
479}
480
481} // namespace AlphaISA
482
483using namespace AlphaISA;
484
485Fault
486SimpleThread::hwrei()
487{
488    PCState pc = pcState();
489    if (!(pc.pc() & 0x3))
490        return std::make_shared<UnimplementedOpcodeFault>();
491
492    pc.npc(readMiscRegNoEffect(IPR_EXC_ADDR));
493    pcState(pc);
494
495    CPA::cpa()->swAutoBegin(tc, pc.npc());
496
497    if (kernelStats)
498        kernelStats->hwrei();
499
500    // FIXME: XXX check for interrupts? XXX
501    return NoFault;
502}
503
504/**
505 * Check for special simulator handling of specific PAL calls.
506 * If return value is false, actual PAL call will be suppressed.
507 */
508bool
509SimpleThread::simPalCheck(int palFunc)
510{
511    if (kernelStats)
512        kernelStats->callpal(palFunc, tc);
513
514    switch (palFunc) {
515      case PAL::halt:
516        halt();
517        if (--System::numSystemsRunning == 0)
518            exitSimLoop("all cpus halted");
519        break;
520
521      case PAL::bpt:
522      case PAL::bugchk:
523        if (system->breakpoint())
524            return false;
525        break;
526    }
527
528    return true;
529}
530