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
|
||||
|
||||
// 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_ZERO && !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
|
||||
|
||||
|
@ -807,8 +807,8 @@ end
|
|||
wire [W_ADDR-1:0] m_exception_return_addr;
|
||||
|
||||
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_jump_req_unchecked && x_jump_misaligned ? EXCEPT_INSTR_MISALIGN :
|
||||
x_csr_illegal_access ? EXCEPT_INSTR_ILLEGAL :
|
||||
|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 :
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
// the lowest-numbered matching region. Check that partial region matches
|
||||
// cause failure no matter the permission, unless there is a lower-numbered
|
||||
// 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***************************************************************
|
||||
|
||||
|
@ -27,6 +30,8 @@ Full match under partial match, negative overhang
|
|||
mcause = 11
|
||||
Partial match under full match, negative overhang
|
||||
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_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(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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue