[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 <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2025-06-02 08:08:02 +01:00
parent bb2011241f
commit 88cffd75a9

View File

@@ -896,13 +896,14 @@ enable_paging_64_loop:
slli t0, a1, SATP_MODE_SHIFT slli t0, a1, SATP_MODE_SHIFT
srli t1, a0, PAGE_SHIFT srli t1, a0, PAGE_SHIFT
or t0, t0, t1 or t0, t0, t1
csrrw zero, satp, t0 csrw satp, t0
sfence.vma sfence.vma
csrrw a2, satp, t0 csrr a2, satp
srli a2, a2, SATP_MODE_SHIFT srli a2, a2, SATP_MODE_SHIFT
/* Loop until we successfully enable paging, or run out of levels */ /* Loop until we successfully enable paging, or run out of levels */
beq a2, a1, 1f beq a2, a1, 1f
csrw satp, zero
addi a1, a1, -1 addi a1, a1, -1
li t0, SATP_MODE_SV39 li t0, SATP_MODE_SV39
bge a1, t0, enable_paging_64_loop bge a1, t0, enable_paging_64_loop
@@ -1074,9 +1075,9 @@ enable_paging_32:
.balign enable_paging_32_xalign .balign enable_paging_32_xalign
/* Start of transition code */ /* Start of transition code */
enable_paging_32_xstart: enable_paging_32_xstart:
csrrw zero, satp, t1 csrw satp, t1
sfence.vma sfence.vma
csrrw a1, satp, t1 csrr a1, satp
beqz a1, 2f beqz a1, 2f
jr t0 jr t0
1: /* Restore temporarily modified PTE */ 1: /* Restore temporarily modified PTE */
@@ -1086,8 +1087,9 @@ enable_paging_32_xstart:
.equ enable_paging_32_xlen, . - enable_paging_32_xstart .equ enable_paging_32_xlen, . - enable_paging_32_xstart
2: srli a1, a1, SATP_MODE_SHIFT 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 bnez a1, 1f
csrw satp, zero
mv tp, zero mv tp, zero
1: 1:
/* Adjust return address to a virtual address */ /* Adjust return address to a virtual address */