faults.hh revision 12850
111482Sandreas.sandberg@arm.com/*
211482Sandreas.sandberg@arm.com * Copyright (c) 2016 RISC-V Foundation
311482Sandreas.sandberg@arm.com * Copyright (c) 2016 The University of Virginia
411482Sandreas.sandberg@arm.com * Copyright (c) 2018 TU Dresden
511482Sandreas.sandberg@arm.com * All rights reserved.
611482Sandreas.sandberg@arm.com *
711482Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
811482Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
911482Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
1011482Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
1111482Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1211482Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
1311482Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
1411482Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
1511482Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
1611482Sandreas.sandberg@arm.com * this software without specific prior written permission.
1711482Sandreas.sandberg@arm.com *
1811482Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1911482Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2011482Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2111482Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2211482Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2311482Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2411482Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2511482Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2611482Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2711482Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2811482Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2911482Sandreas.sandberg@arm.com *
3011482Sandreas.sandberg@arm.com * Authors: Alec Roelke
3111482Sandreas.sandberg@arm.com *          Robert Scheffel
3211482Sandreas.sandberg@arm.com */
3311482Sandreas.sandberg@arm.com
3411482Sandreas.sandberg@arm.com#ifndef __ARCH_RISCV_FAULTS_HH__
3511482Sandreas.sandberg@arm.com#define __ARCH_RISCV_FAULTS_HH__
3611482Sandreas.sandberg@arm.com
3711482Sandreas.sandberg@arm.com#include <map>
3811482Sandreas.sandberg@arm.com#include <string>
3911482Sandreas.sandberg@arm.com
4011482Sandreas.sandberg@arm.com#include "arch/riscv/isa.hh"
4111482Sandreas.sandberg@arm.com#include "arch/riscv/registers.hh"
4211482Sandreas.sandberg@arm.com#include "cpu/thread_context.hh"
4311482Sandreas.sandberg@arm.com#include "sim/faults.hh"
4411482Sandreas.sandberg@arm.com
4511482Sandreas.sandberg@arm.comnamespace RiscvISA
4611482Sandreas.sandberg@arm.com{
4711482Sandreas.sandberg@arm.com
4811482Sandreas.sandberg@arm.comenum FloatException : MiscReg {
4911482Sandreas.sandberg@arm.com    FloatInexact = 0x1,
5011482Sandreas.sandberg@arm.com    FloatUnderflow = 0x2,
5111482Sandreas.sandberg@arm.com    FloatOverflow = 0x4,
5211482Sandreas.sandberg@arm.com    FloatDivZero = 0x8,
5311482Sandreas.sandberg@arm.com    FloatInvalid = 0x10
5411482Sandreas.sandberg@arm.com};
5511482Sandreas.sandberg@arm.com
5611482Sandreas.sandberg@arm.comenum ExceptionCode : MiscReg {
5711482Sandreas.sandberg@arm.com    INST_ADDR_MISALIGNED = 0,
5811482Sandreas.sandberg@arm.com    INST_ACCESS = 1,
5911482Sandreas.sandberg@arm.com    INST_ILLEGAL = 2,
6011482Sandreas.sandberg@arm.com    BREAKPOINT = 3,
6111482Sandreas.sandberg@arm.com    LOAD_ADDR_MISALIGNED = 4,
6211482Sandreas.sandberg@arm.com    LOAD_ACCESS = 5,
6311482Sandreas.sandberg@arm.com    STORE_ADDR_MISALIGNED = 6,
6411482Sandreas.sandberg@arm.com    AMO_ADDR_MISALIGNED = 6,
6511482Sandreas.sandberg@arm.com    STORE_ACCESS = 7,
6611482Sandreas.sandberg@arm.com    AMO_ACCESS = 7,
6711482Sandreas.sandberg@arm.com    ECALL_USER = 8,
6811482Sandreas.sandberg@arm.com    ECALL_SUPER = 9,
6911482Sandreas.sandberg@arm.com    ECALL_MACHINE = 11,
7011482Sandreas.sandberg@arm.com    INST_PAGE = 12,
7111482Sandreas.sandberg@arm.com    LOAD_PAGE = 13,
7211482Sandreas.sandberg@arm.com    STORE_PAGE = 15,
7311482Sandreas.sandberg@arm.com    AMO_PAGE = 15
7411482Sandreas.sandberg@arm.com};
7511482Sandreas.sandberg@arm.com
7611482Sandreas.sandberg@arm.comclass RiscvFault : public FaultBase
7711482Sandreas.sandberg@arm.com{
7811482Sandreas.sandberg@arm.com  protected:
7911482Sandreas.sandberg@arm.com    const FaultName _name;
8011482Sandreas.sandberg@arm.com    const bool _interrupt;
8111482Sandreas.sandberg@arm.com    ExceptionCode _code;
8211482Sandreas.sandberg@arm.com
8311482Sandreas.sandberg@arm.com    RiscvFault(FaultName n, bool i, ExceptionCode c)
8411482Sandreas.sandberg@arm.com        : _name(n), _interrupt(i), _code(c)
8511482Sandreas.sandberg@arm.com    {}
8611482Sandreas.sandberg@arm.com
8711482Sandreas.sandberg@arm.com    FaultName name() const override { return _name; }
8811482Sandreas.sandberg@arm.com    bool isInterrupt() const { return _interrupt; }
8911482Sandreas.sandberg@arm.com    ExceptionCode exception() const { return _code; }
9011482Sandreas.sandberg@arm.com    virtual MiscReg trap_value() const { return 0; }
9111482Sandreas.sandberg@arm.com
9211482Sandreas.sandberg@arm.com    virtual void invokeSE(ThreadContext *tc, const StaticInstPtr &inst);
9311482Sandreas.sandberg@arm.com    void invoke(ThreadContext *tc, const StaticInstPtr &inst) override;
9411482Sandreas.sandberg@arm.com};
9511482Sandreas.sandberg@arm.com
9611482Sandreas.sandberg@arm.comclass Reset : public FaultBase
9711482Sandreas.sandberg@arm.com{
9811482Sandreas.sandberg@arm.com
9911482Sandreas.sandberg@arm.com    public:
10011482Sandreas.sandberg@arm.com        Reset()
10111482Sandreas.sandberg@arm.com            : _name("reset")
10211482Sandreas.sandberg@arm.com        {}
10311482Sandreas.sandberg@arm.com
10411482Sandreas.sandberg@arm.com        FaultName
10511482Sandreas.sandberg@arm.com        name() const override
10611482Sandreas.sandberg@arm.com        {
10711482Sandreas.sandberg@arm.com            return _name;
10811482Sandreas.sandberg@arm.com        }
10911482Sandreas.sandberg@arm.com
11011482Sandreas.sandberg@arm.com        void
11111482Sandreas.sandberg@arm.com        invoke(ThreadContext *tc, const StaticInstPtr &inst =
11211482Sandreas.sandberg@arm.com            StaticInst::nullStaticInstPtr) override;
11311482Sandreas.sandberg@arm.com
11411482Sandreas.sandberg@arm.com    private:
11511482Sandreas.sandberg@arm.com        const FaultName _name;
11611482Sandreas.sandberg@arm.com};
11711482Sandreas.sandberg@arm.com
11811482Sandreas.sandberg@arm.comclass InstFault : public RiscvFault
11911482Sandreas.sandberg@arm.com{
12011482Sandreas.sandberg@arm.com  protected:
12111482Sandreas.sandberg@arm.com    const ExtMachInst _inst;
12211482Sandreas.sandberg@arm.com
12311482Sandreas.sandberg@arm.com  public:
12411482Sandreas.sandberg@arm.com    InstFault(FaultName n, const ExtMachInst inst)
12511482Sandreas.sandberg@arm.com        : RiscvFault(n, false, INST_ILLEGAL), _inst(inst)
12611482Sandreas.sandberg@arm.com    {}
12711482Sandreas.sandberg@arm.com
12811482Sandreas.sandberg@arm.com    MiscReg trap_value() const override { return _inst; }
12911482Sandreas.sandberg@arm.com};
13011482Sandreas.sandberg@arm.com
13111482Sandreas.sandberg@arm.comclass UnknownInstFault : public InstFault
13211482Sandreas.sandberg@arm.com{
13311482Sandreas.sandberg@arm.com  public:
13411482Sandreas.sandberg@arm.com    UnknownInstFault(const ExtMachInst inst)
13511482Sandreas.sandberg@arm.com        : InstFault("Unknown instruction", inst)
13611482Sandreas.sandberg@arm.com    {}
13711482Sandreas.sandberg@arm.com
13811482Sandreas.sandberg@arm.com    void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
13911482Sandreas.sandberg@arm.com};
14011482Sandreas.sandberg@arm.com
14111482Sandreas.sandberg@arm.comclass IllegalInstFault : public InstFault
14211482Sandreas.sandberg@arm.com{
14311482Sandreas.sandberg@arm.com  private:
14411482Sandreas.sandberg@arm.com    const std::string reason;
14511482Sandreas.sandberg@arm.com
14611482Sandreas.sandberg@arm.com  public:
14711482Sandreas.sandberg@arm.com    IllegalInstFault(std::string r, const ExtMachInst inst)
14811482Sandreas.sandberg@arm.com        : InstFault("Illegal instruction", inst)
14911482Sandreas.sandberg@arm.com    {}
15011482Sandreas.sandberg@arm.com
15111482Sandreas.sandberg@arm.com    void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
15211482Sandreas.sandberg@arm.com};
15311482Sandreas.sandberg@arm.com
15411482Sandreas.sandberg@arm.comclass UnimplementedFault : public InstFault
15511482Sandreas.sandberg@arm.com{
15611482Sandreas.sandberg@arm.com  private:
15711482Sandreas.sandberg@arm.com    const std::string instName;
15811482Sandreas.sandberg@arm.com
15911482Sandreas.sandberg@arm.com  public:
16011482Sandreas.sandberg@arm.com    UnimplementedFault(std::string name, const ExtMachInst inst)
16111482Sandreas.sandberg@arm.com        : InstFault("Unimplemented instruction", inst),
16211482Sandreas.sandberg@arm.com          instName(name)
16311482Sandreas.sandberg@arm.com    {}
16411482Sandreas.sandberg@arm.com
16511482Sandreas.sandberg@arm.com    void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
16611482Sandreas.sandberg@arm.com};
16711482Sandreas.sandberg@arm.com
16811482Sandreas.sandberg@arm.comclass IllegalFrmFault: public InstFault
16911482Sandreas.sandberg@arm.com{
17011482Sandreas.sandberg@arm.com  private:
17111482Sandreas.sandberg@arm.com    const uint8_t frm;
17211482Sandreas.sandberg@arm.com
17311482Sandreas.sandberg@arm.com  public:
17411482Sandreas.sandberg@arm.com    IllegalFrmFault(uint8_t r, const ExtMachInst inst)
17511482Sandreas.sandberg@arm.com        : InstFault("Illegal floating-point rounding mode", inst),
17611482Sandreas.sandberg@arm.com          frm(r)
17711482Sandreas.sandberg@arm.com    {}
17811482Sandreas.sandberg@arm.com
17911482Sandreas.sandberg@arm.com    void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
18011482Sandreas.sandberg@arm.com};
18111482Sandreas.sandberg@arm.com
18211482Sandreas.sandberg@arm.comclass AddressFault : public RiscvFault
18311482Sandreas.sandberg@arm.com{
18411482Sandreas.sandberg@arm.com  private:
18511482Sandreas.sandberg@arm.com    const Addr _addr;
18611482Sandreas.sandberg@arm.com
18711482Sandreas.sandberg@arm.com  public:
18811482Sandreas.sandberg@arm.com    AddressFault(const Addr addr, ExceptionCode code)
18911482Sandreas.sandberg@arm.com        : RiscvFault("Address", false, code), _addr(addr)
19011482Sandreas.sandberg@arm.com    {}
19111482Sandreas.sandberg@arm.com
19211482Sandreas.sandberg@arm.com    MiscReg trap_value() const override { return _addr; }
19311482Sandreas.sandberg@arm.com};
19411482Sandreas.sandberg@arm.com
19511482Sandreas.sandberg@arm.comclass BreakpointFault : public RiscvFault
19611482Sandreas.sandberg@arm.com{
19711482Sandreas.sandberg@arm.com  private:
19811482Sandreas.sandberg@arm.com    const PCState pcState;
19911482Sandreas.sandberg@arm.com
20011482Sandreas.sandberg@arm.com  public:
20111482Sandreas.sandberg@arm.com    BreakpointFault(const PCState &pc)
20211482Sandreas.sandberg@arm.com        : RiscvFault("Breakpoint", false, BREAKPOINT), pcState(pc)
20311482Sandreas.sandberg@arm.com    {}
20411482Sandreas.sandberg@arm.com
20511482Sandreas.sandberg@arm.com    MiscReg trap_value() const override { return pcState.pc(); }
20611482Sandreas.sandberg@arm.com    void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
20711482Sandreas.sandberg@arm.com};
20811482Sandreas.sandberg@arm.com
20911482Sandreas.sandberg@arm.comclass SyscallFault : public RiscvFault
21011482Sandreas.sandberg@arm.com{
21111482Sandreas.sandberg@arm.com  public:
21211482Sandreas.sandberg@arm.com    SyscallFault(PrivilegeMode prv)
21311482Sandreas.sandberg@arm.com        : RiscvFault("System call", false, ECALL_USER)
21411482Sandreas.sandberg@arm.com    {
21511482Sandreas.sandberg@arm.com        switch (prv) {
21611482Sandreas.sandberg@arm.com          case PRV_U:
21711482Sandreas.sandberg@arm.com            _code = ECALL_USER;
21811482Sandreas.sandberg@arm.com            break;
21911482Sandreas.sandberg@arm.com          case PRV_S:
22011482Sandreas.sandberg@arm.com            _code = ECALL_SUPER;
22111482Sandreas.sandberg@arm.com            break;
22211482Sandreas.sandberg@arm.com          case PRV_M:
22311482Sandreas.sandberg@arm.com            _code = ECALL_MACHINE;
22411482Sandreas.sandberg@arm.com            break;
22511482Sandreas.sandberg@arm.com          default:
22611482Sandreas.sandberg@arm.com            panic("Unknown privilege mode %d.", prv);
22711482Sandreas.sandberg@arm.com            break;
22811482Sandreas.sandberg@arm.com        }
22911482Sandreas.sandberg@arm.com    }
23011482Sandreas.sandberg@arm.com
23111482Sandreas.sandberg@arm.com    void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
23211482Sandreas.sandberg@arm.com};
23311482Sandreas.sandberg@arm.com
23411482Sandreas.sandberg@arm.com} // namespace RiscvISA
23511482Sandreas.sandberg@arm.com
23611482Sandreas.sandberg@arm.com#endif // __ARCH_RISCV_FAULTS_HH__
23711482Sandreas.sandberg@arm.com