From: "Guo Ren (Alibaba DAMO Academy)" <[email protected]>

The RV64ILP32 ABI has two independent 2GiB address space:
 - 0 ~ 0x7fffffff
 - 0xffffffff80000000 ~ 0xffffffffffffffff

In the rv64ilp32 ABI, 0x80000000 is illegal; hence, use a
temporary trap handler to zero-extend the address for jalr,
load and store operations.

Signed-off-by: Guo Ren (Alibaba DAMO Academy) <[email protected]>
---
 arch/riscv/kernel/head.S | 112 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)

diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index e55a92be12b1..bd2f30aa6d01 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -170,6 +170,118 @@ secondary_start_sbi:
 
 .align 2
 .Lsecondary_park:
+#ifdef CONFIG_ABI_RV64ILP32
+.option push
+.option norelax
+.option norvc
+       addiw sp, sp, -32
+
+       /* zext.w sp */
+       slli  sp, sp, 32
+       srli  sp, sp, 32
+
+       /* zext.w ra */
+       slli ra, ra, 32
+       srli ra, ra, 32
+
+       /* zext.w fp */
+       slli fp, fp, 32
+       srli fp, fp, 32
+
+       /* zext.w tp */
+       slli tp, tp, 32
+       srli tp, tp, 32
+
+       /* save tmp reg */
+       REG_S ra, 24(sp)
+       REG_S fp, 16(sp)
+       REG_S tp,  8(sp)
+       REG_S gp,  0(sp)
+
+       /* zext.w epc */
+       csrr ra, CSR_EPC
+       slli ra, ra, 32
+       srli ra, ra, 32
+       csrw CSR_SEPC, ra
+
+       csrr gp, CSR_CAUSE
+
+       /* EXC_INST_ACCESS */
+       addiw fp, gp, -1
+       beqz fp, 6f
+
+       /* EXC_LOAD_ACCESS */
+       addiw fp, gp, -5
+       beqz fp, 1f
+
+       /* EXC_STORE_ACCESS */
+       addiw fp, gp, -7
+       beqz fp, 1f
+
+       j 7f
+1:
+       /* get inst */
+       lw ra, 0(ra)
+       andi gp, ra, 0x3
+
+       /* c.(lw/sw/ld/sd)sp */
+       addiw fp, gp, -2
+       beqz fp, 6f
+
+       /* lw/sw/ld/sd */
+       addiw fp, gp, -3
+       beqz fp, 2f
+
+       /* c.(lw/sw/ld/sd) */
+       li fp, 0x7
+       slli fp, fp, 7
+       and ra, fp, ra
+       slli ra, ra, 8
+       j 3f
+
+2:
+       /* get rs1 */
+       li fp, 0x1f
+       slli fp, fp, 15
+       and ra, fp, ra
+
+3:
+       /* copy rs1 to rd */
+       mv fp, ra
+       srli fp, fp, 8
+       or ra, fp, ra
+
+       /* modify slli */
+       la fp, 4f
+       lw tp, 0(fp)
+       mv gp, tp
+       or tp, ra, tp
+       sw tp, 0(fp)
+       fence.i
+4:     slli x0, x0, 32
+       sw gp, 0(fp)
+
+       /* modify srli */
+       la fp, 5f
+       lw tp, 0(fp)
+       mv gp, tp
+       or tp, ra, tp
+       sw tp, 0(fp)
+       fence.i
+5:     srli x0, x0, 32
+       sw gp, 0(fp)
+
+6:
+       /* restore tmp reg */
+       REG_L ra, 24(sp)
+       REG_L fp, 16(sp)
+       REG_L tp,  8(sp)
+       REG_L gp,  0(sp)
+       addi sp, sp, 32
+       sret
+.option pop
+7:
+#endif
        /*
         * Park this hart if we:
         *  - have too many harts on CONFIG_RISCV_BOOT_SPINWAIT
-- 
2.40.1


Reply via email to