fixes 64bit behavior of CSR regs
This commit is contained in:
parent
c5465bf9e2
commit
6213445bc4
|
@ -252,8 +252,11 @@ public:
|
||||||
return 0b100010001000; // only machine mode is supported
|
return 0b100010001000; // only machine mode is supported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr bool has_compressed() {
|
||||||
|
return traits<BASE>::MISA_VAL&0b0100;
|
||||||
|
}
|
||||||
constexpr reg_t get_pc_mask() {
|
constexpr reg_t get_pc_mask() {
|
||||||
return traits<BASE>::MISA_VAL&0b0100?~1:~3;
|
return has_compressed()?~1:~3;
|
||||||
}
|
}
|
||||||
|
|
||||||
riscv_hart_m_p(feature_config cfg = feature_config{});
|
riscv_hart_m_p(feature_config cfg = feature_config{});
|
||||||
|
@ -435,7 +438,7 @@ riscv_hart_m_p<BASE, FEAT>::riscv_hart_m_p(feature_config cfg)
|
||||||
csr_rd_cb[addr] = &this_class::read_null;
|
csr_rd_cb[addr] = &this_class::read_null;
|
||||||
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||||
}
|
}
|
||||||
for (unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr){
|
if(traits<BASE>::XLEN==32) for (unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr){
|
||||||
csr_rd_cb[addr] = &this_class::read_null;
|
csr_rd_cb[addr] = &this_class::read_null;
|
||||||
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||||
}
|
}
|
||||||
|
@ -446,7 +449,7 @@ riscv_hart_m_p<BASE, FEAT>::riscv_hart_m_p(feature_config cfg)
|
||||||
for (unsigned addr = hpmcounter3; addr <= hpmcounter31; ++addr){
|
for (unsigned addr = hpmcounter3; addr <= hpmcounter31; ++addr){
|
||||||
csr_rd_cb[addr] = &this_class::read_null;
|
csr_rd_cb[addr] = &this_class::read_null;
|
||||||
}
|
}
|
||||||
for (unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr){
|
if(traits<BASE>::XLEN==32) for (unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr){
|
||||||
csr_rd_cb[addr] = &this_class::read_null;
|
csr_rd_cb[addr] = &this_class::read_null;
|
||||||
//csr_wr_cb[addr] = &this_class::write_csr_reg;
|
//csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||||
}
|
}
|
||||||
|
@ -469,12 +472,12 @@ riscv_hart_m_p<BASE, FEAT>::riscv_hart_m_p(feature_config cfg)
|
||||||
|
|
||||||
csr_rd_cb[mcycle] = &this_class::read_cycle;
|
csr_rd_cb[mcycle] = &this_class::read_cycle;
|
||||||
csr_wr_cb[mcycle] = &this_class::write_cycle;
|
csr_wr_cb[mcycle] = &this_class::write_cycle;
|
||||||
csr_rd_cb[mcycleh] = &this_class::read_cycle;
|
if(traits<BASE>::XLEN==32) csr_rd_cb[mcycleh] = &this_class::read_cycle;
|
||||||
csr_wr_cb[mcycleh] = &this_class::write_cycle;
|
if(traits<BASE>::XLEN==32) csr_wr_cb[mcycleh] = &this_class::write_cycle;
|
||||||
csr_rd_cb[minstret] = &this_class::read_instret;
|
csr_rd_cb[minstret] = &this_class::read_instret;
|
||||||
csr_wr_cb[minstret] = &this_class::write_instret;
|
csr_wr_cb[minstret] = &this_class::write_instret;
|
||||||
csr_rd_cb[minstreth] = &this_class::read_instret;
|
if(traits<BASE>::XLEN==32) csr_rd_cb[minstreth] = &this_class::read_instret;
|
||||||
csr_wr_cb[minstreth] = &this_class::write_instret;
|
if(traits<BASE>::XLEN==32) csr_wr_cb[minstreth] = &this_class::write_instret;
|
||||||
csr_rd_cb[mstatus] = &this_class::read_status;
|
csr_rd_cb[mstatus] = &this_class::read_status;
|
||||||
csr_wr_cb[mstatus] = &this_class::write_status;
|
csr_wr_cb[mstatus] = &this_class::write_status;
|
||||||
csr_rd_cb[mcause] = &this_class::read_cause;
|
csr_rd_cb[mcause] = &this_class::read_cause;
|
||||||
|
@ -633,7 +636,7 @@ iss::status riscv_hart_m_p<BASE, FEAT>::read(const address_type type, const acce
|
||||||
try {
|
try {
|
||||||
switch (space) {
|
switch (space) {
|
||||||
case traits<BASE>::MEM: {
|
case traits<BASE>::MEM: {
|
||||||
auto alignment = is_fetch(access)? (traits<BASE>::MISA_VAL&0x100? 2 : 4) : length;
|
auto alignment = is_fetch(access)? (has_compressed()? 2 : 4) : length;
|
||||||
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
|
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
|
||||||
fault_data = addr;
|
fault_data = addr;
|
||||||
if (is_debug(access)) throw trap_access(0, addr);
|
if (is_debug(access)) throw trap_access(0, addr);
|
||||||
|
@ -869,7 +872,6 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>
|
||||||
if (addr == mcycle) {
|
if (addr == mcycle) {
|
||||||
val = static_cast<reg_t>(cycle_val);
|
val = static_cast<reg_t>(cycle_val);
|
||||||
} else if (addr == mcycleh) {
|
} else if (addr == mcycleh) {
|
||||||
if (sizeof(typename traits<BASE>::reg_t) != 4) return iss::Err;
|
|
||||||
val = static_cast<reg_t>(cycle_val >> 32);
|
val = static_cast<reg_t>(cycle_val >> 32);
|
||||||
}
|
}
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
|
@ -877,8 +879,6 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>
|
||||||
|
|
||||||
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::write_cycle(unsigned addr, reg_t val) {
|
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::write_cycle(unsigned addr, reg_t val) {
|
||||||
if (sizeof(typename traits<BASE>::reg_t) != 4) {
|
if (sizeof(typename traits<BASE>::reg_t) != 4) {
|
||||||
if (addr == mcycleh)
|
|
||||||
return iss::Err;
|
|
||||||
mcycle_csr = static_cast<uint64_t>(val);
|
mcycle_csr = static_cast<uint64_t>(val);
|
||||||
} else {
|
} else {
|
||||||
if (addr == mcycle) {
|
if (addr == mcycle) {
|
||||||
|
@ -895,7 +895,6 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>
|
||||||
if ((addr&0xff) == (minstret&0xff)) {
|
if ((addr&0xff) == (minstret&0xff)) {
|
||||||
val = static_cast<reg_t>(this->instret);
|
val = static_cast<reg_t>(this->instret);
|
||||||
} else if ((addr&0xff) == (minstreth&0xff)) {
|
} else if ((addr&0xff) == (minstreth&0xff)) {
|
||||||
if (sizeof(typename traits<BASE>::reg_t) != 4) return iss::Err;
|
|
||||||
val = static_cast<reg_t>(this->instret >> 32);
|
val = static_cast<reg_t>(this->instret >> 32);
|
||||||
}
|
}
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
|
@ -903,8 +902,6 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>
|
||||||
|
|
||||||
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::write_instret(unsigned addr, reg_t val) {
|
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::write_instret(unsigned addr, reg_t val) {
|
||||||
if (sizeof(typename traits<BASE>::reg_t) != 4) {
|
if (sizeof(typename traits<BASE>::reg_t) != 4) {
|
||||||
if ((addr&0xff) == (minstreth&0xff))
|
|
||||||
return iss::Err;
|
|
||||||
this->instret = static_cast<uint64_t>(val);
|
this->instret = static_cast<uint64_t>(val);
|
||||||
} else {
|
} else {
|
||||||
if ((addr&0xff) == (minstret&0xff)) {
|
if ((addr&0xff) == (minstret&0xff)) {
|
||||||
|
@ -1244,7 +1241,7 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_m_p<BASE, FEAT>::e
|
||||||
csr[mtval] = static_cast<reg_t>(addr);
|
csr[mtval] = static_cast<reg_t>(addr);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
csr[mtval] = (instr & 0x3)==3?instr:instr&0xffff;
|
csr[mtval] = (!has_compressed() || (instr & 0x3)==3)?instr:instr&0xffff;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if((FEAT & FEAT_DEBUG) && (csr[dcsr] & 0x8000)) {
|
if((FEAT & FEAT_DEBUG) && (csr[dcsr] & 0x8000)) {
|
||||||
|
|
|
@ -193,8 +193,11 @@ public:
|
||||||
return m[mode];
|
return m[mode];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr bool has_compressed() {
|
||||||
|
return traits<BASE>::MISA_VAL&0b0100;
|
||||||
|
}
|
||||||
constexpr reg_t get_pc_mask() {
|
constexpr reg_t get_pc_mask() {
|
||||||
return traits<BASE>::MISA_VAL&0b0100?~1:~3;
|
return has_compressed()?~1:~3;
|
||||||
}
|
}
|
||||||
|
|
||||||
riscv_hart_mu_p(feature_config cfg = feature_config{});
|
riscv_hart_mu_p(feature_config cfg = feature_config{});
|
||||||
|
@ -379,7 +382,7 @@ riscv_hart_mu_p<BASE, FEAT>::riscv_hart_mu_p(feature_config cfg)
|
||||||
csr_rd_cb[addr] = &this_class::read_null;
|
csr_rd_cb[addr] = &this_class::read_null;
|
||||||
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||||
}
|
}
|
||||||
for (unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr){
|
if(traits<BASE>::XLEN==32) for (unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr){
|
||||||
csr_rd_cb[addr] = &this_class::read_null;
|
csr_rd_cb[addr] = &this_class::read_null;
|
||||||
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||||
}
|
}
|
||||||
|
@ -390,7 +393,7 @@ riscv_hart_mu_p<BASE, FEAT>::riscv_hart_mu_p(feature_config cfg)
|
||||||
for (unsigned addr = hpmcounter3; addr <= hpmcounter31; ++addr){
|
for (unsigned addr = hpmcounter3; addr <= hpmcounter31; ++addr){
|
||||||
csr_rd_cb[addr] = &this_class::read_null;
|
csr_rd_cb[addr] = &this_class::read_null;
|
||||||
}
|
}
|
||||||
for (unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr){
|
if(traits<BASE>::XLEN==32) for (unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr){
|
||||||
csr_rd_cb[addr] = &this_class::read_null;
|
csr_rd_cb[addr] = &this_class::read_null;
|
||||||
//csr_wr_cb[addr] = &this_class::write_csr_reg;
|
//csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||||
}
|
}
|
||||||
|
@ -414,12 +417,12 @@ riscv_hart_mu_p<BASE, FEAT>::riscv_hart_mu_p(feature_config cfg)
|
||||||
|
|
||||||
csr_rd_cb[mcycle] = &this_class::read_cycle;
|
csr_rd_cb[mcycle] = &this_class::read_cycle;
|
||||||
csr_wr_cb[mcycle] = &this_class::write_cycle;
|
csr_wr_cb[mcycle] = &this_class::write_cycle;
|
||||||
csr_rd_cb[mcycleh] = &this_class::read_cycle;
|
if(traits<BASE>::XLEN==32) csr_rd_cb[mcycleh] = &this_class::read_cycle;
|
||||||
csr_wr_cb[mcycleh] = &this_class::write_cycle;
|
if(traits<BASE>::XLEN==32) csr_wr_cb[mcycleh] = &this_class::write_cycle;
|
||||||
csr_rd_cb[minstret] = &this_class::read_instret;
|
csr_rd_cb[minstret] = &this_class::read_instret;
|
||||||
csr_wr_cb[minstret] = &this_class::write_instret;
|
csr_wr_cb[minstret] = &this_class::write_instret;
|
||||||
csr_rd_cb[minstreth] = &this_class::read_instret;
|
if(traits<BASE>::XLEN==32) csr_rd_cb[minstreth] = &this_class::read_instret;
|
||||||
csr_wr_cb[minstreth] = &this_class::write_instret;
|
if(traits<BASE>::XLEN==32) csr_wr_cb[minstreth] = &this_class::write_instret;
|
||||||
csr_rd_cb[mstatus] = &this_class::read_status;
|
csr_rd_cb[mstatus] = &this_class::read_status;
|
||||||
csr_wr_cb[mstatus] = &this_class::write_status;
|
csr_wr_cb[mstatus] = &this_class::write_status;
|
||||||
csr_rd_cb[mcause] = &this_class::read_cause;
|
csr_rd_cb[mcause] = &this_class::read_cause;
|
||||||
|
@ -713,7 +716,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::read(const address_type type, const acc
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto alignment = is_fetch(access)? (traits<BASE>::MISA_VAL&0x100? 2 : 4) : length;
|
auto alignment = is_fetch(access)? (has_compressed()? 2 : 4) : length;
|
||||||
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
|
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
|
||||||
fault_data = addr;
|
fault_data = addr;
|
||||||
if (is_debug(access)) throw trap_access(0, addr);
|
if (is_debug(access)) throw trap_access(0, addr);
|
||||||
|
@ -957,7 +960,6 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT
|
||||||
if (addr == mcycle) {
|
if (addr == mcycle) {
|
||||||
val = static_cast<reg_t>(cycle_val);
|
val = static_cast<reg_t>(cycle_val);
|
||||||
} else if (addr == mcycleh) {
|
} else if (addr == mcycleh) {
|
||||||
if (sizeof(typename traits<BASE>::reg_t) != 4) return iss::Err;
|
|
||||||
val = static_cast<reg_t>(cycle_val >> 32);
|
val = static_cast<reg_t>(cycle_val >> 32);
|
||||||
}
|
}
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
|
@ -965,8 +967,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_cycle(unsigned addr, reg_t val) {
|
template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::write_cycle(unsigned addr, reg_t val) {
|
||||||
if (sizeof(typename traits<BASE>::reg_t) != 4) {
|
if (sizeof(typename traits<BASE>::reg_t) != 4) {
|
||||||
if (addr == mcycleh)
|
|
||||||
return iss::Err;
|
|
||||||
mcycle_csr = static_cast<uint64_t>(val);
|
mcycle_csr = static_cast<uint64_t>(val);
|
||||||
} else {
|
} else {
|
||||||
if (addr == mcycle) {
|
if (addr == mcycle) {
|
||||||
|
@ -983,7 +983,6 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT
|
||||||
if ((addr&0xff) == (minstret&0xff)) {
|
if ((addr&0xff) == (minstret&0xff)) {
|
||||||
val = static_cast<reg_t>(this->instret);
|
val = static_cast<reg_t>(this->instret);
|
||||||
} else if ((addr&0xff) == (minstreth&0xff)) {
|
} else if ((addr&0xff) == (minstreth&0xff)) {
|
||||||
if (sizeof(typename traits<BASE>::reg_t) != 4) return iss::Err;
|
|
||||||
val = static_cast<reg_t>(this->instret >> 32);
|
val = static_cast<reg_t>(this->instret >> 32);
|
||||||
}
|
}
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
|
@ -991,8 +990,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_instret(unsigned addr, reg_t val) {
|
template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::write_instret(unsigned addr, reg_t val) {
|
||||||
if (sizeof(typename traits<BASE>::reg_t) != 4) {
|
if (sizeof(typename traits<BASE>::reg_t) != 4) {
|
||||||
if ((addr&0xff) == (minstreth&0xff))
|
|
||||||
return iss::Err;
|
|
||||||
this->instret = static_cast<uint64_t>(val);
|
this->instret = static_cast<uint64_t>(val);
|
||||||
} else {
|
} else {
|
||||||
if ((addr&0xff) == (minstret&0xff)) {
|
if ((addr&0xff) == (minstret&0xff)) {
|
||||||
|
@ -1369,7 +1366,7 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_mu_p<BASE, FEAT>::
|
||||||
csr[utval | (new_priv << 8)] = static_cast<reg_t>(addr);
|
csr[utval | (new_priv << 8)] = static_cast<reg_t>(addr);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
csr[utval | (new_priv << 8)] = (instr & 0x3)==3?instr:instr&0xffff;
|
csr[utval | (new_priv << 8)] = (!has_compressed() || (instr & 0x3)==3)?instr:instr&0xffff;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if((FEAT & FEAT_DEBUG) && (csr[dcsr] & 0x8000)) {
|
if((FEAT & FEAT_DEBUG) && (csr[dcsr] & 0x8000)) {
|
||||||
|
|
Loading…
Reference in New Issue