summaryrefslogtreecommitdiff
path: root/lib/sbi/sbi_misaligned_ldst.c
diff options
context:
space:
mode:
authorAnup Patel <anup.patel@wdc.com>2019-12-12 20:21:42 +0300
committerAnup Patel <anup@brainfault.org>2019-12-16 12:18:31 +0300
commit7219477f7b400a2eaa8fac5aedd73ba29eef92d9 (patch)
tree437690397563c753cdfcafe2e9c9fd76e5310342 /lib/sbi/sbi_misaligned_ldst.c
parent2be424bd28560d5399788ed16f663f7785a8c5f9 (diff)
downloadopensbi-7219477f7b400a2eaa8fac5aedd73ba29eef92d9.tar.xz
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>
Diffstat (limited to 'lib/sbi/sbi_misaligned_ldst.c')
-rw-r--r--lib/sbi/sbi_misaligned_ldst.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/lib/sbi/sbi_misaligned_ldst.c b/lib/sbi/sbi_misaligned_ldst.c
index 314b2f3..400372c 100644
--- a/lib/sbi/sbi_misaligned_ldst.c
+++ b/lib/sbi/sbi_misaligned_ldst.c
@@ -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);