faults.hh revision 13547
12292SN/A/*
22329SN/A * Copyright (c) 2016 RISC-V Foundation
32292SN/A * Copyright (c) 2016 The University of Virginia
42292SN/A * Copyright (c) 2018 TU Dresden
52292SN/A * All rights reserved.
62292SN/A *
72292SN/A * Redistribution and use in source and binary forms, with or without
82292SN/A * modification, are permitted provided that the following conditions are
92292SN/A * met: redistributions of source code must retain the above copyright
102292SN/A * notice, this list of conditions and the following disclaimer;
112292SN/A * redistributions in binary form must reproduce the above copyright
122292SN/A * notice, this list of conditions and the following disclaimer in the
132292SN/A * documentation and/or other materials provided with the distribution;
142292SN/A * neither the name of the copyright holders nor the names of its
152292SN/A * contributors may be used to endorse or promote products derived from
162292SN/A * this software without specific prior written permission.
172292SN/A *
182292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
192292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
202292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
212292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
222292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
232292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
242292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
252292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
262292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
272689Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
282689Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
292292SN/A *
302292SN/A * Authors: Alec Roelke
312292SN/A *          Robert Scheffel
322292SN/A */
332292SN/A
342292SN/A#ifndef __ARCH_RISCV_FAULTS_HH__
352292SN/A#define __ARCH_RISCV_FAULTS_HH__
362292SN/A
372292SN/A#include <map>
382292SN/A#include <string>
392292SN/A
402669Sktlim@umich.edu#include "arch/riscv/isa.hh"
412292SN/A#include "arch/riscv/registers.hh"
422292SN/A#include "cpu/thread_context.hh"
432292SN/A#include "sim/faults.hh"
442292SN/A
452292SN/Anamespace RiscvISA
462292SN/A{
472733Sktlim@umich.edu
482292SN/Aenum FloatException : MiscReg {
492292SN/A    FloatInexact = 0x1,
502292SN/A    FloatUnderflow = 0x2,
512292SN/A    FloatOverflow = 0x4,
522348SN/A    FloatDivZero = 0x8,
532292SN/A    FloatInvalid = 0x10
542292SN/A};
552292SN/A
562292SN/Aenum ExceptionCode : MiscReg {
572292SN/A    INST_ADDR_MISALIGNED = 0,
582292SN/A    INST_ACCESS = 1,
592292SN/A    INST_ILLEGAL = 2,
604329Sktlim@umich.edu    BREAKPOINT = 3,
612292SN/A    LOAD_ADDR_MISALIGNED = 4,
622292SN/A    LOAD_ACCESS = 5,
632292SN/A    STORE_ADDR_MISALIGNED = 6,
642292SN/A    AMO_ADDR_MISALIGNED = 6,
652727Sktlim@umich.edu    STORE_ACCESS = 7,
662727Sktlim@umich.edu    AMO_ACCESS = 7,
672727Sktlim@umich.edu    ECALL_USER = 8,
682871Sktlim@umich.edu    ECALL_SUPER = 9,
692871Sktlim@umich.edu    ECALL_MACHINE = 11,
702871Sktlim@umich.edu    INST_PAGE = 12,
712871Sktlim@umich.edu    LOAD_PAGE = 13,
722871Sktlim@umich.edu    STORE_PAGE = 15,
732907Sktlim@umich.edu    AMO_PAGE = 15
742871Sktlim@umich.edu};
752292SN/A
762292SN/Aclass RiscvFault : public FaultBase
772348SN/A{
782307SN/A  protected:
792348SN/A    const FaultName _name;
802307SN/A    const bool _interrupt;
812307SN/A    ExceptionCode _code;
822292SN/A
832292SN/A    RiscvFault(FaultName n, bool i, ExceptionCode c)
842292SN/A        : _name(n), _interrupt(i), _code(c)
852292SN/A    {}
862292SN/A
872292SN/A    FaultName name() const override { return _name; }
882292SN/A    bool isInterrupt() const { return _interrupt; }
892292SN/A    ExceptionCode exception() const { return _code; }
902292SN/A    virtual MiscReg trap_value() const { return 0; }
912292SN/A
922292SN/A    virtual void invokeSE(ThreadContext *tc, const StaticInstPtr &inst);
932329SN/A    void invoke(ThreadContext *tc, const StaticInstPtr &inst) override;
942329SN/A};
952292SN/A
962292SN/Aclass Reset : public FaultBase
972292SN/A{
982292SN/A  private:
992292SN/A    const FaultName _name;
1002292SN/A
1012292SN/A  public:
1022292SN/A    Reset() : _name("reset") {}
1032292SN/A    FaultName name() const override { return _name; }
1042292SN/A
1052292SN/A    void invoke(ThreadContext *tc, const StaticInstPtr &inst =
1062292SN/A        StaticInst::nullStaticInstPtr) override;
1072292SN/A};
1082292SN/A
1092292SN/Aclass InstFault : public RiscvFault
1102329SN/A{
1112329SN/A  protected:
1122329SN/A    const ExtMachInst _inst;
1132292SN/A
1142292SN/A  public:
1152292SN/A    InstFault(FaultName n, const ExtMachInst inst)
1162329SN/A        : RiscvFault(n, false, INST_ILLEGAL), _inst(inst)
1172329SN/A    {}
1182292SN/A
1192292SN/A    MiscReg trap_value() const override { return _inst; }
1202292SN/A};
1212292SN/A
1222292SN/Aclass UnknownInstFault : public InstFault
1232292SN/A{
1242292SN/A  public:
1252292SN/A    UnknownInstFault(const ExtMachInst inst)
1262292SN/A        : InstFault("Unknown instruction", inst)
1272292SN/A    {}
1282292SN/A
1292292SN/A    void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
1302329SN/A};
1312329SN/A
1322292SN/Aclass IllegalInstFault : public InstFault
1332292SN/A{
1342292SN/A  private:
1352292SN/A    const std::string reason;
1362292SN/A
1372292SN/A  public:
1382292SN/A    IllegalInstFault(std::string r, const ExtMachInst inst)
1392329SN/A        : InstFault("Illegal instruction", inst)
1402329SN/A    {}
1412292SN/A
1422292SN/A    void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
1432292SN/A};
1442292SN/A
1452329SN/Aclass UnimplementedFault : public InstFault
1462329SN/A{
1472292SN/A  private:
1482292SN/A    const std::string instName;
1492292SN/A
1502292SN/A  public:
1512292SN/A    UnimplementedFault(std::string name, const ExtMachInst inst)
1522292SN/A        : InstFault("Unimplemented instruction", inst),
1532292SN/A          instName(name)
1542292SN/A    {}
1552329SN/A
1562329SN/A    void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
1572292SN/A};
1582292SN/A
1592329SN/Aclass IllegalFrmFault: public InstFault
1602329SN/A{
1612329SN/A  private:
1622292SN/A    const uint8_t frm;
1632292SN/A
1642292SN/A  public:
1652292SN/A    IllegalFrmFault(uint8_t r, const ExtMachInst inst)
1662292SN/A        : InstFault("Illegal floating-point rounding mode", inst),
1672292SN/A          frm(r)
1682292SN/A    {}
1692329SN/A
1702329SN/A    void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
1712329SN/A};
1722292SN/A
1732292SN/Aclass AddressFault : public RiscvFault
1742292SN/A{
1752292SN/A  private:
1762292SN/A    const Addr _addr;
1772292SN/A
1782292SN/A  public:
1792292SN/A    AddressFault(const Addr addr, ExceptionCode code)
1802292SN/A        : RiscvFault("Address", false, code), _addr(addr)
1812329SN/A    {}
1822329SN/A
1832292SN/A    MiscReg trap_value() const override { return _addr; }
1842292SN/A};
1852292SN/A
1862292SN/Aclass BreakpointFault : public RiscvFault
1872329SN/A{
1882329SN/A  private:
1892292SN/A    const PCState pcState;
1902292SN/A
1912292SN/A  public:
1922292SN/A    BreakpointFault(const PCState &pc)
1932329SN/A        : RiscvFault("Breakpoint", false, BREAKPOINT), pcState(pc)
1942329SN/A    {}
1952292SN/A
1962292SN/A    MiscReg trap_value() const override { return pcState.pc(); }
1972292SN/A    void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
1982292SN/A};
1992329SN/A
2002329SN/Aclass SyscallFault : public RiscvFault
2012292SN/A{
2022292SN/A  public:
2032292SN/A    SyscallFault(PrivilegeMode prv)
2042292SN/A        : RiscvFault("System call", false, ECALL_USER)
2052292SN/A    {
2062292SN/A        switch (prv) {
2072292SN/A          case PRV_U:
2082292SN/A            _code = ECALL_USER;
2092292SN/A            break;
2102292SN/A          case PRV_S:
2112292SN/A            _code = ECALL_SUPER;
2122292SN/A            break;
2132292SN/A          case PRV_M:
2142292SN/A            _code = ECALL_MACHINE;
2152292SN/A            break;
2162292SN/A          default:
2172292SN/A            panic("Unknown privilege mode %d.", prv);
2182292SN/A            break;
2192292SN/A        }
2202292SN/A    }
2212292SN/A
2222292SN/A    void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
2232292SN/A};
2242292SN/A
2252292SN/A} // namespace RiscvISA
2262292SN/A
2272292SN/A#endif // __ARCH_RISCV_FAULTS_HH__
2282292SN/A