faults.hh revision 10205
112855Sgabeblack@google.com/*
212855Sgabeblack@google.com * Copyright (c) 2003-2005 The Regents of The University of Michigan
312855Sgabeblack@google.com * Copyright (c) 2007 MIPS Technologies, Inc.
412855Sgabeblack@google.com * All rights reserved.
512855Sgabeblack@google.com *
612855Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
712855Sgabeblack@google.com * modification, are permitted provided that the following conditions are
812855Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
912855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
1012855Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1112855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1212855Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1312855Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1412855Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1512855Sgabeblack@google.com * this software without specific prior written permission.
1612855Sgabeblack@google.com *
1712855Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1812855Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1912855Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2012855Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2112855Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2212855Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2312855Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2412855Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2512855Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2612855Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2712855Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2812855Sgabeblack@google.com *
2912855Sgabeblack@google.com * Authors: Gabe Black
3012855Sgabeblack@google.com *          Korey Sewell
3112855Sgabeblack@google.com *          Jaidev Patwardhan
3212855Sgabeblack@google.com *          Zhengxing Li
3312855Sgabeblack@google.com *          Deyuan Guo
3412855Sgabeblack@google.com */
3512855Sgabeblack@google.com
3612855Sgabeblack@google.com#ifndef __MIPS_FAULTS_HH__
3712855Sgabeblack@google.com#define __MIPS_FAULTS_HH__
3812855Sgabeblack@google.com
3912855Sgabeblack@google.com#include "arch/mips/pra_constants.hh"
4012855Sgabeblack@google.com#include "cpu/thread_context.hh"
4112855Sgabeblack@google.com#include "debug/MipsPRA.hh"
4212855Sgabeblack@google.com#include "sim/faults.hh"
4312855Sgabeblack@google.com#include "sim/full_system.hh"
4412855Sgabeblack@google.com
4512855Sgabeblack@google.comnamespace MipsISA
4612855Sgabeblack@google.com{
4712855Sgabeblack@google.com
4812855Sgabeblack@google.comtypedef const Addr FaultVect;
4912855Sgabeblack@google.com
5012855Sgabeblack@google.comenum ExcCode {
5112855Sgabeblack@google.com    // A dummy value to use when the code isn't defined or doesn't matter.
5212855Sgabeblack@google.com    ExcCodeDummy = 0,
5312855Sgabeblack@google.com
5412855Sgabeblack@google.com    ExcCodeInt = 0,
5512855Sgabeblack@google.com    ExcCodeMod = 1,
5612855Sgabeblack@google.com    ExcCodeTlbL = 2,
5712855Sgabeblack@google.com    ExcCodeTlbS = 3,
5812855Sgabeblack@google.com    ExcCodeAdEL = 4,
5912855Sgabeblack@google.com    ExcCodeAdES = 5,
6012855Sgabeblack@google.com    ExcCodeIBE = 6,
6112855Sgabeblack@google.com    ExcCodeDBE = 7,
6212855Sgabeblack@google.com    ExcCodeSys = 8,
6312855Sgabeblack@google.com    ExcCodeBp = 9,
6412855Sgabeblack@google.com    ExcCodeRI = 10,
6512855Sgabeblack@google.com    ExcCodeCpU = 11,
6612855Sgabeblack@google.com    ExcCodeOv = 12,
6712855Sgabeblack@google.com    ExcCodeTr = 13,
6812855Sgabeblack@google.com    ExcCodeC2E = 18,
6912855Sgabeblack@google.com    ExcCodeMDMX = 22,
7012855Sgabeblack@google.com    ExcCodeWatch = 23,
7112855Sgabeblack@google.com    ExcCodeMCheck = 24,
7212855Sgabeblack@google.com    ExcCodeThread = 25,
7312855Sgabeblack@google.com    ExcCodeCacheErr = 30
7412855Sgabeblack@google.com};
7512855Sgabeblack@google.com
7612855Sgabeblack@google.comclass MipsFaultBase : public FaultBase
7712855Sgabeblack@google.com{
7812855Sgabeblack@google.com  public:
7912855Sgabeblack@google.com    struct FaultVals
8012855Sgabeblack@google.com    {
8112855Sgabeblack@google.com        const FaultName name;
8212855Sgabeblack@google.com        const FaultVect offset;
8312855Sgabeblack@google.com        const ExcCode code;
8412855Sgabeblack@google.com    };
8512855Sgabeblack@google.com
8612855Sgabeblack@google.com    void setExceptionState(ThreadContext *, uint8_t);
8712855Sgabeblack@google.com
8812855Sgabeblack@google.com    virtual FaultVect offset(ThreadContext *tc) const = 0;
8912855Sgabeblack@google.com    virtual ExcCode code() const = 0;
9012855Sgabeblack@google.com    virtual FaultVect base(ThreadContext *tc) const
9112855Sgabeblack@google.com    {
9212855Sgabeblack@google.com        StatusReg status = tc->readMiscReg(MISCREG_STATUS);
9312855Sgabeblack@google.com        if (!status.bev)
9412855Sgabeblack@google.com            return tc->readMiscReg(MISCREG_EBASE);
9512855Sgabeblack@google.com        else
9612855Sgabeblack@google.com            return 0xbfc00200;
9712855Sgabeblack@google.com    }
9812855Sgabeblack@google.com
9912855Sgabeblack@google.com    FaultVect
10012855Sgabeblack@google.com    vect(ThreadContext *tc) const
10112855Sgabeblack@google.com    {
10212855Sgabeblack@google.com        return base(tc) + offset(tc);
10312855Sgabeblack@google.com    }
10412855Sgabeblack@google.com
10512855Sgabeblack@google.com    void invoke(ThreadContext * tc,
10612855Sgabeblack@google.com            StaticInstPtr inst = StaticInst::nullStaticInstPtr);
10712855Sgabeblack@google.com};
10812855Sgabeblack@google.com
10912855Sgabeblack@google.comtemplate <typename T>
11012855Sgabeblack@google.comclass MipsFault : public MipsFaultBase
11112855Sgabeblack@google.com{
11212855Sgabeblack@google.com  protected:
11312855Sgabeblack@google.com    static FaultVals vals;
11412855Sgabeblack@google.com  public:
11512855Sgabeblack@google.com    FaultName name() const { return vals.name; }
11612855Sgabeblack@google.com    FaultVect offset(ThreadContext *tc) const { return vals.offset; }
11712855Sgabeblack@google.com    ExcCode code() const { return vals.code; }
11812855Sgabeblack@google.com};
11912855Sgabeblack@google.com
12012855Sgabeblack@google.comclass SystemCallFault : public MipsFault<SystemCallFault> {};
12112855Sgabeblack@google.comclass ReservedInstructionFault : public MipsFault<ReservedInstructionFault> {};
12212855Sgabeblack@google.comclass ThreadFault : public MipsFault<ThreadFault> {};
12312855Sgabeblack@google.comclass IntegerOverflowFault : public MipsFault<IntegerOverflowFault> {};
12412855Sgabeblack@google.comclass TrapFault : public MipsFault<TrapFault> {};
12512855Sgabeblack@google.comclass BreakpointFault : public MipsFault<BreakpointFault> {};
12612855Sgabeblack@google.comclass DspStateDisabledFault : public MipsFault<DspStateDisabledFault> {};
12712855Sgabeblack@google.com
12812855Sgabeblack@google.comclass MachineCheckFault : public MipsFault<MachineCheckFault>
12912855Sgabeblack@google.com{
13012855Sgabeblack@google.com  public:
13112855Sgabeblack@google.com    bool isMachineCheckFault() { return true; }
13212855Sgabeblack@google.com};
13312855Sgabeblack@google.com
13412855Sgabeblack@google.comclass ResetFault : public MipsFault<ResetFault>
13512855Sgabeblack@google.com{
13612855Sgabeblack@google.com  public:
13712855Sgabeblack@google.com    void invoke(ThreadContext * tc,
13812855Sgabeblack@google.com            StaticInstPtr inst = StaticInst::nullStaticInstPtr);
13912855Sgabeblack@google.com
14012855Sgabeblack@google.com};
14112855Sgabeblack@google.com
14212855Sgabeblack@google.comclass SoftResetFault : public MipsFault<SoftResetFault>
14312855Sgabeblack@google.com{
14412855Sgabeblack@google.com  public:
14512855Sgabeblack@google.com    void invoke(ThreadContext * tc,
14612855Sgabeblack@google.com            StaticInstPtr inst = StaticInst::nullStaticInstPtr);
14712855Sgabeblack@google.com};
14812855Sgabeblack@google.com
14912855Sgabeblack@google.comclass NonMaskableInterrupt : public MipsFault<NonMaskableInterrupt>
15012855Sgabeblack@google.com{
15112855Sgabeblack@google.com  public:
15212855Sgabeblack@google.com    void invoke(ThreadContext * tc,
15312855Sgabeblack@google.com            StaticInstPtr inst = StaticInst::nullStaticInstPtr);
15412855Sgabeblack@google.com};
15512855Sgabeblack@google.com
15612855Sgabeblack@google.comclass CoprocessorUnusableFault : public MipsFault<CoprocessorUnusableFault>
15712855Sgabeblack@google.com{
15812855Sgabeblack@google.com  protected:
15912855Sgabeblack@google.com    int coProcID;
16012855Sgabeblack@google.com  public:
16112855Sgabeblack@google.com    CoprocessorUnusableFault(int _procid) : coProcID(_procid)
16212855Sgabeblack@google.com    {}
16312855Sgabeblack@google.com
16412855Sgabeblack@google.com    void
16512855Sgabeblack@google.com    invoke(ThreadContext * tc,
16612855Sgabeblack@google.com            StaticInstPtr inst = StaticInst::nullStaticInstPtr)
16712855Sgabeblack@google.com    {
16812855Sgabeblack@google.com        MipsFault<CoprocessorUnusableFault>::invoke(tc, inst);
16912855Sgabeblack@google.com        if (FullSystem) {
17012855Sgabeblack@google.com            CauseReg cause = tc->readMiscReg(MISCREG_CAUSE);
17112855Sgabeblack@google.com            cause.ce = coProcID;
17212855Sgabeblack@google.com            tc->setMiscRegNoEffect(MISCREG_CAUSE, cause);
17312855Sgabeblack@google.com        }
17412855Sgabeblack@google.com    }
17512855Sgabeblack@google.com};
17612855Sgabeblack@google.com
17712855Sgabeblack@google.comclass InterruptFault : public MipsFault<InterruptFault>
17812855Sgabeblack@google.com{
17912855Sgabeblack@google.com  public:
18012855Sgabeblack@google.com    FaultVect
18112855Sgabeblack@google.com    offset(ThreadContext *tc) const
18212855Sgabeblack@google.com    {
18312855Sgabeblack@google.com        CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
18412855Sgabeblack@google.com        // offset 0x200 for release 2, 0x180 for release 1.
18512855Sgabeblack@google.com        return cause.iv ? 0x200 : 0x180;
18612855Sgabeblack@google.com    }
18712855Sgabeblack@google.com};
18812855Sgabeblack@google.com
18912855Sgabeblack@google.comtemplate <typename T>
19012855Sgabeblack@google.comclass AddressFault : public MipsFault<T>
19112855Sgabeblack@google.com{
19212855Sgabeblack@google.com  protected:
19312855Sgabeblack@google.com    Addr vaddr;
19412855Sgabeblack@google.com    bool store;
19512855Sgabeblack@google.com
19612855Sgabeblack@google.com    AddressFault(Addr _vaddr, bool _store) : vaddr(_vaddr), store(_store)
19712855Sgabeblack@google.com    {}
19812855Sgabeblack@google.com
19912855Sgabeblack@google.com    void
20012855Sgabeblack@google.com    invoke(ThreadContext * tc,
20112855Sgabeblack@google.com            StaticInstPtr inst = StaticInst::nullStaticInstPtr)
20212855Sgabeblack@google.com    {
20312855Sgabeblack@google.com        MipsFault<T>::invoke(tc, inst);
20412855Sgabeblack@google.com        if (FullSystem)
20512855Sgabeblack@google.com            tc->setMiscRegNoEffect(MISCREG_BADVADDR, vaddr);
20612855Sgabeblack@google.com    }
20712855Sgabeblack@google.com};
20812855Sgabeblack@google.com
20912855Sgabeblack@google.comclass AddressErrorFault : public AddressFault<AddressErrorFault>
21012855Sgabeblack@google.com{
21112855Sgabeblack@google.com  public:
21212855Sgabeblack@google.com    AddressErrorFault(Addr _vaddr, bool _store) :
21312855Sgabeblack@google.com        AddressFault<AddressErrorFault>(_vaddr, _store)
21412855Sgabeblack@google.com    {}
21512855Sgabeblack@google.com
21612855Sgabeblack@google.com    ExcCode
21712855Sgabeblack@google.com    code() const
21812855Sgabeblack@google.com    {
21912855Sgabeblack@google.com        return store ? ExcCodeAdES : ExcCodeAdEL;
22012855Sgabeblack@google.com    }
22112855Sgabeblack@google.com
22212855Sgabeblack@google.com};
22312855Sgabeblack@google.com
22412855Sgabeblack@google.comtemplate <typename T>
22512855Sgabeblack@google.comclass TlbFault : public AddressFault<T>
22612855Sgabeblack@google.com{
22712855Sgabeblack@google.com  protected:
22812855Sgabeblack@google.com    Addr asid;
22912855Sgabeblack@google.com    Addr vpn;
23012855Sgabeblack@google.com
23112855Sgabeblack@google.com    TlbFault(Addr _asid, Addr _vaddr, Addr _vpn, bool _store) :
23212855Sgabeblack@google.com        AddressFault<T>(_vaddr, _store), asid(_asid), vpn(_vpn)
23312855Sgabeblack@google.com    {}
23412855Sgabeblack@google.com
23512855Sgabeblack@google.com    void
23612855Sgabeblack@google.com    setTlbExceptionState(ThreadContext *tc, uint8_t excCode)
23712855Sgabeblack@google.com    {
23812855Sgabeblack@google.com        this->setExceptionState(tc, excCode);
23912855Sgabeblack@google.com
24012855Sgabeblack@google.com        tc->setMiscRegNoEffect(MISCREG_BADVADDR, this->vaddr);
24112855Sgabeblack@google.com        EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
24212855Sgabeblack@google.com        entryHi.asid = this->asid;
24312855Sgabeblack@google.com        entryHi.vpn2 = this->vpn >> 2;
24412855Sgabeblack@google.com        entryHi.vpn2x = this->vpn & 0x3;
24512855Sgabeblack@google.com        tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
24612855Sgabeblack@google.com
24712855Sgabeblack@google.com        ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
24812855Sgabeblack@google.com        context.badVPN2 = this->vpn >> 2;
24912855Sgabeblack@google.com        tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
25012855Sgabeblack@google.com    }
25112855Sgabeblack@google.com
25212855Sgabeblack@google.com    void
25312855Sgabeblack@google.com    invoke(ThreadContext * tc,
25412855Sgabeblack@google.com            StaticInstPtr inst = StaticInst::nullStaticInstPtr)
25512855Sgabeblack@google.com    {
25612855Sgabeblack@google.com        if (FullSystem) {
25712855Sgabeblack@google.com            DPRINTF(MipsPRA, "Fault %s encountered.\n", this->name());
25812855Sgabeblack@google.com            Addr vect = this->vect(tc);
25912855Sgabeblack@google.com            setTlbExceptionState(tc, this->code());
26012855Sgabeblack@google.com            tc->pcState(vect);
26112855Sgabeblack@google.com        } else {
26212855Sgabeblack@google.com            AddressFault<T>::invoke(tc, inst);
26312855Sgabeblack@google.com        }
26412855Sgabeblack@google.com    }
26512855Sgabeblack@google.com
26612855Sgabeblack@google.com    ExcCode
26712855Sgabeblack@google.com    code() const
26812855Sgabeblack@google.com    {
26912855Sgabeblack@google.com        return this->store ? ExcCodeTlbS : ExcCodeTlbL;
27012855Sgabeblack@google.com    }
27112855Sgabeblack@google.com};
27212855Sgabeblack@google.com
27312855Sgabeblack@google.comclass TlbRefillFault : public TlbFault<TlbRefillFault>
27412855Sgabeblack@google.com{
27512855Sgabeblack@google.com  public:
27612855Sgabeblack@google.com    TlbRefillFault(Addr asid, Addr vaddr, Addr vpn, bool store) :
27712855Sgabeblack@google.com        TlbFault<TlbRefillFault>(asid, vaddr, vpn, store)
27812855Sgabeblack@google.com    {}
27912855Sgabeblack@google.com
28012855Sgabeblack@google.com    FaultVect
28112855Sgabeblack@google.com    offset(ThreadContext *tc) const
28212855Sgabeblack@google.com    {
28312855Sgabeblack@google.com        StatusReg status = tc->readMiscReg(MISCREG_STATUS);
28412855Sgabeblack@google.com        return status.exl ? 0x180 : 0x000;
28512855Sgabeblack@google.com    }
28612855Sgabeblack@google.com};
28712855Sgabeblack@google.com
28812855Sgabeblack@google.comclass TlbInvalidFault : public TlbFault<TlbInvalidFault>
28912855Sgabeblack@google.com{
29012855Sgabeblack@google.com  public:
29112855Sgabeblack@google.com    TlbInvalidFault(Addr asid, Addr vaddr, Addr vpn, bool store) :
29212855Sgabeblack@google.com        TlbFault<TlbInvalidFault>(asid, vaddr, vpn, store)
29312855Sgabeblack@google.com    {}
29412855Sgabeblack@google.com};
29512855Sgabeblack@google.com
29612855Sgabeblack@google.comclass TlbModifiedFault : public TlbFault<TlbModifiedFault>
29712855Sgabeblack@google.com{
29812855Sgabeblack@google.com  public:
29912855Sgabeblack@google.com    TlbModifiedFault(Addr asid, Addr vaddr, Addr vpn) :
30012855Sgabeblack@google.com        TlbFault<TlbModifiedFault>(asid, vaddr, vpn, false)
30112855Sgabeblack@google.com    {}
30212855Sgabeblack@google.com
30312855Sgabeblack@google.com    ExcCode code() const { return MipsFault<TlbModifiedFault>::code(); }
30412855Sgabeblack@google.com};
30512855Sgabeblack@google.com
30612855Sgabeblack@google.com} // namespace MipsISA
30712855Sgabeblack@google.com
30812855Sgabeblack@google.com#endif // __MIPS_FAULTS_HH__
30912855Sgabeblack@google.com