]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[riscv] Support the standard Svpbmt extension for page-based memory types
authorMichael Brown <mcb30@ipxe.org>
Fri, 11 Jul 2025 11:24:02 +0000 (12:24 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 11 Jul 2025 11:24:02 +0000 (12:24 +0100)
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 <mcb30@ipxe.org>
src/arch/riscv/core/svpage.c

index e64c802fe377547cf4b74d71e6c0599cf02c5bae..0728289b0df2e6b26d254c3833ce4db4ad3107e4 100644 (file)
@@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <stdint.h>
 #include <strings.h>
 #include <assert.h>
+#include <ipxe/hart.h>
 #include <ipxe/iomap.h>
 
 /** @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 )