forked from Mirrors/opensbi
		
	lib: Use MTINST CSR in misaligned load/store emulation
We should use MTINST CSR in misaligned load/store emulation whenever possible to avoid unpriv read in getting trapped instruction. This will improve preformance on HW having proper implementation of MTINST CSR. Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
		@@ -26,14 +26,27 @@ int sbi_misaligned_load_handler(u32 hartid, ulong mcause,
 | 
			
		||||
				struct sbi_trap_regs *regs,
 | 
			
		||||
				struct sbi_scratch *scratch)
 | 
			
		||||
{
 | 
			
		||||
	ulong insn;
 | 
			
		||||
	union reg_data val;
 | 
			
		||||
	struct sbi_trap_info uptrap;
 | 
			
		||||
	int i, fp = 0, shift = 0, len = 0;
 | 
			
		||||
	ulong insn = sbi_get_insn(regs->mepc, scratch, &uptrap);
 | 
			
		||||
 | 
			
		||||
	if (uptrap.cause) {
 | 
			
		||||
		uptrap.epc = regs->mepc;
 | 
			
		||||
		return sbi_trap_redirect(regs, &uptrap, scratch);
 | 
			
		||||
	if (tinst & 0x1) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * Bit[0] == 1 implies trapped instruction value is
 | 
			
		||||
		 * transformed instruction or custom instruction.
 | 
			
		||||
		 */
 | 
			
		||||
		insn = tinst | INSN_16BIT_MASK;
 | 
			
		||||
	} else {
 | 
			
		||||
		/*
 | 
			
		||||
		 * Bit[0] == 0 implies trapped instruction value is
 | 
			
		||||
		 * zero or special value.
 | 
			
		||||
		 */
 | 
			
		||||
		insn = sbi_get_insn(regs->mepc, scratch, &uptrap);
 | 
			
		||||
		if (uptrap.cause) {
 | 
			
		||||
			uptrap.epc = regs->mepc;
 | 
			
		||||
			return sbi_trap_redirect(regs, &uptrap, scratch);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((insn & INSN_MASK_LW) == INSN_MATCH_LW) {
 | 
			
		||||
@@ -135,14 +148,27 @@ int sbi_misaligned_store_handler(u32 hartid, ulong mcause,
 | 
			
		||||
				 struct sbi_trap_regs *regs,
 | 
			
		||||
				 struct sbi_scratch *scratch)
 | 
			
		||||
{
 | 
			
		||||
	ulong insn;
 | 
			
		||||
	union reg_data val;
 | 
			
		||||
	struct sbi_trap_info uptrap;
 | 
			
		||||
	int i, len = 0;
 | 
			
		||||
	ulong insn = sbi_get_insn(regs->mepc, scratch, &uptrap);
 | 
			
		||||
 | 
			
		||||
	if (uptrap.cause) {
 | 
			
		||||
		uptrap.epc = regs->mepc;
 | 
			
		||||
		return sbi_trap_redirect(regs, &uptrap, scratch);
 | 
			
		||||
	if (tinst & 0x1) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * Bit[0] == 1 implies trapped instruction value is
 | 
			
		||||
		 * transformed instruction or custom instruction.
 | 
			
		||||
		 */
 | 
			
		||||
		insn = tinst | INSN_16BIT_MASK;
 | 
			
		||||
	} else {
 | 
			
		||||
		/*
 | 
			
		||||
		 * Bit[0] == 0 implies trapped instruction value is
 | 
			
		||||
		 * zero or special value.
 | 
			
		||||
		 */
 | 
			
		||||
		insn = sbi_get_insn(regs->mepc, scratch, &uptrap);
 | 
			
		||||
		if (uptrap.cause) {
 | 
			
		||||
			uptrap.epc = regs->mepc;
 | 
			
		||||
			return sbi_trap_redirect(regs, &uptrap, scratch);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	val.data_ulong = GET_RS2(insn, regs);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user