qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [ RFC 0/6] Improve PMU support
@ 2021-03-19 19:45 Atish Patra
  2021-03-19 19:45 ` [ RFC 1/6] target/riscv: Remove privilege v1.9 specific CSR related code Atish Patra
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Atish Patra @ 2021-03-19 19:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, Sagar Karandikar, Bastian Koppelmann, anup.patel,
	Atish Patra, Alistair Francis, Palmer Dabbelt

The latest version of the SBI specification includes a Performance Monitoring
Unit(PMU) extension[1] which allows the supervisor to start/stop/configure
various PMU events. This series implements basic infrastructure to support
PMU in virt machine. Qemu can support only cycle and instruction counters.
Thus, this series adds only those two events. However, it enables all
the counters and adds all the necessary checks required before accessing
a counter. This will allow us to add any other PMU events in future.

First patch in this series is just a cleanup while PATCH 2-5 adds support
for all the PMU CSR. PATCH 6 adds a DT node as per DT bindings defined in
OpenSBI[2]. PATCH 7 is just a debug patch and is not supposed to be merged.

Here is an output of perf stat while running hackbench with OpenSBI & Linux
kernel patches applied [3].

[root@fedora-riscv riscv]# perf stat -e r8000000000000007 -e r8000000000000006 \
-e r0000000000000002 -e r0000000000000004 -e branch-misses -e cache-misses \
-e cycles -e instructions ./hackbench -pipe 15 process 15

Running with 15*40 (== 600) tasks.
Time: 1.548

 Performance counter stats for './hackbench -pipe 15 process 15':

             7,103      r8000000000000007     (62.56%) --> SBI_PMU_FW_IPI_RECVD
             7,767      r8000000000000006     (12.19%) --> SBI_PMU_FW_IPI_SENT
                 0      r0000000000000002     (24.79%) --> a custom raw event described in DT
     <not counted>      r0000000000000004     (0.00%)  --> non-supported raw event described in DT
                 0      branch-misses         (12.65%) 
                 0      cache-misses          (25.36%)
    27,978,868,702      cycles                (38.12%)
    27,849,527,556      instructions          # 1.00  insn per cycle  (50.46%)

       2.431195184 seconds time elapsed

       1.553153000 seconds user
      13.615924000 seconds sys

The patches can also be found in the github[4].

[1] https://lists.riscv.org/g/tech-unixplatformspec/message/598
[2] https://github.com/atishp04/opensbi/tree/riscv_pmu_v1 
[3] https://github.com/atishp04/linux/tree/riscv_pmu_v1 
[4] https://github.com/atishp04/qemu/tree/riscv_pmu_v1 

Atish Patra (6):
target/riscv: Remove privilege v1.9 specific CSR related code
target/riscv: Implement mcountinhibit CSR
target/riscv: Support mcycle/minstret write operation
target/riscv: Add support for hpmcounters/hpmevents
hw/riscv: virt: Add PMU device tree node to support SBI PMU extension
hw/riscv: virt: DEBUG PATCH to test PMU

hw/riscv/virt.c           |  52 +++-
target/riscv/cpu.c        |   2 +-
target/riscv/cpu.h        |  21 +-
target/riscv/cpu_bits.h   |  27 +-
target/riscv/cpu_helper.c |  12 +-
target/riscv/csr.c        | 601 ++++++++++++++++++++++++++------------
target/riscv/machine.c    |  12 +-
target/riscv/translate.c  |   4 +-
8 files changed, 499 insertions(+), 232 deletions(-)

--
2.25.1



^ permalink raw reply	[flat|nested] 11+ messages in thread

* [ RFC 1/6] target/riscv: Remove privilege v1.9 specific CSR related code
  2021-03-19 19:45 [ RFC 0/6] Improve PMU support Atish Patra
@ 2021-03-19 19:45 ` Atish Patra
  2021-03-22 14:53   ` Alistair Francis
  2021-03-19 19:45 ` [ RFC 2/6] target/riscv: Implement mcountinhibit CSR Atish Patra
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Atish Patra @ 2021-03-19 19:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, Sagar Karandikar, Bastian Koppelmann, anup.patel,
	Atish Patra, Alistair Francis, Palmer Dabbelt

Qemu doesn't support RISC-V privilege specification v1.9. Remove the
remaining v1.9 specific references from the implementation.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
---
 target/riscv/cpu.c        |  2 +-
 target/riscv/cpu.h        |  4 +---
 target/riscv/cpu_bits.h   | 23 ---------------------
 target/riscv/cpu_helper.c | 12 +++++------
 target/riscv/csr.c        | 43 ++++++++++-----------------------------
 target/riscv/machine.c    |  4 +---
 target/riscv/translate.c  |  4 ++--
 7 files changed, 22 insertions(+), 70 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ddea8fbeeb39..c76e4c1a09c9 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -282,7 +282,7 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
         qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vscause ", env->vscause);
     }
     qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval ", env->mtval);
-    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "stval ", env->sbadaddr);
+    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "stval ", env->stval);
     if (riscv_has_ext(env, RVH)) {
         qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "htval ", env->htval);
         qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval2 ", env->mtval2);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0edb2826a27a..7bee351f3c99 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -163,10 +163,8 @@ struct CPURISCVState {
     target_ulong mie;
     target_ulong mideleg;
 
-    target_ulong sptbr;  /* until: priv-1.9.1 */
     target_ulong satp;   /* since: priv-1.10.0 */
-    target_ulong sbadaddr;
-    target_ulong mbadaddr;
+    target_ulong stval;
     target_ulong medeleg;
 
     target_ulong stvec;
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index caf45992070a..b42dd4f8d8b1 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -153,12 +153,6 @@
 /* 32-bit only */
 #define CSR_MSTATUSH        0x310
 
-/* Legacy Counter Setup (priv v1.9.1) */
-/* Update to #define CSR_MCOUNTINHIBIT 0x320 for 1.11.0 */
-#define CSR_MUCOUNTEREN     0x320
-#define CSR_MSCOUNTEREN     0x321
-#define CSR_MHCOUNTEREN     0x322
-
 /* Machine Trap Handling */
 #define CSR_MSCRATCH        0x340
 #define CSR_MEPC            0x341
@@ -166,9 +160,6 @@
 #define CSR_MTVAL           0x343
 #define CSR_MIP             0x344
 
-/* Legacy Machine Trap Handling (priv v1.9.1) */
-#define CSR_MBADADDR        0x343
-
 /* Supervisor Trap Setup */
 #define CSR_SSTATUS         0x100
 #define CSR_SEDELEG         0x102
@@ -184,9 +175,6 @@
 #define CSR_STVAL           0x143
 #define CSR_SIP             0x144
 
-/* Legacy Supervisor Trap Handling (priv v1.9.1) */
-#define CSR_SBADADDR        0x143
-
 /* Supervisor Protection and Translation */
 #define CSR_SPTBR           0x180
 #define CSR_SATP            0x180
@@ -354,14 +342,6 @@
 #define CSR_MHPMCOUNTER30H  0xb9e
 #define CSR_MHPMCOUNTER31H  0xb9f
 
-/* Legacy Machine Protection and Translation (priv v1.9.1) */
-#define CSR_MBASE           0x380
-#define CSR_MBOUND          0x381
-#define CSR_MIBASE          0x382
-#define CSR_MIBOUND         0x383
-#define CSR_MDBASE          0x384
-#define CSR_MDBOUND         0x385
-
 /* mstatus CSR bits */
 #define MSTATUS_UIE         0x00000001
 #define MSTATUS_SIE         0x00000002
@@ -375,10 +355,8 @@
 #define MSTATUS_FS          0x00006000
 #define MSTATUS_XS          0x00018000
 #define MSTATUS_MPRV        0x00020000
-#define MSTATUS_PUM         0x00040000 /* until: priv-1.9.1 */
 #define MSTATUS_SUM         0x00040000 /* since: priv-1.10 */
 #define MSTATUS_MXR         0x00080000
-#define MSTATUS_VM          0x1F000000 /* until: priv-1.9.1 */
 #define MSTATUS_TVM         0x00100000 /* since: priv-1.10 */
 #define MSTATUS_TW          0x00200000 /* since: priv-1.10 */
 #define MSTATUS_TSR         0x00400000 /* since: priv-1.10 */
@@ -416,7 +394,6 @@
 #define SSTATUS_SPP         0x00000100
 #define SSTATUS_FS          0x00006000
 #define SSTATUS_XS          0x00018000
-#define SSTATUS_PUM         0x00040000 /* until: priv-1.9.1 */
 #define SSTATUS_SUM         0x00040000 /* since: priv-1.10 */
 #define SSTATUS_MXR         0x00080000
 
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 2f43939fb6d4..bb0a709c9cab 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -136,8 +136,8 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
         env->vscause = env->scause;
         env->scause = env->scause_hs;
 
-        env->vstval = env->sbadaddr;
-        env->sbadaddr = env->stval_hs;
+        env->vstval = env->stval;
+        env->stval = env->stval_hs;
 
         env->vsatp = env->satp;
         env->satp = env->satp_hs;
@@ -159,8 +159,8 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
         env->scause_hs = env->scause;
         env->scause = env->vscause;
 
-        env->stval_hs = env->sbadaddr;
-        env->sbadaddr = env->vstval;
+        env->stval_hs = env->stval;
+        env->stval = env->vstval;
 
         env->satp_hs = env->satp;
         env->satp = env->vsatp;
@@ -972,7 +972,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
         env->mstatus = s;
         env->scause = cause | ((target_ulong)async << (TARGET_LONG_BITS - 1));
         env->sepc = env->pc;
-        env->sbadaddr = tval;
+        env->stval = tval;
         env->htval = htval;
         env->pc = (env->stvec >> 2 << 2) +
             ((async && (env->stvec & 3) == 1) ? cause * 4 : 0);
@@ -1003,7 +1003,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
         env->mstatus = s;
         env->mcause = cause | ~(((target_ulong)-1) >> async);
         env->mepc = env->pc;
-        env->mbadaddr = tval;
+        env->mtval = tval;
         env->mtval2 = mtval2;
         env->pc = (env->mtvec >> 2 << 2) +
             ((async && (env->mtvec & 3) == 1) ? cause * 4 : 0);
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index fd2e6363f397..7166f8d710a8 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -643,26 +643,6 @@ static int write_mcounteren(CPURISCVState *env, int csrno, target_ulong val)
     return 0;
 }
 
-/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
-static int read_mscounteren(CPURISCVState *env, int csrno, target_ulong *val)
-{
-    if (env->priv_ver < PRIV_VERSION_1_11_0) {
-        return -RISCV_EXCP_ILLEGAL_INST;
-    }
-    *val = env->mcounteren;
-    return 0;
-}
-
-/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
-static int write_mscounteren(CPURISCVState *env, int csrno, target_ulong val)
-{
-    if (env->priv_ver < PRIV_VERSION_1_11_0) {
-        return -RISCV_EXCP_ILLEGAL_INST;
-    }
-    env->mcounteren = val;
-    return 0;
-}
-
 /* Machine Trap Handling */
 static int read_mscratch(CPURISCVState *env, int csrno, target_ulong *val)
 {
@@ -700,15 +680,15 @@ static int write_mcause(CPURISCVState *env, int csrno, target_ulong val)
     return 0;
 }
 
-static int read_mbadaddr(CPURISCVState *env, int csrno, target_ulong *val)
+static int read_mtval(CPURISCVState *env, int csrno, target_ulong *val)
 {
-    *val = env->mbadaddr;
+    *val = env->mtval;
     return 0;
 }
 
-static int write_mbadaddr(CPURISCVState *env, int csrno, target_ulong val)
+static int write_mtval(CPURISCVState *env, int csrno, target_ulong val)
 {
-    env->mbadaddr = val;
+    env->mtval = val;
     return 0;
 }
 
@@ -840,18 +820,19 @@ static int write_scause(CPURISCVState *env, int csrno, target_ulong val)
     return 0;
 }
 
-static int read_sbadaddr(CPURISCVState *env, int csrno, target_ulong *val)
+static int read_stval(CPURISCVState *env, int csrno, target_ulong *val)
 {
-    *val = env->sbadaddr;
+    *val = env->stval;
     return 0;
 }
 
-static int write_sbadaddr(CPURISCVState *env, int csrno, target_ulong val)
+static int write_stval(CPURISCVState *env, int csrno, target_ulong val)
 {
-    env->sbadaddr = val;
+    env->stval = val;
     return 0;
 }
 
+
 static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
                    target_ulong new_value, target_ulong write_mask)
 {
@@ -1418,13 +1399,11 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 
     [CSR_MSTATUSH]    = { "mstatush",   any32, read_mstatush,    write_mstatush    },
 
-    [CSR_MSCOUNTEREN] = { "msounteren", any,   read_mscounteren, write_mscounteren },
-
     /* Machine Trap Handling */
     [CSR_MSCRATCH] = { "mscratch", any,  read_mscratch, write_mscratch },
     [CSR_MEPC]     = { "mepc",     any,  read_mepc,     write_mepc     },
     [CSR_MCAUSE]   = { "mcause",   any,  read_mcause,   write_mcause   },
-    [CSR_MBADADDR] = { "mbadaddr", any,  read_mbadaddr, write_mbadaddr },
+    [CSR_MTVAL]    = { "mtval",    any,  read_mtval,    write_mtval    },
     [CSR_MIP]      = { "mip",      any,  NULL,    NULL, rmw_mip        },
 
     /* Supervisor Trap Setup */
@@ -1437,7 +1416,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
     [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch },
     [CSR_SEPC]     = { "sepc",     smode, read_sepc,     write_sepc     },
     [CSR_SCAUSE]   = { "scause",   smode, read_scause,   write_scause   },
-    [CSR_SBADADDR] = { "sbadaddr", smode, read_sbadaddr, write_sbadaddr },
+    [CSR_STVAL]    = { "stval",    smode, read_stval,   write_stval   },
     [CSR_SIP]      = { "sip",      smode, NULL,    NULL, rmw_sip        },
 
     /* Supervisor Protection and Translation */
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 44d4015bd675..27fcc770aa4b 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -165,10 +165,8 @@ const VMStateDescription vmstate_riscv_cpu = {
         VMSTATE_UINT32(env.miclaim, RISCVCPU),
         VMSTATE_UINTTL(env.mie, RISCVCPU),
         VMSTATE_UINTTL(env.mideleg, RISCVCPU),
-        VMSTATE_UINTTL(env.sptbr, RISCVCPU),
         VMSTATE_UINTTL(env.satp, RISCVCPU),
-        VMSTATE_UINTTL(env.sbadaddr, RISCVCPU),
-        VMSTATE_UINTTL(env.mbadaddr, RISCVCPU),
+        VMSTATE_UINTTL(env.stval, RISCVCPU),
         VMSTATE_UINTTL(env.medeleg, RISCVCPU),
         VMSTATE_UINTTL(env.stvec, RISCVCPU),
         VMSTATE_UINTTL(env.sepc, RISCVCPU),
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 0f28b5f41e4f..1740be3d4bd9 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -130,7 +130,7 @@ static void generate_exception(DisasContext *ctx, int excp)
     ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void generate_exception_mbadaddr(DisasContext *ctx, int excp)
+static void generate_exception_mtval(DisasContext *ctx, int excp)
 {
     tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
     tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
@@ -174,7 +174,7 @@ static void gen_exception_illegal(DisasContext *ctx)
 
 static void gen_exception_inst_addr_mis(DisasContext *ctx)
 {
-    generate_exception_mbadaddr(ctx, RISCV_EXCP_INST_ADDR_MIS);
+    generate_exception_mtval(ctx, RISCV_EXCP_INST_ADDR_MIS);
 }
 
 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [ RFC 2/6] target/riscv: Implement mcountinhibit CSR
  2021-03-19 19:45 [ RFC 0/6] Improve PMU support Atish Patra
  2021-03-19 19:45 ` [ RFC 1/6] target/riscv: Remove privilege v1.9 specific CSR related code Atish Patra
@ 2021-03-19 19:45 ` Atish Patra
  2021-03-31 15:29   ` Alistair Francis
  2021-03-19 19:45 ` [ RFC 3/6] target/riscv: Support mcycle/minstret write operation Atish Patra
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Atish Patra @ 2021-03-19 19:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, Sagar Karandikar, Bastian Koppelmann, anup.patel,
	Atish Patra, Alistair Francis, Palmer Dabbelt

As per the privilege specification v1.11, mcountinhibit allows to start/stop
a pmu counter selectively.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
---
 target/riscv/cpu.h      |  2 ++
 target/riscv/cpu_bits.h |  4 ++++
 target/riscv/csr.c      | 23 +++++++++++++++++++++++
 target/riscv/machine.c  |  1 +
 4 files changed, 30 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7bee351f3c99..ef2a7fdc3980 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -214,6 +214,8 @@ struct CPURISCVState {
     target_ulong scounteren;
     target_ulong mcounteren;
 
+    target_ulong mcountinhibit;
+
     target_ulong sscratch;
     target_ulong mscratch;
 
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index b42dd4f8d8b1..7514d611cd0b 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -283,6 +283,10 @@
 #define CSR_MHPMCOUNTER29   0xb1d
 #define CSR_MHPMCOUNTER30   0xb1e
 #define CSR_MHPMCOUNTER31   0xb1f
+
+/* Machine counter-inhibit register */
+#define CSR_MCOUNTINHIBIT   0x320
+
 #define CSR_MHPMEVENT3      0x323
 #define CSR_MHPMEVENT4      0x324
 #define CSR_MHPMEVENT5      0x325
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 7166f8d710a8..b9d795389532 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -631,6 +631,26 @@ static int write_mtvec(CPURISCVState *env, int csrno, target_ulong val)
     return 0;
 }
 
+static int read_mcountinhibit(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    if (env->priv_ver < PRIV_VERSION_1_11_0) {
+        return -RISCV_EXCP_ILLEGAL_INST;
+    }
+
+    *val = env->mcountinhibit;
+    return 0;
+}
+
+static int write_mcountinhibit(CPURISCVState *env, int csrno, target_ulong val)
+{
+    if (env->priv_ver < PRIV_VERSION_1_11_0) {
+        return -RISCV_EXCP_ILLEGAL_INST;
+    }
+
+    env->mcountinhibit = val;
+    return 0;
+}
+
 static int read_mcounteren(CPURISCVState *env, int csrno, target_ulong *val)
 {
     *val = env->mcounteren;
@@ -1533,6 +1553,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
     [CSR_MHPMCOUNTER30]  = { "mhpmcounter30",  any,    read_zero },
     [CSR_MHPMCOUNTER31]  = { "mhpmcounter31",  any,    read_zero },
 
+    [CSR_MCOUNTINHIBIT]  = { "mcountinhibi",   any,    read_mcountinhibit,
+                                                       write_mcountinhibit },
+
     [CSR_MHPMEVENT3]     = { "mhpmevent3",     any,    read_zero },
     [CSR_MHPMEVENT4]     = { "mhpmevent4",     any,    read_zero },
     [CSR_MHPMEVENT5]     = { "mhpmevent5",     any,    read_zero },
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 27fcc770aa4b..cb7ec8a4c656 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -177,6 +177,7 @@ const VMStateDescription vmstate_riscv_cpu = {
         VMSTATE_UINTTL(env.mtval, RISCVCPU),
         VMSTATE_UINTTL(env.scounteren, RISCVCPU),
         VMSTATE_UINTTL(env.mcounteren, RISCVCPU),
+        VMSTATE_UINTTL(env.mcountinhibit, RISCVCPU),
         VMSTATE_UINTTL(env.sscratch, RISCVCPU),
         VMSTATE_UINTTL(env.mscratch, RISCVCPU),
         VMSTATE_UINT64(env.mfromhost, RISCVCPU),
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [ RFC 3/6] target/riscv: Support mcycle/minstret write operation
  2021-03-19 19:45 [ RFC 0/6] Improve PMU support Atish Patra
  2021-03-19 19:45 ` [ RFC 1/6] target/riscv: Remove privilege v1.9 specific CSR related code Atish Patra
  2021-03-19 19:45 ` [ RFC 2/6] target/riscv: Implement mcountinhibit CSR Atish Patra
@ 2021-03-19 19:45 ` Atish Patra
  2021-04-07 17:34   ` Alistair Francis
  2021-03-19 19:45 ` [ RFC 4/6] target/riscv: Add support for hpmcounters/hpmevents Atish Patra
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Atish Patra @ 2021-03-19 19:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, Sagar Karandikar, Bastian Koppelmann, anup.patel,
	Atish Patra, Alistair Francis, Palmer Dabbelt

mcycle/minstret are actually WARL registers and can be written with any
given value. With SBI PMU extension, it will be used to store a initial
value provided from supervisor OS. The Qemu also need prohibit the counter
increment if mcountinhibit is set.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
---
 target/riscv/cpu.h     |   8 +++
 target/riscv/csr.c     | 111 ++++++++++++++++++++++++++++++++++-------
 target/riscv/machine.c |   4 ++
 3 files changed, 105 insertions(+), 18 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index ef2a7fdc3980..47d6caeb7354 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -216,6 +216,14 @@ struct CPURISCVState {
 
     target_ulong mcountinhibit;
 
+    /* Snapshot values for mcycle & minstret */
+    target_ulong mcycle_prev;
+    target_ulong minstret_prev;
+
+    /* for RV32 */
+    target_ulong mcycleh_prev;
+    target_ulong minstreth_prev;
+
     target_ulong sscratch;
     target_ulong mscratch;
 
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index b9d795389532..61036649b044 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -319,31 +319,106 @@ static int write_vstart(CPURISCVState *env, int csrno, target_ulong val)
 }
 
 /* User Timers and Counters */
-static int read_instret(CPURISCVState *env, int csrno, target_ulong *val)
+
+static target_ulong get_icount_ticks(bool brv32)
 {
+    int64_t val;
+    target_ulong result;
+
 #if !defined(CONFIG_USER_ONLY)
     if (icount_enabled()) {
-        *val = icount_get();
+        val = icount_get();
     } else {
-        *val = cpu_get_host_ticks();
+        val = cpu_get_host_ticks();
     }
 #else
-    *val = cpu_get_host_ticks();
+    val = cpu_get_host_ticks();
 #endif
+
+    if (brv32) {
+        result = val >> 32;
+    } else {
+        result = val;
+    }
+
+    return result;
+}
+
+static int read_cycle(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    if (get_field(env->mcountinhibit, HCOUNTEREN_CY)) {
+        /**
+         * Counter should not increment if inhibit bit is set. We can't really
+         * stop the icount counting. Just return the previous value to indicate
+         * that counter was not incremented.
+         */
+        *val = env->mcycle_prev;
+        return 0;
+    }
+
+    *val = get_icount_ticks(false);
+
+    if (*val > env->mcycle_prev)
+        *val = *val - env->mcycle_prev + env->mphmcounter_val[0];
+    else
+        /* Overflow scenario */
+        *val = UINT64_MAX - env->mcycle_prev + 1 + env->mphmcounter_val[0] + *val;
+
+    return 0;
+}
+
+static int read_instret(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    if (get_field(env->mcountinhibit, HCOUNTEREN_IR)) {
+        *val = env->minstret_prev;
+        return 0;
+    }
+
+    *val = get_icount_ticks(false);
+
+    if (*val > env->minstret_prev)
+        *val = *val - env->minstret_prev + env->mphmcounter_val[2];
+    else
+        /* Overflow scenario */
+        *val = UINT64_MAX - env->minstret_prev + 1 + env->mphmcounter_val[2] + *val;
+
+    return 0;
+}
+
+static int read_cycleh(CPURISCVState *env, int csrno, target_ulong *val)
+{
+
+    if (get_field(env->mcountinhibit, HCOUNTEREN_CY)) {
+        *val = env->mcycleh_prev;
+        return 0;
+    }
+
+    *val = get_icount_ticks(true);
+
+    if (*val > env->mcycleh_prev)
+        *val = *val - env->mcycleh_prev + env->mphmcounterh_val[0];
+    else
+        /* Overflow scenario */
+        *val = UINT32_MAX - env->mcycleh_prev + 1 + env->mphmcounterh_val[0] + *val;
+
     return 0;
 }
 
 static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val)
 {
-#if !defined(CONFIG_USER_ONLY)
-    if (icount_enabled()) {
-        *val = icount_get() >> 32;
-    } else {
-        *val = cpu_get_host_ticks() >> 32;
+    if (get_field(env->mcountinhibit, HCOUNTEREN_IR)) {
+        *val = env->minstreth_prev;
+        return 0;
     }
-#else
-    *val = cpu_get_host_ticks() >> 32;
-#endif
+
+    *val = get_icount_ticks(true);
+
+    if (*val > env->minstreth_prev)
+        *val = *val - env->minstreth_prev + env->mphmcounterh_val[2];
+    else
+        /* Overflow scenario */
+        *val = UINT32_MAX - env->minstreth_prev + 1 + env->mphmcounterh_val[2] + *val;
+
     return 0;
 }
 
@@ -1383,9 +1458,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
     [CSR_VL]       = { "vl",       vs,     read_vl                    },
     [CSR_VTYPE]    = { "vtype",    vs,     read_vtype                 },
     /* User Timers and Counters */
-    [CSR_CYCLE]    = { "cycle",    ctr,    read_instret  },
+    [CSR_CYCLE]    = { "cycle",    ctr,    read_cycle  },
     [CSR_INSTRET]  = { "instret",  ctr,    read_instret  },
-    [CSR_CYCLEH]   = { "cycleh",   ctr32,  read_instreth },
+    [CSR_CYCLEH]   = { "cycleh",   ctr32,  read_cycleh },
     [CSR_INSTRETH] = { "instreth", ctr32,  read_instreth },
 
     /*
@@ -1397,10 +1472,10 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 
 #if !defined(CONFIG_USER_ONLY)
     /* Machine Timers and Counters */
-    [CSR_MCYCLE]    = { "mcycle",    any,   read_instret  },
-    [CSR_MINSTRET]  = { "minstret",  any,   read_instret  },
-    [CSR_MCYCLEH]   = { "mcycleh",   any32, read_instreth },
-    [CSR_MINSTRETH] = { "minstreth", any32, read_instreth },
+    [CSR_MCYCLE]    = { "mcycle",    any,   read_cycle  , write_mhpmcounter},
+    [CSR_MINSTRET]  = { "minstret",  any,   read_instret, write_mhpmcounter},
+    [CSR_MCYCLEH]   = { "mcycleh",   any32, read_cycleh , write_mhpmcounterh},
+    [CSR_MINSTRETH] = { "minstreth", any32, read_instreth , write_mhpmcounterh},
 
     /* Machine Information Registers */
     [CSR_MVENDORID] = { "mvendorid", any,   read_zero    },
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index cb7ec8a4c656..b1410419cc1f 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -178,6 +178,10 @@ const VMStateDescription vmstate_riscv_cpu = {
         VMSTATE_UINTTL(env.scounteren, RISCVCPU),
         VMSTATE_UINTTL(env.mcounteren, RISCVCPU),
         VMSTATE_UINTTL(env.mcountinhibit, RISCVCPU),
+        VMSTATE_UINTTL(env.mcycle_prev, RISCVCPU),
+        VMSTATE_UINTTL(env.mcycleh_prev, RISCVCPU),
+        VMSTATE_UINTTL(env.minstret_prev, RISCVCPU),
+        VMSTATE_UINTTL(env.minstreth_prev, RISCVCPU),
         VMSTATE_UINTTL(env.sscratch, RISCVCPU),
         VMSTATE_UINTTL(env.mscratch, RISCVCPU),
         VMSTATE_UINT64(env.mfromhost, RISCVCPU),
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [ RFC 4/6] target/riscv: Add support for hpmcounters/hpmevents
  2021-03-19 19:45 [ RFC 0/6] Improve PMU support Atish Patra
                   ` (2 preceding siblings ...)
  2021-03-19 19:45 ` [ RFC 3/6] target/riscv: Support mcycle/minstret write operation Atish Patra
@ 2021-03-19 19:45 ` Atish Patra
  2021-04-07 17:34   ` Alistair Francis
  2021-03-19 19:45 ` [ RFC 5/6] hw/riscv: virt: Add PMU device tree node to support SBI PMU extension Atish Patra
  2021-03-19 19:45 ` [ RFC 6/6] hw/riscv: virt: DEBUG PATCH to test PMU Atish Patra
  5 siblings, 1 reply; 11+ messages in thread
From: Atish Patra @ 2021-03-19 19:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, Sagar Karandikar, Bastian Koppelmann, anup.patel,
	Atish Patra, Alistair Francis, Palmer Dabbelt

With SBI PMU extension, user can use any of the available hpmcounters to
track any perf events based on the value written to mhpmevent csr.
Add read/write functionality for these csrs.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
---
 target/riscv/cpu.h     |   7 +
 target/riscv/csr.c     | 444 +++++++++++++++++++++++++++--------------
 target/riscv/machine.c |   3 +
 3 files changed, 302 insertions(+), 152 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 47d6caeb7354..0a2b6da78110 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -220,9 +220,16 @@ struct CPURISCVState {
     target_ulong mcycle_prev;
     target_ulong minstret_prev;
 
+    /* PMU counter configured values */
+    target_ulong mphmcounter_val[32];
+
     /* for RV32 */
     target_ulong mcycleh_prev;
     target_ulong minstreth_prev;
+    target_ulong mphmcounterh_val[32];
+
+    /* PMU event selector configured values */
+    target_ulong mphmevent_val[29];
 
     target_ulong sscratch;
     target_ulong mscratch;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 61036649b044..a0430bbbd145 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -422,6 +422,88 @@ static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val)
     return 0;
 }
 
+static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    int evt_index = csrno - CSR_MHPMEVENT3;
+
+    *val = env->mphmcounter_val[evt_index];
+
+    return 0;
+}
+
+static int write_mhpmevent(CPURISCVState *env, int csrno, target_ulong val)
+{
+    int evt_index = csrno - CSR_MHPMEVENT3;
+
+    env->mphmevent_val[evt_index] = val;
+
+    return 0;
+}
+
+static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val)
+{
+    int ctr_index = csrno - CSR_MHPMCOUNTER3 + 3;
+
+    if (csrno == CSR_MCYCLE) {
+        env->mphmcounter_val[0] = val;
+        env->mcycle_prev = get_icount_ticks(false);
+     } else if (csrno == CSR_MINSTRET) {
+        env->mphmcounter_val[2] = val;
+        env->minstret_prev = get_icount_ticks(false);
+    } else {
+        env->mphmcounter_val[ctr_index] = val;
+    }
+
+    return 0;
+}
+
+static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val)
+{
+    int ctr_index = csrno - CSR_MHPMCOUNTER3 + 3;
+
+    if (csrno == CSR_MCYCLEH) {
+        env->mphmcounterh_val[0] = val;
+        env->mcycleh_prev = get_icount_ticks(true);
+    } else if (csrno == CSR_MINSTRETH) {
+        env->mphmcounterh_val[2] = val;
+        env->minstreth_prev = get_icount_ticks(true);
+    } else {
+        env->mphmcounterh_val[ctr_index] = val;
+    }
+
+    return 0;
+}
+
+static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    int ctr_index;
+
+    if (env->priv == PRV_M) {
+        ctr_index = csrno - CSR_MHPMCOUNTER3 + 3;
+    } else {
+        ctr_index = csrno - CSR_HPMCOUNTER3 + 3;
+    }
+    *val = env->mphmcounter_val[ctr_index];
+
+    return 0;
+}
+
+static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    int ctr_index;
+
+    if (env->priv == PRV_M) {
+        ctr_index = csrno - CSR_MHPMCOUNTER3 + 3;
+    } else {
+        ctr_index = csrno - CSR_HPMCOUNTER3 + 3;
+    }
+
+    *val = env->mphmcounterh_val[ctr_index];
+
+    return 0;
+}
+
+
 #if defined(CONFIG_USER_ONLY)
 static int read_time(CPURISCVState *env, int csrno, target_ulong *val)
 {
@@ -1568,157 +1650,215 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
     [CSR_PMPADDR15] =  { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
 
     /* Performance Counters */
-    [CSR_HPMCOUNTER3]    = { "hpmcounter3",    ctr,    read_zero },
-    [CSR_HPMCOUNTER4]    = { "hpmcounter4",    ctr,    read_zero },
-    [CSR_HPMCOUNTER5]    = { "hpmcounter5",    ctr,    read_zero },
-    [CSR_HPMCOUNTER6]    = { "hpmcounter6",    ctr,    read_zero },
-    [CSR_HPMCOUNTER7]    = { "hpmcounter7",    ctr,    read_zero },
-    [CSR_HPMCOUNTER8]    = { "hpmcounter8",    ctr,    read_zero },
-    [CSR_HPMCOUNTER9]    = { "hpmcounter9",    ctr,    read_zero },
-    [CSR_HPMCOUNTER10]   = { "hpmcounter10",   ctr,    read_zero },
-    [CSR_HPMCOUNTER11]   = { "hpmcounter11",   ctr,    read_zero },
-    [CSR_HPMCOUNTER12]   = { "hpmcounter12",   ctr,    read_zero },
-    [CSR_HPMCOUNTER13]   = { "hpmcounter13",   ctr,    read_zero },
-    [CSR_HPMCOUNTER14]   = { "hpmcounter14",   ctr,    read_zero },
-    [CSR_HPMCOUNTER15]   = { "hpmcounter15",   ctr,    read_zero },
-    [CSR_HPMCOUNTER16]   = { "hpmcounter16",   ctr,    read_zero },
-    [CSR_HPMCOUNTER17]   = { "hpmcounter17",   ctr,    read_zero },
-    [CSR_HPMCOUNTER18]   = { "hpmcounter18",   ctr,    read_zero },
-    [CSR_HPMCOUNTER19]   = { "hpmcounter19",   ctr,    read_zero },
-    [CSR_HPMCOUNTER20]   = { "hpmcounter20",   ctr,    read_zero },
-    [CSR_HPMCOUNTER21]   = { "hpmcounter21",   ctr,    read_zero },
-    [CSR_HPMCOUNTER22]   = { "hpmcounter22",   ctr,    read_zero },
-    [CSR_HPMCOUNTER23]   = { "hpmcounter23",   ctr,    read_zero },
-    [CSR_HPMCOUNTER24]   = { "hpmcounter24",   ctr,    read_zero },
-    [CSR_HPMCOUNTER25]   = { "hpmcounter25",   ctr,    read_zero },
-    [CSR_HPMCOUNTER26]   = { "hpmcounter26",   ctr,    read_zero },
-    [CSR_HPMCOUNTER27]   = { "hpmcounter27",   ctr,    read_zero },
-    [CSR_HPMCOUNTER28]   = { "hpmcounter28",   ctr,    read_zero },
-    [CSR_HPMCOUNTER29]   = { "hpmcounter29",   ctr,    read_zero },
-    [CSR_HPMCOUNTER30]   = { "hpmcounter30",   ctr,    read_zero },
-    [CSR_HPMCOUNTER31]   = { "hpmcounter31",   ctr,    read_zero },
-
-    [CSR_MHPMCOUNTER3]   = { "mhpmcounter3",   any,    read_zero },
-    [CSR_MHPMCOUNTER4]   = { "mhpmcounter4",   any,    read_zero },
-    [CSR_MHPMCOUNTER5]   = { "mhpmcounter5",   any,    read_zero },
-    [CSR_MHPMCOUNTER6]   = { "mhpmcounter6",   any,    read_zero },
-    [CSR_MHPMCOUNTER7]   = { "mhpmcounter7",   any,    read_zero },
-    [CSR_MHPMCOUNTER8]   = { "mhpmcounter8",   any,    read_zero },
-    [CSR_MHPMCOUNTER9]   = { "mhpmcounter9",   any,    read_zero },
-    [CSR_MHPMCOUNTER10]  = { "mhpmcounter10",  any,    read_zero },
-    [CSR_MHPMCOUNTER11]  = { "mhpmcounter11",  any,    read_zero },
-    [CSR_MHPMCOUNTER12]  = { "mhpmcounter12",  any,    read_zero },
-    [CSR_MHPMCOUNTER13]  = { "mhpmcounter13",  any,    read_zero },
-    [CSR_MHPMCOUNTER14]  = { "mhpmcounter14",  any,    read_zero },
-    [CSR_MHPMCOUNTER15]  = { "mhpmcounter15",  any,    read_zero },
-    [CSR_MHPMCOUNTER16]  = { "mhpmcounter16",  any,    read_zero },
-    [CSR_MHPMCOUNTER17]  = { "mhpmcounter17",  any,    read_zero },
-    [CSR_MHPMCOUNTER18]  = { "mhpmcounter18",  any,    read_zero },
-    [CSR_MHPMCOUNTER19]  = { "mhpmcounter19",  any,    read_zero },
-    [CSR_MHPMCOUNTER20]  = { "mhpmcounter20",  any,    read_zero },
-    [CSR_MHPMCOUNTER21]  = { "mhpmcounter21",  any,    read_zero },
-    [CSR_MHPMCOUNTER22]  = { "mhpmcounter22",  any,    read_zero },
-    [CSR_MHPMCOUNTER23]  = { "mhpmcounter23",  any,    read_zero },
-    [CSR_MHPMCOUNTER24]  = { "mhpmcounter24",  any,    read_zero },
-    [CSR_MHPMCOUNTER25]  = { "mhpmcounter25",  any,    read_zero },
-    [CSR_MHPMCOUNTER26]  = { "mhpmcounter26",  any,    read_zero },
-    [CSR_MHPMCOUNTER27]  = { "mhpmcounter27",  any,    read_zero },
-    [CSR_MHPMCOUNTER28]  = { "mhpmcounter28",  any,    read_zero },
-    [CSR_MHPMCOUNTER29]  = { "mhpmcounter29",  any,    read_zero },
-    [CSR_MHPMCOUNTER30]  = { "mhpmcounter30",  any,    read_zero },
-    [CSR_MHPMCOUNTER31]  = { "mhpmcounter31",  any,    read_zero },
-
-    [CSR_MCOUNTINHIBIT]  = { "mcountinhibi",   any,    read_mcountinhibit,
-                                                       write_mcountinhibit },
-
-    [CSR_MHPMEVENT3]     = { "mhpmevent3",     any,    read_zero },
-    [CSR_MHPMEVENT4]     = { "mhpmevent4",     any,    read_zero },
-    [CSR_MHPMEVENT5]     = { "mhpmevent5",     any,    read_zero },
-    [CSR_MHPMEVENT6]     = { "mhpmevent6",     any,    read_zero },
-    [CSR_MHPMEVENT7]     = { "mhpmevent7",     any,    read_zero },
-    [CSR_MHPMEVENT8]     = { "mhpmevent8",     any,    read_zero },
-    [CSR_MHPMEVENT9]     = { "mhpmevent9",     any,    read_zero },
-    [CSR_MHPMEVENT10]    = { "mhpmevent10",    any,    read_zero },
-    [CSR_MHPMEVENT11]    = { "mhpmevent11",    any,    read_zero },
-    [CSR_MHPMEVENT12]    = { "mhpmevent12",    any,    read_zero },
-    [CSR_MHPMEVENT13]    = { "mhpmevent13",    any,    read_zero },
-    [CSR_MHPMEVENT14]    = { "mhpmevent14",    any,    read_zero },
-    [CSR_MHPMEVENT15]    = { "mhpmevent15",    any,    read_zero },
-    [CSR_MHPMEVENT16]    = { "mhpmevent16",    any,    read_zero },
-    [CSR_MHPMEVENT17]    = { "mhpmevent17",    any,    read_zero },
-    [CSR_MHPMEVENT18]    = { "mhpmevent18",    any,    read_zero },
-    [CSR_MHPMEVENT19]    = { "mhpmevent19",    any,    read_zero },
-    [CSR_MHPMEVENT20]    = { "mhpmevent20",    any,    read_zero },
-    [CSR_MHPMEVENT21]    = { "mhpmevent21",    any,    read_zero },
-    [CSR_MHPMEVENT22]    = { "mhpmevent22",    any,    read_zero },
-    [CSR_MHPMEVENT23]    = { "mhpmevent23",    any,    read_zero },
-    [CSR_MHPMEVENT24]    = { "mhpmevent24",    any,    read_zero },
-    [CSR_MHPMEVENT25]    = { "mhpmevent25",    any,    read_zero },
-    [CSR_MHPMEVENT26]    = { "mhpmevent26",    any,    read_zero },
-    [CSR_MHPMEVENT27]    = { "mhpmevent27",    any,    read_zero },
-    [CSR_MHPMEVENT28]    = { "mhpmevent28",    any,    read_zero },
-    [CSR_MHPMEVENT29]    = { "mhpmevent29",    any,    read_zero },
-    [CSR_MHPMEVENT30]    = { "mhpmevent30",    any,    read_zero },
-    [CSR_MHPMEVENT31]    = { "mhpmevent31",    any,    read_zero },
-
-    [CSR_HPMCOUNTER3H]   = { "hpmcounter3h",   ctr32,  read_zero },
-    [CSR_HPMCOUNTER4H]   = { "hpmcounter4h",   ctr32,  read_zero },
-    [CSR_HPMCOUNTER5H]   = { "hpmcounter5h",   ctr32,  read_zero },
-    [CSR_HPMCOUNTER6H]   = { "hpmcounter6h",   ctr32,  read_zero },
-    [CSR_HPMCOUNTER7H]   = { "hpmcounter7h",   ctr32,  read_zero },
-    [CSR_HPMCOUNTER8H]   = { "hpmcounter8h",   ctr32,  read_zero },
-    [CSR_HPMCOUNTER9H]   = { "hpmcounter9h",   ctr32,  read_zero },
-    [CSR_HPMCOUNTER10H]  = { "hpmcounter10h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER11H]  = { "hpmcounter11h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER12H]  = { "hpmcounter12h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER13H]  = { "hpmcounter13h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER14H]  = { "hpmcounter14h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER15H]  = { "hpmcounter15h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER16H]  = { "hpmcounter16h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER17H]  = { "hpmcounter17h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER18H]  = { "hpmcounter18h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER19H]  = { "hpmcounter19h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER20H]  = { "hpmcounter20h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER21H]  = { "hpmcounter21h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER22H]  = { "hpmcounter22h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER23H]  = { "hpmcounter23h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER24H]  = { "hpmcounter24h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER25H]  = { "hpmcounter25h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER26H]  = { "hpmcounter26h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER27H]  = { "hpmcounter27h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER28H]  = { "hpmcounter28h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER29H]  = { "hpmcounter29h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER30H]  = { "hpmcounter30h",  ctr32,  read_zero },
-    [CSR_HPMCOUNTER31H]  = { "hpmcounter31h",  ctr32,  read_zero },
-
-    [CSR_MHPMCOUNTER3H]  = { "mhpmcounter3h",  any32,  read_zero },
-    [CSR_MHPMCOUNTER4H]  = { "mhpmcounter4h",  any32,  read_zero },
-    [CSR_MHPMCOUNTER5H]  = { "mhpmcounter5h",  any32,  read_zero },
-    [CSR_MHPMCOUNTER6H]  = { "mhpmcounter6h",  any32,  read_zero },
-    [CSR_MHPMCOUNTER7H]  = { "mhpmcounter7h",  any32,  read_zero },
-    [CSR_MHPMCOUNTER8H]  = { "mhpmcounter8h",  any32,  read_zero },
-    [CSR_MHPMCOUNTER9H]  = { "mhpmcounter9h",  any32,  read_zero },
-    [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", any32,  read_zero },
-    [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", any32,  read_zero },
-    [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", any32,  read_zero },
-    [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", any32,  read_zero },
-    [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", any32,  read_zero },
-    [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", any32,  read_zero },
-    [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", any32,  read_zero },
-    [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", any32,  read_zero },
-    [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", any32,  read_zero },
-    [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", any32,  read_zero },
-    [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", any32,  read_zero },
-    [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", any32,  read_zero },
-    [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", any32,  read_zero },
-    [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", any32,  read_zero },
-    [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", any32,  read_zero },
-    [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", any32,  read_zero },
-    [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", any32,  read_zero },
-    [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", any32,  read_zero },
-    [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", any32,  read_zero },
-    [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", any32,  read_zero },
-    [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", any32,  read_zero },
-    [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", any32,  read_zero },
+    [CSR_HPMCOUNTER3]    = { "hpmcounter3",    ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER4]    = { "hpmcounter4",    ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER5]    = { "hpmcounter5",    ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER6]    = { "hpmcounter6",    ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER7]    = { "hpmcounter7",    ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER8]    = { "hpmcounter8",    ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER9]    = { "hpmcounter9",    ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER10]   = { "hpmcounter10",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER11]   = { "hpmcounter11",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER12]   = { "hpmcounter12",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER13]   = { "hpmcounter13",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER14]   = { "hpmcounter14",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER15]   = { "hpmcounter15",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER16]   = { "hpmcounter16",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER17]   = { "hpmcounter17",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER18]   = { "hpmcounter18",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER19]   = { "hpmcounter19",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER20]   = { "hpmcounter20",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER21]   = { "hpmcounter21",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER22]   = { "hpmcounter22",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER23]   = { "hpmcounter23",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER24]   = { "hpmcounter24",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER25]   = { "hpmcounter25",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER26]   = { "hpmcounter26",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER27]   = { "hpmcounter27",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER28]   = { "hpmcounter28",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER29]   = { "hpmcounter29",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER30]   = { "hpmcounter30",   ctr,    read_hpmcounter },
+    [CSR_HPMCOUNTER31]   = { "hpmcounter31",   ctr,    read_hpmcounter },
+
+    [CSR_MHPMCOUNTER3]   = { "mhpmcounter3",   any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER4]   = { "mhpmcounter4",   any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER5]   = { "mhpmcounter5",   any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER6]   = { "mhpmcounter6",   any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER7]   = { "mhpmcounter7",   any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER8]   = { "mhpmcounter8",   any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER9]   = { "mhpmcounter9",   any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER10]  = { "mhpmcounter10",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER11]  = { "mhpmcounter11",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER12]  = { "mhpmcounter12",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER13]  = { "mhpmcounter13",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER14]  = { "mhpmcounter14",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER15]  = { "mhpmcounter15",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER16]  = { "mhpmcounter16",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER17]  = { "mhpmcounter17",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER18]  = { "mhpmcounter18",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER19]  = { "mhpmcounter19",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER20]  = { "mhpmcounter20",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER21]  = { "mhpmcounter21",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER22]  = { "mhpmcounter22",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER23]  = { "mhpmcounter23",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER24]  = { "mhpmcounter24",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER25]  = { "mhpmcounter25",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER26]  = { "mhpmcounter26",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER27]  = { "mhpmcounter27",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER28]  = { "mhpmcounter28",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER29]  = { "mhpmcounter29",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER30]  = { "mhpmcounter30",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+    [CSR_MHPMCOUNTER31]  = { "mhpmcounter31",  any,    read_hpmcounter,
+                                                       write_mhpmcounter },
+
+    [CSR_MCOUNTINHIBIT]  = { "mcountinhibit",  any, read_mcountinhibit,
+                                                    write_mcountinhibit },
+
+    [CSR_MHPMEVENT3]     = { "mhpmevent3",     any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT4]     = { "mhpmevent4",     any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT5]     = { "mhpmevent5",     any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT6]     = { "mhpmevent6",     any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT7]     = { "mhpmevent7",     any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT8]     = { "mhpmevent8",     any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT9]     = { "mhpmevent9",     any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT10]    = { "mhpmevent10",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT11]    = { "mhpmevent11",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT12]    = { "mhpmevent12",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT13]    = { "mhpmevent13",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT14]    = { "mhpmevent14",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT15]    = { "mhpmevent15",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT16]    = { "mhpmevent16",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT17]    = { "mhpmevent17",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT18]    = { "mhpmevent18",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT19]    = { "mhpmevent19",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT20]    = { "mhpmevent20",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT21]    = { "mhpmevent21",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT22]    = { "mhpmevent22",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT23]    = { "mhpmevent23",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT24]    = { "mhpmevent24",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT25]    = { "mhpmevent25",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT26]    = { "mhpmevent26",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT27]    = { "mhpmevent27",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT28]    = { "mhpmevent28",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT29]    = { "mhpmevent29",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT30]    = { "mhpmevent30",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+    [CSR_MHPMEVENT31]    = { "mhpmevent31",    any,    read_mhpmevent,
+                                                       write_mhpmevent },
+
+    [CSR_HPMCOUNTER3H]   = { "hpmcounter3h",   ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER4H]   = { "hpmcounter4h",   ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER5H]   = { "hpmcounter5h",   ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER6H]   = { "hpmcounter6h",   ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER7H]   = { "hpmcounter7h",   ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER8H]   = { "hpmcounter8h",   ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER9H]   = { "hpmcounter9h",   ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER10H]  = { "hpmcounter10h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER11H]  = { "hpmcounter11h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER12H]  = { "hpmcounter12h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER13H]  = { "hpmcounter13h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER14H]  = { "hpmcounter14h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER15H]  = { "hpmcounter15h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER16H]  = { "hpmcounter16h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER17H]  = { "hpmcounter17h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER18H]  = { "hpmcounter18h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER19H]  = { "hpmcounter19h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER20H]  = { "hpmcounter20h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER21H]  = { "hpmcounter21h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER22H]  = { "hpmcounter22h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER23H]  = { "hpmcounter23h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER24H]  = { "hpmcounter24h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER25H]  = { "hpmcounter25h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER26H]  = { "hpmcounter26h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER27H]  = { "hpmcounter27h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER28H]  = { "hpmcounter28h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER29H]  = { "hpmcounter29h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER30H]  = { "hpmcounter30h",  ctr32,  read_hpmcounterh },
+    [CSR_HPMCOUNTER31H]  = { "hpmcounter31h",  ctr32,  read_hpmcounterh },
+
+    [CSR_MHPMCOUNTER3H]  = { "mhpmcounter3h",  any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER4H]  = { "mhpmcounter4h",  any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER5H]  = { "mhpmcounter5h",  any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER6H]  = { "mhpmcounter6h",  any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER7H]  = { "mhpmcounter7h",  any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER8H]  = { "mhpmcounter8h",  any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER9H]  = { "mhpmcounter9h",  any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", any32,  read_hpmcounterh },
+    [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", any32,  read_hpmcounterh },
 #endif /* !CONFIG_USER_ONLY */
 };
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index b1410419cc1f..d70531402d86 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -182,6 +182,9 @@ const VMStateDescription vmstate_riscv_cpu = {
         VMSTATE_UINTTL(env.mcycleh_prev, RISCVCPU),
         VMSTATE_UINTTL(env.minstret_prev, RISCVCPU),
         VMSTATE_UINTTL(env.minstreth_prev, RISCVCPU),
+        VMSTATE_UINTTL_ARRAY(env.mphmcounter_val, RISCVCPU, 32),
+        VMSTATE_UINTTL_ARRAY(env.mphmcounterh_val, RISCVCPU, 32),
+        VMSTATE_UINTTL_ARRAY(env.mphmevent_val, RISCVCPU, 29),
         VMSTATE_UINTTL(env.sscratch, RISCVCPU),
         VMSTATE_UINTTL(env.mscratch, RISCVCPU),
         VMSTATE_UINT64(env.mfromhost, RISCVCPU),
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [ RFC 5/6] hw/riscv: virt: Add PMU device tree node to support SBI PMU extension
  2021-03-19 19:45 [ RFC 0/6] Improve PMU support Atish Patra
                   ` (3 preceding siblings ...)
  2021-03-19 19:45 ` [ RFC 4/6] target/riscv: Add support for hpmcounters/hpmevents Atish Patra
@ 2021-03-19 19:45 ` Atish Patra
  2021-03-19 19:45 ` [ RFC 6/6] hw/riscv: virt: DEBUG PATCH to test PMU Atish Patra
  5 siblings, 0 replies; 11+ messages in thread
From: Atish Patra @ 2021-03-19 19:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, Sagar Karandikar, Bastian Koppelmann, anup.patel,
	Atish Patra, Alistair Francis, Palmer Dabbelt

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



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [ RFC 6/6] hw/riscv: virt: DEBUG PATCH to test PMU
  2021-03-19 19:45 [ RFC 0/6] Improve PMU support Atish Patra
                   ` (4 preceding siblings ...)
  2021-03-19 19:45 ` [ RFC 5/6] hw/riscv: virt: Add PMU device tree node to support SBI PMU extension Atish Patra
@ 2021-03-19 19:45 ` Atish Patra
  5 siblings, 0 replies; 11+ messages in thread
From: Atish Patra @ 2021-03-19 19:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, Sagar Karandikar, Bastian Koppelmann, anup.patel,
	Atish Patra, Alistair Francis, Palmer Dabbelt

** DO NOT MERGE IT **

This is just a test patch to test various kinds of PMU events. The counters
don't actually increment as virt machine doesn't support any of the PMU
events. However, it helps to test the OpenSBI/Kernel implementation.

Please ignore this patch while merging it.

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

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 84570ad6425b..59d8325bf2a1 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -194,7 +194,9 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
     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] = {};
+    uint32_t pmu_event_map[6] = {};
+    uint32_t pmu_event_ctr_map[12] = {};
+    uint32_t pmu_raw_event_ctr_map[6] = {};
 
     if (mc->dtb) {
         fdt = s->fdt = load_device_tree(mc->dtb, &s->fdt_size);
@@ -288,18 +290,46 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
 
         rc = fdt_path_offset(fdt, "/pmu");
         if (rc == -FDT_ERR_NOTFOUND) {
+                pmu_event_map[0] = cpu_to_be32(0x00000009);
+                pmu_event_map[1] = cpu_to_be32(0x00000000);
+                pmu_event_map[2] = cpu_to_be32(0x00000200);
+                pmu_event_map[3] = cpu_to_be32(0x00010000);
+                pmu_event_map[4] = cpu_to_be32(0x00000100);
+                pmu_event_map[5] = cpu_to_be32(0x00000002);
                 pmu_name = g_strdup_printf("/pmu");
                 qemu_fdt_add_subnode(fdt, pmu_name);
                 qemu_fdt_setprop_string(fdt, pmu_name, "compatible",
                                         "riscv,pmu");
+                qemu_fdt_setprop(fdt, pmu_name, "opensbi,event-to-mhpmevent",
+                                 pmu_event_map, sizeof(pmu_event_map));
+
                 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);
+
+                pmu_event_ctr_map[6] = cpu_to_be32(0x00000003);
+                pmu_event_ctr_map[7] = cpu_to_be32(0x0000000A);
+                pmu_event_ctr_map[8] = cpu_to_be32(0x00000FF8);
+                pmu_event_ctr_map[9] = cpu_to_be32(0x00010000);
+                pmu_event_ctr_map[10] = cpu_to_be32(0x001C000);
+                pmu_event_ctr_map[11] = cpu_to_be32(0x00001F0);
+
                 qemu_fdt_setprop(fdt, pmu_name, "opensbi,event-to-counters",
-                                 pmu_event_ctr_map, sizeof(pmu_event_ctr_map));
+                             pmu_event_ctr_map, sizeof(pmu_event_ctr_map));
+
+                pmu_raw_event_ctr_map[0] = cpu_to_be32(0x00000000);
+                pmu_raw_event_ctr_map[1] = cpu_to_be32(0x00000002);
+                pmu_raw_event_ctr_map[2] = cpu_to_be32(0x00000F00);
+                pmu_raw_event_ctr_map[3] = cpu_to_be32(0x00000000);
+                pmu_raw_event_ctr_map[4] = cpu_to_be32(0x00000003);
+                pmu_raw_event_ctr_map[5] = cpu_to_be32(0x000000F0);
+                qemu_fdt_setprop(fdt, pmu_name, "opensbi,raw-event-to-counters",
+                                 pmu_raw_event_ctr_map,
+                                 sizeof(pmu_raw_event_ctr_map));
+
                 g_free(pmu_name);
         }
         addr = memmap[VIRT_DRAM].base + riscv_socket_mem_offset(mc, socket);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [ RFC 1/6] target/riscv: Remove privilege v1.9 specific CSR related code
  2021-03-19 19:45 ` [ RFC 1/6] target/riscv: Remove privilege v1.9 specific CSR related code Atish Patra
@ 2021-03-22 14:53   ` Alistair Francis
  0 siblings, 0 replies; 11+ messages in thread
From: Alistair Francis @ 2021-03-22 14:53 UTC (permalink / raw)
  To: Atish Patra
  Cc: open list:RISC-V, Sagar Karandikar, Bastian Koppelmann,
	Anup Patel, qemu-devel@nongnu.org Developers, Alistair Francis,
	Palmer Dabbelt

On Fri, Mar 19, 2021 at 3:46 PM Atish Patra <atish.patra@wdc.com> wrote:
>
> Qemu doesn't support RISC-V privilege specification v1.9. Remove the
> remaining v1.9 specific references from the implementation.
>
> Signed-off-by: Atish Patra <atish.patra@wdc.com>

This is a great change. There is actually a patch around on the
mailing list doing something similar, but it was never merged.

> ---
>  target/riscv/cpu.c        |  2 +-
>  target/riscv/cpu.h        |  4 +---
>  target/riscv/cpu_bits.h   | 23 ---------------------
>  target/riscv/cpu_helper.c | 12 +++++------
>  target/riscv/csr.c        | 43 ++++++++++-----------------------------
>  target/riscv/machine.c    |  4 +---
>  target/riscv/translate.c  |  4 ++--
>  7 files changed, 22 insertions(+), 70 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index ddea8fbeeb39..c76e4c1a09c9 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -282,7 +282,7 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
>          qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vscause ", env->vscause);
>      }
>      qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval ", env->mtval);
> -    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "stval ", env->sbadaddr);
> +    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "stval ", env->stval);
>      if (riscv_has_ext(env, RVH)) {
>          qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "htval ", env->htval);
>          qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval2 ", env->mtval2);
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 0edb2826a27a..7bee351f3c99 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -163,10 +163,8 @@ struct CPURISCVState {
>      target_ulong mie;
>      target_ulong mideleg;
>
> -    target_ulong sptbr;  /* until: priv-1.9.1 */
>      target_ulong satp;   /* since: priv-1.10.0 */
> -    target_ulong sbadaddr;
> -    target_ulong mbadaddr;
> +    target_ulong stval;
>      target_ulong medeleg;
>
>      target_ulong stvec;
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index caf45992070a..b42dd4f8d8b1 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -153,12 +153,6 @@
>  /* 32-bit only */
>  #define CSR_MSTATUSH        0x310
>
> -/* Legacy Counter Setup (priv v1.9.1) */
> -/* Update to #define CSR_MCOUNTINHIBIT 0x320 for 1.11.0 */
> -#define CSR_MUCOUNTEREN     0x320
> -#define CSR_MSCOUNTEREN     0x321
> -#define CSR_MHCOUNTEREN     0x322
> -
>  /* Machine Trap Handling */
>  #define CSR_MSCRATCH        0x340
>  #define CSR_MEPC            0x341
> @@ -166,9 +160,6 @@
>  #define CSR_MTVAL           0x343
>  #define CSR_MIP             0x344
>
> -/* Legacy Machine Trap Handling (priv v1.9.1) */
> -#define CSR_MBADADDR        0x343
> -
>  /* Supervisor Trap Setup */
>  #define CSR_SSTATUS         0x100
>  #define CSR_SEDELEG         0x102
> @@ -184,9 +175,6 @@
>  #define CSR_STVAL           0x143
>  #define CSR_SIP             0x144
>
> -/* Legacy Supervisor Trap Handling (priv v1.9.1) */
> -#define CSR_SBADADDR        0x143
> -
>  /* Supervisor Protection and Translation */
>  #define CSR_SPTBR           0x180
>  #define CSR_SATP            0x180
> @@ -354,14 +342,6 @@
>  #define CSR_MHPMCOUNTER30H  0xb9e
>  #define CSR_MHPMCOUNTER31H  0xb9f
>
> -/* Legacy Machine Protection and Translation (priv v1.9.1) */
> -#define CSR_MBASE           0x380
> -#define CSR_MBOUND          0x381
> -#define CSR_MIBASE          0x382
> -#define CSR_MIBOUND         0x383
> -#define CSR_MDBASE          0x384
> -#define CSR_MDBOUND         0x385
> -
>  /* mstatus CSR bits */
>  #define MSTATUS_UIE         0x00000001
>  #define MSTATUS_SIE         0x00000002
> @@ -375,10 +355,8 @@
>  #define MSTATUS_FS          0x00006000
>  #define MSTATUS_XS          0x00018000
>  #define MSTATUS_MPRV        0x00020000
> -#define MSTATUS_PUM         0x00040000 /* until: priv-1.9.1 */
>  #define MSTATUS_SUM         0x00040000 /* since: priv-1.10 */
>  #define MSTATUS_MXR         0x00080000
> -#define MSTATUS_VM          0x1F000000 /* until: priv-1.9.1 */
>  #define MSTATUS_TVM         0x00100000 /* since: priv-1.10 */
>  #define MSTATUS_TW          0x00200000 /* since: priv-1.10 */
>  #define MSTATUS_TSR         0x00400000 /* since: priv-1.10 */
> @@ -416,7 +394,6 @@
>  #define SSTATUS_SPP         0x00000100
>  #define SSTATUS_FS          0x00006000
>  #define SSTATUS_XS          0x00018000
> -#define SSTATUS_PUM         0x00040000 /* until: priv-1.9.1 */
>  #define SSTATUS_SUM         0x00040000 /* since: priv-1.10 */
>  #define SSTATUS_MXR         0x00080000
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 2f43939fb6d4..bb0a709c9cab 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -136,8 +136,8 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
>          env->vscause = env->scause;
>          env->scause = env->scause_hs;
>
> -        env->vstval = env->sbadaddr;
> -        env->sbadaddr = env->stval_hs;
> +        env->vstval = env->stval;
> +        env->stval = env->stval_hs;
>
>          env->vsatp = env->satp;
>          env->satp = env->satp_hs;
> @@ -159,8 +159,8 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
>          env->scause_hs = env->scause;
>          env->scause = env->vscause;
>
> -        env->stval_hs = env->sbadaddr;
> -        env->sbadaddr = env->vstval;
> +        env->stval_hs = env->stval;
> +        env->stval = env->vstval;
>
>          env->satp_hs = env->satp;
>          env->satp = env->vsatp;
> @@ -972,7 +972,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
>          env->mstatus = s;
>          env->scause = cause | ((target_ulong)async << (TARGET_LONG_BITS - 1));
>          env->sepc = env->pc;
> -        env->sbadaddr = tval;
> +        env->stval = tval;
>          env->htval = htval;
>          env->pc = (env->stvec >> 2 << 2) +
>              ((async && (env->stvec & 3) == 1) ? cause * 4 : 0);
> @@ -1003,7 +1003,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
>          env->mstatus = s;
>          env->mcause = cause | ~(((target_ulong)-1) >> async);
>          env->mepc = env->pc;
> -        env->mbadaddr = tval;
> +        env->mtval = tval;
>          env->mtval2 = mtval2;
>          env->pc = (env->mtvec >> 2 << 2) +
>              ((async && (env->mtvec & 3) == 1) ? cause * 4 : 0);
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index fd2e6363f397..7166f8d710a8 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -643,26 +643,6 @@ static int write_mcounteren(CPURISCVState *env, int csrno, target_ulong val)
>      return 0;
>  }
>
> -/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
> -static int read_mscounteren(CPURISCVState *env, int csrno, target_ulong *val)
> -{
> -    if (env->priv_ver < PRIV_VERSION_1_11_0) {
> -        return -RISCV_EXCP_ILLEGAL_INST;
> -    }
> -    *val = env->mcounteren;
> -    return 0;
> -}
> -
> -/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
> -static int write_mscounteren(CPURISCVState *env, int csrno, target_ulong val)
> -{
> -    if (env->priv_ver < PRIV_VERSION_1_11_0) {
> -        return -RISCV_EXCP_ILLEGAL_INST;
> -    }
> -    env->mcounteren = val;
> -    return 0;
> -}
> -
>  /* Machine Trap Handling */
>  static int read_mscratch(CPURISCVState *env, int csrno, target_ulong *val)
>  {
> @@ -700,15 +680,15 @@ static int write_mcause(CPURISCVState *env, int csrno, target_ulong val)
>      return 0;
>  }
>
> -static int read_mbadaddr(CPURISCVState *env, int csrno, target_ulong *val)
> +static int read_mtval(CPURISCVState *env, int csrno, target_ulong *val)
>  {
> -    *val = env->mbadaddr;
> +    *val = env->mtval;
>      return 0;
>  }
>
> -static int write_mbadaddr(CPURISCVState *env, int csrno, target_ulong val)
> +static int write_mtval(CPURISCVState *env, int csrno, target_ulong val)
>  {
> -    env->mbadaddr = val;
> +    env->mtval = val;
>      return 0;
>  }
>
> @@ -840,18 +820,19 @@ static int write_scause(CPURISCVState *env, int csrno, target_ulong val)
>      return 0;
>  }
>
> -static int read_sbadaddr(CPURISCVState *env, int csrno, target_ulong *val)
> +static int read_stval(CPURISCVState *env, int csrno, target_ulong *val)
>  {
> -    *val = env->sbadaddr;
> +    *val = env->stval;
>      return 0;
>  }
>
> -static int write_sbadaddr(CPURISCVState *env, int csrno, target_ulong val)
> +static int write_stval(CPURISCVState *env, int csrno, target_ulong val)
>  {
> -    env->sbadaddr = val;
> +    env->stval = val;
>      return 0;
>  }
>
> +
>  static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
>                     target_ulong new_value, target_ulong write_mask)
>  {
> @@ -1418,13 +1399,11 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>
>      [CSR_MSTATUSH]    = { "mstatush",   any32, read_mstatush,    write_mstatush    },
>
> -    [CSR_MSCOUNTEREN] = { "msounteren", any,   read_mscounteren, write_mscounteren },
> -
>      /* Machine Trap Handling */
>      [CSR_MSCRATCH] = { "mscratch", any,  read_mscratch, write_mscratch },
>      [CSR_MEPC]     = { "mepc",     any,  read_mepc,     write_mepc     },
>      [CSR_MCAUSE]   = { "mcause",   any,  read_mcause,   write_mcause   },
> -    [CSR_MBADADDR] = { "mbadaddr", any,  read_mbadaddr, write_mbadaddr },
> +    [CSR_MTVAL]    = { "mtval",    any,  read_mtval,    write_mtval    },
>      [CSR_MIP]      = { "mip",      any,  NULL,    NULL, rmw_mip        },
>
>      /* Supervisor Trap Setup */
> @@ -1437,7 +1416,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>      [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch },
>      [CSR_SEPC]     = { "sepc",     smode, read_sepc,     write_sepc     },
>      [CSR_SCAUSE]   = { "scause",   smode, read_scause,   write_scause   },
> -    [CSR_SBADADDR] = { "sbadaddr", smode, read_sbadaddr, write_sbadaddr },
> +    [CSR_STVAL]    = { "stval",    smode, read_stval,   write_stval   },
>      [CSR_SIP]      = { "sip",      smode, NULL,    NULL, rmw_sip        },
>
>      /* Supervisor Protection and Translation */
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index 44d4015bd675..27fcc770aa4b 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -165,10 +165,8 @@ const VMStateDescription vmstate_riscv_cpu = {
>          VMSTATE_UINT32(env.miclaim, RISCVCPU),
>          VMSTATE_UINTTL(env.mie, RISCVCPU),
>          VMSTATE_UINTTL(env.mideleg, RISCVCPU),
> -        VMSTATE_UINTTL(env.sptbr, RISCVCPU),
>          VMSTATE_UINTTL(env.satp, RISCVCPU),
> -        VMSTATE_UINTTL(env.sbadaddr, RISCVCPU),
> -        VMSTATE_UINTTL(env.mbadaddr, RISCVCPU),
> +        VMSTATE_UINTTL(env.stval, RISCVCPU),
>          VMSTATE_UINTTL(env.medeleg, RISCVCPU),
>          VMSTATE_UINTTL(env.stvec, RISCVCPU),
>          VMSTATE_UINTTL(env.sepc, RISCVCPU),

As you are changing the vmstate you also need to bump the vmstate
version. I'll just squash that in with this patch as I would really
like to see this merged.

Alistair

> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 0f28b5f41e4f..1740be3d4bd9 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -130,7 +130,7 @@ static void generate_exception(DisasContext *ctx, int excp)
>      ctx->base.is_jmp = DISAS_NORETURN;
>  }
>
> -static void generate_exception_mbadaddr(DisasContext *ctx, int excp)
> +static void generate_exception_mtval(DisasContext *ctx, int excp)
>  {
>      tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
>      tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
> @@ -174,7 +174,7 @@ static void gen_exception_illegal(DisasContext *ctx)
>
>  static void gen_exception_inst_addr_mis(DisasContext *ctx)
>  {
> -    generate_exception_mbadaddr(ctx, RISCV_EXCP_INST_ADDR_MIS);
> +    generate_exception_mtval(ctx, RISCV_EXCP_INST_ADDR_MIS);
>  }
>
>  static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
> --
> 2.25.1
>
>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [ RFC 2/6] target/riscv: Implement mcountinhibit CSR
  2021-03-19 19:45 ` [ RFC 2/6] target/riscv: Implement mcountinhibit CSR Atish Patra
@ 2021-03-31 15:29   ` Alistair Francis
  0 siblings, 0 replies; 11+ messages in thread
From: Alistair Francis @ 2021-03-31 15:29 UTC (permalink / raw)
  To: Atish Patra
  Cc: open list:RISC-V, Sagar Karandikar, Bastian Koppelmann,
	Anup Patel, qemu-devel@nongnu.org Developers, Alistair Francis,
	Palmer Dabbelt

On Fri, Mar 19, 2021 at 3:46 PM Atish Patra <atish.patra@wdc.com> wrote:
>
> As per the privilege specification v1.11, mcountinhibit allows to start/stop
> a pmu counter selectively.
>
> Signed-off-by: Atish Patra <atish.patra@wdc.com>
> ---
>  target/riscv/cpu.h      |  2 ++
>  target/riscv/cpu_bits.h |  4 ++++
>  target/riscv/csr.c      | 23 +++++++++++++++++++++++
>  target/riscv/machine.c  |  1 +
>  4 files changed, 30 insertions(+)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 7bee351f3c99..ef2a7fdc3980 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -214,6 +214,8 @@ struct CPURISCVState {
>      target_ulong scounteren;
>      target_ulong mcounteren;
>
> +    target_ulong mcountinhibit;
> +
>      target_ulong sscratch;
>      target_ulong mscratch;
>
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index b42dd4f8d8b1..7514d611cd0b 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -283,6 +283,10 @@
>  #define CSR_MHPMCOUNTER29   0xb1d
>  #define CSR_MHPMCOUNTER30   0xb1e
>  #define CSR_MHPMCOUNTER31   0xb1f
> +
> +/* Machine counter-inhibit register */
> +#define CSR_MCOUNTINHIBIT   0x320
> +
>  #define CSR_MHPMEVENT3      0x323
>  #define CSR_MHPMEVENT4      0x324
>  #define CSR_MHPMEVENT5      0x325
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 7166f8d710a8..b9d795389532 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -631,6 +631,26 @@ static int write_mtvec(CPURISCVState *env, int csrno, target_ulong val)
>      return 0;
>  }
>
> +static int read_mcountinhibit(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    if (env->priv_ver < PRIV_VERSION_1_11_0) {
> +        return -RISCV_EXCP_ILLEGAL_INST;
> +    }
> +
> +    *val = env->mcountinhibit;
> +    return 0;
> +}
> +
> +static int write_mcountinhibit(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    if (env->priv_ver < PRIV_VERSION_1_11_0) {
> +        return -RISCV_EXCP_ILLEGAL_INST;
> +    }
> +
> +    env->mcountinhibit = val;
> +    return 0;
> +}

This will probably need a rebase as a large change to CSR access
functions is in the works.

> +
>  static int read_mcounteren(CPURISCVState *env, int csrno, target_ulong *val)
>  {
>      *val = env->mcounteren;
> @@ -1533,6 +1553,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>      [CSR_MHPMCOUNTER30]  = { "mhpmcounter30",  any,    read_zero },
>      [CSR_MHPMCOUNTER31]  = { "mhpmcounter31",  any,    read_zero },
>
> +    [CSR_MCOUNTINHIBIT]  = { "mcountinhibi",   any,    read_mcountinhibit,
> +                                                       write_mcountinhibit },
> +
>      [CSR_MHPMEVENT3]     = { "mhpmevent3",     any,    read_zero },
>      [CSR_MHPMEVENT4]     = { "mhpmevent4",     any,    read_zero },
>      [CSR_MHPMEVENT5]     = { "mhpmevent5",     any,    read_zero },
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index 27fcc770aa4b..cb7ec8a4c656 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -177,6 +177,7 @@ const VMStateDescription vmstate_riscv_cpu = {
>          VMSTATE_UINTTL(env.mtval, RISCVCPU),
>          VMSTATE_UINTTL(env.scounteren, RISCVCPU),
>          VMSTATE_UINTTL(env.mcounteren, RISCVCPU),
> +        VMSTATE_UINTTL(env.mcountinhibit, RISCVCPU),
>          VMSTATE_UINTTL(env.sscratch, RISCVCPU),
>          VMSTATE_UINTTL(env.mscratch, RISCVCPU),
>          VMSTATE_UINT64(env.mfromhost, RISCVCPU),

A bump will be required here.

Otherwise:

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> --
> 2.25.1
>
>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [ RFC 4/6] target/riscv: Add support for hpmcounters/hpmevents
  2021-03-19 19:45 ` [ RFC 4/6] target/riscv: Add support for hpmcounters/hpmevents Atish Patra
@ 2021-04-07 17:34   ` Alistair Francis
  0 siblings, 0 replies; 11+ messages in thread
From: Alistair Francis @ 2021-04-07 17:34 UTC (permalink / raw)
  To: Atish Patra
  Cc: open list:RISC-V, Sagar Karandikar, Bastian Koppelmann,
	Anup Patel, qemu-devel@nongnu.org Developers, Alistair Francis,
	Palmer Dabbelt

On Fri, Mar 19, 2021 at 3:46 PM Atish Patra <atish.patra@wdc.com> wrote:
>
> With SBI PMU extension, user can use any of the available hpmcounters to
> track any perf events based on the value written to mhpmevent csr.
> Add read/write functionality for these csrs.
>
> Signed-off-by: Atish Patra <atish.patra@wdc.com>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.h     |   7 +
>  target/riscv/csr.c     | 444 +++++++++++++++++++++++++++--------------
>  target/riscv/machine.c |   3 +
>  3 files changed, 302 insertions(+), 152 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 47d6caeb7354..0a2b6da78110 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -220,9 +220,16 @@ struct CPURISCVState {
>      target_ulong mcycle_prev;
>      target_ulong minstret_prev;
>
> +    /* PMU counter configured values */
> +    target_ulong mphmcounter_val[32];
> +
>      /* for RV32 */
>      target_ulong mcycleh_prev;
>      target_ulong minstreth_prev;
> +    target_ulong mphmcounterh_val[32];
> +
> +    /* PMU event selector configured values */
> +    target_ulong mphmevent_val[29];
>
>      target_ulong sscratch;
>      target_ulong mscratch;
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 61036649b044..a0430bbbd145 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -422,6 +422,88 @@ static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val)
>      return 0;
>  }
>
> +static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    int evt_index = csrno - CSR_MHPMEVENT3;
> +
> +    *val = env->mphmcounter_val[evt_index];
> +
> +    return 0;
> +}
> +
> +static int write_mhpmevent(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    int evt_index = csrno - CSR_MHPMEVENT3;
> +
> +    env->mphmevent_val[evt_index] = val;
> +
> +    return 0;
> +}
> +
> +static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    int ctr_index = csrno - CSR_MHPMCOUNTER3 + 3;
> +
> +    if (csrno == CSR_MCYCLE) {
> +        env->mphmcounter_val[0] = val;
> +        env->mcycle_prev = get_icount_ticks(false);
> +     } else if (csrno == CSR_MINSTRET) {
> +        env->mphmcounter_val[2] = val;
> +        env->minstret_prev = get_icount_ticks(false);
> +    } else {
> +        env->mphmcounter_val[ctr_index] = val;
> +    }
> +
> +    return 0;
> +}
> +
> +static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    int ctr_index = csrno - CSR_MHPMCOUNTER3 + 3;
> +
> +    if (csrno == CSR_MCYCLEH) {
> +        env->mphmcounterh_val[0] = val;
> +        env->mcycleh_prev = get_icount_ticks(true);
> +    } else if (csrno == CSR_MINSTRETH) {
> +        env->mphmcounterh_val[2] = val;
> +        env->minstreth_prev = get_icount_ticks(true);
> +    } else {
> +        env->mphmcounterh_val[ctr_index] = val;
> +    }
> +
> +    return 0;
> +}
> +
> +static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    int ctr_index;
> +
> +    if (env->priv == PRV_M) {
> +        ctr_index = csrno - CSR_MHPMCOUNTER3 + 3;
> +    } else {
> +        ctr_index = csrno - CSR_HPMCOUNTER3 + 3;
> +    }
> +    *val = env->mphmcounter_val[ctr_index];
> +
> +    return 0;
> +}
> +
> +static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    int ctr_index;
> +
> +    if (env->priv == PRV_M) {
> +        ctr_index = csrno - CSR_MHPMCOUNTER3 + 3;
> +    } else {
> +        ctr_index = csrno - CSR_HPMCOUNTER3 + 3;
> +    }
> +
> +    *val = env->mphmcounterh_val[ctr_index];
> +
> +    return 0;
> +}
> +
> +
>  #if defined(CONFIG_USER_ONLY)
>  static int read_time(CPURISCVState *env, int csrno, target_ulong *val)
>  {
> @@ -1568,157 +1650,215 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>      [CSR_PMPADDR15] =  { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
>
>      /* Performance Counters */
> -    [CSR_HPMCOUNTER3]    = { "hpmcounter3",    ctr,    read_zero },
> -    [CSR_HPMCOUNTER4]    = { "hpmcounter4",    ctr,    read_zero },
> -    [CSR_HPMCOUNTER5]    = { "hpmcounter5",    ctr,    read_zero },
> -    [CSR_HPMCOUNTER6]    = { "hpmcounter6",    ctr,    read_zero },
> -    [CSR_HPMCOUNTER7]    = { "hpmcounter7",    ctr,    read_zero },
> -    [CSR_HPMCOUNTER8]    = { "hpmcounter8",    ctr,    read_zero },
> -    [CSR_HPMCOUNTER9]    = { "hpmcounter9",    ctr,    read_zero },
> -    [CSR_HPMCOUNTER10]   = { "hpmcounter10",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER11]   = { "hpmcounter11",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER12]   = { "hpmcounter12",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER13]   = { "hpmcounter13",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER14]   = { "hpmcounter14",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER15]   = { "hpmcounter15",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER16]   = { "hpmcounter16",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER17]   = { "hpmcounter17",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER18]   = { "hpmcounter18",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER19]   = { "hpmcounter19",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER20]   = { "hpmcounter20",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER21]   = { "hpmcounter21",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER22]   = { "hpmcounter22",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER23]   = { "hpmcounter23",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER24]   = { "hpmcounter24",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER25]   = { "hpmcounter25",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER26]   = { "hpmcounter26",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER27]   = { "hpmcounter27",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER28]   = { "hpmcounter28",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER29]   = { "hpmcounter29",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER30]   = { "hpmcounter30",   ctr,    read_zero },
> -    [CSR_HPMCOUNTER31]   = { "hpmcounter31",   ctr,    read_zero },
> -
> -    [CSR_MHPMCOUNTER3]   = { "mhpmcounter3",   any,    read_zero },
> -    [CSR_MHPMCOUNTER4]   = { "mhpmcounter4",   any,    read_zero },
> -    [CSR_MHPMCOUNTER5]   = { "mhpmcounter5",   any,    read_zero },
> -    [CSR_MHPMCOUNTER6]   = { "mhpmcounter6",   any,    read_zero },
> -    [CSR_MHPMCOUNTER7]   = { "mhpmcounter7",   any,    read_zero },
> -    [CSR_MHPMCOUNTER8]   = { "mhpmcounter8",   any,    read_zero },
> -    [CSR_MHPMCOUNTER9]   = { "mhpmcounter9",   any,    read_zero },
> -    [CSR_MHPMCOUNTER10]  = { "mhpmcounter10",  any,    read_zero },
> -    [CSR_MHPMCOUNTER11]  = { "mhpmcounter11",  any,    read_zero },
> -    [CSR_MHPMCOUNTER12]  = { "mhpmcounter12",  any,    read_zero },
> -    [CSR_MHPMCOUNTER13]  = { "mhpmcounter13",  any,    read_zero },
> -    [CSR_MHPMCOUNTER14]  = { "mhpmcounter14",  any,    read_zero },
> -    [CSR_MHPMCOUNTER15]  = { "mhpmcounter15",  any,    read_zero },
> -    [CSR_MHPMCOUNTER16]  = { "mhpmcounter16",  any,    read_zero },
> -    [CSR_MHPMCOUNTER17]  = { "mhpmcounter17",  any,    read_zero },
> -    [CSR_MHPMCOUNTER18]  = { "mhpmcounter18",  any,    read_zero },
> -    [CSR_MHPMCOUNTER19]  = { "mhpmcounter19",  any,    read_zero },
> -    [CSR_MHPMCOUNTER20]  = { "mhpmcounter20",  any,    read_zero },
> -    [CSR_MHPMCOUNTER21]  = { "mhpmcounter21",  any,    read_zero },
> -    [CSR_MHPMCOUNTER22]  = { "mhpmcounter22",  any,    read_zero },
> -    [CSR_MHPMCOUNTER23]  = { "mhpmcounter23",  any,    read_zero },
> -    [CSR_MHPMCOUNTER24]  = { "mhpmcounter24",  any,    read_zero },
> -    [CSR_MHPMCOUNTER25]  = { "mhpmcounter25",  any,    read_zero },
> -    [CSR_MHPMCOUNTER26]  = { "mhpmcounter26",  any,    read_zero },
> -    [CSR_MHPMCOUNTER27]  = { "mhpmcounter27",  any,    read_zero },
> -    [CSR_MHPMCOUNTER28]  = { "mhpmcounter28",  any,    read_zero },
> -    [CSR_MHPMCOUNTER29]  = { "mhpmcounter29",  any,    read_zero },
> -    [CSR_MHPMCOUNTER30]  = { "mhpmcounter30",  any,    read_zero },
> -    [CSR_MHPMCOUNTER31]  = { "mhpmcounter31",  any,    read_zero },
> -
> -    [CSR_MCOUNTINHIBIT]  = { "mcountinhibi",   any,    read_mcountinhibit,
> -                                                       write_mcountinhibit },
> -
> -    [CSR_MHPMEVENT3]     = { "mhpmevent3",     any,    read_zero },
> -    [CSR_MHPMEVENT4]     = { "mhpmevent4",     any,    read_zero },
> -    [CSR_MHPMEVENT5]     = { "mhpmevent5",     any,    read_zero },
> -    [CSR_MHPMEVENT6]     = { "mhpmevent6",     any,    read_zero },
> -    [CSR_MHPMEVENT7]     = { "mhpmevent7",     any,    read_zero },
> -    [CSR_MHPMEVENT8]     = { "mhpmevent8",     any,    read_zero },
> -    [CSR_MHPMEVENT9]     = { "mhpmevent9",     any,    read_zero },
> -    [CSR_MHPMEVENT10]    = { "mhpmevent10",    any,    read_zero },
> -    [CSR_MHPMEVENT11]    = { "mhpmevent11",    any,    read_zero },
> -    [CSR_MHPMEVENT12]    = { "mhpmevent12",    any,    read_zero },
> -    [CSR_MHPMEVENT13]    = { "mhpmevent13",    any,    read_zero },
> -    [CSR_MHPMEVENT14]    = { "mhpmevent14",    any,    read_zero },
> -    [CSR_MHPMEVENT15]    = { "mhpmevent15",    any,    read_zero },
> -    [CSR_MHPMEVENT16]    = { "mhpmevent16",    any,    read_zero },
> -    [CSR_MHPMEVENT17]    = { "mhpmevent17",    any,    read_zero },
> -    [CSR_MHPMEVENT18]    = { "mhpmevent18",    any,    read_zero },
> -    [CSR_MHPMEVENT19]    = { "mhpmevent19",    any,    read_zero },
> -    [CSR_MHPMEVENT20]    = { "mhpmevent20",    any,    read_zero },
> -    [CSR_MHPMEVENT21]    = { "mhpmevent21",    any,    read_zero },
> -    [CSR_MHPMEVENT22]    = { "mhpmevent22",    any,    read_zero },
> -    [CSR_MHPMEVENT23]    = { "mhpmevent23",    any,    read_zero },
> -    [CSR_MHPMEVENT24]    = { "mhpmevent24",    any,    read_zero },
> -    [CSR_MHPMEVENT25]    = { "mhpmevent25",    any,    read_zero },
> -    [CSR_MHPMEVENT26]    = { "mhpmevent26",    any,    read_zero },
> -    [CSR_MHPMEVENT27]    = { "mhpmevent27",    any,    read_zero },
> -    [CSR_MHPMEVENT28]    = { "mhpmevent28",    any,    read_zero },
> -    [CSR_MHPMEVENT29]    = { "mhpmevent29",    any,    read_zero },
> -    [CSR_MHPMEVENT30]    = { "mhpmevent30",    any,    read_zero },
> -    [CSR_MHPMEVENT31]    = { "mhpmevent31",    any,    read_zero },
> -
> -    [CSR_HPMCOUNTER3H]   = { "hpmcounter3h",   ctr32,  read_zero },
> -    [CSR_HPMCOUNTER4H]   = { "hpmcounter4h",   ctr32,  read_zero },
> -    [CSR_HPMCOUNTER5H]   = { "hpmcounter5h",   ctr32,  read_zero },
> -    [CSR_HPMCOUNTER6H]   = { "hpmcounter6h",   ctr32,  read_zero },
> -    [CSR_HPMCOUNTER7H]   = { "hpmcounter7h",   ctr32,  read_zero },
> -    [CSR_HPMCOUNTER8H]   = { "hpmcounter8h",   ctr32,  read_zero },
> -    [CSR_HPMCOUNTER9H]   = { "hpmcounter9h",   ctr32,  read_zero },
> -    [CSR_HPMCOUNTER10H]  = { "hpmcounter10h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER11H]  = { "hpmcounter11h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER12H]  = { "hpmcounter12h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER13H]  = { "hpmcounter13h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER14H]  = { "hpmcounter14h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER15H]  = { "hpmcounter15h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER16H]  = { "hpmcounter16h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER17H]  = { "hpmcounter17h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER18H]  = { "hpmcounter18h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER19H]  = { "hpmcounter19h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER20H]  = { "hpmcounter20h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER21H]  = { "hpmcounter21h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER22H]  = { "hpmcounter22h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER23H]  = { "hpmcounter23h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER24H]  = { "hpmcounter24h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER25H]  = { "hpmcounter25h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER26H]  = { "hpmcounter26h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER27H]  = { "hpmcounter27h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER28H]  = { "hpmcounter28h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER29H]  = { "hpmcounter29h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER30H]  = { "hpmcounter30h",  ctr32,  read_zero },
> -    [CSR_HPMCOUNTER31H]  = { "hpmcounter31h",  ctr32,  read_zero },
> -
> -    [CSR_MHPMCOUNTER3H]  = { "mhpmcounter3h",  any32,  read_zero },
> -    [CSR_MHPMCOUNTER4H]  = { "mhpmcounter4h",  any32,  read_zero },
> -    [CSR_MHPMCOUNTER5H]  = { "mhpmcounter5h",  any32,  read_zero },
> -    [CSR_MHPMCOUNTER6H]  = { "mhpmcounter6h",  any32,  read_zero },
> -    [CSR_MHPMCOUNTER7H]  = { "mhpmcounter7h",  any32,  read_zero },
> -    [CSR_MHPMCOUNTER8H]  = { "mhpmcounter8h",  any32,  read_zero },
> -    [CSR_MHPMCOUNTER9H]  = { "mhpmcounter9h",  any32,  read_zero },
> -    [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", any32,  read_zero },
> -    [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", any32,  read_zero },
> +    [CSR_HPMCOUNTER3]    = { "hpmcounter3",    ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER4]    = { "hpmcounter4",    ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER5]    = { "hpmcounter5",    ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER6]    = { "hpmcounter6",    ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER7]    = { "hpmcounter7",    ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER8]    = { "hpmcounter8",    ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER9]    = { "hpmcounter9",    ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER10]   = { "hpmcounter10",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER11]   = { "hpmcounter11",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER12]   = { "hpmcounter12",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER13]   = { "hpmcounter13",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER14]   = { "hpmcounter14",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER15]   = { "hpmcounter15",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER16]   = { "hpmcounter16",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER17]   = { "hpmcounter17",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER18]   = { "hpmcounter18",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER19]   = { "hpmcounter19",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER20]   = { "hpmcounter20",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER21]   = { "hpmcounter21",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER22]   = { "hpmcounter22",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER23]   = { "hpmcounter23",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER24]   = { "hpmcounter24",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER25]   = { "hpmcounter25",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER26]   = { "hpmcounter26",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER27]   = { "hpmcounter27",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER28]   = { "hpmcounter28",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER29]   = { "hpmcounter29",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER30]   = { "hpmcounter30",   ctr,    read_hpmcounter },
> +    [CSR_HPMCOUNTER31]   = { "hpmcounter31",   ctr,    read_hpmcounter },
> +
> +    [CSR_MHPMCOUNTER3]   = { "mhpmcounter3",   any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER4]   = { "mhpmcounter4",   any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER5]   = { "mhpmcounter5",   any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER6]   = { "mhpmcounter6",   any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER7]   = { "mhpmcounter7",   any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER8]   = { "mhpmcounter8",   any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER9]   = { "mhpmcounter9",   any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER10]  = { "mhpmcounter10",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER11]  = { "mhpmcounter11",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER12]  = { "mhpmcounter12",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER13]  = { "mhpmcounter13",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER14]  = { "mhpmcounter14",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER15]  = { "mhpmcounter15",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER16]  = { "mhpmcounter16",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER17]  = { "mhpmcounter17",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER18]  = { "mhpmcounter18",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER19]  = { "mhpmcounter19",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER20]  = { "mhpmcounter20",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER21]  = { "mhpmcounter21",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER22]  = { "mhpmcounter22",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER23]  = { "mhpmcounter23",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER24]  = { "mhpmcounter24",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER25]  = { "mhpmcounter25",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER26]  = { "mhpmcounter26",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER27]  = { "mhpmcounter27",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER28]  = { "mhpmcounter28",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER29]  = { "mhpmcounter29",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER30]  = { "mhpmcounter30",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +    [CSR_MHPMCOUNTER31]  = { "mhpmcounter31",  any,    read_hpmcounter,
> +                                                       write_mhpmcounter },
> +
> +    [CSR_MCOUNTINHIBIT]  = { "mcountinhibit",  any, read_mcountinhibit,
> +                                                    write_mcountinhibit },
> +
> +    [CSR_MHPMEVENT3]     = { "mhpmevent3",     any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT4]     = { "mhpmevent4",     any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT5]     = { "mhpmevent5",     any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT6]     = { "mhpmevent6",     any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT7]     = { "mhpmevent7",     any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT8]     = { "mhpmevent8",     any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT9]     = { "mhpmevent9",     any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT10]    = { "mhpmevent10",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT11]    = { "mhpmevent11",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT12]    = { "mhpmevent12",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT13]    = { "mhpmevent13",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT14]    = { "mhpmevent14",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT15]    = { "mhpmevent15",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT16]    = { "mhpmevent16",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT17]    = { "mhpmevent17",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT18]    = { "mhpmevent18",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT19]    = { "mhpmevent19",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT20]    = { "mhpmevent20",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT21]    = { "mhpmevent21",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT22]    = { "mhpmevent22",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT23]    = { "mhpmevent23",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT24]    = { "mhpmevent24",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT25]    = { "mhpmevent25",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT26]    = { "mhpmevent26",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT27]    = { "mhpmevent27",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT28]    = { "mhpmevent28",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT29]    = { "mhpmevent29",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT30]    = { "mhpmevent30",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +    [CSR_MHPMEVENT31]    = { "mhpmevent31",    any,    read_mhpmevent,
> +                                                       write_mhpmevent },
> +
> +    [CSR_HPMCOUNTER3H]   = { "hpmcounter3h",   ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER4H]   = { "hpmcounter4h",   ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER5H]   = { "hpmcounter5h",   ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER6H]   = { "hpmcounter6h",   ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER7H]   = { "hpmcounter7h",   ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER8H]   = { "hpmcounter8h",   ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER9H]   = { "hpmcounter9h",   ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER10H]  = { "hpmcounter10h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER11H]  = { "hpmcounter11h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER12H]  = { "hpmcounter12h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER13H]  = { "hpmcounter13h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER14H]  = { "hpmcounter14h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER15H]  = { "hpmcounter15h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER16H]  = { "hpmcounter16h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER17H]  = { "hpmcounter17h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER18H]  = { "hpmcounter18h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER19H]  = { "hpmcounter19h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER20H]  = { "hpmcounter20h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER21H]  = { "hpmcounter21h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER22H]  = { "hpmcounter22h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER23H]  = { "hpmcounter23h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER24H]  = { "hpmcounter24h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER25H]  = { "hpmcounter25h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER26H]  = { "hpmcounter26h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER27H]  = { "hpmcounter27h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER28H]  = { "hpmcounter28h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER29H]  = { "hpmcounter29h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER30H]  = { "hpmcounter30h",  ctr32,  read_hpmcounterh },
> +    [CSR_HPMCOUNTER31H]  = { "hpmcounter31h",  ctr32,  read_hpmcounterh },
> +
> +    [CSR_MHPMCOUNTER3H]  = { "mhpmcounter3h",  any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER4H]  = { "mhpmcounter4h",  any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER5H]  = { "mhpmcounter5h",  any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER6H]  = { "mhpmcounter6h",  any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER7H]  = { "mhpmcounter7h",  any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER8H]  = { "mhpmcounter8h",  any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER9H]  = { "mhpmcounter9h",  any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", any32,  read_hpmcounterh },
> +    [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", any32,  read_hpmcounterh },
>  #endif /* !CONFIG_USER_ONLY */
>  };
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index b1410419cc1f..d70531402d86 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -182,6 +182,9 @@ const VMStateDescription vmstate_riscv_cpu = {
>          VMSTATE_UINTTL(env.mcycleh_prev, RISCVCPU),
>          VMSTATE_UINTTL(env.minstret_prev, RISCVCPU),
>          VMSTATE_UINTTL(env.minstreth_prev, RISCVCPU),
> +        VMSTATE_UINTTL_ARRAY(env.mphmcounter_val, RISCVCPU, 32),
> +        VMSTATE_UINTTL_ARRAY(env.mphmcounterh_val, RISCVCPU, 32),
> +        VMSTATE_UINTTL_ARRAY(env.mphmevent_val, RISCVCPU, 29),
>          VMSTATE_UINTTL(env.sscratch, RISCVCPU),
>          VMSTATE_UINTTL(env.mscratch, RISCVCPU),
>          VMSTATE_UINT64(env.mfromhost, RISCVCPU),
> --
> 2.25.1
>
>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [ RFC 3/6] target/riscv: Support mcycle/minstret write operation
  2021-03-19 19:45 ` [ RFC 3/6] target/riscv: Support mcycle/minstret write operation Atish Patra
@ 2021-04-07 17:34   ` Alistair Francis
  0 siblings, 0 replies; 11+ messages in thread
From: Alistair Francis @ 2021-04-07 17:34 UTC (permalink / raw)
  To: Atish Patra
  Cc: open list:RISC-V, Sagar Karandikar, Bastian Koppelmann,
	Anup Patel, qemu-devel@nongnu.org Developers, Alistair Francis,
	Palmer Dabbelt

On Fri, Mar 19, 2021 at 3:49 PM Atish Patra <atish.patra@wdc.com> wrote:
>
> mcycle/minstret are actually WARL registers and can be written with any
> given value. With SBI PMU extension, it will be used to store a initial
> value provided from supervisor OS. The Qemu also need prohibit the counter
> increment if mcountinhibit is set.
>
> Signed-off-by: Atish Patra <atish.patra@wdc.com>
> ---
>  target/riscv/cpu.h     |   8 +++
>  target/riscv/csr.c     | 111 ++++++++++++++++++++++++++++++++++-------
>  target/riscv/machine.c |   4 ++
>  3 files changed, 105 insertions(+), 18 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index ef2a7fdc3980..47d6caeb7354 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -216,6 +216,14 @@ struct CPURISCVState {
>
>      target_ulong mcountinhibit;
>
> +    /* Snapshot values for mcycle & minstret */
> +    target_ulong mcycle_prev;
> +    target_ulong minstret_prev;
> +
> +    /* for RV32 */
> +    target_ulong mcycleh_prev;
> +    target_ulong minstreth_prev;
> +
>      target_ulong sscratch;
>      target_ulong mscratch;
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index b9d795389532..61036649b044 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -319,31 +319,106 @@ static int write_vstart(CPURISCVState *env, int csrno, target_ulong val)
>  }
>
>  /* User Timers and Counters */
> -static int read_instret(CPURISCVState *env, int csrno, target_ulong *val)
> +
> +static target_ulong get_icount_ticks(bool brv32)
>  {
> +    int64_t val;
> +    target_ulong result;
> +
>  #if !defined(CONFIG_USER_ONLY)
>      if (icount_enabled()) {
> -        *val = icount_get();
> +        val = icount_get();
>      } else {
> -        *val = cpu_get_host_ticks();
> +        val = cpu_get_host_ticks();
>      }
>  #else
> -    *val = cpu_get_host_ticks();
> +    val = cpu_get_host_ticks();
>  #endif
> +
> +    if (brv32) {
> +        result = val >> 32;
> +    } else {
> +        result = val;
> +    }
> +
> +    return result;
> +}
> +
> +static int read_cycle(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    if (get_field(env->mcountinhibit, HCOUNTEREN_CY)) {
> +        /**
> +         * Counter should not increment if inhibit bit is set. We can't really
> +         * stop the icount counting. Just return the previous value to indicate
> +         * that counter was not incremented.
> +         */
> +        *val = env->mcycle_prev;
> +        return 0;
> +    }
> +
> +    *val = get_icount_ticks(false);
> +
> +    if (*val > env->mcycle_prev)
> +        *val = *val - env->mcycle_prev + env->mphmcounter_val[0];
> +    else
> +        /* Overflow scenario */
> +        *val = UINT64_MAX - env->mcycle_prev + 1 + env->mphmcounter_val[0] + *val;

QEMU expects brackets even on single line if statements.

Otherwise:

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair


> +
> +    return 0;
> +}
> +
> +static int read_instret(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    if (get_field(env->mcountinhibit, HCOUNTEREN_IR)) {
> +        *val = env->minstret_prev;
> +        return 0;
> +    }
> +
> +    *val = get_icount_ticks(false);
> +
> +    if (*val > env->minstret_prev)
> +        *val = *val - env->minstret_prev + env->mphmcounter_val[2];
> +    else
> +        /* Overflow scenario */
> +        *val = UINT64_MAX - env->minstret_prev + 1 + env->mphmcounter_val[2] + *val;
> +
> +    return 0;
> +}
> +
> +static int read_cycleh(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +
> +    if (get_field(env->mcountinhibit, HCOUNTEREN_CY)) {
> +        *val = env->mcycleh_prev;
> +        return 0;
> +    }
> +
> +    *val = get_icount_ticks(true);
> +
> +    if (*val > env->mcycleh_prev)
> +        *val = *val - env->mcycleh_prev + env->mphmcounterh_val[0];
> +    else
> +        /* Overflow scenario */
> +        *val = UINT32_MAX - env->mcycleh_prev + 1 + env->mphmcounterh_val[0] + *val;
> +
>      return 0;
>  }
>
>  static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val)
>  {
> -#if !defined(CONFIG_USER_ONLY)
> -    if (icount_enabled()) {
> -        *val = icount_get() >> 32;
> -    } else {
> -        *val = cpu_get_host_ticks() >> 32;
> +    if (get_field(env->mcountinhibit, HCOUNTEREN_IR)) {
> +        *val = env->minstreth_prev;
> +        return 0;
>      }
> -#else
> -    *val = cpu_get_host_ticks() >> 32;
> -#endif
> +
> +    *val = get_icount_ticks(true);
> +
> +    if (*val > env->minstreth_prev)
> +        *val = *val - env->minstreth_prev + env->mphmcounterh_val[2];
> +    else
> +        /* Overflow scenario */
> +        *val = UINT32_MAX - env->minstreth_prev + 1 + env->mphmcounterh_val[2] + *val;
> +
>      return 0;
>  }
>
> @@ -1383,9 +1458,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>      [CSR_VL]       = { "vl",       vs,     read_vl                    },
>      [CSR_VTYPE]    = { "vtype",    vs,     read_vtype                 },
>      /* User Timers and Counters */
> -    [CSR_CYCLE]    = { "cycle",    ctr,    read_instret  },
> +    [CSR_CYCLE]    = { "cycle",    ctr,    read_cycle  },
>      [CSR_INSTRET]  = { "instret",  ctr,    read_instret  },
> -    [CSR_CYCLEH]   = { "cycleh",   ctr32,  read_instreth },
> +    [CSR_CYCLEH]   = { "cycleh",   ctr32,  read_cycleh },
>      [CSR_INSTRETH] = { "instreth", ctr32,  read_instreth },
>
>      /*
> @@ -1397,10 +1472,10 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>
>  #if !defined(CONFIG_USER_ONLY)
>      /* Machine Timers and Counters */
> -    [CSR_MCYCLE]    = { "mcycle",    any,   read_instret  },
> -    [CSR_MINSTRET]  = { "minstret",  any,   read_instret  },
> -    [CSR_MCYCLEH]   = { "mcycleh",   any32, read_instreth },
> -    [CSR_MINSTRETH] = { "minstreth", any32, read_instreth },
> +    [CSR_MCYCLE]    = { "mcycle",    any,   read_cycle  , write_mhpmcounter},
> +    [CSR_MINSTRET]  = { "minstret",  any,   read_instret, write_mhpmcounter},
> +    [CSR_MCYCLEH]   = { "mcycleh",   any32, read_cycleh , write_mhpmcounterh},
> +    [CSR_MINSTRETH] = { "minstreth", any32, read_instreth , write_mhpmcounterh},
>
>      /* Machine Information Registers */
>      [CSR_MVENDORID] = { "mvendorid", any,   read_zero    },
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index cb7ec8a4c656..b1410419cc1f 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -178,6 +178,10 @@ const VMStateDescription vmstate_riscv_cpu = {
>          VMSTATE_UINTTL(env.scounteren, RISCVCPU),
>          VMSTATE_UINTTL(env.mcounteren, RISCVCPU),
>          VMSTATE_UINTTL(env.mcountinhibit, RISCVCPU),
> +        VMSTATE_UINTTL(env.mcycle_prev, RISCVCPU),
> +        VMSTATE_UINTTL(env.mcycleh_prev, RISCVCPU),
> +        VMSTATE_UINTTL(env.minstret_prev, RISCVCPU),
> +        VMSTATE_UINTTL(env.minstreth_prev, RISCVCPU),
>          VMSTATE_UINTTL(env.sscratch, RISCVCPU),
>          VMSTATE_UINTTL(env.mscratch, RISCVCPU),
>          VMSTATE_UINT64(env.mfromhost, RISCVCPU),
> --
> 2.25.1
>
>


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2021-04-07 17:55 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-19 19:45 [ RFC 0/6] Improve PMU support Atish Patra
2021-03-19 19:45 ` [ RFC 1/6] target/riscv: Remove privilege v1.9 specific CSR related code Atish Patra
2021-03-22 14:53   ` Alistair Francis
2021-03-19 19:45 ` [ RFC 2/6] target/riscv: Implement mcountinhibit CSR Atish Patra
2021-03-31 15:29   ` Alistair Francis
2021-03-19 19:45 ` [ RFC 3/6] target/riscv: Support mcycle/minstret write operation Atish Patra
2021-04-07 17:34   ` Alistair Francis
2021-03-19 19:45 ` [ RFC 4/6] target/riscv: Add support for hpmcounters/hpmevents Atish Patra
2021-04-07 17:34   ` Alistair Francis
2021-03-19 19:45 ` [ RFC 5/6] hw/riscv: virt: Add PMU device tree node to support SBI PMU extension Atish Patra
2021-03-19 19:45 ` [ RFC 6/6] hw/riscv: virt: DEBUG PATCH to test PMU Atish Patra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).