qemu-riscv
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ RFC 5/6] hw/riscv: virt: Add PMU device tree node to support SBI PMU e


From: Atish Patra
Subject: [ RFC 5/6] hw/riscv: virt: Add PMU device tree node to support SBI PMU extension
Date: Fri, 19 Mar 2021 12:45:33 -0700

Qemu can't really support any PMU events other than cycle & instructions
counters. Add a PMU device tree node only for these events based on device
tree bindings defined in OpenSBI

Signed-off-by: Atish Patra <atish.patra@wdc.com>
---
 hw/riscv/virt.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 4f0c2fbca071..84570ad6425b 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -42,6 +42,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/pci/pci.h"
 #include "hw/pci-host/gpex.h"
+#include <libfdt.h>
 
 static const MemMapEntry virt_memmap[] = {
     [VIRT_DEBUG] =       {        0x0,         0x100 },
@@ -180,7 +181,7 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry 
*memmap,
                        uint64_t mem_size, const char *cmdline, bool is_32_bit)
 {
     void *fdt;
-    int i, cpu, socket;
+    int i, cpu, socket, rc;
     MachineState *mc = MACHINE(s);
     uint64_t addr, size;
     uint32_t *clint_cells, *plic_cells;
@@ -190,9 +191,10 @@ static void create_fdt(RISCVVirtState *s, const 
MemMapEntry *memmap,
     uint32_t phandle = 1, plic_mmio_phandle = 1;
     uint32_t plic_pcie_phandle = 1, plic_virtio_phandle = 1;
     char *mem_name, *cpu_name, *core_name, *intc_name;
-    char *name, *clint_name, *plic_name, *clust_name;
+    char *name, *clint_name, *plic_name, *clust_name, *pmu_name;
     hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2;
     hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
+    uint32_t pmu_event_ctr_map[6] = {};
 
     if (mc->dtb) {
         fdt = s->fdt = load_device_tree(mc->dtb, &s->fdt_size);
@@ -284,6 +286,22 @@ static void create_fdt(RISCVVirtState *s, const 
MemMapEntry *memmap,
             g_free(cpu_name);
         }
 
+        rc = fdt_path_offset(fdt, "/pmu");
+        if (rc == -FDT_ERR_NOTFOUND) {
+                pmu_name = g_strdup_printf("/pmu");
+                qemu_fdt_add_subnode(fdt, pmu_name);
+                qemu_fdt_setprop_string(fdt, pmu_name, "compatible",
+                                        "riscv,pmu");
+                pmu_event_ctr_map[0] = cpu_to_be32(0x00000001);
+                pmu_event_ctr_map[1] = cpu_to_be32(0x00000001);
+                pmu_event_ctr_map[2] = cpu_to_be32(0x00000001);
+                pmu_event_ctr_map[3] = cpu_to_be32(0x00000002);
+                pmu_event_ctr_map[4] = cpu_to_be32(0x00000002);
+                pmu_event_ctr_map[5] = cpu_to_be32(0x00000004);
+                qemu_fdt_setprop(fdt, pmu_name, "opensbi,event-to-counters",
+                                 pmu_event_ctr_map, sizeof(pmu_event_ctr_map));
+                g_free(pmu_name);
+        }
         addr = memmap[VIRT_DRAM].base + riscv_socket_mem_offset(mc, socket);
         size = riscv_socket_mem_size(mc, socket);
         mem_name = g_strdup_printf("/memory@%lx", (long)addr);
-- 
2.25.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]