faults.hh revision 12136
16502Snate@binkert.org/*
26502Snate@binkert.org * Copyright (c) 2016 RISC-V Foundation
36502Snate@binkert.org * Copyright (c) 2016 The University of Virginia
46502Snate@binkert.org * All rights reserved.
56502Snate@binkert.org *
66502Snate@binkert.org * Redistribution and use in source and binary forms, with or without
76502Snate@binkert.org * modification, are permitted provided that the following conditions are
86502Snate@binkert.org * met: redistributions of source code must retain the above copyright
96502Snate@binkert.org * notice, this list of conditions and the following disclaimer;
106502Snate@binkert.org * redistributions in binary form must reproduce the above copyright
116502Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
126502Snate@binkert.org * documentation and/or other materials provided with the distribution;
136502Snate@binkert.org * neither the name of the copyright holders nor the names of its
146502Snate@binkert.org * contributors may be used to endorse or promote products derived from
156502Snate@binkert.org * this software without specific prior written permission.
166502Snate@binkert.org *
176502Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186502Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196502Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206502Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216502Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226502Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236502Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246502Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256502Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266502Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276651Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286502Snate@binkert.org *
296502Snate@binkert.org * Authors: Alec Roelke
306502Snate@binkert.org */
316502Snate@binkert.org
326502Snate@binkert.org#ifndef __ARCH_RISCV_FAULTS_HH__
336502Snate@binkert.org#define __ARCH_RISCV_FAULTS_HH__
346502Snate@binkert.org
356502Snate@binkert.org#include <string>
366502Snate@binkert.org
376502Snate@binkert.org#include "cpu/thread_context.hh"
386502Snate@binkert.org#include "sim/faults.hh"
396502Snate@binkert.org
406502Snate@binkert.orgnamespace RiscvISA
416502Snate@binkert.org{
426502Snate@binkert.org
436502Snate@binkert.orgconst uint32_t FloatInexact = 1 << 0;
446502Snate@binkert.orgconst uint32_t FloatUnderflow = 1 << 1;
456502Snate@binkert.orgconst uint32_t FloatOverflow = 1 << 2;
466502Snate@binkert.orgconst uint32_t FloatDivZero = 1 << 3;
476502Snate@binkert.orgconst uint32_t FloatInvalid = 1 << 4;
486502Snate@binkert.org
496502Snate@binkert.orgenum ExceptionCode {
506502Snate@binkert.org    INST_ADDR_MISALIGNED = 0,
516502Snate@binkert.org    INST_ACCESS = 1,
526502Snate@binkert.org    INST_ILLEGAL = 2,
536502Snate@binkert.org    BREAKPOINT = 3,
546502Snate@binkert.org    LOAD_ADDR_MISALIGNED = 4,
556502Snate@binkert.org    LOAD_ACCESS = 5,
566502Snate@binkert.org    STORE_ADDR_MISALIGNED = 6,
576502Snate@binkert.org    AMO_ADDR_MISALIGNED = 6,
586999Snate@binkert.org    STORE_ACCESS = 7,
596999Snate@binkert.org    AMO_ACCESS = 7,
606999Snate@binkert.org    ECALL_USER = 8,
616502Snate@binkert.org    ECALL_SUPER = 9,
626502Snate@binkert.org    ECALL_HYPER = 10,
636502Snate@binkert.org    ECALL_MACH = 11
646999Snate@binkert.org};
656999Snate@binkert.org
666502Snate@binkert.orgenum InterruptCode {
676651Snate@binkert.org    SOFTWARE,
686651Snate@binkert.org    TIMER
696502Snate@binkert.org};
706502Snate@binkert.org
716502Snate@binkert.orgclass RiscvFault : public FaultBase
726502Snate@binkert.org{
736502Snate@binkert.org  protected:
746502Snate@binkert.org    const FaultName _name;
756502Snate@binkert.org    const ExceptionCode _code;
766502Snate@binkert.org    const InterruptCode _int;
776502Snate@binkert.org
786502Snate@binkert.org    RiscvFault(FaultName n, ExceptionCode c, InterruptCode i)
796502Snate@binkert.org        : _name(n), _code(c), _int(i)
806502Snate@binkert.org    {}
816502Snate@binkert.org
826502Snate@binkert.org    FaultName
836502Snate@binkert.org    name() const
846502Snate@binkert.org    {
856502Snate@binkert.org        return _name;
866502Snate@binkert.org    }
876502Snate@binkert.org
886502Snate@binkert.org    ExceptionCode
896502Snate@binkert.org    exception() const
906502Snate@binkert.org    {
916502Snate@binkert.org        return _code;
926502Snate@binkert.org    }
936502Snate@binkert.org
946502Snate@binkert.org    InterruptCode
956502Snate@binkert.org    interrupt() const
966502Snate@binkert.org    {
976502Snate@binkert.org        return _int;
986502Snate@binkert.org    }
996502Snate@binkert.org
1006502Snate@binkert.org    virtual void
1016502Snate@binkert.org    invoke_se(ThreadContext *tc, const StaticInstPtr &inst);
1026502Snate@binkert.org
1036502Snate@binkert.org    void
1046502Snate@binkert.org    invoke(ThreadContext *tc, const StaticInstPtr &inst);
1056502Snate@binkert.org};
1066502Snate@binkert.org
1076502Snate@binkert.org
1086502Snate@binkert.orgclass UnknownInstFault : public RiscvFault
1096502Snate@binkert.org{
1106502Snate@binkert.org  public:
1116502Snate@binkert.org    UnknownInstFault() : RiscvFault("Unknown instruction", INST_ILLEGAL,
1126502Snate@binkert.org            SOFTWARE)
1136502Snate@binkert.org    {}
1146502Snate@binkert.org
1156502Snate@binkert.org    void
1166502Snate@binkert.org    invoke_se(ThreadContext *tc, const StaticInstPtr &inst);
1176502Snate@binkert.org};
1186502Snate@binkert.org
1196502Snate@binkert.orgclass IllegalInstFault : public RiscvFault
1206502Snate@binkert.org{
1216502Snate@binkert.org  private:
1226502Snate@binkert.org    const std::string reason;
1236502Snate@binkert.org  public:
1246502Snate@binkert.org    IllegalInstFault(std::string r)
1256502Snate@binkert.org        : RiscvFault("Illegal instruction", INST_ILLEGAL, SOFTWARE),
1266999Snate@binkert.org          reason(r)
1276502Snate@binkert.org    {}
1286502Snate@binkert.org
1296502Snate@binkert.org    void invoke_se(ThreadContext *tc, const StaticInstPtr &inst);
1306502Snate@binkert.org};
1316502Snate@binkert.org
1326502Snate@binkert.orgclass UnimplementedFault : public RiscvFault
1336502Snate@binkert.org{
1346502Snate@binkert.org  private:
1356502Snate@binkert.org    const std::string instName;
1366502Snate@binkert.org  public:
1376502Snate@binkert.org    UnimplementedFault(std::string name)
1386502Snate@binkert.org        : RiscvFault("Unimplemented instruction", INST_ILLEGAL, SOFTWARE),
1396502Snate@binkert.org        instName(name)
1406502Snate@binkert.org    {}
1416502Snate@binkert.org
1426502Snate@binkert.org    void
1436502Snate@binkert.org    invoke_se(ThreadContext *tc, const StaticInstPtr &inst);
1446502Snate@binkert.org};
1456502Snate@binkert.org
1466502Snate@binkert.orgclass IllegalFrmFault: public RiscvFault
1476502Snate@binkert.org{
1486502Snate@binkert.org  private:
1496502Snate@binkert.org    const uint8_t frm;
1506502Snate@binkert.org  public:
1516502Snate@binkert.org    IllegalFrmFault(uint8_t r)
1526502Snate@binkert.org        : RiscvFault("Illegal floating-point rounding mode", INST_ILLEGAL,
1536502Snate@binkert.org                SOFTWARE),
1546502Snate@binkert.org        frm(r)
1556502Snate@binkert.org    {}
1566502Snate@binkert.org
1576502Snate@binkert.org    void invoke_se(ThreadContext *tc, const StaticInstPtr &inst);
1586502Snate@binkert.org};
1596502Snate@binkert.org
1606502Snate@binkert.orgclass BreakpointFault : public RiscvFault
1616502Snate@binkert.org{
1626502Snate@binkert.org  public:
1636502Snate@binkert.org    BreakpointFault() : RiscvFault("Breakpoint", BREAKPOINT, SOFTWARE)
1646502Snate@binkert.org    {}
1656502Snate@binkert.org
1666502Snate@binkert.org    void
1676502Snate@binkert.org    invoke_se(ThreadContext *tc, const StaticInstPtr &inst);
1686502Snate@binkert.org};
1696502Snate@binkert.org
1706502Snate@binkert.orgclass SyscallFault : public RiscvFault
1716502Snate@binkert.org{
1726502Snate@binkert.org  public:
1736502Snate@binkert.org    // TODO: replace ECALL_USER with the appropriate privilege level of the
1746502Snate@binkert.org    // caller
1756502Snate@binkert.org    SyscallFault() : RiscvFault("System call", ECALL_USER, SOFTWARE)
1766502Snate@binkert.org    {}
1776502Snate@binkert.org
1786502Snate@binkert.org    void
1796502Snate@binkert.org    invoke_se(ThreadContext *tc, const StaticInstPtr &inst);
1806502Snate@binkert.org};
1816502Snate@binkert.org
1826502Snate@binkert.org} // namespace RiscvISA
1836502Snate@binkert.org
1846502Snate@binkert.org#endif // __ARCH_RISCV_FAULTS_HH__
1856502Snate@binkert.org