From d539a420df919b3f9b808703b5f8d62bc485fe15 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 11 Jul 2025 12:24:02 +0100 Subject: [PATCH] [riscv] Support the standard Svpbmt extension for page-based memory types Set the appropriate Svpbmt type bits within page table entries if the extension is supported. Tested only in QEMU so far, due to the lack of availability of real hardware supporting Svpbmt. Signed-off-by: Michael Brown --- src/arch/riscv/core/svpage.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/arch/riscv/core/svpage.c b/src/arch/riscv/core/svpage.c index e64c802fe..0728289b0 100644 --- a/src/arch/riscv/core/svpage.c +++ b/src/arch/riscv/core/svpage.c @@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include +#include #include /** @file @@ -67,6 +68,15 @@ enum pte_flags { PTE_LAST = 0x100, }; +/** Page-based memory type (Svpbmt) */ +#define PTE_SVPBMT( x ) ( ( ( unsigned long long ) (x) ) << 61 ) + +/** Page is non-cacheable memory (Svpbmt) */ +#define PTE_SVPBMT_NC PTE_SVPBMT ( 1 ) + +/** Page maps I/O addresses (Svpbmt) */ +#define PTE_SVPBMT_IO PTE_SVPBMT ( 2 ) + /** Page table entry address */ #define PTE_PPN( addr ) ( (addr) >> 2 ) @@ -239,6 +249,11 @@ static void svpage_unmap ( const volatile void *virt ) { */ static void * svpage_ioremap ( unsigned long bus_addr, size_t len ) { unsigned long attrs = ( PTE_V | PTE_R | PTE_W | PTE_A | PTE_D ); + int rc; + + /* Add Svpbmt attributes if applicable */ + if ( ( rc = hart_supported ( "_svpbmt" ) ) == 0 ) + attrs |= PTE_SVPBMT_IO; /* Map pages for I/O */ return svpage_map ( bus_addr, len, attrs ); @@ -251,6 +266,11 @@ static void * svpage_ioremap ( unsigned long bus_addr, size_t len ) { */ void * svpage_dma32 ( void ) { unsigned long attrs = ( PTE_V | PTE_R | PTE_W | PTE_A | PTE_D ); + int rc; + + /* Add Svpbmt attributes if applicable */ + if ( ( rc = hart_supported ( "_svpbmt" ) ) == 0 ) + attrs |= PTE_SVPBMT_NC; /* Create mapping, if necessary */ if ( ! svpage_dma32_base ) -- 2.47.3