mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-08-25 07:41:42 +01:00
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_trap_regs *regs,
|
||||||
struct sbi_scratch *scratch)
|
struct sbi_scratch *scratch)
|
||||||
{
|
{
|
||||||
|
ulong insn;
|
||||||
union reg_data val;
|
union reg_data val;
|
||||||
struct sbi_trap_info uptrap;
|
struct sbi_trap_info uptrap;
|
||||||
int i, fp = 0, shift = 0, len = 0;
|
int i, fp = 0, shift = 0, len = 0;
|
||||||
ulong insn = sbi_get_insn(regs->mepc, scratch, &uptrap);
|
|
||||||
|
|
||||||
if (uptrap.cause) {
|
if (tinst & 0x1) {
|
||||||
uptrap.epc = regs->mepc;
|
/*
|
||||||
return sbi_trap_redirect(regs, &uptrap, scratch);
|
* 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) {
|
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_trap_regs *regs,
|
||||||
struct sbi_scratch *scratch)
|
struct sbi_scratch *scratch)
|
||||||
{
|
{
|
||||||
|
ulong insn;
|
||||||
union reg_data val;
|
union reg_data val;
|
||||||
struct sbi_trap_info uptrap;
|
struct sbi_trap_info uptrap;
|
||||||
int i, len = 0;
|
int i, len = 0;
|
||||||
ulong insn = sbi_get_insn(regs->mepc, scratch, &uptrap);
|
|
||||||
|
|
||||||
if (uptrap.cause) {
|
if (tinst & 0x1) {
|
||||||
uptrap.epc = regs->mepc;
|
/*
|
||||||
return sbi_trap_redirect(regs, &uptrap, scratch);
|
* 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);
|
val.data_ulong = GET_RS2(insn, regs);
|
||||||
|
Reference in New Issue
Block a user