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