OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [cpu_fnc_plugin/] [riscv-rv64i-priv.cpp] - Diff between revs 2 and 4

Show entire file | Details | Blame | View Log

Rev 2 Rev 4
Line 5... Line 5...
 * @brief      Base ISA implementation (extension I, privileged level).
 * @brief      Base ISA implementation (extension I, privileged level).
 */
 */
 
 
#include "api_utils.h"
#include "api_utils.h"
#include "riscv-isa.h"
#include "riscv-isa.h"
#include "instructions.h"
#include "cpu_riscv_func.h"
 
 
namespace debugger {
namespace debugger {
 
 
void generateException(uint64_t code, CpuContextType *data);
 
void generateInterrupt(uint64_t code, CpuContextType *data);
 
 
 
uint64_t readCSR(uint32_t idx, CpuContextType *data) {
 
    uint64_t ret = data->csr[idx];
 
    switch (idx) {
 
    case CSR_mtime:
 
        ret = data->step_cnt;
 
        break;
 
    default:;
 
    }
 
    return ret;
 
}
 
 
 
void writeCSR(uint32_t idx, uint64_t val, CpuContextType *data) {
 
    switch (idx) {
 
    // Read-Only registers
 
    case CSR_misa:
 
    case CSR_mvendorid:
 
    case CSR_marchid:
 
    case CSR_mimplementationid:
 
    case CSR_mhartid:
 
        break;
 
    case CSR_mtime:
 
        break;
 
    default:
 
        data->csr[idx] = val;
 
    }
 
}
 
 
 
/**
/**
 * @brief The CSRRC (Atomic Read and Clear Bit in CSR).
 * @brief The CSRRC (Atomic Read and Clear Bit in CSR).
 *
 *
 * Instruction reads the value of the CSR, zeroextends the value to XLEN bits,
 * Instruction reads the value of the CSR, zeroextends the value to XLEN bits,
 * and writes it to integer register rd. The initial value in integer
 * and writes it to integer register rd. The initial value in integer
 * register rs1 specifies bit positions to be cleared in the CSR. Any bit that
 * register rs1 specifies bit positions to be cleared in the CSR. Any bit that
 * is high in rs1 will cause the corresponding bit to be cleared in the CSR,
 * is high in rs1 will cause the corresponding bit to be cleared in the CSR,
 * if that CSR bit is writable. Other bits in the CSR are unaffected.
 * if that CSR bit is writable. Other bits in the CSR are unaffected.
 */
 */
class CSRRC : public IsaProcessor {
class CSRRC : public RiscvInstruction {
public:
public:
    CSRRC() : IsaProcessor("CSRRC", "?????????????????011?????1110011") {}
    CSRRC(CpuRiver_Functional *icpu) :
 
        RiscvInstruction(icpu, "CSRRC", "?????????????????011?????1110011") {}
 
 
    virtual void exec(uint32_t *payload, CpuContextType *data) {
    virtual int exec(Reg64Type *payload) {
        ISA_I_type u;
        ISA_I_type u;
        u.value = payload[0];
        u.value = payload->buf32[0];
 
 
        uint64_t clr_mask = ~data->regs[u.bits.rs1];
        uint64_t clr_mask = ~R[u.bits.rs1];
        uint64_t csr = readCSR(u.bits.imm, data);
        uint64_t csr = icpu_->readCSR(u.bits.imm);
        if (u.bits.rd) {
        if (u.bits.rd) {
            data->regs[u.bits.rd] = csr;
            R[u.bits.rd] = csr;
        }
        }
        writeCSR(u.bits.imm, (csr & clr_mask), data);
        icpu_->writeCSR(u.bits.imm, (csr & clr_mask));
        data->npc = data->pc + 4;
        return 4;
    }
    }
};
};
 
 
/**
/**
 * @brief The CSRRCI (Atomic Read and Clear Bit in CSR immediate).
 * @brief The CSRRCI (Atomic Read and Clear Bit in CSR immediate).
 *
 *
 * Similar to CSRRC except it updates the CSR using a 5-bit zero-extended
 * Similar to CSRRC except it updates the CSR using a 5-bit zero-extended
 * immediate (zimm[4:0]) encoded in the rs1 field instead of a value from
 * immediate (zimm[4:0]) encoded in the rs1 field instead of a value from
 * an integer register.
 * an integer register.
 */
 */
class CSRRCI : public IsaProcessor {
class CSRRCI : public RiscvInstruction {
public:
public:
    CSRRCI() : IsaProcessor("CSRRCI", "?????????????????111?????1110011") {}
    CSRRCI(CpuRiver_Functional *icpu) :
 
        RiscvInstruction(icpu, "CSRRCI", "?????????????????111?????1110011") {}
 
 
    virtual void exec(uint32_t *payload, CpuContextType *data) {
    virtual int exec(Reg64Type *payload) {
        ISA_I_type u;
        ISA_I_type u;
        u.value = payload[0];
        u.value = payload->buf32[0];
 
 
        uint64_t clr_mask = ~static_cast<uint64_t>((u.bits.rs1));
        uint64_t clr_mask = ~static_cast<uint64_t>((u.bits.rs1));
        uint64_t csr = readCSR(u.bits.imm, data);
        uint64_t csr = icpu_->readCSR(u.bits.imm);
        if (u.bits.rd) {
        if (u.bits.rd) {
            data->regs[u.bits.rd] = csr;
            R[u.bits.rd] = csr;
        }
        }
        writeCSR(u.bits.imm, (csr & clr_mask), data);
        icpu_->writeCSR(u.bits.imm, (csr & clr_mask));
        data->npc = data->pc + 4;
        return 4;
    }
    }
};
};
 
 
/**
/**
 * @brief The CSRRS (Atomic Read and Set Bit in CSR).
 * @brief The CSRRS (Atomic Read and Set Bit in CSR).
Line 102... Line 74...
 * high in rs1 will cause the corresponding bit to be set in the CSR, if that
 * high in rs1 will cause the corresponding bit to be set in the CSR, if that
 * CSR bit is writable. Other bits in the CSR are unaffected (though CSRs
 * CSR bit is writable. Other bits in the CSR are unaffected (though CSRs
 * might have side effects when written).
 * might have side effects when written).
 *   The CSRR pseudo instruction (read CSR), when rs1 = 0.
 *   The CSRR pseudo instruction (read CSR), when rs1 = 0.
 */
 */
class CSRRS : public IsaProcessor {
class CSRRS : public RiscvInstruction {
public:
public:
    CSRRS() : IsaProcessor("CSRRS", "?????????????????010?????1110011") {}
    CSRRS(CpuRiver_Functional *icpu) :
 
        RiscvInstruction(icpu, "CSRRS", "?????????????????010?????1110011") {}
 
 
    virtual void exec(uint32_t *payload, CpuContextType *data) {
    virtual int exec(Reg64Type *payload) {
        ISA_I_type u;
        ISA_I_type u;
        u.value = payload[0];
        u.value = payload->buf32[0];
 
 
        uint64_t set_mask = data->regs[u.bits.rs1];
        uint64_t set_mask = R[u.bits.rs1];
        uint64_t csr = readCSR(u.bits.imm, data);
        uint64_t csr = icpu_->readCSR(u.bits.imm);
        if (u.bits.rd) {
        if (u.bits.rd) {
            data->regs[u.bits.rd] = csr;
            R[u.bits.rd] = csr;
        }
        }
        writeCSR(u.bits.imm, (csr | set_mask), data);
        icpu_->writeCSR(u.bits.imm, (csr | set_mask));
        data->npc = data->pc + 4;
        return 4;
    }
    }
};
};
 
 
/**
/**
 * @brief The CSRRSI (Atomic Read and Set Bit in CSR immediate).
 * @brief The CSRRSI (Atomic Read and Set Bit in CSR immediate).
 *
 *
 * Similar to CSRRS except it updates the CSR using a 5-bit zero-extended
 * Similar to CSRRS except it updates the CSR using a 5-bit zero-extended
 * immediate (zimm[4:0]) encoded in the rs1 field instead of a value from
 * immediate (zimm[4:0]) encoded in the rs1 field instead of a value from
 * an integer register.
 * an integer register.
 */
 */
class CSRRSI : public IsaProcessor {
class CSRRSI : public RiscvInstruction {
public:
public:
    CSRRSI() : IsaProcessor("CSRRSI", "?????????????????110?????1110011") {}
    CSRRSI(CpuRiver_Functional *icpu) :
 
        RiscvInstruction(icpu, "CSRRSI", "?????????????????110?????1110011") {}
 
 
    virtual void exec(uint32_t *payload, CpuContextType *data) {
    virtual int exec(Reg64Type *payload) {
        ISA_I_type u;
        ISA_I_type u;
        u.value = payload[0];
        u.value = payload->buf32[0];
 
 
        uint64_t set_mask = u.bits.rs1;
        uint64_t set_mask = u.bits.rs1;
        uint64_t csr = readCSR(u.bits.imm, data);
        uint64_t csr = icpu_->readCSR(u.bits.imm);
        if (u.bits.rd) {
        if (u.bits.rd) {
            data->regs[u.bits.rd] = csr;
            R[u.bits.rd] = csr;
        }
        }
        writeCSR(u.bits.imm, (csr | set_mask), data);
        icpu_->writeCSR(u.bits.imm, (csr | set_mask));
        data->npc = data->pc + 4;
        return 4;
    }
    }
};
};
 
 
/**
/**
 * @brief The CSRRW (Atomic Read/Write CSR).
 * @brief The CSRRW (Atomic Read/Write CSR).
Line 154... Line 128...
 * CSRRW reads the old value of the CSR, zero-extends the value to XLEN bits,
 * CSRRW reads the old value of the CSR, zero-extends the value to XLEN bits,
 * then writes it to integer register rd. The initial value in rs1 is written
 * then writes it to integer register rd. The initial value in rs1 is written
 * to the CSR.
 * to the CSR.
 *   The CSRW pseudo instruction (write CSR), when rs1 = 0.
 *   The CSRW pseudo instruction (write CSR), when rs1 = 0.
 */
 */
class CSRRW : public IsaProcessor {
class CSRRW : public RiscvInstruction {
public:
public:
    CSRRW() : IsaProcessor("CSRRW", "?????????????????001?????1110011") {}
    CSRRW(CpuRiver_Functional *icpu) :
 
        RiscvInstruction(icpu, "CSRRW", "?????????????????001?????1110011") {}
 
 
    virtual void exec(uint32_t *payload, CpuContextType *data) {
    virtual int exec(Reg64Type *payload) {
        ISA_I_type u;
        ISA_I_type u;
        u.value = payload[0];
        u.value = payload->buf32[0];
 
 
        uint64_t wr_value = data->regs[u.bits.rs1];
        uint64_t wr_value = R[u.bits.rs1];
        if (u.bits.rd) {
        if (u.bits.rd) {
            data->regs[u.bits.rd] = readCSR(u.bits.imm, data);
            R[u.bits.rd] = icpu_->readCSR(u.bits.imm);
        }
        }
        writeCSR(u.bits.imm, wr_value, data);
        icpu_->writeCSR(u.bits.imm, wr_value);
        data->npc = data->pc + 4;
        return 4;
    }
    }
};
};
 
 
/**
/**
 * @brief The CSRRWI (Atomic Read/Write CSR immediate).
 * @brief The CSRRWI (Atomic Read/Write CSR immediate).
 *
 *
 * Similar to CSRRW except it updates the CSR using a 5-bit zero-extended
 * Similar to CSRRW except it updates the CSR using a 5-bit zero-extended
 * immediate (zimm[4:0]) encoded in the rs1 field instead of a value from
 * immediate (zimm[4:0]) encoded in the rs1 field instead of a value from
 * an integer register.
 * an integer register.
 */
 */
class CSRRWI : public IsaProcessor {
class CSRRWI : public RiscvInstruction {
public:
public:
    CSRRWI() : IsaProcessor("CSRRWI", "?????????????????101?????1110011") {}
    CSRRWI(CpuRiver_Functional *icpu) :
 
        RiscvInstruction(icpu, "CSRRWI", "?????????????????101?????1110011") {}
 
 
    virtual void exec(uint32_t *payload, CpuContextType *data) {
    virtual int exec(Reg64Type *payload) {
        ISA_I_type u;
        ISA_I_type u;
        u.value = payload[0];
        u.value = payload->buf32[0];
 
 
        uint64_t wr_value = u.bits.rs1;
        uint64_t wr_value = u.bits.rs1;
        if (u.bits.rd) {
        if (u.bits.rd) {
            data->regs[u.bits.rd] = readCSR(u.bits.imm, data);
            R[u.bits.rd] = icpu_->readCSR(u.bits.imm);
        }
        }
        writeCSR(u.bits.imm, wr_value, data);
        icpu_->writeCSR(u.bits.imm, wr_value);
        data->npc = data->pc + 4;
        return 4;
    }
    }
};
};
 
 
/**
/**
 * @brief MRET, HRET, SRET, or URET
 * @brief MRET, HRET, SRET, or URET
Line 209... Line 185...
 * User-level interrupts are an optional extension and have been allocated
 * User-level interrupts are an optional extension and have been allocated
 * the ISA extension letter N. If user-level interrupts are omitted, the UIE
 * the ISA extension letter N. If user-level interrupts are omitted, the UIE
 * and UPIE bits are hardwired to zero. For all other supported privilege
 * and UPIE bits are hardwired to zero. For all other supported privilege
 * modes x, the x IE, x PIE, and x PP fields are required to be implemented.
 * modes x, the x IE, x PIE, and x PP fields are required to be implemented.
 */
 */
class URET : public IsaProcessor {
class URET : public RiscvInstruction {
public:
public:
    URET() : IsaProcessor("URET", "00000000001000000000000001110011") {}
    URET(CpuRiver_Functional *icpu) :
 
        RiscvInstruction(icpu, "URET", "00000000001000000000000001110011") {}
 
 
    virtual void exec(uint32_t *payload, CpuContextType *data) {
    virtual int exec(Reg64Type *payload) {
        if (data->cur_prv_level != PRV_U) {
        if (icpu_->getPrvLevel() != PRV_U) {
            generateException(EXCEPTION_InstrIllegal, data);
            icpu_->raiseSignal(EXCEPTION_InstrIllegal);
            return;
            return 4;
        }
        }
        csr_mstatus_type mstatus;
        csr_mstatus_type mstatus;
        mstatus.value = readCSR(CSR_mstatus, data);
        mstatus.value = icpu_->readCSR(CSR_mstatus);
 
 
        uint64_t xepc = (PRV_U << 8) + 0x41;
        uint64_t xepc = (PRV_U << 8) + 0x41;
        data->npc = readCSR(static_cast<uint32_t>(xepc), data);
        icpu_->setBranch(icpu_->readCSR(static_cast<uint32_t>(xepc)));
 
 
        bool is_N_extension = false;
        bool is_N_extension = false;
        if (is_N_extension) {
        if (is_N_extension) {
            mstatus.bits.UIE = mstatus.bits.UPIE;
            mstatus.bits.UIE = mstatus.bits.UPIE;
            mstatus.bits.UPIE = 1;
            mstatus.bits.UPIE = 1;
            // User mode not changed.
            // User mode not changed.
        } else {
        } else {
            mstatus.bits.UIE = 0;
            mstatus.bits.UIE = 0;
            mstatus.bits.UPIE = 0;
            mstatus.bits.UPIE = 0;
        }
        }
        data->cur_prv_level = PRV_U;
        icpu_->setPrvLevel(PRV_U);
        writeCSR(CSR_mstatus, mstatus.value, data);
        icpu_->writeCSR(CSR_mstatus, mstatus.value);
 
        return 4;
    }
    }
};
};
 
 
/**
/**
 * @brief SRET return from super-user mode
 * @brief SRET return from super-user mode
 */
 */
class SRET : public IsaProcessor {
class SRET : public RiscvInstruction {
public:
public:
    SRET() : IsaProcessor("SRET", "00010000001000000000000001110011") {}
    SRET(CpuRiver_Functional *icpu) :
 
        RiscvInstruction(icpu, "SRET", "00010000001000000000000001110011") {}
 
 
    virtual void exec(uint32_t *payload, CpuContextType *data) {
    virtual int exec(Reg64Type *payload) {
        if (data->cur_prv_level != PRV_S) {
        if (icpu_->getPrvLevel() != PRV_S) {
            generateException(EXCEPTION_InstrIllegal, data);
            icpu_->raiseSignal(EXCEPTION_InstrIllegal);
            return;
            return 4;
        }
        }
        csr_mstatus_type mstatus;
        csr_mstatus_type mstatus;
        mstatus.value = readCSR(CSR_mstatus, data);
        mstatus.value = icpu_->readCSR(CSR_mstatus);
 
 
        uint64_t xepc = (PRV_S << 8) + 0x41;
        uint64_t xepc = (PRV_S << 8) + 0x41;
        data->npc = readCSR(static_cast<uint32_t>(xepc), data);
        icpu_->setBranch(icpu_->readCSR(static_cast<uint32_t>(xepc)));
 
 
        mstatus.bits.SIE = mstatus.bits.SPIE;
        mstatus.bits.SIE = mstatus.bits.SPIE;
        mstatus.bits.SPIE = 1;
        mstatus.bits.SPIE = 1;
        data->cur_prv_level = mstatus.bits.SPP;
        icpu_->setPrvLevel(mstatus.bits.SPP);
        mstatus.bits.SPP = PRV_U;
        mstatus.bits.SPP = PRV_U;
 
 
        writeCSR(CSR_mstatus, mstatus.value, data);
        icpu_->writeCSR(CSR_mstatus, mstatus.value);
 
        return 4;
    }
    }
};
};
 
 
/**
/**
 * @brief HRET return from hypervisor mode
 * @brief HRET return from hypervisor mode
 */
 */
class HRET : public IsaProcessor {
class HRET : public RiscvInstruction {
public:
public:
    HRET() : IsaProcessor("HRET", "00100000001000000000000001110011") {}
    HRET(CpuRiver_Functional *icpu) :
 
        RiscvInstruction(icpu, "HRET", "00100000001000000000000001110011") {}
 
 
    virtual void exec(uint32_t *payload, CpuContextType *data) {
    virtual int exec(Reg64Type *payload) {
        if (data->cur_prv_level != PRV_H) {
        if (icpu_->getPrvLevel() != PRV_H) {
            generateException(EXCEPTION_InstrIllegal, data);
            icpu_->raiseSignal(EXCEPTION_InstrIllegal);
            return;
            return 4;
        }
        }
        csr_mstatus_type mstatus;
        csr_mstatus_type mstatus;
        mstatus.value = readCSR(CSR_mstatus, data);
        mstatus.value = icpu_->readCSR(CSR_mstatus);
 
 
        uint64_t xepc = (PRV_H << 8) + 0x41;
        uint64_t xepc = (PRV_H << 8) + 0x41;
        data->npc = readCSR(static_cast<uint32_t>(xepc), data);
        icpu_->setBranch(icpu_->readCSR(static_cast<uint32_t>(xepc)));
 
 
        mstatus.bits.HIE = mstatus.bits.HPIE;
        mstatus.bits.HIE = mstatus.bits.HPIE;
        mstatus.bits.HPIE = 1;
        mstatus.bits.HPIE = 1;
        data->cur_prv_level = mstatus.bits.HPP;
        icpu_->setPrvLevel(mstatus.bits.HPP);
        mstatus.bits.HPP = PRV_U;
        mstatus.bits.HPP = PRV_U;
 
 
        writeCSR(CSR_mstatus, mstatus.value, data);
        icpu_->writeCSR(CSR_mstatus, mstatus.value);
 
        return 4;
    }
    }
};
};
 
 
/**
/**
 * @brief MRET return from machine mode
 * @brief MRET return from machine mode
 */
 */
class MRET : public IsaProcessor {
class MRET : public RiscvInstruction {
public:
public:
    MRET() : IsaProcessor("MRET", "00110000001000000000000001110011") {}
    MRET(CpuRiver_Functional *icpu) :
 
        RiscvInstruction(icpu, "MRET", "00110000001000000000000001110011") {}
 
 
    virtual void exec(uint32_t *payload, CpuContextType *data) {
    virtual int exec(Reg64Type *payload) {
        if (data->cur_prv_level != PRV_M) {
        if (icpu_->getPrvLevel() != PRV_M) {
            generateException(EXCEPTION_InstrIllegal, data);
            icpu_->raiseSignal(EXCEPTION_InstrIllegal);
            return;
            return 4;
        }
        }
        csr_mstatus_type mstatus;
        csr_mstatus_type mstatus;
        mstatus.value = readCSR(CSR_mstatus, data);
        mstatus.value = icpu_->readCSR(CSR_mstatus);
 
 
        uint64_t xepc = (PRV_M << 8) + 0x41;
        uint64_t xepc = (PRV_M << 8) + 0x41;
        data->npc = readCSR(static_cast<uint32_t>(xepc), data);
        icpu_->setBranch(icpu_->readCSR(static_cast<uint32_t>(xepc)));
 
 
        mstatus.bits.MIE = mstatus.bits.MPIE;
        mstatus.bits.MIE = mstatus.bits.MPIE;
        mstatus.bits.MPIE = 1;
        mstatus.bits.MPIE = 1;
        data->cur_prv_level = mstatus.bits.MPP;
        icpu_->setPrvLevel(mstatus.bits.MPP);
        mstatus.bits.MPP = PRV_U;
        mstatus.bits.MPP = PRV_U;
 
 
        // Emulating interrupt strob (not pulse from external controller)
        icpu_->writeCSR(CSR_mstatus, mstatus.value);
        if (data->interrupt_pending) {
        return 4;
            generateInterrupt(INTERRUPT_MExternal, data);
 
        }
 
 
 
        writeCSR(CSR_mstatus, mstatus.value, data);
 
    }
    }
};
};
 
 
 
 
/**
/**
 * @brief FENCE (memory barrier)
 * @brief FENCE (memory barrier)
 *
 *
 * Not used in functional model so that cache is not modeling.
 * Not used in functional model so that cache is not modeling.
 */
 */
class FENCE : public IsaProcessor {
class FENCE : public RiscvInstruction {
public:
public:
    FENCE() : IsaProcessor("FENCE", "?????????????????000?????0001111") {}
    FENCE(CpuRiver_Functional *icpu) :
 
        RiscvInstruction(icpu, "FENCE", "?????????????????000?????0001111") {}
 
 
    virtual void exec(uint32_t *payload, CpuContextType *data) {
    virtual int exec(Reg64Type *payload) {
        data->npc = data->pc + 4;
        return 4;
    }
    }
};
};
 
 
/**
/**
 * @brief FENCE_I (memory barrier)
 * @brief FENCE_I (memory barrier)
 *
 *
 * Not used in functional model so that cache is not modeling.
 * Not used in functional model so that cache is not modeling.
 */
 */
class FENCE_I : public IsaProcessor {
class FENCE_I : public RiscvInstruction {
public:
public:
    FENCE_I() : IsaProcessor("FENCE_I", "?????????????????001?????0001111") {}
    FENCE_I(CpuRiver_Functional *icpu) :
 
        RiscvInstruction(icpu, "FENCE_I", "?????????????????001?????0001111") {}
 
 
    virtual void exec(uint32_t *payload, CpuContextType *data) {
    virtual int exec(Reg64Type *payload) {
        data->npc = data->pc + 4;
        return 4;
    }
    }
};
};
 
 
/**
/**
 * @brief EBREAK (breakpoint instruction)
 * @brief EBREAK (breakpoint instruction)
 *
 *
 * The EBREAK instruction is used by debuggers to cause control to be
 * The EBREAK instruction is used by debuggers to cause control to be
 * transferred back to a debug-ging environment.
 * transferred back to a debug-ging environment.
 */
 */
class EBREAK : public IsaProcessor {
class EBREAK : public RiscvInstruction {
public:
public:
    EBREAK() : IsaProcessor("EBREAK", "00000000000100000000000001110011") {}
    EBREAK(CpuRiver_Functional *icpu) :
 
        RiscvInstruction(icpu, "EBREAK", "00000000000100000000000001110011") {}
 
 
    virtual void exec(uint32_t *payload, CpuContextType *data) {
    virtual int exec(Reg64Type *payload) {
        data->npc = data->pc + 4;
        icpu_->raiseSignal(EXCEPTION_Breakpoint);
        data->br_status_ena = true;
        return 4;
        generateException(EXCEPTION_Breakpoint, data);
 
    }
    }
};
};
 
 
/**
/**
 * @brief ECALL (environment call instruction)
 * @brief ECALL (environment call instruction)
Line 378... Line 359...
 * The ECALL instruction is used to make a request to the supporting execution
 * The ECALL instruction is used to make a request to the supporting execution
 * environment, which isusually an operating system. The ABI for the system
 * environment, which isusually an operating system. The ABI for the system
 * will define how parameters for the environment request are passed, but usually
 * will define how parameters for the environment request are passed, but usually
 * these will be in defined locations in the integer register file.
 * these will be in defined locations in the integer register file.
 */
 */
class ECALL : public IsaProcessor {
class ECALL : public RiscvInstruction {
public:
public:
    ECALL() : IsaProcessor("ECALL", "00000000000000000000000001110011") {}
    ECALL(CpuRiver_Functional *icpu) :
 
        RiscvInstruction(icpu, "ECALL", "00000000000000000000000001110011") {}
 
 
    virtual void exec(uint32_t *payload, CpuContextType *data) {
    virtual int exec(Reg64Type *payload) {
        data->npc = data->pc + 4;
        switch (icpu_->getPrvLevel()) {
        switch (data->cur_prv_level) {
 
        case PRV_M:
        case PRV_M:
            generateException(EXCEPTION_CallFromMmode, data);
            icpu_->raiseSignal(EXCEPTION_CallFromMmode);
            break;
            break;
        case PRV_U:
        case PRV_U:
            generateException(EXCEPTION_CallFromUmode, data);
            icpu_->raiseSignal(EXCEPTION_CallFromUmode);
            break;
            break;
        default:;
        default:;
        }
        }
 
        return 4;
    }
    }
};
};
 
 
 
 
void addIsaPrivilegedRV64I(CpuContextType *data, AttributeType *out) {
void CpuRiver_Functional::addIsaPrivilegedRV64I() {
    addSupportedInstruction(new CSRRC, out);
    addSupportedInstruction(new CSRRC(this));
    addSupportedInstruction(new CSRRCI, out);
    addSupportedInstruction(new CSRRCI(this));
    addSupportedInstruction(new CSRRS, out);
    addSupportedInstruction(new CSRRS(this));
    addSupportedInstruction(new CSRRSI, out);
    addSupportedInstruction(new CSRRSI(this));
    addSupportedInstruction(new CSRRW, out);
    addSupportedInstruction(new CSRRW(this));
    addSupportedInstruction(new CSRRWI, out);
    addSupportedInstruction(new CSRRWI(this));
    addSupportedInstruction(new URET, out);
    addSupportedInstruction(new URET(this));
    addSupportedInstruction(new SRET, out);
    addSupportedInstruction(new SRET(this));
    addSupportedInstruction(new HRET, out);
    addSupportedInstruction(new HRET(this));
    addSupportedInstruction(new MRET, out);
    addSupportedInstruction(new MRET(this));
    addSupportedInstruction(new FENCE, out);
    addSupportedInstruction(new FENCE(this));
    addSupportedInstruction(new FENCE_I, out);
    addSupportedInstruction(new FENCE_I(this));
    addSupportedInstruction(new ECALL, out);
    addSupportedInstruction(new ECALL(this));
    addSupportedInstruction(new EBREAK, out);
    addSupportedInstruction(new EBREAK(this));
 
 
    // TODO:
    // TODO:
    /*
    /*
  def DRET               = BitPat("b01111011001000000000000001110011")
  def DRET               = BitPat("b01111011001000000000000001110011")
  def SFENCE_VM          = BitPat("b000100000100?????000000001110011")
  def SFENCE_VMA         = BitPat("b0001001??????????000000001110011")
  def WFI                = BitPat("b00010000010100000000000001110011")  // wait for interrupt
  def WFI                = BitPat("b00010000010100000000000001110011")  // wait for interrupt
 
 
    def RDCYCLE            = BitPat("b11000000000000000010?????1110011")
    def RDCYCLE            = BitPat("b11000000000000000010?????1110011")
    def RDTIME             = BitPat("b11000000000100000010?????1110011")
    def RDTIME             = BitPat("b11000000000100000010?????1110011")
    def RDINSTRET          = BitPat("b11000000001000000010?????1110011")
    def RDINSTRET          = BitPat("b11000000001000000010?????1110011")
    def RDCYCLEH           = BitPat("b11001000000000000010?????1110011")
    def RDCYCLEH           = BitPat("b11001000000000000010?????1110011")
    def RDTIMEH            = BitPat("b11001000000100000010?????1110011")
    def RDTIMEH            = BitPat("b11001000000100000010?????1110011")
    def RDINSTRETH         = BitPat("b11001000001000000010?????1110011")
    def RDINSTRETH         = BitPat("b11001000001000000010?????1110011")
    def ECALL              = BitPat("b00000000000000000000000001110011")
 
    def EBREAK             = BitPat("b00000000000100000000000001110011")
 
    */
    */
 
 
    /**
    /**
     * The 'U', 'S', and 'H' bits will be set if there is support for
     * The 'U', 'S', and 'H' bits will be set if there is support for
     * user, supervisor, and hypervisor privilege modes respectively.
     * user, supervisor, and hypervisor privilege modes respectively.
     */
     */
    data->csr[CSR_misa] |= (1LL << ('U' - 'A'));
    uint64_t isa = portCSR_.read(CSR_misa).val;
    data->csr[CSR_misa] |= (1LL << ('S' - 'A'));
    isa |= (1LL << ('U' - 'A'));
    data->csr[CSR_misa] |= (1LL << ('H' - 'A'));
    isa |= (1LL << ('S' - 'A'));
 
    isa |= (1LL << ('H' - 'A'));
 
    portCSR_.write(CSR_misa, isa);
}
}
 
 
}  // namespace debugger
}  // namespace debugger
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.