diff mbox series

[RFC,V3,16/43] rv64ilp32_abi: riscv: Support physical addresses >= 0x80000000

Message ID 20250325121624.523258-17-guoren@kernel.org (mailing list archive)
State New
Headers show
Series rv64ilp32_abi: Build CONFIG_64BIT kernel-self with ILP32 ABI | expand

Commit Message

Guo Ren March 25, 2025, 12:15 p.m. UTC
From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>

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) <guoren@kernel.org>
---
 arch/riscv/kernel/head.S | 112 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)
diff mbox series

Patch

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