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