4 Commits

11 changed files with 181 additions and 76 deletions

16
gen_input/TGC_B.core_desc Normal file
View File

@ -0,0 +1,16 @@
import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
Core TGC_B provides RV32I {
architectural_state {
unsigned XLEN=32;
unsigned PCLEN=32;
// definitions for the architecture wrapper
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
unsigned MISA_VAL = 0b01000000000000000000000100000000;
unsigned PGSIZE = 0x1000; //1 << 12;
unsigned PGMASK = 0xfff; //PGSIZE-1
}
}

15
gen_input/TGC_C.core_desc Normal file
View File

@ -0,0 +1,15 @@
import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
Core TGC_C provides RV32I, RV32M, RV32IC {
architectural_state {
unsigned XLEN=32;
unsigned PCLEN=32;
// definitions for the architecture wrapper
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
unsigned MISA_VAL = 0b01000000000000000001000100000100;
unsigned PGSIZE = 0x1000; //1 << 12;
unsigned PGMASK = 0xfff; //PGSIZE-1
}
}

13
gen_input/TGC_D.core_desc Normal file
View File

@ -0,0 +1,13 @@
import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
Core TGC_D provides RV32I, RV32M, RV32IC {
architectural_state {
unsigned XLEN=32;
unsigned PCLEN=32;
// definitions for the architecture wrapper
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
unsigned MISA_VAL = 0b01000000000000000001000100000100;
}
}

View File

@ -0,0 +1,73 @@
import "CoreDSL-Instruction-Set-Description/RISCVBase.core_desc"
import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
InstructionSet X_RB_MAC extends RISCVBase {
architectural_state {
register unsigned<64> ACC;
}
instructions {
RESET_ACC { // v-- funct7 v-- funct3
encoding: 7'd0 :: 10'b0 :: 3'd0 :: 5'b0 :: 7'b0001011;
behavior: ACC = 0;
}
GET_ACC_LO {
encoding: 7'd1 :: 10'b0 :: 3'd0 :: rd[4:0] :: 7'b0001011;
behavior: if (rd != 0) X[rd] = ACC[31:0];
}
GET_ACC_HI {
encoding: 7'd2 :: 10'b0 :: 3'd0 :: rd[4:0] :: 7'b0001011;
behavior: if (rd != 0) X[rd] = ACC[63:32];
}
MACU_32 {
encoding: 7'd0 :: rs2[4:0] :: rs1[4:0] :: 3'd1 :: 5'b0 :: 7'b0001011;
behavior: {
unsigned<64> mul = X[rs1] * X[rs2];
unsigned<33> add = mul[31:0] + ACC[31:0];
ACC = add[31:0];
}
}
MACS_32 {
encoding: 7'd1 :: rs2[4:0] :: rs1[4:0] :: 3'd1 :: 5'b0 :: 7'b0001011;
behavior: {
signed<64> mul = ((signed) X[rs1]) * ((signed) X[rs2]);
signed<33> add = ((signed) mul[31:0]) + ((signed) ACC[31:0]);
ACC = add[31:0]; // bit range always yields unsigned type
}
}
MACU_64 {
encoding: 7'd0 :: rs2[4:0] :: rs1[4:0] :: 3'd2 :: 5'b0 :: 7'b0001011;
behavior: {
unsigned<64> mul = X[rs1] * X[rs2];
unsigned<65> add = mul + ACC;
ACC = add[63:0];
}
}
MACS_64 {
encoding: 7'd1 :: rs2[4:0] :: rs1[4:0] :: 3'd2 :: 5'b0 :: 7'b0001011;
behavior: {
signed<64> mul = ((signed) X[rs1]) * ((signed) X[rs2]);
signed<65> add = mul + ((signed) ACC);
ACC = add[63:0];
}
}
}
}
Core TGC_D_XRB_MAC provides RV32I, RV32M, RV32IC, X_RB_MAC {
architectural_state {
unsigned XLEN=32;
unsigned PCLEN=32;
// definitions for the architecture wrapper
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
unsigned MISA_VAL = 0b01000000000000000001000100000100;
}
}

View File

@ -1,37 +0,0 @@
import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
Core TGC_B provides RV32I {
architectural_state {
unsigned XLEN=32;
unsigned PCLEN=32;
// definitions for the architecture wrapper
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
unsigned MISA_VAL = 0b01000000000000000000000100000000;
unsigned PGSIZE = 0x1000; //1 << 12;
unsigned PGMASK = 0xfff; //PGSIZE-1
}
}
Core TGC_C provides RV32I, RV32M, RV32IC {
architectural_state {
unsigned XLEN=32;
unsigned PCLEN=32;
// definitions for the architecture wrapper
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
unsigned MISA_VAL = 0b01000000000000000001000100000100;
unsigned PGSIZE = 0x1000; //1 << 12;
unsigned PGMASK = 0xfff; //PGSIZE-1
}
}
Core TGC_D provides RV32I, RV32M, RV32IC {
architectural_state {
unsigned XLEN=32;
unsigned PCLEN=32;
// definitions for the architecture wrapper
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
unsigned MISA_VAL = 0b01000000000000000001000100000100;
}
}

View File

@ -362,8 +362,8 @@ riscv_hart_m_p<BASE>::riscv_hart_m_p()
csr_rd_cb[mie] = &this_class::read_ie;
csr_wr_cb[mie] = &this_class::write_ie;
csr_rd_cb[mhartid] = &this_class::read_hartid;
csr_rd_cb[mcounteren] = &this_class::read_null;
csr_wr_cb[mcounteren] = &this_class::write_null;
// csr_rd_cb[mcounteren] = &this_class::read_null;
// csr_wr_cb[mcounteren] = &this_class::write_null;
csr_wr_cb[misa] = &this_class::write_null;
csr_wr_cb[mvendorid] = &this_class::write_null;
csr_wr_cb[marchid] = &this_class::write_null;

View File

@ -145,7 +145,7 @@ public:
mstatus_t mstatus;
static const reg_t mstatus_reset_val = 0;
static const reg_t mstatus_reset_val = 0x1800;
void write_mstatus(T val, unsigned priv_lvl) {
auto mask = get_mask(priv_lvl);
@ -398,7 +398,7 @@ private:
iss::status read_ip(unsigned addr, reg_t &val);
iss::status write_ip(unsigned addr, reg_t val);
iss::status read_hartid(unsigned addr, reg_t &val);
iss::status write_mepc(unsigned addr, reg_t val);
iss::status write_epc(unsigned addr, reg_t val);
iss::status read_satp(unsigned addr, reg_t &val);
iss::status write_satp(unsigned addr, reg_t val);
iss::status read_fcsr(unsigned addr, reg_t &val);
@ -954,8 +954,8 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_ip(unsigned
return iss::Ok;
}
template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_epc(unsigned addr, reg_t val) {
csr[addr] = val & get_pc_mask();
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_epc(unsigned addr, reg_t val) {
csr[addr] = val & get_pc_mask();
return iss::Ok;
}

View File

@ -146,7 +146,7 @@ public:
mstatus_t mstatus;
static const reg_t mstatus_reset_val = 0;
static const reg_t mstatus_reset_val = 0x1800; // MPP set to 1
void write_mstatus(T val, unsigned priv_lvl) {
auto mask = get_mask(priv_lvl);
@ -543,25 +543,27 @@ template <typename BASE, features_e FEAT> bool riscv_hart_mu_p<BASE, FEAT>::pmp_
constexpr auto PMP_NA4 =0x2U;
constexpr auto PMP_NAPOT =0x3U;
reg_t base = 0;
auto any_active = false;
for (size_t i = 0; i < 16; i++) {
reg_t tor = csr[pmpaddr0+i] << PMP_SHIFT;
uint8_t cfg = csr[pmpcfg0+(i/4)]>>(i%4);
if (cfg & PMP_A) {
any_active=true;
auto pmp_a = (cfg & PMP_A) >> 3;
bool is_tor = pmp_a == PMP_TOR;
bool is_na4 = pmp_a == PMP_NA4;
auto is_tor = pmp_a == PMP_TOR;
auto is_na4 = pmp_a == PMP_NA4;
reg_t mask = (csr[pmpaddr0+i] << 1) | (!is_na4);
mask = ~(mask & ~(mask + 1)) << PMP_SHIFT;
// Check each 4-byte sector of the access
bool any_match = false;
bool all_match = true;
auto any_match = false;
auto all_match = true;
for (reg_t offset = 0; offset < len; offset += 1 << PMP_SHIFT) {
reg_t cur_addr = addr + offset;
bool napot_match = ((cur_addr ^ tor) & mask) == 0;
bool tor_match = base <= cur_addr && cur_addr < tor;
bool match = is_tor ? tor_match : napot_match;
auto napot_match = ((cur_addr ^ tor) & mask) == 0;
auto tor_match = base <= cur_addr && cur_addr < tor;
auto match = is_tor ? tor_match : napot_match;
any_match |= match;
all_match &= match;
}
@ -577,7 +579,7 @@ template <typename BASE, features_e FEAT> bool riscv_hart_mu_p<BASE, FEAT>::pmp_
}
base = tor;
}
return this->reg.PRIV == PRIV_M;
return !any_active || this->reg.PRIV == PRIV_M;
}
@ -926,8 +928,6 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT
template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::write_ie(unsigned addr, reg_t val) {
auto mask = get_irq_wrmask((addr >> 8) & 0x3);
if(this->reg.PRIV==0)
mask&= ~(0xff<<4); // STIE and UTIE are read only in user and supervisor mode
csr[mie] = (csr[mie] & ~mask) | (val & mask);
check_interrupt();
return iss::Ok;
@ -1256,27 +1256,33 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_mu_p<BASE, FEAT>::
template <typename BASE, features_e FEAT> uint64_t riscv_hart_mu_p<BASE, FEAT>::leave_trap(uint64_t flags) {
auto cur_priv = this->reg.PRIV;
auto inst_priv = (flags & 0x3)? 3:0;
auto status = state.mstatus;
// pop the relevant lower-privilege interrupt enable and privilege mode stack
// clear respective yIE
switch (inst_priv) {
case PRIV_M:
this->reg.PRIV = state.mstatus.MPP;
state.mstatus.MPP = 0; // clear mpp to U mode
state.mstatus.MIE = state.mstatus.MPIE;
state.mstatus.MPIE = 1;
break;
case PRIV_U:
this->reg.PRIV = 0;
state.mstatus.UIE = state.mstatus.UPIE;
state.mstatus.UPIE = 1;
break;
if(inst_priv>cur_priv){
auto trap_val = 0x80ULL << 24 | (2 << 16); // illegal instruction
this->reg.trap_state = trap_val;
this->reg.NEXT_PC = std::numeric_limits<uint32_t>::max();
} else {
auto status = state.mstatus;
// pop the relevant lower-privilege interrupt enable and privilege mode stack
// clear respective yIE
switch (inst_priv) {
case PRIV_M:
this->reg.PRIV = state.mstatus.MPP;
state.mstatus.MPP = 0; // clear mpp to U mode
state.mstatus.MIE = state.mstatus.MPIE;
state.mstatus.MPIE = 1;
break;
case PRIV_U:
this->reg.PRIV = 0;
state.mstatus.UIE = state.mstatus.UPIE;
state.mstatus.UPIE = 1;
break;
}
// sets the pc to the value stored in the x epc register.
this->reg.NEXT_PC = csr[uepc | inst_priv << 8];
CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to "
<< lvl[this->reg.PRIV];
check_interrupt();
}
// sets the pc to the value stored in the x epc register.
this->reg.NEXT_PC = csr[uepc | inst_priv << 8];
CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to "
<< lvl[this->reg.PRIV];
check_interrupt();
return this->reg.NEXT_PC;
}

View File

@ -49,6 +49,11 @@ using tgc_b_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_b>;
#include "iss/arch/tgc_d.h"
using tgc_d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
#endif
#ifdef CORE_TGC_D_XRB_MAC
#include "iss/arch/riscv_hart_mu_p.h"
#include "iss/arch/tgc_d_xrb_mac.h"
using tgc_d_xrb_mac_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d_xrb_mac, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
#endif
#ifdef WITH_LLVM
#include <iss/llvm/jit_helper.h>
#endif
@ -138,6 +143,12 @@ int main(int argc, char *argv[]) {
std::tie(cpu, vm) =
iss::create_cpu<tgc_d_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
} else
#endif
#ifdef CORE_TGC_D_XRB_MAC
if (isa_opt == "tgc_d_xrb_mac") {
std::tie(cpu, vm) =
iss::create_cpu<tgc_d_xrb_mac_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
} else
#endif
{
LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as<std::string>() << std::endl;

View File

@ -44,6 +44,11 @@ using tgc_c_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_c>;
#include "iss/arch/tgc_d.h"
using tgc_d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d, iss::arch::FEAT_PMP>;
#endif
#ifdef CORE_TGC_D_XRB_MAC
#include "iss/arch/riscv_hart_mu_p.h"
#include "iss/arch/tgc_d_xrb_mac.h"
using tgc_d_xrb_mac_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d_xrb_mac, iss::arch::FEAT_PMP>;
#endif
#include "iss/debugger/encoderdecoder.h"
#include "iss/debugger/gdb_session.h"
#include "iss/debugger/server.h"
@ -285,6 +290,9 @@ public:
#endif
#ifdef CORE_TGC_D
CREATE_CORE(tgc_d)
#endif
#ifdef CORE_TGC_D_XRB_MACD
CREATE_CORE(tgc_d_xrb_mac)
#endif
{
LOG(ERROR) << "Illegal argument value for core type: " << type << std::endl;

View File

@ -4138,8 +4138,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
this->do_sync(POST_SYNC, std::numeric_limits<unsigned>::max());
pc.val = super::core.enter_trap(std::numeric_limits<uint64_t>::max(), pc.val, 0);
} else {
if (is_jump_to_self_enabled(cond) && (insn == 0x0000006f || (insn&0xffff)==0xa001))
throw simulation_stopped(0); // 'J 0' or 'C.J 0'
if (is_jump_to_self_enabled(cond) &&
(insn == 0x0000006f || (insn&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
auto f = decode_inst(insn);
pc = (this->*f)(pc, insn);
}