fix alignment check for unaligned debugger accesses
This commit is contained in:
parent
e382217e04
commit
5da4e6b424
|
@ -567,22 +567,22 @@ 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: {
|
||||||
if (unlikely((access == iss::access_type::FETCH || access == iss::access_type::DEBUG_FETCH) && (addr & 0x1) == 1)) {
|
auto alignment = is_fetch(access)? (traits<BASE>::MISA_VAL&0x100? 2 : 4) : length;
|
||||||
|
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
|
||||||
fault_data = addr;
|
fault_data = addr;
|
||||||
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
if (is_debug(access)) throw trap_access(0, addr);
|
||||||
this->trap_state = (1 << 31); // issue trap 0
|
this->trap_state = (1 << 31); // issue trap 0
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
auto alignment = access == iss::access_type::FETCH? (traits<BASE>::MISA_VAL&0x100? 2 : 4) : length;
|
if(!is_debug(access) && (addr&(alignment-1))){
|
||||||
if(alignment>1 && (addr&(alignment-1))){
|
|
||||||
this->trap_state = 1<<31 | 4<<16;
|
this->trap_state = 1<<31 | 4<<16;
|
||||||
fault_data=addr;
|
fault_data=addr;
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
auto phys_addr = type==iss::address_type::PHYSICAL?phys_addr_t{access, space, addr}:BASE::v2p(iss::addr_t{access, type, space, addr});
|
auto phys_addr = type==iss::address_type::PHYSICAL?phys_addr_t{access, space, addr}:BASE::v2p(iss::addr_t{access, type, space, addr});
|
||||||
auto res = iss::Err;
|
auto res = iss::Err;
|
||||||
if(access != access_type::FETCH && memfn_range.size()){
|
if(!is_fetch(access) && memfn_range.size()){
|
||||||
auto it = std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple<uint64_t, uint64_t> const& a){
|
auto it = std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple<uint64_t, uint64_t> const& a){
|
||||||
return std::get<0>(a)<=phys_addr.val && (std::get<0>(a)+std::get<1>(a))>phys_addr.val;
|
return std::get<0>(a)<=phys_addr.val && (std::get<0>(a)+std::get<1>(a))>phys_addr.val;
|
||||||
});
|
});
|
||||||
|
|
|
@ -611,13 +611,19 @@ iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_
|
||||||
try {
|
try {
|
||||||
switch (space) {
|
switch (space) {
|
||||||
case traits<BASE>::MEM: {
|
case traits<BASE>::MEM: {
|
||||||
if (unlikely((access == iss::access_type::FETCH || access == iss::access_type::DEBUG_FETCH) && (addr & 0x1) == 1)) {
|
auto alignment = is_fetch(access)? (traits<BASE>::MISA_VAL&0x100? 2 : 4) : length;
|
||||||
|
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
|
||||||
fault_data = addr;
|
fault_data = addr;
|
||||||
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
||||||
this->trap_state = (1 << 31); // issue trap 0
|
this->trap_state = (1 << 31); // issue trap 0
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
if(!is_debug(access) && (addr&(alignment-1))){
|
||||||
|
this->trap_state = 1<<31 | 4<<16;
|
||||||
|
fault_data=addr;
|
||||||
|
return iss::Err;
|
||||||
|
}
|
||||||
if (unlikely((addr & ~PGMASK) != ((addr + length - 1) & ~PGMASK))) { // we may cross a page boundary
|
if (unlikely((addr & ~PGMASK) != ((addr + length - 1) & ~PGMASK))) { // we may cross a page boundary
|
||||||
vm_info vm = hart_state_type::decode_vm_info(this->reg.PRIV, state.satp);
|
vm_info vm = hart_state_type::decode_vm_info(this->reg.PRIV, state.satp);
|
||||||
if (vm.levels != 0) { // VM is active
|
if (vm.levels != 0) { // VM is active
|
||||||
|
|
|
@ -705,22 +705,22 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::read(const address_type type, const acc
|
||||||
switch (space) {
|
switch (space) {
|
||||||
case traits<BASE>::MEM: {
|
case traits<BASE>::MEM: {
|
||||||
if(FEAT & FEAT_PMP){
|
if(FEAT & FEAT_PMP){
|
||||||
if(!pmp_check(access, addr, length) && (access&access_type::DEBUG) != access_type::DEBUG) {
|
if(!pmp_check(access, addr, length) && !is_debug(access)) {
|
||||||
fault_data = addr;
|
fault_data = addr;
|
||||||
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
if (is_debug(access)) throw trap_access(0, addr);
|
||||||
this->trap_state = (1 << 31) | ((access==access_type::FETCH?1:5) << 16); // issue trap 1
|
this->trap_state = (1 << 31) | ((access==access_type::FETCH?1:5) << 16); // issue trap 1
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (unlikely((access == iss::access_type::FETCH || access == iss::access_type::DEBUG_FETCH) && (addr & 0x1) == 1)) {
|
auto alignment = is_fetch(access)? (traits<BASE>::MISA_VAL&0x100? 2 : 4) : length;
|
||||||
|
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
|
||||||
fault_data = addr;
|
fault_data = addr;
|
||||||
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
if (is_debug(access)) throw trap_access(0, addr);
|
||||||
this->trap_state = (1 << 31); // issue trap 0
|
this->trap_state = (1 << 31); // issue trap 0
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
auto alignment = access == iss::access_type::FETCH? (traits<BASE>::MISA_VAL&0x100? 2 : 4) : length;
|
if(!is_debug(access) && (addr&(alignment-1))){
|
||||||
if(alignment>1 && (addr&(alignment-1))){
|
|
||||||
this->trap_state = 1<<31 | 4<<16;
|
this->trap_state = 1<<31 | 4<<16;
|
||||||
fault_data=addr;
|
fault_data=addr;
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
|
|
Loading…
Reference in New Issue