diff mbox series

[v3,5/7] xen/riscv: implement data and instruction cache operations

Message ID 33cf536f15356db894be5bde557060585cc2e410.1734452721.git.oleksii.kurochko@gmail.com (mailing list archive)
State New
Headers show
Series Unflattening and relocation of host device tree | expand

Commit Message

Oleksii Kurochko Dec. 17, 2024, 4:32 p.m. UTC
Implement following cache operations:
- clean_and_invalidate_dcache_va_range()
- clean_dcache_va_range()
- invalidate_icache()

The first two functions may require support for the CMO (Cache Management
Operations) extension and/or hardware-specific instructions.
Currently, only QEMU is supported, which does not model cache behavior.
Therefore, clean_and_invalidate_dcache_va_range() and clean_dcache_va_range()
are implemented to simply return 0. For other cases, generate compilation error
so a user won't miss to update this function if necessery.
If hardware supports CMO or hardware-specific instructions, these functions
should be updated accordingly. To support current implementation of these
function CONFIG_QEMU_PLATFORM is introduced.

invalidate_icache() is implemented using fence.i instruction as
mentioned in the unpriv spec:
  The FENCE.I instruction was designed to support a wide variety of
  implementations. A simple implementation can flush the local instruction
  cache and the instruction pipeline when the FENCE.I is executed.
  A more complex implementation might snoop the instruction (data) cache
  on every data (instruction) cache miss, or use an inclusive unified
  private L2 cache to invalidate lines from the primary instruction cache
  when they are being written by a local store instruction.
  If instruction and data caches are kept coherent in this way, or if the
  memory system consists of only uncached RAMs, then just the fetch pipeline
  needs to be flushed at a FENCE.I.
The FENCE.I instruction requires the presence of the Zifencei extension,
which might not always be available. However, Xen uses the RV64G ISA, which
guarantees the presence of the Zifencei extension. According to the
unprivileged ISA specification (version 20240411):
  One goal of the RISC-V project is that it be used as a stable software
  development target. For this purpose, we define a combination of a base ISA
  (RV32I or RV64I) plus selected standard extensions (IMAFD, Zicsr, Zifencei)
  as a "general-purpose" ISA, and we use the abbreviation G for the
  IMAFDZicsr_Zifencei combination of instruction-set extensions.

Set CONFIG_QEMU_PLATFORM=y in tiny64_defconfig to have proper implemtation of
clean_and_invalidate_dcache_va_range() and clean_dcache_va_range() for CI.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - Updates for config QEMU:
   - Rename CONFIG_QEMU to CONFIG_QEMU_PLATFORM.
   - Drop "depends on RISCV_64" property for Config QEMU_PLATFORM.
   - Split help string.
 - Update implementation of the functions: clean_and_invalidate_dcache_va_range()
   and clean_dcache_va_range().
 - Minimal code style fixes: move second argument of clean_and_invalidate_dcache_va_range()
   to next line.
 - Update the commit message.
---
Changes in V2:
 - Update the commit message and subject:
   - drop information about HAS_CMO;
   - add information about Zifencei extension;
 - Introdce platforms directory and CONFIG_QEMU; update implementation of
   data/instruction cache operations as returning 0 for CONFIG_QEMU and for
   others - return -ENOTSUPP.
 - Drop HAS_CMO config.
---
 xen/arch/riscv/Kconfig                  |  2 ++
 xen/arch/riscv/configs/tiny64_defconfig |  1 +
 xen/arch/riscv/include/asm/page.h       | 22 +++++++++++++++++++++-
 xen/arch/riscv/platforms/Kconfig        |  5 +++++
 4 files changed, 29 insertions(+), 1 deletion(-)
 create mode 100644 xen/arch/riscv/platforms/Kconfig

Comments

Jan Beulich Dec. 19, 2024, 9:16 a.m. UTC | #1
On 17.12.2024 17:32, Oleksii Kurochko wrote:
> Implement following cache operations:
> - clean_and_invalidate_dcache_va_range()
> - clean_dcache_va_range()
> - invalidate_icache()
> 
> The first two functions may require support for the CMO (Cache Management
> Operations) extension and/or hardware-specific instructions.
> Currently, only QEMU is supported, which does not model cache behavior.
> Therefore, clean_and_invalidate_dcache_va_range() and clean_dcache_va_range()
> are implemented to simply return 0. For other cases, generate compilation error
> so a user won't miss to update this function if necessery.
> If hardware supports CMO or hardware-specific instructions, these functions
> should be updated accordingly. To support current implementation of these
> function CONFIG_QEMU_PLATFORM is introduced.
> 
> invalidate_icache() is implemented using fence.i instruction as
> mentioned in the unpriv spec:
>   The FENCE.I instruction was designed to support a wide variety of
>   implementations. A simple implementation can flush the local instruction
>   cache and the instruction pipeline when the FENCE.I is executed.
>   A more complex implementation might snoop the instruction (data) cache
>   on every data (instruction) cache miss, or use an inclusive unified
>   private L2 cache to invalidate lines from the primary instruction cache
>   when they are being written by a local store instruction.
>   If instruction and data caches are kept coherent in this way, or if the
>   memory system consists of only uncached RAMs, then just the fetch pipeline
>   needs to be flushed at a FENCE.I.
> The FENCE.I instruction requires the presence of the Zifencei extension,
> which might not always be available. However, Xen uses the RV64G ISA, which
> guarantees the presence of the Zifencei extension. According to the
> unprivileged ISA specification (version 20240411):
>   One goal of the RISC-V project is that it be used as a stable software
>   development target. For this purpose, we define a combination of a base ISA
>   (RV32I or RV64I) plus selected standard extensions (IMAFD, Zicsr, Zifencei)
>   as a "general-purpose" ISA, and we use the abbreviation G for the
>   IMAFDZicsr_Zifencei combination of instruction-set extensions.
> 
> Set CONFIG_QEMU_PLATFORM=y in tiny64_defconfig to have proper implemtation of
> clean_and_invalidate_dcache_va_range() and clean_dcache_va_range() for CI.
> 
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

I'm not entirely happy with this (and where it appears to be moving us), but
for the time being it's perhaps good enough, so
Acked-by: Jan Beulich <jbeulich@suse.com>
Albeit with ...

> @@ -148,9 +149,28 @@ static inline bool pte_is_mapping(pte_t p)
>      return (p.pte & PTE_VALID) && (p.pte & PTE_ACCESS_MASK);
>  }
>  
> +static inline int clean_and_invalidate_dcache_va_range(const void *p,
> +                                                       unsigned long size)
> +{
> +#ifndef CONFIG_QEMU_PLATFORM
> +    #error "should clean_and_invalidate_dcache_va_range() be updated?"
> +#endif
> +
> +    return 0;
> +}
> +
> +static inline int clean_dcache_va_range(const void *p, unsigned long size)
> +{
> +#ifndef CONFIG_QEMU_PLATFORM
> +    #error "should clean_dcache_va_range() be updated?"
> +#endif
> +
> +    return 0;
> +}

... the #-es moved back to the 1st column, which I'll take the liberty of
doing while committing. Personally I wonder anyway why these aren't simply
BUILD_BUG_ON("unimplemented").

Jan
diff mbox series

Patch

diff --git a/xen/arch/riscv/Kconfig b/xen/arch/riscv/Kconfig
index 1858004676..00f329054c 100644
--- a/xen/arch/riscv/Kconfig
+++ b/xen/arch/riscv/Kconfig
@@ -52,6 +52,8 @@  config RISCV_ISA_C
 
 endmenu
 
+source "arch/riscv/platforms/Kconfig"
+
 source "common/Kconfig"
 
 source "drivers/Kconfig"
diff --git a/xen/arch/riscv/configs/tiny64_defconfig b/xen/arch/riscv/configs/tiny64_defconfig
index fc7a04872f..6af563bd73 100644
--- a/xen/arch/riscv/configs/tiny64_defconfig
+++ b/xen/arch/riscv/configs/tiny64_defconfig
@@ -10,3 +10,4 @@  CONFIG_RISCV_64=y
 CONFIG_DEBUG=y
 CONFIG_DEBUG_INFO=y
 CONFIG_EXPERT=y
+CONFIG_QEMU_PLATFORM=y
diff --git a/xen/arch/riscv/include/asm/page.h b/xen/arch/riscv/include/asm/page.h
index bf3f75e85d..c82432dc67 100644
--- a/xen/arch/riscv/include/asm/page.h
+++ b/xen/arch/riscv/include/asm/page.h
@@ -7,6 +7,7 @@ 
 
 #include <xen/bug.h>
 #include <xen/const.h>
+#include <xen/errno.h>
 #include <xen/types.h>
 
 #include <asm/atomic.h>
@@ -148,9 +149,28 @@  static inline bool pte_is_mapping(pte_t p)
     return (p.pte & PTE_VALID) && (p.pte & PTE_ACCESS_MASK);
 }
 
+static inline int clean_and_invalidate_dcache_va_range(const void *p,
+                                                       unsigned long size)
+{
+#ifndef CONFIG_QEMU_PLATFORM
+    #error "should clean_and_invalidate_dcache_va_range() be updated?"
+#endif
+
+    return 0;
+}
+
+static inline int clean_dcache_va_range(const void *p, unsigned long size)
+{
+#ifndef CONFIG_QEMU_PLATFORM
+    #error "should clean_dcache_va_range() be updated?"
+#endif
+
+    return 0;
+}
+
 static inline void invalidate_icache(void)
 {
-    BUG_ON("unimplemented");
+    asm volatile ( "fence.i" ::: "memory" );
 }
 
 #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
diff --git a/xen/arch/riscv/platforms/Kconfig b/xen/arch/riscv/platforms/Kconfig
new file mode 100644
index 0000000000..710423a59a
--- /dev/null
+++ b/xen/arch/riscv/platforms/Kconfig
@@ -0,0 +1,5 @@ 
+config QEMU_PLATFORM
+	bool "QEMU based platform support"
+	help
+	  Enable all the required drivers for QEMU riscv64
+	  virt emulated machine.