Fix bad mepc reported after branching to a branch in a no-X address range
This commit is contained in:
parent
cd3125b6e5
commit
f2876eb51f
|
@ -712,13 +712,13 @@ end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
// Be careful not to take branches whose comparisons depend on a load result
|
// Be careful not to take branches whose comparisons depend on a load result
|
||||||
wire x_jump_req_if_aligned = !x_stall_on_raw && (
|
wire x_jump_req_unchecked = !x_stall_on_raw && (
|
||||||
d_branchcond == BCOND_ALWAYS ||
|
d_branchcond == BCOND_ALWAYS ||
|
||||||
d_branchcond == BCOND_ZERO && !x_branch_cmp ||
|
d_branchcond == BCOND_ZERO && !x_branch_cmp ||
|
||||||
d_branchcond == BCOND_NZERO && x_branch_cmp
|
d_branchcond == BCOND_NZERO && x_branch_cmp
|
||||||
);
|
);
|
||||||
|
|
||||||
assign x_jump_req = x_jump_req_if_aligned && !x_jump_misaligned;
|
assign x_jump_req = x_jump_req_unchecked && !x_jump_misaligned && !x_exec_pmp_fail;
|
||||||
|
|
||||||
// Memory protection
|
// Memory protection
|
||||||
|
|
||||||
|
@ -807,8 +807,8 @@ end
|
||||||
wire [W_ADDR-1:0] m_exception_return_addr;
|
wire [W_ADDR-1:0] m_exception_return_addr;
|
||||||
|
|
||||||
wire [W_EXCEPT-1:0] x_except =
|
wire [W_EXCEPT-1:0] x_except =
|
||||||
x_jump_req_if_aligned && x_jump_misaligned ? EXCEPT_INSTR_MISALIGN :
|
|
||||||
x_exec_pmp_fail ? EXCEPT_INSTR_FAULT :
|
x_exec_pmp_fail ? EXCEPT_INSTR_FAULT :
|
||||||
|
x_jump_req_unchecked && x_jump_misaligned ? EXCEPT_INSTR_MISALIGN :
|
||||||
x_csr_illegal_access ? EXCEPT_INSTR_ILLEGAL :
|
x_csr_illegal_access ? EXCEPT_INSTR_ILLEGAL :
|
||||||
|EXTENSION_A && x_unaligned_addr && d_memop_is_amo ? EXCEPT_STORE_ALIGN :
|
|EXTENSION_A && x_unaligned_addr && d_memop_is_amo ? EXCEPT_STORE_ALIGN :
|
||||||
|EXTENSION_A && x_amo_phase == 3'h4 && x_unaligned_addr ? EXCEPT_STORE_ALIGN :
|
|EXTENSION_A && x_amo_phase == 3'h4 && x_unaligned_addr ? EXCEPT_STORE_ALIGN :
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
// the lowest-numbered matching region. Check that partial region matches
|
// the lowest-numbered matching region. Check that partial region matches
|
||||||
// cause failure no matter the permission, unless there is a lower-numbered
|
// cause failure no matter the permission, unless there is a lower-numbered
|
||||||
// fully matching region.
|
// fully matching region.
|
||||||
|
//
|
||||||
|
// Check that jumping to a branch in non-X-permitted memory points mepc at the
|
||||||
|
// branch, not its target (known corner case)
|
||||||
|
|
||||||
/*EXPECTED-OUTPUT***************************************************************
|
/*EXPECTED-OUTPUT***************************************************************
|
||||||
|
|
||||||
|
@ -27,6 +30,8 @@ Full match under partial match, negative overhang
|
||||||
mcause = 11
|
mcause = 11
|
||||||
Partial match under full match, negative overhang
|
Partial match under full match, negative overhang
|
||||||
mcause = 1
|
mcause = 1
|
||||||
|
Jump to bad jump
|
||||||
|
OK
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
@ -63,6 +68,26 @@ void __attribute__((aligned(4), naked)) do_nops() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __attribute__((naked)) do_jump() {
|
||||||
|
asm (
|
||||||
|
"j 1f\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"1:\n"
|
||||||
|
"ret\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#define MCAUSE_INSTR_FAULT 1
|
#define MCAUSE_INSTR_FAULT 1
|
||||||
#define MCAUSE_ECALL 11
|
#define MCAUSE_ECALL 11
|
||||||
|
|
||||||
|
@ -175,5 +200,12 @@ int main() {
|
||||||
tb_assert(read_csr(mcause) == MCAUSE_INSTR_FAULT, "Should get instruction fault on partial match\n");
|
tb_assert(read_csr(mcause) == MCAUSE_INSTR_FAULT, "Should get instruction fault on partial match\n");
|
||||||
tb_assert(read_csr(mepc) == (uint32_t)&do_nops + 2, "Bad mepc\n");
|
tb_assert(read_csr(mepc) == (uint32_t)&do_nops + 2, "Bad mepc\n");
|
||||||
|
|
||||||
|
tb_puts("Jump to bad jump\n");
|
||||||
|
write_pmpcfg(0, 0);
|
||||||
|
write_pmpcfg(1, 0);
|
||||||
|
enter_umode(&do_jump);
|
||||||
|
tb_assert(read_csr(mepc) == (uint32_t)&do_jump, "Bad mepc\n");
|
||||||
|
tb_puts("OK\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue