platform: generic: add CVA6 platform and support for PMU

LE RHUN Jimmy jimmy.lerhun at thalesgroup.com
Thu Dec 4 07:57:53 PST 2025


Classified as: {OPEN}

Add a new generic platform called CVA6 (https://github.com/openhwgroup/cva6).
Add support for Performance Monitoring Unit for this platform.

I hope it is in the right place this time.

Signed-off-by: Jimmy Le Rhun <jimmy.lerhun at thalesgroup.com> 

---
platform/generic/Kconfig                |   4 +
 platform/generic/configs/defconfig      |   1 +
 platform/generic/openhwgroup/cva6.c     | 185 ++++++++++++++++++++++++++++++++
 platform/generic/openhwgroup/objects.mk |   3 +
 4 files changed, 193 insertions(+)

diff --git a/platform/generic/Kconfig b/platform/generic/Kconfig index 4b9bcfc..b8adb16 100644
--- a/platform/generic/Kconfig
+++ b/platform/generic/Kconfig
@@ -43,6 +43,10 @@ config PLATFORM_ANDES_QILAI
 	select ANDES_SBI
 	default n
 
+config PLATFORM_OPENHWGROUP_CVA6
+	bool "OpenHWGroup CVA6 support"
+	default n
+
 config PLATFORM_OPENHWGROUP_OPENPITON
 	bool "OpenHWGroup Openpiton support"
 	default n
diff --git a/platform/generic/configs/defconfig b/platform/generic/configs/defconfig
index fb90bb3..f705934 100644
--- a/platform/generic/configs/defconfig
+++ b/platform/generic/configs/defconfig
@@ -9,6 +9,7 @@ CONFIG_PLATFORM_STARFIVE_JH7110=y  CONFIG_PLATFORM_THEAD=y  CONFIG_PLATFORM_MIPS_P8700=y  CONFIG_PLATFORM_OPENHWGROUP_OPENPITON=y
+CONFIG_PLATFORM_OPENHWGROUP_CVA6=y
 CONFIG_FDT_CPPC=y
 CONFIG_FDT_CPPC_RPMI=y
 CONFIG_FDT_GPIO=y
diff --git a/platform/generic/openhwgroup/cva6.c b/platform/generic/openhwgroup/cva6.c
new file mode 100644
index 0000000..bf44a50
--- /dev/null
+++ b/platform/generic/openhwgroup/cva6.c
@@ -0,0 +1,185 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (C) 2019 FORTH-ICS/CARV
+ *				Panagiotis Peristerakis <perister at ics.forth.gr>
+ * Copyright (C) 2025 Thales Research & Technology
+ *				Jimmy Le Rhun <jimmy.lerhun at thalesgroup.com>
+ */
+
+#include <platform_override.h>
+#include <sbi/sbi_console.h>
+#include <sbi/sbi_pmu.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/fdt/fdt_fixup.h>
+#include <sbi_utils/ipi/aclint_mswi.h>
+#include <sbi_utils/irqchip/plic.h>
+#include <sbi_utils/serial/uart8250.h>
+#include <sbi_utils/timer/aclint_mtimer.h>
+
+#define CVA6_UART_ADDR			0x10000000ULL
+#define CVA6_UART_FREQ			50000000
+#define CVA6_UART_BAUDRATE		115200
+#define CVA6_UART_REG_SHIFT		2
+#define CVA6_UART_REG_WIDTH		4
+#define CVA6_UART_REG_OFFSET		0
+#define CVA6_UART_CAPS			0
+#define CVA6_PLIC_ADDR			0xc000000ULL
+#define CVA6_PLIC_SIZE			(0x200000 + \
+						 (CVA6_HART_COUNT * 0x1000))
+#define CVA6_PLIC_NUM_SOURCES		3
+#define CVA6_HART_COUNT			1
+#define CVA6_CLINT_ADDR			0x2000000ULL
+#define CVA6_ACLINT_MTIMER_FREQ		1000000
+#define CVA6_ACLINT_MSWI_ADDR			(CVA6_CLINT_ADDR + \
+						 CLINT_MSWI_OFFSET)
+#define CVA6_ACLINT_MTIMER_ADDR		(CVA6_CLINT_ADDR + \
+						 CLINT_MTIMER_OFFSET)
+
+#define CVA6_PERFCOUNTER_MASK		0x000001F8	//six configurable counters
+#define CVA6_PERFEVENTS			22		//number of available events
+#define CVA6_PERFEVENTS_RANGE		0x0000001F	//five bits to encode 22 events
+
+static struct plic_data plic = {
+	.addr = (unsigned long)CVA6_PLIC_ADDR,
+	.size = CVA6_PLIC_SIZE,
+	.num_src = CVA6_PLIC_NUM_SOURCES,
+	.flags = PLIC_FLAG_ARIANE_BUG,
+	.context_map = {
+		[0] = { 0, 1 },
+	},
+};
+
+static struct aclint_mswi_data mswi = {
+	.addr = (unsigned long)CVA6_ACLINT_MSWI_ADDR,
+	.size = ACLINT_MSWI_SIZE,
+	.first_hartid = 0,
+	.hart_count = CVA6_HART_COUNT,
+};
+
+static struct aclint_mtimer_data mtimer = {
+	.mtime_freq = CVA6_ACLINT_MTIMER_FREQ,
+	.mtime_addr = (unsigned long)CVA6_ACLINT_MTIMER_ADDR +
+		      ACLINT_DEFAULT_MTIME_OFFSET,
+	.mtime_size = ACLINT_DEFAULT_MTIME_SIZE,
+	.mtimecmp_addr = (unsigned long)CVA6_ACLINT_MTIMER_ADDR +
+			 ACLINT_DEFAULT_MTIMECMP_OFFSET,
+	.mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE,
+	.first_hartid = 0,
+	.hart_count = CVA6_HART_COUNT,
+	.has_64bit_mmio = true,
+};
+
+/*
+ * Initialize the cva6 console.
+ */
+static int cva6_console_init(void)
+{
+	return uart8250_init(CVA6_UART_ADDR,
+			     CVA6_UART_FREQ,
+			     CVA6_UART_BAUDRATE,
+			     CVA6_UART_REG_SHIFT,
+			     CVA6_UART_REG_WIDTH,
+			     CVA6_UART_REG_OFFSET,
+			     CVA6_UART_CAPS);
+}
+
+/*
+ * Initialize IPI for current HART.
+ */
+static int cva6_ipi_init(void)
+{
+	return aclint_mswi_cold_init(&mswi);
+}
+
+/*
+ * CVA6 platform early initialization.
+ */
+static int cva6_early_init(bool cold_boot) {
+	int ret;
+	ret = cva6_console_init();
+	if (ret)
+		return ret;
+
+	ret = cva6_ipi_init();
+
+	return ret;
+}
+
+/*
+ * CVA6 platform final initialization.
+ */
+static int cva6_final_init(bool cold_boot) {
+	void *fdt;
+
+	if (!cold_boot)
+		return 0;
+
+	fdt = fdt_get_address_rw();
+	fdt_fixups(fdt);
+
+	return 0;
+}
+
+/*
+ * Initialize the cva6 interrupt controller for current HART.
+ */
+static int cva6_irqchip_init(void)
+{
+	return plic_cold_irqchip_init(&plic);
+}
+
+/*
+ * Initialize cva6 timer for current HART.
+ */
+static int cva6_timer_init(void)
+{
+		return aclint_mtimer_cold_init(&mtimer, NULL); }
+
+/*
+ * Performance Monitoring Unit
+ */
+static const struct sbi_pmu_device cva6_pmu_device = {
+	.name = "cva6-pmu",
+};
+
+static int cva6_pmu_init(void)
+{
+	int ret = 0;
+	sbi_pmu_set_device(&cva6_pmu_device);
+	/* All 6 assignable counters can be assigned any of 22 hardware events */
+	/* Specify raw events, from 1 to 22. */
+	for (int i=1; i<=CVA6_PERFEVENTS; i++)
+		/* select = event id; select_mask = up to 32, 5 bits; cmap = six counters, mhpm_couter3 to 8 */
+		ret |= sbi_pmu_add_raw_event_counter_map( i, CVA6_PERFEVENTS_RANGE, 
+CVA6_PERFCOUNTER_MASK);
+
+	if (ret)
+		sbi_printf("%s: sbi pmu add event failed (error %d)\n", __func__, 
+ret);
+
+	return ret;
+}
+
+static int cva6_platform_init(const void *fdt, int nodeoff, const 
+struct fdt_match *match) {
+	generic_platform_ops.early_init = cva6_early_init;
+	generic_platform_ops.timer_init = cva6_timer_init;
+	generic_platform_ops.irqchip_init = cva6_irqchip_init;
+	generic_platform_ops.final_init = cva6_final_init;
+	generic_platform_ops.pmu_init = cva6_pmu_init;
+
+	return 0;
+}
+
+/* found in 
+cva6-yocto/meta-cva6-yocto/recipes-kernel/linux/linux-yocto/0001-cva6-genesys2-add-32-and-64-bits-dts.patch */ static const struct fdt_match cva6_match[] = {
+	{ .compatible = "eth,cva6-bare-dev" },
+	{ },
+};
+
+const struct fdt_driver openhwgroup_cva6 = {
+	.match_table = cva6_match,
+	.init = cva6_platform_init,
+};
+
diff --git a/platform/generic/openhwgroup/objects.mk b/platform/generic/openhwgroup/objects.mk
index ab6ca79..94a2b3c 100644
--- a/platform/generic/openhwgroup/objects.mk
+++ b/platform/generic/openhwgroup/objects.mk
@@ -3,6 +3,9 @@
 #
 # Copyright (c) 2020 Western Digital Corporation or its affiliates.
 #
+carray-platform_override_modules-$(CONFIG_PLATFORM_OPENHWGROUP_CVA6) += 
+openhwgroup_cva6
+platform-objs-$(CONFIG_PLATFORM_OPENHWGROUP_CVA6) += openhwgroup/cva6.o
 
 carray-platform_override_modules-$(CONFIG_PLATFORM_OPENHWGROUP_OPENPITON) += openhwgroup_openpiton
 platform-objs-$(CONFIG_PLATFORM_OPENHWGROUP_OPENPITON) += openhwgroup/openpiton.o
+

{OPEN}



More information about the opensbi mailing list