lib: sbi: Add variable-length unprivilege access functions

sbi_load/store_loop read/write variable-length buffer unprivileged.
Both function use the widest aligned 8/4/2/1 byte load/stores in each
loop to reduce the total number of iterations.

Also switch the scalar/vector misaligned handlers to make use of such
functions to simplify code.

Miscellaneous: remove the unnecessary [taddr] in inline assembly

Signed-off-by: Bo Gan <ganboing@gmail.com>
Tested-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260609060024.706-4-ganboing@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Bo Gan
2026-06-08 23:00:23 -07:00
committed by Anup Patel
parent 1475f147f6
commit 914aeddaf1
4 changed files with 122 additions and 42 deletions
+8 -16
View File
@@ -471,7 +471,6 @@ static int sbi_misaligned_ld_emulator(ulong insn, int rlen, ulong addr,
const struct sbi_trap_info *orig_trap = &tcntx->trap;
struct sbi_trap_regs *regs = &tcntx->regs;
struct sbi_trap_info uptrap;
int i;
if (!rlen) {
if (IS_VECTOR_LOAD_STORE(insn))
@@ -484,13 +483,10 @@ static int sbi_misaligned_ld_emulator(ulong insn, int rlen, ulong addr,
if (addr != orig_trap->tval)
return SBI_EFAIL;
for (i = 0; i < rlen; i++) {
out_val->data_bytes[i] =
sbi_load_u8((void *)(addr + i), &uptrap);
if (uptrap.cause) {
sbi_misaligned_tinst_fixup(orig_trap, &uptrap);
return sbi_trap_redirect(regs, &uptrap);
}
sbi_load_loop(out_val->data_bytes, addr, rlen, &uptrap);
if (uptrap.cause) {
sbi_misaligned_tinst_fixup(orig_trap, &uptrap);
return sbi_trap_redirect(regs, &uptrap);
}
return rlen;
}
@@ -507,7 +503,6 @@ static int sbi_misaligned_st_emulator(ulong insn, int wlen, ulong addr,
const struct sbi_trap_info *orig_trap = &tcntx->trap;
struct sbi_trap_regs *regs = &tcntx->regs;
struct sbi_trap_info uptrap;
int i;
if (!wlen) {
if (IS_VECTOR_LOAD_STORE(insn))
@@ -520,13 +515,10 @@ static int sbi_misaligned_st_emulator(ulong insn, int wlen, ulong addr,
if (addr != orig_trap->tval)
return SBI_EFAIL;
for (i = 0; i < wlen; i++) {
sbi_store_u8((void *)(addr + i),
in_val.data_bytes[i], &uptrap);
if (uptrap.cause) {
sbi_misaligned_tinst_fixup(orig_trap, &uptrap);
return sbi_trap_redirect(regs, &uptrap);
}
sbi_store_loop(in_val.data_bytes, addr, wlen, &uptrap);
if (uptrap.cause) {
sbi_misaligned_tinst_fixup(orig_trap, &uptrap);
return sbi_trap_redirect(regs, &uptrap);
}
return wlen;
}