public inbox for dev@dpdk.org
 help / color / mirror / Atom feed
From: dangshiwei <1138222970gg@gmail.com>
To: dev@dpdk.org
Cc: stanislaw.kardach@gmail.com, sunyuechi@iscas.ac.cn,
	thomas@monjalon.net, dangshiwei <1138222970gg@gmail.com>
Subject: [PATCH] eal/riscv: add RISC-V specific I/O device memory operations
Date: Fri, 13 Mar 2026 22:08:35 +0800	[thread overview]
Message-ID: <20260313140836.3847-1-1138222970gg@gmail.com> (raw)

The current rte_io.h for RISC-V only includes generic/rte_io.h,
which uses volatile pointer casts for MMIO read/write. While this
prevents compiler optimizations, it does not prevent CPU-level
reordering on RISC-V, which is a weak-ordered architecture.

This patch adds a RISC-V specific implementation using explicit
load/store instructions:
- lbu/lhu/lwu/ld for reads (zero-extending to avoid sign-bit pollution)
- sb/sh/sw/sd for writes
- lwu is used for 32-bit reads on RV64 for correct zero-extension;
  lw is used on RV32 where it is naturally full-width
- 64-bit operations are guarded with RTE_ARCH_64 for RV32 compatibility

The "memory" clobber is retained in relaxed variants to prevent the
compiler from reordering these accesses with respect to other memory
operations, while still omitting the hardware fence instructions.
Unlike ARM64 which is a strong-ordered architecture, this additional
constraint is necessary on RISC-V.

Signed-off-by: dangshiwei <1138222970gg@gmail.com>
---
 lib/eal/riscv/include/rte_io.h | 185 ++++++++++++++++++++++++++++++++-
 1 file changed, 182 insertions(+), 3 deletions(-)

diff --git a/lib/eal/riscv/include/rte_io.h b/lib/eal/riscv/include/rte_io.h
index 4ae1f087ba..ffb6dcad68 100644
--- a/lib/eal/riscv/include/rte_io.h
+++ b/lib/eal/riscv/include/rte_io.h
@@ -3,11 +3,190 @@
  * Copyright(c) 2022 StarFive
  * Copyright(c) 2022 SiFive
  * Copyright(c) 2022 Semihalf
+ * Copyright(c) 2026 Dangshiwei
  */
 
-#ifndef RTE_IO_RISCV_H
-#define RTE_IO_RISCV_H
+#ifndef _RTE_IO_RISCV_H_
+#define _RTE_IO_RISCV_H_
+
+#include <stdint.h>
+
+#define RTE_OVERRIDE_IO_H
 
 #include "generic/rte_io.h"
+#include <rte_compat.h>
+#include "rte_atomic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Unlike ARM64 which is a strong-ordered architecture, RISC-V is a
+ * weak-ordered architecture. The "memory" clobber is added to the relaxed
+ * variants to prevent the compiler from reordering these accesses with
+ * respect to other memory operations, while still omitting the hardware
+ * fence instructions.
+ */
+
+/* relaxed read */
+
+static __rte_always_inline uint8_t
+rte_read8_relaxed(const volatile void *addr)
+{
+	uint8_t val;
+	asm volatile("lbu %0, 0(%1)" : "=r"(val) : "r"(addr) : "memory");
+	return val;
+}
+
+static __rte_always_inline uint16_t
+rte_read16_relaxed(const volatile void *addr)
+{
+	uint16_t val;
+	asm volatile("lhu %0, 0(%1)" : "=r"(val) : "r"(addr) : "memory");
+	return val;
+}
+
+static __rte_always_inline uint32_t
+rte_read32_relaxed(const volatile void *addr)
+{
+	uint32_t val;
+#ifdef RTE_ARCH_64
+	/* lwu is RV64-only: zero-extends to avoid sign-bit pollution */
+	asm volatile("lwu %0, 0(%1)" : "=r"(val) : "r"(addr) : "memory");
+#else
+	/* on RV32, lw is full-width, no extension needed */
+	asm volatile("lw %0, 0(%1)" : "=r"(val) : "r"(addr) : "memory");
+#endif
+	return val;
+}
+
+#ifdef RTE_ARCH_64
+static __rte_always_inline uint64_t
+rte_read64_relaxed(const volatile void *addr)
+{
+	uint64_t val;
+	asm volatile("ld %0, 0(%1)" : "=r"(val) : "r"(addr) : "memory");
+	return val;
+}
+#endif
+
+/* relaxed write */
+
+static __rte_always_inline void
+rte_write8_relaxed(uint8_t val, volatile void *addr)
+{
+	asm volatile("sb %1, 0(%0)" : : "r"(addr), "r"(val) : "memory");
+}
+
+static __rte_always_inline void
+rte_write16_relaxed(uint16_t val, volatile void *addr)
+{
+	asm volatile("sh %1, 0(%0)" : : "r"(addr), "r"(val) : "memory");
+}
+
+static __rte_always_inline void
+rte_write32_relaxed(uint32_t val, volatile void *addr)
+{
+	asm volatile("sw %1, 0(%0)" : : "r"(addr), "r"(val) : "memory");
+}
+
+#ifdef RTE_ARCH_64
+static __rte_always_inline void
+rte_write64_relaxed(uint64_t val, volatile void *addr)
+{
+	asm volatile("sd %1, 0(%0)" : : "r"(addr), "r"(val) : "memory");
+}
+#endif
+
+/* read with I/O memory barrier */
+
+static __rte_always_inline uint8_t
+rte_read8(const volatile void *addr)
+{
+	uint8_t val = rte_read8_relaxed(addr);
+	rte_io_rmb();
+	return val;
+}
+
+static __rte_always_inline uint16_t
+rte_read16(const volatile void *addr)
+{
+	uint16_t val = rte_read16_relaxed(addr);
+	rte_io_rmb();
+	return val;
+}
+
+static __rte_always_inline uint32_t
+rte_read32(const volatile void *addr)
+{
+	uint32_t val = rte_read32_relaxed(addr);
+	rte_io_rmb();
+	return val;
+}
+
+#ifdef RTE_ARCH_64
+static __rte_always_inline uint64_t
+rte_read64(const volatile void *addr)
+{
+	uint64_t val = rte_read64_relaxed(addr);
+	rte_io_rmb();
+	return val;
+}
+#endif
+
+/* write with I/O memory barrier */
+
+static __rte_always_inline void
+rte_write8(uint8_t val, volatile void *addr)
+{
+	rte_io_wmb();
+	rte_write8_relaxed(val, addr);
+}
+
+static __rte_always_inline void
+rte_write16(uint16_t val, volatile void *addr)
+{
+	rte_io_wmb();
+	rte_write16_relaxed(val, addr);
+}
+
+static __rte_always_inline void
+rte_write32(uint32_t val, volatile void *addr)
+{
+	rte_io_wmb();
+	rte_write32_relaxed(val, addr);
+}
+
+#ifdef RTE_ARCH_64
+static __rte_always_inline void
+rte_write64(uint64_t val, volatile void *addr)
+{
+	rte_io_wmb();
+	rte_write64_relaxed(val, addr);
+}
+#endif
+
+/*
+ * RISC-V currently has no write-combining store instructions.
+ * Fall back to normal write.
+ */
+__rte_experimental
+static __rte_always_inline void
+rte_write32_wc(uint32_t val, volatile void *addr)
+{
+	rte_write32(val, addr);
+}
+
+__rte_experimental
+static __rte_always_inline void
+rte_write32_wc_relaxed(uint32_t val, volatile void *addr)
+{
+	rte_write32_relaxed(val, addr);
+}
+
+#ifdef __cplusplus
+}
+#endif
 
-#endif /* RTE_IO_RISCV_H */
+#endif /* _RTE_IO_RISCV_H_ */
-- 
2.43.0


             reply	other threads:[~2026-03-13 14:08 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-13 14:08 dangshiwei [this message]
2026-03-28 13:43 ` [PATCH] eal/riscv: add RISC-V specific I/O device memory operations sunyuechi
2026-03-28 18:54 ` [PATCH v2 2/3] " dangshiwei

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260313140836.3847-1-1138222970gg@gmail.com \
    --to=1138222970gg@gmail.com \
    --cc=dev@dpdk.org \
    --cc=stanislaw.kardach@gmail.com \
    --cc=sunyuechi@iscas.ac.cn \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox