]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[riscv] Create coherent DMA mapping for low 4GB of address space
authorMichael Brown <mcb30@ipxe.org>
Fri, 4 Jul 2025 13:23:37 +0000 (14:23 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 4 Jul 2025 15:10:51 +0000 (16:10 +0100)
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 <mcb30@ipxe.org>
src/arch/riscv/prefix/libprefix.S

index 0482ffe3142256c5b3bd912250fbfa802338d2ff..75fac1f5db0f48db665ccd0805dd9a9baf6a0b87 100644 (file)
@@ -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)