From d75d10df16964f4bf93cbaa083efc8bee313281a Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 4 Jul 2025 14:23:37 +0100 Subject: [PATCH] [riscv] Create coherent DMA mapping for low 4GB of address space Use PTEs 256-259 to create a mapping of the 32-bit physical address space with attributes suitable for coherent DMA mappings. Signed-off-by: Michael Brown --- src/arch/riscv/prefix/libprefix.S | 32 +++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/arch/riscv/prefix/libprefix.S b/src/arch/riscv/prefix/libprefix.S index 0482ffe31..75fac1f5d 100644 --- a/src/arch/riscv/prefix/libprefix.S +++ b/src/arch/riscv/prefix/libprefix.S @@ -785,17 +785,27 @@ page_table: * higher bits set, and so cannot identity-map to a 55-bit * physical address). * + * - PTE[256-259] : Coherent DMA mapping + * + * These are 1GB "gigapages" used to map the low 4GB of the + * physical address space with caching disabled, for use by + * coherent DMA mappings. + * + * We use 1GB "gigapages" even for Sv48 and Sv57, since this + * allows the virtual address base 0xffffffc000000000 to remain a + * constant regardless of supported paging level. + * * - PTE[x-y] : Virtual address map for iPXE * * These are 2MB "megapages" used to map the link-time virtual * address range used by iPXE itself. We can use any 2MB-aligned - * range within 0xffffffffe0000000-0xffffffffffc00000, which + * range within 0xffffffffe0800000-0xffffffffffc00000, which * breaks down as: * * VPN[4] = 511 (in Sv57, must be all-ones in Sv48 and Sv39) * VPN[3] = 511 (in Sv57 and Sv48, must be all-ones in Sv39) * VPN[2] = 511 (in all paging levels) - * VPN[1] = 256-510 (in all paging levels) + * VPN[1] = 260-510 (in all paging levels) * VPN[0] = 0 (in all paging levels) * * In most builds, only a single 2MB "megapage" will be needed. @@ -878,6 +888,24 @@ enable_paging_64: ori t0, t0, PTE_V STOREN t0, -PTE_SIZE(a3) + /* Calculate PTE stride for coherent DMA map + * + * PPN[2] LSB is PTE bit 28 in all paging modes, and so the + * stride is always ( 1 << 28 ) + */ + li a4, 1 + slli a4, a4, PTE_PPN2_LSB + + /* Construct PTE[256-259] for 32-bit coherent DMA map */ + addi a3, a3, -( ( PTE_COUNT / 2 ) * PTE_SIZE ) + li t0, ( 1 << ( 32 - VPN2_LSB ) ) + li t1, ( PTE_LEAF & ~PTE_X ) +1: STOREN t1, (a3) + addi a3, a3, PTE_SIZE + add t1, t1, a4 + addi t0, t0, -1 + bgtz t0, 1b + /* Construct base page table entry for address zero */ li t0, PTE_LEAF STOREN t0, (a0) -- 2.47.2