[PATCH 3/6] riscv: andes: Implement noncached memory using SBI PMA

Leo Yu-Chi Liang ycliang at andestech.com
Thu Mar 19 09:37:10 CET 2026


Implement noncached memory region management for Andes RISC-V
platforms using SBI PMA (Physical Memory Attribute) calls:

- noncached_init(): Compute region below malloc area, probe PMA
  support via sbi_pma_probe(), then configure the region as
  non-cacheable bufferable using sbi_pma_set() with NAPOT and
  NON_CACHE_BUF flags.
- noncached_alloc(): Bump allocator from the noncached region.
- noncached_set_region(): No-op since PMA handles attributes.
- noncached_free(): Release PMA entry, with probe-before-free
  guard to avoid calling free on unsupported firmware.

Also call noncached_free() in cleanup_before_linux() before
cache_flush() so the PMA entry is released before handing off
to Linux.

Signed-off-by: Leo Yu-Chi Liang <ycliang at andestech.com>
---
 arch/riscv/cpu/andes/Makefile   |  1 +
 arch/riscv/cpu/andes/cpu.c      |  3 ++
 arch/riscv/cpu/andes/noncache.c | 79 +++++++++++++++++++++++++++++++++
 include/cpu_func.h              |  1 +
 4 files changed, 84 insertions(+)
 create mode 100644 arch/riscv/cpu/andes/noncache.c

diff --git a/arch/riscv/cpu/andes/Makefile b/arch/riscv/cpu/andes/Makefile
index 35a1a2fb836..f3602f6f598 100644
--- a/arch/riscv/cpu/andes/Makefile
+++ b/arch/riscv/cpu/andes/Makefile
@@ -6,3 +6,4 @@
 obj-y	:= cpu.o
 obj-y	+= cache.o
 obj-y	+= spl.o
+obj-$(CONFIG_SYS_HAS_NONCACHED_MEMORY) += noncache.o
diff --git a/arch/riscv/cpu/andes/cpu.c b/arch/riscv/cpu/andes/cpu.c
index feb755a4f0d..3aa89d86b6b 100644
--- a/arch/riscv/cpu/andes/cpu.c
+++ b/arch/riscv/cpu/andes/cpu.c
@@ -22,6 +22,9 @@ int cleanup_before_linux(void)
 {
 	disable_interrupts();
 
+	if (IS_ENABLED(CONFIG_SYS_HAS_NONCACHED_MEMORY))
+		noncached_free();
+
 	cache_flush();
 
 	return 0;
diff --git a/arch/riscv/cpu/andes/noncache.c b/arch/riscv/cpu/andes/noncache.c
new file mode 100644
index 00000000000..9886a757620
--- /dev/null
+++ b/arch/riscv/cpu/andes/noncache.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2026 Andes Technology Corporation
+ * Rick Chen, Andes Technology Corporation <rick at andestech.com>
+ */
+
+#include <cpu_func.h>
+#include <log.h>
+#include <malloc.h>
+#include <asm/sbi.h>
+#include <asm/system.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+static unsigned long noncached_start;
+static unsigned long noncached_end;
+static unsigned long noncached_next;
+
+void noncached_set_region(void)
+{
+}
+
+int noncached_init(void)
+{
+	phys_addr_t start, end;
+	size_t size;
+	int ret;
+
+	/* If this calculation changes, update board_f.c:reserve_noncached() */
+	end = ALIGN(mem_malloc_start, MMU_SECTION_SIZE) - MMU_SECTION_SIZE;
+	size = ALIGN(CONFIG_SYS_NONCACHED_MEMORY, MMU_SECTION_SIZE);
+	start = end - size;
+
+	debug("mapping memory %pa-%pa non-cached\n", &start, &end);
+
+	ret = sbi_pma_probe();
+	if (ret <= 0) {
+		debug("PMA probe failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = sbi_pma_set(start, size,
+			  ANDES_PMACFG_ETYP_NAPOT |
+			  ANDES_PMACFG_MTYP_MEM_NON_CACHE_BUF);
+	if (ret) {
+		debug("PMA set failed: %d\n", ret);
+		return ret;
+	}
+
+	noncached_start = start;
+	noncached_end = end;
+	noncached_next = start;
+
+	return 0;
+}
+
+phys_addr_t noncached_alloc(size_t size, size_t align)
+{
+	phys_addr_t next = ALIGN(noncached_next, align);
+
+	if (next >= noncached_end || (noncached_end - next) < size)
+		return 0;
+
+	debug("allocated %zu bytes of uncached memory @%pa\n", size, &next);
+	noncached_next = next + size;
+
+	return next;
+}
+
+void noncached_free(void)
+{
+	if (!noncached_start)
+		return;
+
+	if (sbi_pma_probe() <= 0)
+		return;
+
+	sbi_pma_free(noncached_start);
+}
diff --git a/include/cpu_func.h b/include/cpu_func.h
index 70a41ead3f7..061d497d454 100644
--- a/include/cpu_func.h
+++ b/include/cpu_func.h
@@ -100,6 +100,7 @@ int noncached_init(void);
 void noncached_set_region(void);
 
 phys_addr_t noncached_alloc(size_t size, size_t align);
+void noncached_free(void);
 
 enum {
 	/* Disable caches (else flush caches but leave them active) */
-- 
2.34.1



More information about the U-Boot mailing list