From 3fd54e4f3a84915470582d93d001e7229783aa06 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 4 Jul 2025 14:37:31 +0100 Subject: [PATCH] [riscv] Construct invariant portions of page table outside the loop The page table entries for the identity map vary according to the paging level in use, and so must be constructed within the loop used to detect the maximum supported paging level. Other page table entries are invariant between paging levels, and so may be constructed just once before entering the loop. Signed-off-by: Michael Brown --- src/arch/riscv/prefix/libprefix.S | 97 ++++++++++++++++--------------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/src/arch/riscv/prefix/libprefix.S b/src/arch/riscv/prefix/libprefix.S index cf62338b5..0482ffe31 100644 --- a/src/arch/riscv/prefix/libprefix.S +++ b/src/arch/riscv/prefix/libprefix.S @@ -865,6 +865,19 @@ enable_paging_64: la t1, _prefix sub tp, t1, t0 + /* Zero PTE[0-511] */ + li t0, PTE_COUNT + mv a3, a0 +1: STOREN zero, (a3) + addi a3, a3, PTE_SIZE + addi t0, t0, -1 + bgtz t0, 1b + + /* Construct PTE[511] as next level page table pointer */ + srli t0, a0, PTE_PPN_SHIFT + ori t0, t0, PTE_V + STOREN t0, -PTE_SIZE(a3) + /* Construct base page table entry for address zero */ li t0, PTE_LEAF STOREN t0, (a0) @@ -889,54 +902,6 @@ enable_paging_64: STOREN t0, (a3) 1: mv a0, a3 - /* Find highest supported paging level */ - li a1, SATP_MODE_SV57 -enable_paging_64_loop: - - /* Calculate PTE stride for identity map at this paging level - * - * a1 == 10 == Sv57: PPN[4] LSB is PTE bit 46 => stride := 1 << 46 - * a1 == 9 == Sv48: PPN[3] LSB is PTE bit 37 => stride := 1 << 37 - * a1 == 8 == Sv39: PPN[2] LSB is PTE bit 28 => stride := 1 << 28 - * - * and so we calculate stride a4 := ( 1 << ( 9 * a1 - 44 ) ) - */ - slli a4, a1, 3 - add a4, a4, a1 - addi a4, a4, -44 - li t0, 1 - sll a4, t0, a4 - - /* Calculate size of accessible physical address space - * - * The identity map comprises only the lower half of the PTEs, - * since virtual addresses for the higher half must have all - * high bits set, and so cannot form part of an identity map. - */ - slli a5, a4, ( PTE_PPN_SHIFT + ( PTE_COUNT_LOG2 - 1 ) ) - - /* Construct PTE[0-255] for identity map */ - mv a3, a0 - li t0, ( PTE_COUNT / 2 ) - LOADN t1, (a0) -1: STOREN t1, (a3) - addi a3, a3, PTE_SIZE - add t1, t1, a4 - addi t0, t0, -1 - bgtz t0, 1b - - /* Zero PTE[256-511] */ - li t0, ( PTE_COUNT / 2 ) -1: STOREN zero, (a3) - addi a3, a3, PTE_SIZE - addi t0, t0, -1 - bgtz t0, 1b - - /* Construct PTE[511] as next level page table pointer */ - srli t0, a0, PTE_PPN_SHIFT - ori t0, t0, PTE_V - STOREN t0, -PTE_SIZE(a3) - /* Calculate PTE[x] address for iPXE virtual address map */ LOADN t0, prefix_link srli t0, t0, VPN1_LSB @@ -972,6 +937,42 @@ enable_paging_64_loop: add t0, t0, a4 ble t0, t2, 1b + /* Find highest supported paging level */ + li a1, SATP_MODE_SV57 +enable_paging_64_loop: + + /* Calculate PTE stride for identity map at this paging level + * + * a1 == 10 == Sv57: PPN[4] LSB is PTE bit 46 => stride := 1 << 46 + * a1 == 9 == Sv48: PPN[3] LSB is PTE bit 37 => stride := 1 << 37 + * a1 == 8 == Sv39: PPN[2] LSB is PTE bit 28 => stride := 1 << 28 + * + * and so we calculate stride a4 := ( 1 << ( 9 * a1 - 44 ) ) + */ + slli a4, a1, 3 + add a4, a4, a1 + addi a4, a4, -44 + li t0, 1 + sll a4, t0, a4 + + /* Calculate size of accessible physical address space + * + * The identity map comprises only the lower half of the PTEs, + * since virtual addresses for the higher half must have all + * high bits set, and so cannot form part of an identity map. + */ + slli a5, a4, ( PTE_PPN_SHIFT + ( PTE_COUNT_LOG2 - 1 ) ) + + /* Construct PTE[0-255] for identity map at this paging level */ + mv a3, a0 + li t0, ( PTE_COUNT / 2 ) + LOADN t1, (a0) +1: STOREN t1, (a3) + addi a3, a3, PTE_SIZE + add t1, t1, a4 + addi t0, t0, -1 + bgtz t0, 1b + /* Attempt to enable paging, and read back active paging level */ slli t0, a1, SATP_MODE_SHIFT srli t1, a0, PAGE_SHIFT -- 2.47.3