From 88cffd75a9c2cc15780d465fe4e9ccf45719d6c9 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 2 Jun 2025 08:08:02 +0100 Subject: [PATCH] [riscv] Zero SATP after any failed attempt to enable paging The RISC-V specification states that "if SATP is written with an unsupported mode, the entire write has no effect; no fields in SATP are modified". We currently rely on this specified behaviour when calculating the early UART base address: if SATP has a non-zero value then we assume that paging must be enabled. The XuanTie C910 CPU (as used in the Lichee Pi 4A) does not conform to this specified behaviour. Writing SATP with an unsupported mode will leave SATP.MODE as zero (i.e. bare physical addressing) but the write to SATP.PPN will still take effect, leaving SATP with an illegal non-zero value. Work around this misbehaviour by explicitly writing zero to SATP if we detect that the mode change has not taken effect (e.g. because the CPU does not support the requested paging mode). Signed-off-by: Michael Brown --- src/arch/riscv/prefix/libprefix.S | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/arch/riscv/prefix/libprefix.S b/src/arch/riscv/prefix/libprefix.S index 8fa9a6781..583f27117 100644 --- a/src/arch/riscv/prefix/libprefix.S +++ b/src/arch/riscv/prefix/libprefix.S @@ -896,13 +896,14 @@ enable_paging_64_loop: slli t0, a1, SATP_MODE_SHIFT srli t1, a0, PAGE_SHIFT or t0, t0, t1 - csrrw zero, satp, t0 + csrw satp, t0 sfence.vma - csrrw a2, satp, t0 + csrr a2, satp srli a2, a2, SATP_MODE_SHIFT /* Loop until we successfully enable paging, or run out of levels */ beq a2, a1, 1f + csrw satp, zero addi a1, a1, -1 li t0, SATP_MODE_SV39 bge a1, t0, enable_paging_64_loop @@ -1074,9 +1075,9 @@ enable_paging_32: .balign enable_paging_32_xalign /* Start of transition code */ enable_paging_32_xstart: - csrrw zero, satp, t1 + csrw satp, t1 sfence.vma - csrrw a1, satp, t1 + csrr a1, satp beqz a1, 2f jr t0 1: /* Restore temporarily modified PTE */ @@ -1086,8 +1087,9 @@ enable_paging_32_xstart: .equ enable_paging_32_xlen, . - enable_paging_32_xstart 2: srli a1, a1, SATP_MODE_SHIFT - /* Clear virtual address offset if paging is not enabled */ + /* Zero SATP and virtual address offset if paging is not enabled */ bnez a1, 1f + csrw satp, zero mv tp, zero 1: /* Adjust return address to a virtual address */ -- 2.47.3