* [PULL 01/30] target/riscv: Add zimop extension
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:09 ` [PULL 02/30] disas/riscv: Support zimop disassemble Alistair Francis
` (29 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, LIU Zhiwei, Alistair Francis, Deepak Gupta
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Zimop extension defines an encoding space for 40 MOPs.The Zimop
extension defines 32 MOP instructions named MOP.R.n, where n is
an integer between 0 and 31, inclusive. The Zimop extension
additionally defines 8 MOP instructions named MOP.RR.n, where n
is an integer between 0 and 7.
These 40 MOPs initially are defined to simply write zero to x[rd],
but are designed to be redefined by later extensions to perform some
other action.
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Deepak Gupta <debug@rivosinc.com>
Message-ID: <20240709113652.1239-2-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu_cfg.h | 1 +
target/riscv/insn32.decode | 11 ++++++
target/riscv/cpu.c | 2 ++
target/riscv/translate.c | 1 +
target/riscv/insn_trans/trans_rvzimop.c.inc | 37 +++++++++++++++++++++
5 files changed, 52 insertions(+)
create mode 100644 target/riscv/insn_trans/trans_rvzimop.c.inc
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index fb7eebde52..9f53512053 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -71,6 +71,7 @@ struct RISCVCPUConfig {
bool ext_zihintntl;
bool ext_zihintpause;
bool ext_zihpm;
+ bool ext_zimop;
bool ext_ztso;
bool ext_smstateen;
bool ext_sstc;
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index f22df04cfd..60da673153 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -38,6 +38,8 @@
%imm_bs 30:2 !function=ex_shift_3
%imm_rnum 20:4
%imm_z6 26:1 15:5
+%imm_mop5 30:1 26:2 20:2
+%imm_mop3 30:1 26:2
# Argument sets:
&empty
@@ -56,6 +58,8 @@
&r2nfvm vm rd rs1 nf
&rnfvm vm rd rs1 rs2 nf
&k_aes shamt rs2 rs1 rd
+&mop5 imm rd rs1
+&mop3 imm rd rs1 rs2
# Formats 32:
@r ....... ..... ..... ... ..... ....... &r %rs2 %rs1 %rd
@@ -98,6 +102,9 @@
@k_aes .. ..... ..... ..... ... ..... ....... &k_aes shamt=%imm_bs %rs2 %rs1 %rd
@i_aes .. ..... ..... ..... ... ..... ....... &i imm=%imm_rnum %rs1 %rd
+@mop5 . . .. .. .... .. ..... ... ..... ....... &mop5 imm=%imm_mop5 %rd %rs1
+@mop3 . . .. .. . ..... ..... ... ..... ....... &mop3 imm=%imm_mop3 %rd %rs1 %rs2
+
# Formats 64:
@sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd
@@ -1010,3 +1017,7 @@ amocas_w 00101 . . ..... ..... 010 ..... 0101111 @atom_st
amocas_d 00101 . . ..... ..... 011 ..... 0101111 @atom_st
# *** RV64 Zacas Standard Extension ***
amocas_q 00101 . . ..... ..... 100 ..... 0101111 @atom_st
+
+# *** Zimop may-be-operation extension ***
+mop_r_n 1 . 00 .. 0111 .. ..... 100 ..... 1110011 @mop5
+mop_rr_n 1 . 00 .. 1 ..... ..... 100 ..... 1110011 @mop3
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c53b0d5b40..ac503826ce 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -113,6 +113,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl),
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
ISA_EXT_DATA_ENTRY(zihpm, PRIV_VERSION_1_12_0, ext_zihpm),
+ ISA_EXT_DATA_ENTRY(zimop, PRIV_VERSION_1_13_0, ext_zimop),
ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
ISA_EXT_DATA_ENTRY(za64rs, PRIV_VERSION_1_12_0, has_priv_1_11),
ISA_EXT_DATA_ENTRY(zaamo, PRIV_VERSION_1_12_0, ext_zaamo),
@@ -1471,6 +1472,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
MULTI_EXT_CFG_BOOL("zicsr", ext_zicsr, true),
MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),
MULTI_EXT_CFG_BOOL("zihintpause", ext_zihintpause, true),
+ MULTI_EXT_CFG_BOOL("zimop", ext_zimop, false),
MULTI_EXT_CFG_BOOL("zacas", ext_zacas, false),
MULTI_EXT_CFG_BOOL("zaamo", ext_zaamo, false),
MULTI_EXT_CFG_BOOL("zalrsc", ext_zalrsc, false),
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 0569224e53..379b68289f 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1099,6 +1099,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
#include "insn_trans/trans_rvzacas.c.inc"
#include "insn_trans/trans_rvzawrs.c.inc"
#include "insn_trans/trans_rvzicbo.c.inc"
+#include "insn_trans/trans_rvzimop.c.inc"
#include "insn_trans/trans_rvzfa.c.inc"
#include "insn_trans/trans_rvzfh.c.inc"
#include "insn_trans/trans_rvk.c.inc"
diff --git a/target/riscv/insn_trans/trans_rvzimop.c.inc b/target/riscv/insn_trans/trans_rvzimop.c.inc
new file mode 100644
index 0000000000..165aacd2b6
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzimop.c.inc
@@ -0,0 +1,37 @@
+/*
+ * RISC-V translation routines for May-Be-Operation(zimop).
+ *
+ * Copyright (c) 2024 Alibaba Group.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define REQUIRE_ZIMOP(ctx) do { \
+ if (!ctx->cfg_ptr->ext_zimop) { \
+ return false; \
+ } \
+} while (0)
+
+static bool trans_mop_r_n(DisasContext *ctx, arg_mop_r_n *a)
+{
+ REQUIRE_ZIMOP(ctx);
+ gen_set_gpr(ctx, a->rd, ctx->zero);
+ return true;
+}
+
+static bool trans_mop_rr_n(DisasContext *ctx, arg_mop_rr_n *a)
+{
+ REQUIRE_ZIMOP(ctx);
+ gen_set_gpr(ctx, a->rd, ctx->zero);
+ return true;
+}
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 02/30] disas/riscv: Support zimop disassemble
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
2024-07-18 2:09 ` [PULL 01/30] target/riscv: Add zimop extension Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:09 ` [PULL 03/30] target/riscv: Add zcmop extension Alistair Francis
` (28 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, LIU Zhiwei, Alistair Francis, Deepak Gupta
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Deepak Gupta <debug@rivosinc.com>
Message-ID: <20240709113652.1239-3-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
disas/riscv.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 98 insertions(+)
diff --git a/disas/riscv.c b/disas/riscv.c
index 90d6b26de9..0b82ab2322 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -906,6 +906,46 @@ typedef enum {
rv_op_amocas_w = 875,
rv_op_amocas_d = 876,
rv_op_amocas_q = 877,
+ rv_mop_r_0 = 878,
+ rv_mop_r_1 = 879,
+ rv_mop_r_2 = 880,
+ rv_mop_r_3 = 881,
+ rv_mop_r_4 = 882,
+ rv_mop_r_5 = 883,
+ rv_mop_r_6 = 884,
+ rv_mop_r_7 = 885,
+ rv_mop_r_8 = 886,
+ rv_mop_r_9 = 887,
+ rv_mop_r_10 = 888,
+ rv_mop_r_11 = 889,
+ rv_mop_r_12 = 890,
+ rv_mop_r_13 = 891,
+ rv_mop_r_14 = 892,
+ rv_mop_r_15 = 893,
+ rv_mop_r_16 = 894,
+ rv_mop_r_17 = 895,
+ rv_mop_r_18 = 896,
+ rv_mop_r_19 = 897,
+ rv_mop_r_20 = 898,
+ rv_mop_r_21 = 899,
+ rv_mop_r_22 = 900,
+ rv_mop_r_23 = 901,
+ rv_mop_r_24 = 902,
+ rv_mop_r_25 = 903,
+ rv_mop_r_26 = 904,
+ rv_mop_r_27 = 905,
+ rv_mop_r_28 = 906,
+ rv_mop_r_29 = 907,
+ rv_mop_r_30 = 908,
+ rv_mop_r_31 = 909,
+ rv_mop_rr_0 = 910,
+ rv_mop_rr_1 = 911,
+ rv_mop_rr_2 = 912,
+ rv_mop_rr_3 = 913,
+ rv_mop_rr_4 = 914,
+ rv_mop_rr_5 = 915,
+ rv_mop_rr_6 = 916,
+ rv_mop_rr_7 = 917,
} rv_op;
/* register names */
@@ -2096,6 +2136,46 @@ const rv_opcode_data rvi_opcode_data[] = {
{ "amocas.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amocas.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amocas.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "mop.r.0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.2", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.3", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.4", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.5", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.6", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.7", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.9", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.10", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.11", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.12", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.13", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.14", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.15", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.16", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.17", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.18", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.19", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.20", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.21", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.22", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.23", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.24", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.25", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.26", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.27", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.28", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.29", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.30", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.r.31", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+ { "mop.rr.0", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+ { "mop.rr.1", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+ { "mop.rr.2", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+ { "mop.rr.3", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+ { "mop.rr.4", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+ { "mop.rr.5", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+ { "mop.rr.6", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+ { "mop.rr.7", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
};
/* CSR names */
@@ -3855,6 +3935,24 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 1: op = rv_op_csrrw; break;
case 2: op = rv_op_csrrs; break;
case 3: op = rv_op_csrrc; break;
+ case 4:
+ if (dec->cfg->ext_zimop) {
+ int imm_mop5, imm_mop3;
+ if ((extract32(inst, 22, 10) & 0b1011001111)
+ == 0b1000000111) {
+ imm_mop5 = deposit32(deposit32(extract32(inst, 20, 2),
+ 2, 2,
+ extract32(inst, 26, 2)),
+ 4, 1, extract32(inst, 30, 1));
+ op = rv_mop_r_0 + imm_mop5;
+ } else if ((extract32(inst, 25, 7) & 0b1011001)
+ == 0b1000001) {
+ imm_mop3 = deposit32(extract32(inst, 26, 2),
+ 2, 1, extract32(inst, 30, 1));
+ op = rv_mop_rr_0 + imm_mop3;
+ }
+ }
+ break;
case 5: op = rv_op_csrrwi; break;
case 6: op = rv_op_csrrsi; break;
case 7: op = rv_op_csrrci; break;
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 03/30] target/riscv: Add zcmop extension
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
2024-07-18 2:09 ` [PULL 01/30] target/riscv: Add zimop extension Alistair Francis
2024-07-18 2:09 ` [PULL 02/30] disas/riscv: Support zimop disassemble Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:09 ` [PULL 04/30] disas/riscv: Support zcmop disassemble Alistair Francis
` (27 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, LIU Zhiwei, Alistair Francis, Deepak Gupta
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Zcmop defines eight 16-bit MOP instructions named C.MOP.n, where n is
an odd integer between 1 and 15, inclusive. C.MOP.n is encoded in
the reserved encoding space corresponding to C.LUI xn, 0.
Unlike the MOPs defined in the Zimop extension, the C.MOP.n instructions
are defined to not write any register.
In current implementation, C.MOP.n only has an check function, without any
other more behavior.
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Deepak Gupta <debug@rivosinc.com>
Message-ID: <20240709113652.1239-4-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu_cfg.h | 1 +
target/riscv/insn16.decode | 1 +
target/riscv/cpu.c | 2 ++
target/riscv/tcg/tcg-cpu.c | 5 ++++
target/riscv/translate.c | 1 +
target/riscv/insn_trans/trans_rvzcmop.c.inc | 29 +++++++++++++++++++++
6 files changed, 39 insertions(+)
create mode 100644 target/riscv/insn_trans/trans_rvzcmop.c.inc
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 9f53512053..d85e54b475 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -72,6 +72,7 @@ struct RISCVCPUConfig {
bool ext_zihintpause;
bool ext_zihpm;
bool ext_zimop;
+ bool ext_zcmop;
bool ext_ztso;
bool ext_smstateen;
bool ext_sstc;
diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index b96c534e73..3953bcf82d 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -140,6 +140,7 @@ sw 110 ... ... .. ... 00 @cs_w
addi 000 . ..... ..... 01 @ci
addi 010 . ..... ..... 01 @c_li
{
+ c_mop_n 011 0 0 n:3 1 00000 01
illegal 011 0 ----- 00000 01 # c.addi16sp and c.lui, RES nzimm=0
addi 011 . 00010 ..... 01 @c_addi16sp
lui 011 . ..... ..... 01 @c_lui
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ac503826ce..f4f8287a6d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -131,6 +131,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(zcf, PRIV_VERSION_1_12_0, ext_zcf),
ISA_EXT_DATA_ENTRY(zcd, PRIV_VERSION_1_12_0, ext_zcd),
ISA_EXT_DATA_ENTRY(zce, PRIV_VERSION_1_12_0, ext_zce),
+ ISA_EXT_DATA_ENTRY(zcmop, PRIV_VERSION_1_13_0, ext_zcmop),
ISA_EXT_DATA_ENTRY(zcmp, PRIV_VERSION_1_12_0, ext_zcmp),
ISA_EXT_DATA_ENTRY(zcmt, PRIV_VERSION_1_12_0, ext_zcmt),
ISA_EXT_DATA_ENTRY(zba, PRIV_VERSION_1_12_0, ext_zba),
@@ -1473,6 +1474,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),
MULTI_EXT_CFG_BOOL("zihintpause", ext_zihintpause, true),
MULTI_EXT_CFG_BOOL("zimop", ext_zimop, false),
+ MULTI_EXT_CFG_BOOL("zcmop", ext_zcmop, false),
MULTI_EXT_CFG_BOOL("zacas", ext_zacas, false),
MULTI_EXT_CFG_BOOL("zaamo", ext_zaamo, false),
MULTI_EXT_CFG_BOOL("zalrsc", ext_zalrsc, false),
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index ecf366d6c7..b8814ab753 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -549,6 +549,11 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
}
}
+ if (cpu->cfg.ext_zcmop && !cpu->cfg.ext_zca) {
+ error_setg(errp, "Zcmop extensions require Zca");
+ return;
+ }
+
if (mcc->misa_mxl_max != MXL_RV32 && cpu->cfg.ext_zcf) {
error_setg(errp, "Zcf extension is only relevant to RV32");
return;
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 379b68289f..8a546f4ece 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1114,6 +1114,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
/* Include the auto-generated decoder for 16 bit insn */
#include "decode-insn16.c.inc"
#include "insn_trans/trans_rvzce.c.inc"
+#include "insn_trans/trans_rvzcmop.c.inc"
/* Include decoders for factored-out extensions */
#include "decode-XVentanaCondOps.c.inc"
diff --git a/target/riscv/insn_trans/trans_rvzcmop.c.inc b/target/riscv/insn_trans/trans_rvzcmop.c.inc
new file mode 100644
index 0000000000..7205586508
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzcmop.c.inc
@@ -0,0 +1,29 @@
+/*
+ * RISC-V translation routines for compressed May-Be-Operation(zcmop).
+ *
+ * Copyright (c) 2024 Alibaba Group.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define REQUIRE_ZCMOP(ctx) do { \
+ if (!ctx->cfg_ptr->ext_zcmop) { \
+ return false; \
+ } \
+} while (0)
+
+static bool trans_c_mop_n(DisasContext *ctx, arg_c_mop_n *a)
+{
+ REQUIRE_ZCMOP(ctx);
+ return true;
+}
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 04/30] disas/riscv: Support zcmop disassemble
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (2 preceding siblings ...)
2024-07-18 2:09 ` [PULL 03/30] target/riscv: Add zcmop extension Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:09 ` [PULL 05/30] target/riscv: Support Zama16b extension Alistair Francis
` (26 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, LIU Zhiwei, Alistair Francis, Deepak Gupta
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Although in QEMU disassemble, we usually lift compressed instruction
to an normal format when display the instruction name. For C.MOP.n,
it is more reasonable to directly display its compressed name, because
its behavior can be redefined by later extension.
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Deepak Gupta <debug@rivosinc.com>
Message-ID: <20240709113652.1239-5-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
disas/riscv.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/disas/riscv.c b/disas/riscv.c
index 0b82ab2322..d29cb1ff7d 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -946,6 +946,14 @@ typedef enum {
rv_mop_rr_5 = 915,
rv_mop_rr_6 = 916,
rv_mop_rr_7 = 917,
+ rv_c_mop_1 = 918,
+ rv_c_mop_3 = 919,
+ rv_c_mop_5 = 920,
+ rv_c_mop_7 = 921,
+ rv_c_mop_9 = 922,
+ rv_c_mop_11 = 923,
+ rv_c_mop_13 = 924,
+ rv_c_mop_15 = 925,
} rv_op;
/* register names */
@@ -2176,6 +2184,14 @@ const rv_opcode_data rvi_opcode_data[] = {
{ "mop.rr.5", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
{ "mop.rr.6", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
{ "mop.rr.7", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+ { "c.mop.1", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
+ { "c.mop.3", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
+ { "c.mop.5", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
+ { "c.mop.7", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
+ { "c.mop.9", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
+ { "c.mop.11", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
+ { "c.mop.13", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
+ { "c.mop.15", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
};
/* CSR names */
@@ -2532,6 +2548,13 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
break;
case 2: op = rv_op_c_li; break;
case 3:
+ if (dec->cfg->ext_zcmop) {
+ if ((((inst >> 2) & 0b111111) == 0b100000) &&
+ (((inst >> 11) & 0b11) == 0b0)) {
+ op = rv_c_mop_1 + ((inst >> 8) & 0b111);
+ break;
+ }
+ }
switch ((inst >> 7) & 0b11111) {
case 2: op = rv_op_c_addi16sp; break;
default: op = rv_op_c_lui; break;
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 05/30] target/riscv: Support Zama16b extension
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (3 preceding siblings ...)
2024-07-18 2:09 ` [PULL 04/30] disas/riscv: Support zcmop disassemble Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-22 23:32 ` Alistair Francis
2024-07-18 2:09 ` [PULL 06/30] target/riscv: Move gen_amo before implement Zabha Alistair Francis
` (25 subsequent siblings)
30 siblings, 1 reply; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, LIU Zhiwei, Alistair Francis
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Zama16b is the property that misaligned load/stores/atomics within
a naturally aligned 16-byte region are atomic.
According to the specification, Zama16b applies only to AMOs, loads
and stores defined in the base ISAs, and loads and stores of no more
than XLEN bits defined in the F, D, and Q extensions. Thus it should
not apply to zacas or RVC instructions.
For an instruction in that set, if all accessed bytes lie within 16B granule,
the instruction will not raise an exception for reasons of address alignment,
and the instruction will give rise to only one memory operation for the
purposes of RVWMO—i.e., it will execute atomically.
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240709113652.1239-6-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu_cfg.h | 1 +
target/riscv/cpu.c | 2 ++
target/riscv/insn_trans/trans_rva.c.inc | 42 ++++++++++++++-----------
target/riscv/insn_trans/trans_rvd.c.inc | 14 +++++++--
target/riscv/insn_trans/trans_rvf.c.inc | 14 +++++++--
target/riscv/insn_trans/trans_rvi.c.inc | 6 ++++
6 files changed, 57 insertions(+), 22 deletions(-)
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index d85e54b475..ddbfae37e5 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -83,6 +83,7 @@ struct RISCVCPUConfig {
bool ext_zdinx;
bool ext_zaamo;
bool ext_zacas;
+ bool ext_zama16b;
bool ext_zalrsc;
bool ext_zawrs;
bool ext_zfa;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index f4f8287a6d..de9c06904f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -118,6 +118,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(za64rs, PRIV_VERSION_1_12_0, has_priv_1_11),
ISA_EXT_DATA_ENTRY(zaamo, PRIV_VERSION_1_12_0, ext_zaamo),
ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas),
+ ISA_EXT_DATA_ENTRY(zama16b, PRIV_VERSION_1_13_0, ext_zama16b),
ISA_EXT_DATA_ENTRY(zalrsc, PRIV_VERSION_1_12_0, ext_zalrsc),
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
@@ -1476,6 +1477,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
MULTI_EXT_CFG_BOOL("zimop", ext_zimop, false),
MULTI_EXT_CFG_BOOL("zcmop", ext_zcmop, false),
MULTI_EXT_CFG_BOOL("zacas", ext_zacas, false),
+ MULTI_EXT_CFG_BOOL("zama16b", ext_zama16b, false),
MULTI_EXT_CFG_BOOL("zaamo", ext_zaamo, false),
MULTI_EXT_CFG_BOOL("zalrsc", ext_zalrsc, false),
MULTI_EXT_CFG_BOOL("zawrs", ext_zawrs, true),
diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
index 4a9e4591d1..eb080baddd 100644
--- a/target/riscv/insn_trans/trans_rva.c.inc
+++ b/target/riscv/insn_trans/trans_rva.c.inc
@@ -103,6 +103,12 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
TCGv dest = dest_gpr(ctx, a->rd);
TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE);
+ if (ctx->cfg_ptr->ext_zama16b) {
+ mop |= MO_ATOM_WITHIN16;
+ } else {
+ mop |= MO_ALIGN;
+ }
+
decode_save_opc(ctx);
src1 = get_address(ctx, a->rs1, 0);
func(dest, src1, src2, ctx->mem_idx, mop);
@@ -126,55 +132,55 @@ static bool trans_sc_w(DisasContext *ctx, arg_sc_w *a)
static bool trans_amoswap_w(DisasContext *ctx, arg_amoswap_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TESL));
+ return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TESL);
}
static bool trans_amoadd_w(DisasContext *ctx, arg_amoadd_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, (MO_ALIGN | MO_TESL));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TESL);
}
static bool trans_amoxor_w(DisasContext *ctx, arg_amoxor_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, (MO_ALIGN | MO_TESL));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TESL);
}
static bool trans_amoand_w(DisasContext *ctx, arg_amoand_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, (MO_ALIGN | MO_TESL));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TESL);
}
static bool trans_amoor_w(DisasContext *ctx, arg_amoor_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, (MO_ALIGN | MO_TESL));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TESL);
}
static bool trans_amomin_w(DisasContext *ctx, arg_amomin_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, (MO_ALIGN | MO_TESL));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TESL);
}
static bool trans_amomax_w(DisasContext *ctx, arg_amomax_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, (MO_ALIGN | MO_TESL));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TESL);
}
static bool trans_amominu_w(DisasContext *ctx, arg_amominu_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, (MO_ALIGN | MO_TESL));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TESL);
}
static bool trans_amomaxu_w(DisasContext *ctx, arg_amomaxu_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TESL));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TESL);
}
static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a)
@@ -195,61 +201,61 @@ static bool trans_amoswap_d(DisasContext *ctx, arg_amoswap_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TEUQ));
+ return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TEUQ);
}
static bool trans_amoadd_d(DisasContext *ctx, arg_amoadd_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, (MO_ALIGN | MO_TEUQ));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TEUQ);
}
static bool trans_amoxor_d(DisasContext *ctx, arg_amoxor_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, (MO_ALIGN | MO_TEUQ));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TEUQ);
}
static bool trans_amoand_d(DisasContext *ctx, arg_amoand_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, (MO_ALIGN | MO_TEUQ));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TEUQ);
}
static bool trans_amoor_d(DisasContext *ctx, arg_amoor_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, (MO_ALIGN | MO_TEUQ));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TEUQ);
}
static bool trans_amomin_d(DisasContext *ctx, arg_amomin_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, (MO_ALIGN | MO_TEUQ));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TEUQ);
}
static bool trans_amomax_d(DisasContext *ctx, arg_amomax_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, (MO_ALIGN | MO_TEUQ));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TEUQ);
}
static bool trans_amominu_d(DisasContext *ctx, arg_amominu_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, (MO_ALIGN | MO_TEUQ));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TEUQ);
}
static bool trans_amomaxu_d(DisasContext *ctx, arg_amomaxu_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
- return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TEUQ));
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TEUQ);
}
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
index d9ce9e407f..1f5fac65a2 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -42,13 +42,18 @@
static bool trans_fld(DisasContext *ctx, arg_fld *a)
{
TCGv addr;
+ MemOp memop = MO_TEUQ;
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVD);
+ if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) {
+ memop |= MO_ATOM_WITHIN16;
+ }
+
decode_save_opc(ctx);
addr = get_address(ctx, a->rs1, a->imm);
- tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEUQ);
+ tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, memop);
mark_fs_dirty(ctx);
return true;
@@ -57,13 +62,18 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
{
TCGv addr;
+ MemOp memop = MO_TEUQ;
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVD);
+ if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) {
+ memop |= MO_ATOM_WITHIN16;
+ }
+
decode_save_opc(ctx);
addr = get_address(ctx, a->rs1, a->imm);
- tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUQ);
+ tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, memop);
return true;
}
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
index 97a368970b..f771aa1939 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -43,14 +43,19 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
{
TCGv_i64 dest;
TCGv addr;
+ MemOp memop = MO_TEUL;
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVF);
+ if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) {
+ memop |= MO_ATOM_WITHIN16;
+ }
+
decode_save_opc(ctx);
addr = get_address(ctx, a->rs1, a->imm);
dest = cpu_fpr[a->rd];
- tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
+ tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, memop);
gen_nanbox_s(dest, dest);
mark_fs_dirty(ctx);
@@ -60,13 +65,18 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
{
TCGv addr;
+ MemOp memop = MO_TEUL;
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVF);
+ if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) {
+ memop |= MO_ATOM_WITHIN16;
+ }
+
decode_save_opc(ctx);
addr = get_address(ctx, a->rs1, a->imm);
- tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
+ tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, memop);
return true;
}
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index ad40d3e87f..98e3806d5e 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -268,6 +268,9 @@ static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
{
bool out;
+ if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) {
+ memop |= MO_ATOM_WITHIN16;
+ }
decode_save_opc(ctx);
if (get_xl(ctx) == MXL_RV128) {
out = gen_load_i128(ctx, a, memop);
@@ -366,6 +369,9 @@ static bool gen_store_i128(DisasContext *ctx, arg_sb *a, MemOp memop)
static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
{
+ if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) {
+ memop |= MO_ATOM_WITHIN16;
+ }
decode_save_opc(ctx);
if (get_xl(ctx) == MXL_RV128) {
return gen_store_i128(ctx, a, memop);
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PULL 05/30] target/riscv: Support Zama16b extension
2024-07-18 2:09 ` [PULL 05/30] target/riscv: Support Zama16b extension Alistair Francis
@ 2024-07-22 23:32 ` Alistair Francis
2024-07-23 1:15 ` LIU Zhiwei
0 siblings, 1 reply; 45+ messages in thread
From: Alistair Francis @ 2024-07-22 23:32 UTC (permalink / raw)
To: qemu-devel; +Cc: LIU Zhiwei, Alistair Francis
On Thu, Jul 18, 2024 at 12:10 PM Alistair Francis <alistair23@gmail.com> wrote:
>
> From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
>
> Zama16b is the property that misaligned load/stores/atomics within
> a naturally aligned 16-byte region are atomic.
>
> According to the specification, Zama16b applies only to AMOs, loads
> and stores defined in the base ISAs, and loads and stores of no more
> than XLEN bits defined in the F, D, and Q extensions. Thus it should
> not apply to zacas or RVC instructions.
>
> For an instruction in that set, if all accessed bytes lie within 16B granule,
> the instruction will not raise an exception for reasons of address alignment,
> and the instruction will give rise to only one memory operation for the
> purposes of RVWMO—i.e., it will execute atomically.
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> Message-ID: <20240709113652.1239-6-zhiwei_liu@linux.alibaba.com>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/cpu_cfg.h | 1 +
> target/riscv/cpu.c | 2 ++
> target/riscv/insn_trans/trans_rva.c.inc | 42 ++++++++++++++-----------
> target/riscv/insn_trans/trans_rvd.c.inc | 14 +++++++--
> target/riscv/insn_trans/trans_rvf.c.inc | 14 +++++++--
> target/riscv/insn_trans/trans_rvi.c.inc | 6 ++++
> 6 files changed, 57 insertions(+), 22 deletions(-)
>
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index d85e54b475..ddbfae37e5 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -83,6 +83,7 @@ struct RISCVCPUConfig {
> bool ext_zdinx;
> bool ext_zaamo;
> bool ext_zacas;
> + bool ext_zama16b;
> bool ext_zalrsc;
> bool ext_zawrs;
> bool ext_zfa;
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index f4f8287a6d..de9c06904f 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -118,6 +118,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
> ISA_EXT_DATA_ENTRY(za64rs, PRIV_VERSION_1_12_0, has_priv_1_11),
> ISA_EXT_DATA_ENTRY(zaamo, PRIV_VERSION_1_12_0, ext_zaamo),
> ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas),
> + ISA_EXT_DATA_ENTRY(zama16b, PRIV_VERSION_1_13_0, ext_zama16b),
> ISA_EXT_DATA_ENTRY(zalrsc, PRIV_VERSION_1_12_0, ext_zalrsc),
> ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
> ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
> @@ -1476,6 +1477,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
> MULTI_EXT_CFG_BOOL("zimop", ext_zimop, false),
> MULTI_EXT_CFG_BOOL("zcmop", ext_zcmop, false),
> MULTI_EXT_CFG_BOOL("zacas", ext_zacas, false),
> + MULTI_EXT_CFG_BOOL("zama16b", ext_zama16b, false),
> MULTI_EXT_CFG_BOOL("zaamo", ext_zaamo, false),
> MULTI_EXT_CFG_BOOL("zalrsc", ext_zalrsc, false),
> MULTI_EXT_CFG_BOOL("zawrs", ext_zawrs, true),
> diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
> index 4a9e4591d1..eb080baddd 100644
> --- a/target/riscv/insn_trans/trans_rva.c.inc
> +++ b/target/riscv/insn_trans/trans_rva.c.inc
> @@ -103,6 +103,12 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
> TCGv dest = dest_gpr(ctx, a->rd);
> TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE);
>
> + if (ctx->cfg_ptr->ext_zama16b) {
> + mop |= MO_ATOM_WITHIN16;
> + } else {
> + mop |= MO_ALIGN;
> + }
> +
> decode_save_opc(ctx);
> src1 = get_address(ctx, a->rs1, 0);
> func(dest, src1, src2, ctx->mem_idx, mop);
> @@ -126,55 +132,55 @@ static bool trans_sc_w(DisasContext *ctx, arg_sc_w *a)
> static bool trans_amoswap_w(DisasContext *ctx, arg_amoswap_w *a)
> {
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TESL));
> + return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TESL);
> }
>
> static bool trans_amoadd_w(DisasContext *ctx, arg_amoadd_w *a)
> {
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, (MO_ALIGN | MO_TESL));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TESL);
> }
>
> static bool trans_amoxor_w(DisasContext *ctx, arg_amoxor_w *a)
> {
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, (MO_ALIGN | MO_TESL));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TESL);
> }
>
> static bool trans_amoand_w(DisasContext *ctx, arg_amoand_w *a)
> {
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, (MO_ALIGN | MO_TESL));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TESL);
> }
>
> static bool trans_amoor_w(DisasContext *ctx, arg_amoor_w *a)
> {
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, (MO_ALIGN | MO_TESL));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TESL);
> }
>
> static bool trans_amomin_w(DisasContext *ctx, arg_amomin_w *a)
> {
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, (MO_ALIGN | MO_TESL));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TESL);
> }
>
> static bool trans_amomax_w(DisasContext *ctx, arg_amomax_w *a)
> {
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, (MO_ALIGN | MO_TESL));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TESL);
> }
>
> static bool trans_amominu_w(DisasContext *ctx, arg_amominu_w *a)
> {
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, (MO_ALIGN | MO_TESL));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TESL);
> }
>
> static bool trans_amomaxu_w(DisasContext *ctx, arg_amomaxu_w *a)
> {
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TESL));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TESL);
> }
>
> static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a)
> @@ -195,61 +201,61 @@ static bool trans_amoswap_d(DisasContext *ctx, arg_amoswap_d *a)
> {
> REQUIRE_64BIT(ctx);
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TEUQ));
> + return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TEUQ);
> }
>
> static bool trans_amoadd_d(DisasContext *ctx, arg_amoadd_d *a)
> {
> REQUIRE_64BIT(ctx);
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, (MO_ALIGN | MO_TEUQ));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TEUQ);
> }
>
> static bool trans_amoxor_d(DisasContext *ctx, arg_amoxor_d *a)
> {
> REQUIRE_64BIT(ctx);
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, (MO_ALIGN | MO_TEUQ));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TEUQ);
> }
>
> static bool trans_amoand_d(DisasContext *ctx, arg_amoand_d *a)
> {
> REQUIRE_64BIT(ctx);
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, (MO_ALIGN | MO_TEUQ));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TEUQ);
> }
>
> static bool trans_amoor_d(DisasContext *ctx, arg_amoor_d *a)
> {
> REQUIRE_64BIT(ctx);
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, (MO_ALIGN | MO_TEUQ));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TEUQ);
> }
>
> static bool trans_amomin_d(DisasContext *ctx, arg_amomin_d *a)
> {
> REQUIRE_64BIT(ctx);
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, (MO_ALIGN | MO_TEUQ));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TEUQ);
> }
>
> static bool trans_amomax_d(DisasContext *ctx, arg_amomax_d *a)
> {
> REQUIRE_64BIT(ctx);
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, (MO_ALIGN | MO_TEUQ));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TEUQ);
> }
>
> static bool trans_amominu_d(DisasContext *ctx, arg_amominu_d *a)
> {
> REQUIRE_64BIT(ctx);
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, (MO_ALIGN | MO_TEUQ));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TEUQ);
> }
>
> static bool trans_amomaxu_d(DisasContext *ctx, arg_amomaxu_d *a)
> {
> REQUIRE_64BIT(ctx);
> REQUIRE_A_OR_ZAAMO(ctx);
> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TEUQ));
> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TEUQ);
> }
> diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
> index d9ce9e407f..1f5fac65a2 100644
> --- a/target/riscv/insn_trans/trans_rvd.c.inc
> +++ b/target/riscv/insn_trans/trans_rvd.c.inc
> @@ -42,13 +42,18 @@
> static bool trans_fld(DisasContext *ctx, arg_fld *a)
> {
> TCGv addr;
> + MemOp memop = MO_TEUQ;
>
> REQUIRE_FPU;
> REQUIRE_EXT(ctx, RVD);
>
> + if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) {
Richard pointed out that checking the cur_insn_len looks a bit strange.
He's right, the length of the instruction has no impact. We should
instead just check for ext_zama16b
Do you mind sending a followup patch to remove all of the instruction
length checks?
Alistair
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PULL 05/30] target/riscv: Support Zama16b extension
2024-07-22 23:32 ` Alistair Francis
@ 2024-07-23 1:15 ` LIU Zhiwei
0 siblings, 0 replies; 45+ messages in thread
From: LIU Zhiwei @ 2024-07-23 1:15 UTC (permalink / raw)
To: Alistair Francis, qemu-devel; +Cc: LIU Zhiwei, Alistair Francis
On 2024/7/23 7:32, Alistair Francis wrote:
> On Thu, Jul 18, 2024 at 12:10 PM Alistair Francis <alistair23@gmail.com> wrote:
>> From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
>>
>> Zama16b is the property that misaligned load/stores/atomics within
>> a naturally aligned 16-byte region are atomic.
>>
>> According to the specification, Zama16b applies only to AMOs, loads
>> and stores defined in the base ISAs, and loads and stores of no more
>> than XLEN bits defined in the F, D, and Q extensions. Thus it should
>> not apply to zacas or RVC instructions.
>>
>> For an instruction in that set, if all accessed bytes lie within 16B granule,
>> the instruction will not raise an exception for reasons of address alignment,
>> and the instruction will give rise to only one memory operation for the
>> purposes of RVWMO—i.e., it will execute atomically.
>>
>> Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
>> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
>> Message-ID: <20240709113652.1239-6-zhiwei_liu@linux.alibaba.com>
>> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
>> ---
>> target/riscv/cpu_cfg.h | 1 +
>> target/riscv/cpu.c | 2 ++
>> target/riscv/insn_trans/trans_rva.c.inc | 42 ++++++++++++++-----------
>> target/riscv/insn_trans/trans_rvd.c.inc | 14 +++++++--
>> target/riscv/insn_trans/trans_rvf.c.inc | 14 +++++++--
>> target/riscv/insn_trans/trans_rvi.c.inc | 6 ++++
>> 6 files changed, 57 insertions(+), 22 deletions(-)
>>
>> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
>> index d85e54b475..ddbfae37e5 100644
>> --- a/target/riscv/cpu_cfg.h
>> +++ b/target/riscv/cpu_cfg.h
>> @@ -83,6 +83,7 @@ struct RISCVCPUConfig {
>> bool ext_zdinx;
>> bool ext_zaamo;
>> bool ext_zacas;
>> + bool ext_zama16b;
>> bool ext_zalrsc;
>> bool ext_zawrs;
>> bool ext_zfa;
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index f4f8287a6d..de9c06904f 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -118,6 +118,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
>> ISA_EXT_DATA_ENTRY(za64rs, PRIV_VERSION_1_12_0, has_priv_1_11),
>> ISA_EXT_DATA_ENTRY(zaamo, PRIV_VERSION_1_12_0, ext_zaamo),
>> ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas),
>> + ISA_EXT_DATA_ENTRY(zama16b, PRIV_VERSION_1_13_0, ext_zama16b),
>> ISA_EXT_DATA_ENTRY(zalrsc, PRIV_VERSION_1_12_0, ext_zalrsc),
>> ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
>> ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
>> @@ -1476,6 +1477,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
>> MULTI_EXT_CFG_BOOL("zimop", ext_zimop, false),
>> MULTI_EXT_CFG_BOOL("zcmop", ext_zcmop, false),
>> MULTI_EXT_CFG_BOOL("zacas", ext_zacas, false),
>> + MULTI_EXT_CFG_BOOL("zama16b", ext_zama16b, false),
>> MULTI_EXT_CFG_BOOL("zaamo", ext_zaamo, false),
>> MULTI_EXT_CFG_BOOL("zalrsc", ext_zalrsc, false),
>> MULTI_EXT_CFG_BOOL("zawrs", ext_zawrs, true),
>> diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
>> index 4a9e4591d1..eb080baddd 100644
>> --- a/target/riscv/insn_trans/trans_rva.c.inc
>> +++ b/target/riscv/insn_trans/trans_rva.c.inc
>> @@ -103,6 +103,12 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
>> TCGv dest = dest_gpr(ctx, a->rd);
>> TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE);
>>
>> + if (ctx->cfg_ptr->ext_zama16b) {
>> + mop |= MO_ATOM_WITHIN16;
>> + } else {
>> + mop |= MO_ALIGN;
>> + }
>> +
>> decode_save_opc(ctx);
>> src1 = get_address(ctx, a->rs1, 0);
>> func(dest, src1, src2, ctx->mem_idx, mop);
>> @@ -126,55 +132,55 @@ static bool trans_sc_w(DisasContext *ctx, arg_sc_w *a)
>> static bool trans_amoswap_w(DisasContext *ctx, arg_amoswap_w *a)
>> {
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TESL));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TESL);
>> }
>>
>> static bool trans_amoadd_w(DisasContext *ctx, arg_amoadd_w *a)
>> {
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, (MO_ALIGN | MO_TESL));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TESL);
>> }
>>
>> static bool trans_amoxor_w(DisasContext *ctx, arg_amoxor_w *a)
>> {
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, (MO_ALIGN | MO_TESL));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TESL);
>> }
>>
>> static bool trans_amoand_w(DisasContext *ctx, arg_amoand_w *a)
>> {
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, (MO_ALIGN | MO_TESL));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TESL);
>> }
>>
>> static bool trans_amoor_w(DisasContext *ctx, arg_amoor_w *a)
>> {
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, (MO_ALIGN | MO_TESL));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TESL);
>> }
>>
>> static bool trans_amomin_w(DisasContext *ctx, arg_amomin_w *a)
>> {
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, (MO_ALIGN | MO_TESL));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TESL);
>> }
>>
>> static bool trans_amomax_w(DisasContext *ctx, arg_amomax_w *a)
>> {
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, (MO_ALIGN | MO_TESL));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TESL);
>> }
>>
>> static bool trans_amominu_w(DisasContext *ctx, arg_amominu_w *a)
>> {
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, (MO_ALIGN | MO_TESL));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TESL);
>> }
>>
>> static bool trans_amomaxu_w(DisasContext *ctx, arg_amomaxu_w *a)
>> {
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TESL));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TESL);
>> }
>>
>> static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a)
>> @@ -195,61 +201,61 @@ static bool trans_amoswap_d(DisasContext *ctx, arg_amoswap_d *a)
>> {
>> REQUIRE_64BIT(ctx);
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TEUQ));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TEUQ);
>> }
>>
>> static bool trans_amoadd_d(DisasContext *ctx, arg_amoadd_d *a)
>> {
>> REQUIRE_64BIT(ctx);
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, (MO_ALIGN | MO_TEUQ));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TEUQ);
>> }
>>
>> static bool trans_amoxor_d(DisasContext *ctx, arg_amoxor_d *a)
>> {
>> REQUIRE_64BIT(ctx);
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, (MO_ALIGN | MO_TEUQ));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TEUQ);
>> }
>>
>> static bool trans_amoand_d(DisasContext *ctx, arg_amoand_d *a)
>> {
>> REQUIRE_64BIT(ctx);
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, (MO_ALIGN | MO_TEUQ));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TEUQ);
>> }
>>
>> static bool trans_amoor_d(DisasContext *ctx, arg_amoor_d *a)
>> {
>> REQUIRE_64BIT(ctx);
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, (MO_ALIGN | MO_TEUQ));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TEUQ);
>> }
>>
>> static bool trans_amomin_d(DisasContext *ctx, arg_amomin_d *a)
>> {
>> REQUIRE_64BIT(ctx);
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, (MO_ALIGN | MO_TEUQ));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TEUQ);
>> }
>>
>> static bool trans_amomax_d(DisasContext *ctx, arg_amomax_d *a)
>> {
>> REQUIRE_64BIT(ctx);
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, (MO_ALIGN | MO_TEUQ));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TEUQ);
>> }
>>
>> static bool trans_amominu_d(DisasContext *ctx, arg_amominu_d *a)
>> {
>> REQUIRE_64BIT(ctx);
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, (MO_ALIGN | MO_TEUQ));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TEUQ);
>> }
>>
>> static bool trans_amomaxu_d(DisasContext *ctx, arg_amomaxu_d *a)
>> {
>> REQUIRE_64BIT(ctx);
>> REQUIRE_A_OR_ZAAMO(ctx);
>> - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TEUQ));
>> + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TEUQ);
>> }
>> diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
>> index d9ce9e407f..1f5fac65a2 100644
>> --- a/target/riscv/insn_trans/trans_rvd.c.inc
>> +++ b/target/riscv/insn_trans/trans_rvd.c.inc
>> @@ -42,13 +42,18 @@
>> static bool trans_fld(DisasContext *ctx, arg_fld *a)
>> {
>> TCGv addr;
>> + MemOp memop = MO_TEUQ;
>>
>> REQUIRE_FPU;
>> REQUIRE_EXT(ctx, RVD);
>>
>> + if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) {
> Richard pointed out that checking the cur_insn_len looks a bit strange.
>
> He's right, the length of the instruction has no impact. We should
> instead just check for ext_zama16b
>
> Do you mind sending a followup patch to remove all of the instruction
> length checks?
Sure. Once I didn't notice that these instruction decode functions, such
as trans_fld, will never be RVC instructions.
Thanks,
Zhiwei
>
> Alistair
>
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PULL 06/30] target/riscv: Move gen_amo before implement Zabha
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (4 preceding siblings ...)
2024-07-18 2:09 ` [PULL 05/30] target/riscv: Support Zama16b extension Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:09 ` [PULL 07/30] target/riscv: Add AMO instructions for Zabha Alistair Francis
` (24 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, LIU Zhiwei, Alistair Francis
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240709113652.1239-7-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/translate.c | 21 +++++++++++++++++++++
target/riscv/insn_trans/trans_rva.c.inc | 21 ---------------------
2 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 8a546f4ece..133550d6e2 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1077,6 +1077,27 @@ static bool gen_unary_per_ol(DisasContext *ctx, arg_r2 *a, DisasExtend ext,
return gen_unary(ctx, a, ext, f_tl);
}
+static bool gen_amo(DisasContext *ctx, arg_atomic *a,
+ void(*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
+ MemOp mop)
+{
+ TCGv dest = dest_gpr(ctx, a->rd);
+ TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE);
+
+ if (ctx->cfg_ptr->ext_zama16b) {
+ mop |= MO_ATOM_WITHIN16;
+ } else {
+ mop |= MO_ALIGN;
+ }
+
+ decode_save_opc(ctx);
+ src1 = get_address(ctx, a->rs1, 0);
+ func(dest, src1, src2, ctx->mem_idx, mop);
+
+ gen_set_gpr(ctx, a->rd, dest);
+ return true;
+}
+
static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
index eb080baddd..39bbf60f3c 100644
--- a/target/riscv/insn_trans/trans_rva.c.inc
+++ b/target/riscv/insn_trans/trans_rva.c.inc
@@ -96,27 +96,6 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
return true;
}
-static bool gen_amo(DisasContext *ctx, arg_atomic *a,
- void(*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
- MemOp mop)
-{
- TCGv dest = dest_gpr(ctx, a->rd);
- TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE);
-
- if (ctx->cfg_ptr->ext_zama16b) {
- mop |= MO_ATOM_WITHIN16;
- } else {
- mop |= MO_ALIGN;
- }
-
- decode_save_opc(ctx);
- src1 = get_address(ctx, a->rs1, 0);
- func(dest, src1, src2, ctx->mem_idx, mop);
-
- gen_set_gpr(ctx, a->rd, dest);
- return true;
-}
-
static bool trans_lr_w(DisasContext *ctx, arg_lr_w *a)
{
REQUIRE_A_OR_ZALRSC(ctx);
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 07/30] target/riscv: Add AMO instructions for Zabha
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (5 preceding siblings ...)
2024-07-18 2:09 ` [PULL 06/30] target/riscv: Move gen_amo before implement Zabha Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:09 ` [PULL 08/30] target/riscv: Move gen_cmpxchg before adding amocas.[b|h] Alistair Francis
` (23 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, LIU Zhiwei, Alistair Francis
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240709113652.1239-8-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu_cfg.h | 1 +
target/riscv/insn32.decode | 20 +++
target/riscv/translate.c | 4 +-
target/riscv/insn_trans/trans_rvzabha.c.inc | 131 ++++++++++++++++++++
4 files changed, 155 insertions(+), 1 deletion(-)
create mode 100644 target/riscv/insn_trans/trans_rvzabha.c.inc
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index ddbfae37e5..120905a254 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -84,6 +84,7 @@ struct RISCVCPUConfig {
bool ext_zaamo;
bool ext_zacas;
bool ext_zama16b;
+ bool ext_zabha;
bool ext_zalrsc;
bool ext_zawrs;
bool ext_zfa;
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 60da673153..3bad6372f2 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -1021,3 +1021,23 @@ amocas_q 00101 . . ..... ..... 100 ..... 0101111 @atom_st
# *** Zimop may-be-operation extension ***
mop_r_n 1 . 00 .. 0111 .. ..... 100 ..... 1110011 @mop5
mop_rr_n 1 . 00 .. 1 ..... ..... 100 ..... 1110011 @mop3
+
+# *** Zabhb Standard Extension ***
+amoswap_b 00001 . . ..... ..... 000 ..... 0101111 @atom_st
+amoadd_b 00000 . . ..... ..... 000 ..... 0101111 @atom_st
+amoxor_b 00100 . . ..... ..... 000 ..... 0101111 @atom_st
+amoand_b 01100 . . ..... ..... 000 ..... 0101111 @atom_st
+amoor_b 01000 . . ..... ..... 000 ..... 0101111 @atom_st
+amomin_b 10000 . . ..... ..... 000 ..... 0101111 @atom_st
+amomax_b 10100 . . ..... ..... 000 ..... 0101111 @atom_st
+amominu_b 11000 . . ..... ..... 000 ..... 0101111 @atom_st
+amomaxu_b 11100 . . ..... ..... 000 ..... 0101111 @atom_st
+amoswap_h 00001 . . ..... ..... 001 ..... 0101111 @atom_st
+amoadd_h 00000 . . ..... ..... 001 ..... 0101111 @atom_st
+amoxor_h 00100 . . ..... ..... 001 ..... 0101111 @atom_st
+amoand_h 01100 . . ..... ..... 001 ..... 0101111 @atom_st
+amoor_h 01000 . . ..... ..... 001 ..... 0101111 @atom_st
+amomin_h 10000 . . ..... ..... 001 ..... 0101111 @atom_st
+amomax_h 10100 . . ..... ..... 001 ..... 0101111 @atom_st
+amominu_h 11000 . . ..... ..... 001 ..... 0101111 @atom_st
+amomaxu_h 11100 . . ..... ..... 001 ..... 0101111 @atom_st
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 133550d6e2..4a3e786560 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1083,8 +1083,9 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
{
TCGv dest = dest_gpr(ctx, a->rd);
TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE);
+ MemOp size = mop & MO_SIZE;
- if (ctx->cfg_ptr->ext_zama16b) {
+ if (ctx->cfg_ptr->ext_zama16b && size >= MO_32) {
mop |= MO_ATOM_WITHIN16;
} else {
mop |= MO_ALIGN;
@@ -1118,6 +1119,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
#include "insn_trans/trans_rvb.c.inc"
#include "insn_trans/trans_rvzicond.c.inc"
#include "insn_trans/trans_rvzacas.c.inc"
+#include "insn_trans/trans_rvzabha.c.inc"
#include "insn_trans/trans_rvzawrs.c.inc"
#include "insn_trans/trans_rvzicbo.c.inc"
#include "insn_trans/trans_rvzimop.c.inc"
diff --git a/target/riscv/insn_trans/trans_rvzabha.c.inc b/target/riscv/insn_trans/trans_rvzabha.c.inc
new file mode 100644
index 0000000000..9093a1cfc1
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzabha.c.inc
@@ -0,0 +1,131 @@
+/*
+ * RISC-V translation routines for the Zabha Standard Extension.
+ *
+ * Copyright (c) 2024 Alibaba Group
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define REQUIRE_ZABHA(ctx) do { \
+ if (!ctx->cfg_ptr->ext_zabha) { \
+ return false; \
+ } \
+} while (0)
+
+static bool trans_amoswap_b(DisasContext *ctx, arg_amoswap_b *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_SB);
+}
+
+static bool trans_amoadd_b(DisasContext *ctx, arg_amoadd_b *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_SB);
+}
+
+static bool trans_amoxor_b(DisasContext *ctx, arg_amoxor_b *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_SB);
+}
+
+static bool trans_amoand_b(DisasContext *ctx, arg_amoand_b *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_SB);
+}
+
+static bool trans_amoor_b(DisasContext *ctx, arg_amoor_b *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_SB);
+}
+
+static bool trans_amomin_b(DisasContext *ctx, arg_amomin_b *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_SB);
+}
+
+static bool trans_amomax_b(DisasContext *ctx, arg_amomax_b *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_SB);
+}
+
+static bool trans_amominu_b(DisasContext *ctx, arg_amominu_b *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_SB);
+}
+
+static bool trans_amomaxu_b(DisasContext *ctx, arg_amomaxu_b *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_SB);
+}
+
+static bool trans_amoswap_h(DisasContext *ctx, arg_amoswap_h *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TESW);
+}
+
+static bool trans_amoadd_h(DisasContext *ctx, arg_amoadd_h *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TESW);
+}
+
+static bool trans_amoxor_h(DisasContext *ctx, arg_amoxor_h *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TESW);
+}
+
+static bool trans_amoand_h(DisasContext *ctx, arg_amoand_h *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TESW);
+}
+
+static bool trans_amoor_h(DisasContext *ctx, arg_amoor_h *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TESW);
+}
+
+static bool trans_amomin_h(DisasContext *ctx, arg_amomin_h *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TESW);
+}
+
+static bool trans_amomax_h(DisasContext *ctx, arg_amomax_h *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TESW);
+}
+
+static bool trans_amominu_h(DisasContext *ctx, arg_amominu_h *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TESW);
+}
+
+static bool trans_amomaxu_h(DisasContext *ctx, arg_amomaxu_h *a)
+{
+ REQUIRE_ZABHA(ctx);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TESW);
+}
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 08/30] target/riscv: Move gen_cmpxchg before adding amocas.[b|h]
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (6 preceding siblings ...)
2024-07-18 2:09 ` [PULL 07/30] target/riscv: Add AMO instructions for Zabha Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:09 ` [PULL 09/30] target/riscv: Add amocas.[b|h] for Zabha Alistair Francis
` (22 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, LIU Zhiwei, Alistair Francis
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240709113652.1239-9-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/translate.c | 13 +++++++++++++
target/riscv/insn_trans/trans_rvzacas.c.inc | 13 -------------
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 4a3e786560..acba90f170 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1099,6 +1099,19 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
return true;
}
+static bool gen_cmpxchg(DisasContext *ctx, arg_atomic *a, MemOp mop)
+{
+ TCGv dest = get_gpr(ctx, a->rd, EXT_NONE);
+ TCGv src1 = get_address(ctx, a->rs1, 0);
+ TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
+
+ decode_save_opc(ctx);
+ tcg_gen_atomic_cmpxchg_tl(dest, src1, dest, src2, ctx->mem_idx, mop);
+
+ gen_set_gpr(ctx, a->rd, dest);
+ return true;
+}
+
static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
diff --git a/target/riscv/insn_trans/trans_rvzacas.c.inc b/target/riscv/insn_trans/trans_rvzacas.c.inc
index 5d274d4c08..fcced99fc7 100644
--- a/target/riscv/insn_trans/trans_rvzacas.c.inc
+++ b/target/riscv/insn_trans/trans_rvzacas.c.inc
@@ -22,19 +22,6 @@
} \
} while (0)
-static bool gen_cmpxchg(DisasContext *ctx, arg_atomic *a, MemOp mop)
-{
- TCGv dest = get_gpr(ctx, a->rd, EXT_NONE);
- TCGv src1 = get_address(ctx, a->rs1, 0);
- TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
-
- decode_save_opc(ctx);
- tcg_gen_atomic_cmpxchg_tl(dest, src1, dest, src2, ctx->mem_idx, mop);
-
- gen_set_gpr(ctx, a->rd, dest);
- return true;
-}
-
static bool trans_amocas_w(DisasContext *ctx, arg_amocas_w *a)
{
REQUIRE_ZACAS(ctx);
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 09/30] target/riscv: Add amocas.[b|h] for Zabha
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (7 preceding siblings ...)
2024-07-18 2:09 ` [PULL 08/30] target/riscv: Move gen_cmpxchg before adding amocas.[b|h] Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:09 ` [PULL 10/30] target/riscv: Expose zabha extension as a cpu property Alistair Francis
` (21 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, LIU Zhiwei, Alistair Francis
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240709113652.1239-10-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/insn32.decode | 2 ++
target/riscv/insn_trans/trans_rvzabha.c.inc | 14 ++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 3bad6372f2..c45b8fa1d8 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -1041,3 +1041,5 @@ amomin_h 10000 . . ..... ..... 001 ..... 0101111 @atom_st
amomax_h 10100 . . ..... ..... 001 ..... 0101111 @atom_st
amominu_h 11000 . . ..... ..... 001 ..... 0101111 @atom_st
amomaxu_h 11100 . . ..... ..... 001 ..... 0101111 @atom_st
+amocas_b 00101 . . ..... ..... 000 ..... 0101111 @atom_st
+amocas_h 00101 . . ..... ..... 001 ..... 0101111 @atom_st
diff --git a/target/riscv/insn_trans/trans_rvzabha.c.inc b/target/riscv/insn_trans/trans_rvzabha.c.inc
index 9093a1cfc1..ce8edcba62 100644
--- a/target/riscv/insn_trans/trans_rvzabha.c.inc
+++ b/target/riscv/insn_trans/trans_rvzabha.c.inc
@@ -129,3 +129,17 @@ static bool trans_amomaxu_h(DisasContext *ctx, arg_amomaxu_h *a)
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TESW);
}
+
+static bool trans_amocas_b(DisasContext *ctx, arg_amocas_b *a)
+{
+ REQUIRE_ZACAS(ctx);
+ REQUIRE_ZABHA(ctx);
+ return gen_cmpxchg(ctx, a, MO_SB);
+}
+
+static bool trans_amocas_h(DisasContext *ctx, arg_amocas_h *a)
+{
+ REQUIRE_ZACAS(ctx);
+ REQUIRE_ZABHA(ctx);
+ return gen_cmpxchg(ctx, a, MO_ALIGN | MO_TESW);
+}
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 10/30] target/riscv: Expose zabha extension as a cpu property
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (8 preceding siblings ...)
2024-07-18 2:09 ` [PULL 09/30] target/riscv: Add amocas.[b|h] for Zabha Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:09 ` [PULL 11/30] disas/riscv: Support zabha disassemble Alistair Francis
` (20 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, LIU Zhiwei, Alistair Francis
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240709113652.1239-11-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index de9c06904f..33ef4eb795 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -117,6 +117,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
ISA_EXT_DATA_ENTRY(za64rs, PRIV_VERSION_1_12_0, has_priv_1_11),
ISA_EXT_DATA_ENTRY(zaamo, PRIV_VERSION_1_12_0, ext_zaamo),
+ ISA_EXT_DATA_ENTRY(zabha, PRIV_VERSION_1_13_0, ext_zabha),
ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas),
ISA_EXT_DATA_ENTRY(zama16b, PRIV_VERSION_1_13_0, ext_zama16b),
ISA_EXT_DATA_ENTRY(zalrsc, PRIV_VERSION_1_12_0, ext_zalrsc),
@@ -1478,6 +1479,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
MULTI_EXT_CFG_BOOL("zcmop", ext_zcmop, false),
MULTI_EXT_CFG_BOOL("zacas", ext_zacas, false),
MULTI_EXT_CFG_BOOL("zama16b", ext_zama16b, false),
+ MULTI_EXT_CFG_BOOL("zabha", ext_zabha, false),
MULTI_EXT_CFG_BOOL("zaamo", ext_zaamo, false),
MULTI_EXT_CFG_BOOL("zalrsc", ext_zalrsc, false),
MULTI_EXT_CFG_BOOL("zawrs", ext_zawrs, true),
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 11/30] disas/riscv: Support zabha disassemble
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (9 preceding siblings ...)
2024-07-18 2:09 ` [PULL 10/30] target/riscv: Expose zabha extension as a cpu property Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:09 ` [PULL 12/30] target/riscv: Validate the mode in write_vstvec Alistair Francis
` (19 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, LIU Zhiwei, Alistair Francis
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240709113652.1239-12-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
disas/riscv.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/disas/riscv.c b/disas/riscv.c
index d29cb1ff7d..c8364c2b07 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -954,6 +954,26 @@ typedef enum {
rv_c_mop_11 = 923,
rv_c_mop_13 = 924,
rv_c_mop_15 = 925,
+ rv_op_amoswap_b = 926,
+ rv_op_amoadd_b = 927,
+ rv_op_amoxor_b = 928,
+ rv_op_amoor_b = 929,
+ rv_op_amoand_b = 930,
+ rv_op_amomin_b = 931,
+ rv_op_amomax_b = 932,
+ rv_op_amominu_b = 933,
+ rv_op_amomaxu_b = 934,
+ rv_op_amoswap_h = 935,
+ rv_op_amoadd_h = 936,
+ rv_op_amoxor_h = 937,
+ rv_op_amoor_h = 938,
+ rv_op_amoand_h = 939,
+ rv_op_amomin_h = 940,
+ rv_op_amomax_h = 941,
+ rv_op_amominu_h = 942,
+ rv_op_amomaxu_h = 943,
+ rv_op_amocas_b = 944,
+ rv_op_amocas_h = 945,
} rv_op;
/* register names */
@@ -2192,6 +2212,26 @@ const rv_opcode_data rvi_opcode_data[] = {
{ "c.mop.11", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
{ "c.mop.13", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
{ "c.mop.15", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
+ { "amoswap.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amoadd.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amoxor.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amoor.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amoand.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amomin.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amomax.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amominu.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amomaxu.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amoswap.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amoadd.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amoxor.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amoor.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amoand.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amomin.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amomax.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amominu.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amomaxu.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amocas.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "amocas.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
};
/* CSR names */
@@ -2986,9 +3026,13 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 11:
switch (((inst >> 24) & 0b11111000) |
((inst >> 12) & 0b00000111)) {
+ case 0: op = rv_op_amoadd_b; break;
+ case 1: op = rv_op_amoadd_h; break;
case 2: op = rv_op_amoadd_w; break;
case 3: op = rv_op_amoadd_d; break;
case 4: op = rv_op_amoadd_q; break;
+ case 8: op = rv_op_amoswap_b; break;
+ case 9: op = rv_op_amoswap_h; break;
case 10: op = rv_op_amoswap_w; break;
case 11: op = rv_op_amoswap_d; break;
case 12: op = rv_op_amoswap_q; break;
@@ -3010,27 +3054,43 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 26: op = rv_op_sc_w; break;
case 27: op = rv_op_sc_d; break;
case 28: op = rv_op_sc_q; break;
+ case 32: op = rv_op_amoxor_b; break;
+ case 33: op = rv_op_amoxor_h; break;
case 34: op = rv_op_amoxor_w; break;
case 35: op = rv_op_amoxor_d; break;
case 36: op = rv_op_amoxor_q; break;
+ case 40: op = rv_op_amocas_b; break;
+ case 41: op = rv_op_amocas_h; break;
case 42: op = rv_op_amocas_w; break;
case 43: op = rv_op_amocas_d; break;
case 44: op = rv_op_amocas_q; break;
+ case 64: op = rv_op_amoor_b; break;
+ case 65: op = rv_op_amoor_h; break;
case 66: op = rv_op_amoor_w; break;
case 67: op = rv_op_amoor_d; break;
case 68: op = rv_op_amoor_q; break;
+ case 96: op = rv_op_amoand_b; break;
+ case 97: op = rv_op_amoand_h; break;
case 98: op = rv_op_amoand_w; break;
case 99: op = rv_op_amoand_d; break;
case 100: op = rv_op_amoand_q; break;
+ case 128: op = rv_op_amomin_b; break;
+ case 129: op = rv_op_amomin_h; break;
case 130: op = rv_op_amomin_w; break;
case 131: op = rv_op_amomin_d; break;
case 132: op = rv_op_amomin_q; break;
+ case 160: op = rv_op_amomax_b; break;
+ case 161: op = rv_op_amomax_h; break;
case 162: op = rv_op_amomax_w; break;
case 163: op = rv_op_amomax_d; break;
case 164: op = rv_op_amomax_q; break;
+ case 192: op = rv_op_amominu_b; break;
+ case 193: op = rv_op_amominu_h; break;
case 194: op = rv_op_amominu_w; break;
case 195: op = rv_op_amominu_d; break;
case 196: op = rv_op_amominu_q; break;
+ case 224: op = rv_op_amomaxu_b; break;
+ case 225: op = rv_op_amomaxu_h; break;
case 226: op = rv_op_amomaxu_w; break;
case 227: op = rv_op_amomaxu_d; break;
case 228: op = rv_op_amomaxu_q; break;
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 12/30] target/riscv: Validate the mode in write_vstvec
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (10 preceding siblings ...)
2024-07-18 2:09 ` [PULL 11/30] disas/riscv: Support zabha disassemble Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:09 ` [PULL 13/30] disas/riscv: Add decode for Zawrs extension Alistair Francis
` (18 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Jiayi Li, Alistair Francis, LIU Zhiwei
From: Jiayi Li <lijiayi@eswincomputing.com>
Base on the riscv-privileged spec, vstvec substitutes for the usual stvec.
Therefore, the encoding of the MODE should also be restricted to 0 and 1.
Signed-off-by: Jiayi Li <lijiayi@eswincomputing.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Message-ID: <20240701022553.1982-1-lijiayi@eswincomputing.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/csr.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 432c59dc66..f9229d92ab 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3791,7 +3791,12 @@ static RISCVException read_vstvec(CPURISCVState *env, int csrno,
static RISCVException write_vstvec(CPURISCVState *env, int csrno,
target_ulong val)
{
- env->vstvec = val;
+ /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
+ if ((val & 3) < 2) {
+ env->vstvec = val;
+ } else {
+ qemu_log_mask(LOG_UNIMP, "CSR_VSTVEC: reserved mode not supported\n");
+ }
return RISCV_EXCP_NONE;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 13/30] disas/riscv: Add decode for Zawrs extension
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (11 preceding siblings ...)
2024-07-18 2:09 ` [PULL 12/30] target/riscv: Validate the mode in write_vstvec Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:09 ` [PULL 14/30] target/riscv/kvm: update KVM regs to Linux 6.10-rc5 Alistair Francis
` (17 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Balaji Ravikumar, Rob Bradford, Alistair Francis
From: Balaji Ravikumar <bravikumar@rivosinc.com>
Add disassembly support for these instructions from Zawrs:
* wrs.sto
* wrs.nto
Signed-off-by: Balaji Ravikumar <bravikumar@rivosinc.com>
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240705165316.127494-1-rbradford@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
disas/riscv.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/disas/riscv.c b/disas/riscv.c
index c8364c2b07..5965574d87 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -974,6 +974,8 @@ typedef enum {
rv_op_amomaxu_h = 943,
rv_op_amocas_b = 944,
rv_op_amocas_h = 945,
+ rv_op_wrs_sto = 946,
+ rv_op_wrs_nto = 947,
} rv_op;
/* register names */
@@ -2232,6 +2234,8 @@ const rv_opcode_data rvi_opcode_data[] = {
{ "amomaxu.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amocas.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amocas.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+ { "wrs.sto", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
+ { "wrs.nto", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
};
/* CSR names */
@@ -3980,6 +3984,8 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 0: op = rv_op_ecall; break;
case 32: op = rv_op_ebreak; break;
case 64: op = rv_op_uret; break;
+ case 416: op = rv_op_wrs_nto; break;
+ case 928: op = rv_op_wrs_sto; break;
}
break;
case 256:
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 14/30] target/riscv/kvm: update KVM regs to Linux 6.10-rc5
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (12 preceding siblings ...)
2024-07-18 2:09 ` [PULL 13/30] disas/riscv: Add decode for Zawrs extension Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:09 ` [PULL 15/30] target/riscv: Combine set_mode and set_virt functions Alistair Francis
` (16 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Daniel Henrique Barboza, Alistair Francis
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Two new regs added: ztso and zacas.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240709085431.455541-1-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/kvm/kvm-cpu.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 1047961fed..f6e3156b8d 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -281,6 +281,7 @@ static KVMCPUConfig kvm_multi_ext_cfgs[] = {
KVM_EXT_CFG("zihintntl", ext_zihintntl, KVM_RISCV_ISA_EXT_ZIHINTNTL),
KVM_EXT_CFG("zihintpause", ext_zihintpause, KVM_RISCV_ISA_EXT_ZIHINTPAUSE),
KVM_EXT_CFG("zihpm", ext_zihpm, KVM_RISCV_ISA_EXT_ZIHPM),
+ KVM_EXT_CFG("zacas", ext_zacas, KVM_RISCV_ISA_EXT_ZACAS),
KVM_EXT_CFG("zfa", ext_zfa, KVM_RISCV_ISA_EXT_ZFA),
KVM_EXT_CFG("zfh", ext_zfh, KVM_RISCV_ISA_EXT_ZFH),
KVM_EXT_CFG("zfhmin", ext_zfhmin, KVM_RISCV_ISA_EXT_ZFHMIN),
@@ -298,6 +299,7 @@ static KVMCPUConfig kvm_multi_ext_cfgs[] = {
KVM_EXT_CFG("zksed", ext_zksed, KVM_RISCV_ISA_EXT_ZKSED),
KVM_EXT_CFG("zksh", ext_zksh, KVM_RISCV_ISA_EXT_ZKSH),
KVM_EXT_CFG("zkt", ext_zkt, KVM_RISCV_ISA_EXT_ZKT),
+ KVM_EXT_CFG("ztso", ext_ztso, KVM_RISCV_ISA_EXT_ZTSO),
KVM_EXT_CFG("zvbb", ext_zvbb, KVM_RISCV_ISA_EXT_ZVBB),
KVM_EXT_CFG("zvbc", ext_zvbc, KVM_RISCV_ISA_EXT_ZVBC),
KVM_EXT_CFG("zvfh", ext_zvfh, KVM_RISCV_ISA_EXT_ZVFH),
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 15/30] target/riscv: Combine set_mode and set_virt functions.
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (13 preceding siblings ...)
2024-07-18 2:09 ` [PULL 14/30] target/riscv/kvm: update KVM regs to Linux 6.10-rc5 Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:09 ` [PULL 16/30] target/riscv: Fix the predicate functions for mhpmeventhX CSRs Alistair Francis
` (15 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Rajnesh Kanwal, Alistair Francis,
Daniel Henrique Barboza
From: Rajnesh Kanwal <rkanwal@rivosinc.com>
Combining riscv_cpu_set_virt_enabled() and riscv_cpu_set_mode()
functions. This is to make complete mode change information
available through a single function.
This allows to easily differentiate between HS->VS, VS->HS
and VS->VS transitions when executing state update codes.
For example: One use-case which inspired this change is
to update mode-specific instruction and cycle counters
which requires information of both prev mode and current
mode.
Signed-off-by: Rajnesh Kanwal <rkanwal@rivosinc.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20240711-smcntrpmf_v7-v8-1-b7c38ae7b263@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 2 +-
target/riscv/cpu_helper.c | 57 +++++++++++++++++++--------------------
target/riscv/op_helper.c | 17 +++++-------
3 files changed, 35 insertions(+), 41 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 87742047ce..6520e0f5d5 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -567,7 +567,7 @@ void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv,
RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit);
#endif /* !CONFIG_USER_ONLY */
-void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
+void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en);
void riscv_translate_init(void);
G_NORETURN void riscv_raise_exception(CPURISCVState *env,
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 6709622dd3..10d3fdaed3 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -619,30 +619,6 @@ void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen)
env->geilen = geilen;
}
-/* This function can only be called to set virt when RVH is enabled */
-void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable)
-{
- /* Flush the TLB on all virt mode changes. */
- if (env->virt_enabled != enable) {
- tlb_flush(env_cpu(env));
- }
-
- env->virt_enabled = enable;
-
- if (enable) {
- /*
- * The guest external interrupts from an interrupt controller are
- * delivered only when the Guest/VM is running (i.e. V=1). This means
- * any guest external interrupt which is triggered while the Guest/VM
- * is not running (i.e. V=0) will be missed on QEMU resulting in guest
- * with sluggish response to serial console input and other I/O events.
- *
- * To solve this, we check and inject interrupt after setting V=1.
- */
- riscv_cpu_update_mip(env, 0, 0);
- }
-}
-
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts)
{
CPURISCVState *env = &cpu->env;
@@ -715,7 +691,7 @@ void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv,
}
}
-void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
+void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en)
{
g_assert(newpriv <= PRV_M && newpriv != PRV_RESERVED);
@@ -736,6 +712,28 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
* preemptive context switch. As a result, do both.
*/
env->load_res = -1;
+
+ if (riscv_has_ext(env, RVH)) {
+ /* Flush the TLB on all virt mode changes. */
+ if (env->virt_enabled != virt_en) {
+ tlb_flush(env_cpu(env));
+ }
+
+ env->virt_enabled = virt_en;
+ if (virt_en) {
+ /*
+ * The guest external interrupts from an interrupt controller are
+ * delivered only when the Guest/VM is running (i.e. V=1). This
+ * means any guest external interrupt which is triggered while the
+ * Guest/VM is not running (i.e. V=0) will be missed on QEMU
+ * resulting in guest with sluggish response to serial console
+ * input and other I/O events.
+ *
+ * To solve this, we check and inject interrupt after setting V=1.
+ */
+ riscv_cpu_update_mip(env, 0, 0);
+ }
+ }
}
/*
@@ -1648,6 +1646,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
{
RISCVCPU *cpu = RISCV_CPU(cs);
CPURISCVState *env = &cpu->env;
+ bool virt = env->virt_enabled;
bool write_gva = false;
uint64_t s;
@@ -1778,7 +1777,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
htval = env->guest_phys_fault_addr;
- riscv_cpu_set_virt_enabled(env, 0);
+ virt = false;
} else {
/* Trap into HS mode */
env->hstatus = set_field(env->hstatus, HSTATUS_SPV, false);
@@ -1799,7 +1798,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
env->htinst = tinst;
env->pc = (env->stvec >> 2 << 2) +
((async && (env->stvec & 3) == 1) ? cause * 4 : 0);
- riscv_cpu_set_mode(env, PRV_S);
+ riscv_cpu_set_mode(env, PRV_S, virt);
} else {
/* handle the trap in M-mode */
if (riscv_has_ext(env, RVH)) {
@@ -1815,7 +1814,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
mtval2 = env->guest_phys_fault_addr;
/* Trapping to M mode, virt is disabled */
- riscv_cpu_set_virt_enabled(env, 0);
+ virt = false;
}
s = env->mstatus;
@@ -1830,7 +1829,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
env->mtinst = tinst;
env->pc = (env->mtvec >> 2 << 2) +
((async && (env->mtvec & 3) == 1) ? cause * 4 : 0);
- riscv_cpu_set_mode(env, PRV_M);
+ riscv_cpu_set_mode(env, PRV_M, virt);
}
/*
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 2baf5bc3ca..ec1408ba0f 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -264,7 +264,7 @@ void helper_cbo_inval(CPURISCVState *env, target_ulong address)
target_ulong helper_sret(CPURISCVState *env)
{
uint64_t mstatus;
- target_ulong prev_priv, prev_virt;
+ target_ulong prev_priv, prev_virt = env->virt_enabled;
if (!(env->priv >= PRV_S)) {
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
@@ -307,11 +307,9 @@ target_ulong helper_sret(CPURISCVState *env)
if (prev_virt) {
riscv_cpu_swap_hypervisor_regs(env);
}
-
- riscv_cpu_set_virt_enabled(env, prev_virt);
}
- riscv_cpu_set_mode(env, prev_priv);
+ riscv_cpu_set_mode(env, prev_priv, prev_virt);
return retpc;
}
@@ -347,16 +345,13 @@ target_ulong helper_mret(CPURISCVState *env)
mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
}
env->mstatus = mstatus;
- riscv_cpu_set_mode(env, prev_priv);
-
- if (riscv_has_ext(env, RVH)) {
- if (prev_virt) {
- riscv_cpu_swap_hypervisor_regs(env);
- }
- riscv_cpu_set_virt_enabled(env, prev_virt);
+ if (riscv_has_ext(env, RVH) && prev_virt) {
+ riscv_cpu_swap_hypervisor_regs(env);
}
+ riscv_cpu_set_mode(env, prev_priv, prev_virt);
+
return retpc;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 16/30] target/riscv: Fix the predicate functions for mhpmeventhX CSRs
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (14 preceding siblings ...)
2024-07-18 2:09 ` [PULL 15/30] target/riscv: Combine set_mode and set_virt functions Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:09 ` [PULL 17/30] target/riscv: Add cycle & instret privilege mode filtering properties Alistair Francis
` (14 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Atish Patra, Daniel Henrique Barboza,
Alistair Francis
From: Atish Patra <atishp@rivosinc.com>
mhpmeventhX CSRs are available for RV32. The predicate function
should check that first before checking sscofpmf extension.
Fixes: 14664483457b ("target/riscv: Add sscofpmf extension support")
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Message-ID: <20240711-smcntrpmf_v7-v8-2-b7c38ae7b263@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/csr.c | 67 ++++++++++++++++++++++++++--------------------
1 file changed, 38 insertions(+), 29 deletions(-)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index f9229d92ab..1bcf75f91f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -227,6 +227,15 @@ static RISCVException sscofpmf(CPURISCVState *env, int csrno)
return RISCV_EXCP_NONE;
}
+static RISCVException sscofpmf_32(CPURISCVState *env, int csrno)
+{
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ return sscofpmf(env, csrno);
+}
+
static RISCVException any(CPURISCVState *env, int csrno)
{
return RISCV_EXCP_NONE;
@@ -5106,91 +5115,91 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
[CSR_MHPMEVENT31] = { "mhpmevent31", any, read_mhpmevent,
write_mhpmevent },
- [CSR_MHPMEVENT3H] = { "mhpmevent3h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT3H] = { "mhpmevent3h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT4H] = { "mhpmevent4h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT4H] = { "mhpmevent4h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT5H] = { "mhpmevent5h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT5H] = { "mhpmevent5h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT6H] = { "mhpmevent6h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT6H] = { "mhpmevent6h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT7H] = { "mhpmevent7h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT7H] = { "mhpmevent7h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT8H] = { "mhpmevent8h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT8H] = { "mhpmevent8h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT9H] = { "mhpmevent9h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT9H] = { "mhpmevent9h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT10H] = { "mhpmevent10h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT10H] = { "mhpmevent10h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT11H] = { "mhpmevent11h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT11H] = { "mhpmevent11h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT12H] = { "mhpmevent12h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT12H] = { "mhpmevent12h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT13H] = { "mhpmevent13h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT13H] = { "mhpmevent13h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT14H] = { "mhpmevent14h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT14H] = { "mhpmevent14h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT15H] = { "mhpmevent15h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT15H] = { "mhpmevent15h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT16H] = { "mhpmevent16h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT16H] = { "mhpmevent16h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT17H] = { "mhpmevent17h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT17H] = { "mhpmevent17h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT18H] = { "mhpmevent18h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT18H] = { "mhpmevent18h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT19H] = { "mhpmevent19h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT19H] = { "mhpmevent19h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT20H] = { "mhpmevent20h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT20H] = { "mhpmevent20h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT21H] = { "mhpmevent21h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT21H] = { "mhpmevent21h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT22H] = { "mhpmevent22h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT22H] = { "mhpmevent22h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT23H] = { "mhpmevent23h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT23H] = { "mhpmevent23h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT24H] = { "mhpmevent24h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT24H] = { "mhpmevent24h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT25H] = { "mhpmevent25h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT25H] = { "mhpmevent25h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT26H] = { "mhpmevent26h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT26H] = { "mhpmevent26h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT27H] = { "mhpmevent27h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT27H] = { "mhpmevent27h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT28H] = { "mhpmevent28h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT28H] = { "mhpmevent28h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT29H] = { "mhpmevent29h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT29H] = { "mhpmevent29h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT30H] = { "mhpmevent30h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT30H] = { "mhpmevent30h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_MHPMEVENT31H] = { "mhpmevent31h", sscofpmf, read_mhpmeventh,
+ [CSR_MHPMEVENT31H] = { "mhpmevent31h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 17/30] target/riscv: Add cycle & instret privilege mode filtering properties
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (15 preceding siblings ...)
2024-07-18 2:09 ` [PULL 16/30] target/riscv: Fix the predicate functions for mhpmeventhX CSRs Alistair Francis
@ 2024-07-18 2:09 ` Alistair Francis
2024-07-18 2:10 ` [PULL 18/30] target/riscv: Add cycle & instret privilege mode filtering definitions Alistair Francis
` (13 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:09 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Kaiwen Xue, Daniel Henrique Barboza, Atish Patra,
Alistair Francis
From: Kaiwen Xue <kaiwenx@rivosinc.com>
This adds the properties for ISA extension smcntrpmf. Patches
implementing it will follow.
Signed-off-by: Kaiwen Xue <kaiwenx@rivosinc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240711-smcntrpmf_v7-v8-3-b7c38ae7b263@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu_cfg.h | 1 +
target/riscv/cpu.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 120905a254..8b272fb826 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -76,6 +76,7 @@ struct RISCVCPUConfig {
bool ext_ztso;
bool ext_smstateen;
bool ext_sstc;
+ bool ext_smcntrpmf;
bool ext_svadu;
bool ext_svinval;
bool ext_svnapot;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 33ef4eb795..4efe7ee3b0 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -182,6 +182,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
+ ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 18/30] target/riscv: Add cycle & instret privilege mode filtering definitions
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (16 preceding siblings ...)
2024-07-18 2:09 ` [PULL 17/30] target/riscv: Add cycle & instret privilege mode filtering properties Alistair Francis
@ 2024-07-18 2:10 ` Alistair Francis
2024-07-18 2:10 ` [PULL 19/30] target/riscv: Add cycle & instret privilege mode filtering support Alistair Francis
` (12 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:10 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Kaiwen Xue, Daniel Henrique Barboza, Alistair Francis,
Atish Patra
From: Kaiwen Xue <kaiwenx@rivosinc.com>
This adds the definitions for ISA extension smcntrpmf.
Signed-off-by: Kaiwen Xue <kaiwenx@rivosinc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Message-ID: <20240711-smcntrpmf_v7-v8-4-b7c38ae7b263@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 6 ++++++
target/riscv/cpu_bits.h | 29 +++++++++++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6520e0f5d5..980e2154cd 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -362,6 +362,12 @@ struct CPUArchState {
uint32_t mcountinhibit;
+ /* PMU cycle & instret privilege mode filtering */
+ target_ulong mcyclecfg;
+ target_ulong mcyclecfgh;
+ target_ulong minstretcfg;
+ target_ulong minstretcfgh;
+
/* PMU counter state */
PMUCTRState pmu_ctrs[RV_MAX_MHPMCOUNTERS];
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index c257c5ed7d..5faa817453 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -397,6 +397,10 @@
/* Machine counter-inhibit register */
#define CSR_MCOUNTINHIBIT 0x320
+/* Machine counter configuration registers */
+#define CSR_MCYCLECFG 0x321
+#define CSR_MINSTRETCFG 0x322
+
#define CSR_MHPMEVENT3 0x323
#define CSR_MHPMEVENT4 0x324
#define CSR_MHPMEVENT5 0x325
@@ -427,6 +431,9 @@
#define CSR_MHPMEVENT30 0x33e
#define CSR_MHPMEVENT31 0x33f
+#define CSR_MCYCLECFGH 0x721
+#define CSR_MINSTRETCFGH 0x722
+
#define CSR_MHPMEVENT3H 0x723
#define CSR_MHPMEVENT4H 0x724
#define CSR_MHPMEVENT5H 0x725
@@ -884,6 +891,28 @@ typedef enum RISCVException {
/* PMU related bits */
#define MIE_LCOFIE (1 << IRQ_PMU_OVF)
+#define MCYCLECFG_BIT_MINH BIT_ULL(62)
+#define MCYCLECFGH_BIT_MINH BIT(30)
+#define MCYCLECFG_BIT_SINH BIT_ULL(61)
+#define MCYCLECFGH_BIT_SINH BIT(29)
+#define MCYCLECFG_BIT_UINH BIT_ULL(60)
+#define MCYCLECFGH_BIT_UINH BIT(28)
+#define MCYCLECFG_BIT_VSINH BIT_ULL(59)
+#define MCYCLECFGH_BIT_VSINH BIT(27)
+#define MCYCLECFG_BIT_VUINH BIT_ULL(58)
+#define MCYCLECFGH_BIT_VUINH BIT(26)
+
+#define MINSTRETCFG_BIT_MINH BIT_ULL(62)
+#define MINSTRETCFGH_BIT_MINH BIT(30)
+#define MINSTRETCFG_BIT_SINH BIT_ULL(61)
+#define MINSTRETCFGH_BIT_SINH BIT(29)
+#define MINSTRETCFG_BIT_UINH BIT_ULL(60)
+#define MINSTRETCFGH_BIT_UINH BIT(28)
+#define MINSTRETCFG_BIT_VSINH BIT_ULL(59)
+#define MINSTRETCFGH_BIT_VSINH BIT(27)
+#define MINSTRETCFG_BIT_VUINH BIT_ULL(58)
+#define MINSTRETCFGH_BIT_VUINH BIT(26)
+
#define MHPMEVENT_BIT_OF BIT_ULL(63)
#define MHPMEVENTH_BIT_OF BIT(31)
#define MHPMEVENT_BIT_MINH BIT_ULL(62)
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 19/30] target/riscv: Add cycle & instret privilege mode filtering support
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (17 preceding siblings ...)
2024-07-18 2:10 ` [PULL 18/30] target/riscv: Add cycle & instret privilege mode filtering definitions Alistair Francis
@ 2024-07-18 2:10 ` Alistair Francis
2024-07-18 2:10 ` [PULL 20/30] target/riscv: Only set INH fields if priv mode is available Alistair Francis
` (11 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:10 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Kaiwen Xue, Atish Patra, Daniel Henrique Barboza,
Alistair Francis
From: Kaiwen Xue <kaiwenx@rivosinc.com>
QEMU only calculates dummy cycles and instructions, so there is no
actual means to stop the icount in QEMU. Hence this patch merely adds
the functionality of accessing the cfg registers, and cause no actual
effects on the counting of cycle and instret counters.
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Signed-off-by: Kaiwen Xue <kaiwenx@rivosinc.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240711-smcntrpmf_v7-v8-5-b7c38ae7b263@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu_bits.h | 12 ++++
target/riscv/csr.c | 138 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 149 insertions(+), 1 deletion(-)
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 5faa817453..32b068f18a 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -926,6 +926,18 @@ typedef enum RISCVException {
#define MHPMEVENT_BIT_VUINH BIT_ULL(58)
#define MHPMEVENTH_BIT_VUINH BIT(26)
+#define MHPMEVENT_FILTER_MASK (MHPMEVENT_BIT_MINH | \
+ MHPMEVENT_BIT_SINH | \
+ MHPMEVENT_BIT_UINH | \
+ MHPMEVENT_BIT_VSINH | \
+ MHPMEVENT_BIT_VUINH)
+
+#define MHPMEVENTH_FILTER_MASK (MHPMEVENTH_BIT_MINH | \
+ MHPMEVENTH_BIT_SINH | \
+ MHPMEVENTH_BIT_UINH | \
+ MHPMEVENTH_BIT_VSINH | \
+ MHPMEVENTH_BIT_VUINH)
+
#define MHPMEVENT_SSCOF_MASK _ULL(0xFFFF000000000000)
#define MHPMEVENT_IDX_MASK 0xFFFFF
#define MHPMEVENT_SSCOF_RESVD 16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 1bcf75f91f..8831d4f5ec 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -30,7 +30,6 @@
#include "qemu/guest-random.h"
#include "qapi/error.h"
-
/* CSR function table public API */
void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
{
@@ -236,6 +235,24 @@ static RISCVException sscofpmf_32(CPURISCVState *env, int csrno)
return sscofpmf(env, csrno);
}
+static RISCVException smcntrpmf(CPURISCVState *env, int csrno)
+{
+ if (!riscv_cpu_cfg(env)->ext_smcntrpmf) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException smcntrpmf_32(CPURISCVState *env, int csrno)
+{
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ return smcntrpmf(env, csrno);
+}
+
static RISCVException any(CPURISCVState *env, int csrno)
{
return RISCV_EXCP_NONE;
@@ -830,6 +847,111 @@ static RISCVException read_hpmcounterh(CPURISCVState *env, int csrno,
#else /* CONFIG_USER_ONLY */
+static RISCVException read_mcyclecfg(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+ *val = env->mcyclecfg;
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mcyclecfg(CPURISCVState *env, int csrno,
+ target_ulong val)
+{
+ uint64_t inh_avail_mask;
+
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ env->mcyclecfg = val;
+ } else {
+ /* Set xINH fields if priv mode supported */
+ inh_avail_mask = ~MHPMEVENT_FILTER_MASK | MCYCLECFG_BIT_MINH;
+ inh_avail_mask |= riscv_has_ext(env, RVU) ? MCYCLECFG_BIT_UINH : 0;
+ inh_avail_mask |= riscv_has_ext(env, RVS) ? MCYCLECFG_BIT_SINH : 0;
+ inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+ riscv_has_ext(env, RVU)) ? MCYCLECFG_BIT_VUINH : 0;
+ inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+ riscv_has_ext(env, RVS)) ? MCYCLECFG_BIT_VSINH : 0;
+ env->mcyclecfg = val & inh_avail_mask;
+ }
+
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_mcyclecfgh(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+ *val = env->mcyclecfgh;
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mcyclecfgh(CPURISCVState *env, int csrno,
+ target_ulong val)
+{
+ target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
+ MCYCLECFGH_BIT_MINH);
+
+ /* Set xINH fields if priv mode supported */
+ inh_avail_mask |= riscv_has_ext(env, RVU) ? MCYCLECFGH_BIT_UINH : 0;
+ inh_avail_mask |= riscv_has_ext(env, RVS) ? MCYCLECFGH_BIT_SINH : 0;
+ inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+ riscv_has_ext(env, RVU)) ? MCYCLECFGH_BIT_VUINH : 0;
+ inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+ riscv_has_ext(env, RVS)) ? MCYCLECFGH_BIT_VSINH : 0;
+
+ env->mcyclecfgh = val & inh_avail_mask;
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_minstretcfg(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+ *val = env->minstretcfg;
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_minstretcfg(CPURISCVState *env, int csrno,
+ target_ulong val)
+{
+ uint64_t inh_avail_mask;
+
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ env->minstretcfg = val;
+ } else {
+ inh_avail_mask = ~MHPMEVENT_FILTER_MASK | MINSTRETCFG_BIT_MINH;
+ inh_avail_mask |= riscv_has_ext(env, RVU) ? MINSTRETCFG_BIT_UINH : 0;
+ inh_avail_mask |= riscv_has_ext(env, RVS) ? MINSTRETCFG_BIT_SINH : 0;
+ inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+ riscv_has_ext(env, RVU)) ? MINSTRETCFG_BIT_VUINH : 0;
+ inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+ riscv_has_ext(env, RVS)) ? MINSTRETCFG_BIT_VSINH : 0;
+ env->minstretcfg = val & inh_avail_mask;
+ }
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_minstretcfgh(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+ *val = env->minstretcfgh;
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_minstretcfgh(CPURISCVState *env, int csrno,
+ target_ulong val)
+{
+ target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
+ MINSTRETCFGH_BIT_MINH);
+
+ inh_avail_mask |= riscv_has_ext(env, RVU) ? MINSTRETCFGH_BIT_UINH : 0;
+ inh_avail_mask |= riscv_has_ext(env, RVS) ? MINSTRETCFGH_BIT_SINH : 0;
+ inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+ riscv_has_ext(env, RVU)) ? MINSTRETCFGH_BIT_VUINH : 0;
+ inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+ riscv_has_ext(env, RVS)) ? MINSTRETCFGH_BIT_VSINH : 0;
+
+ env->minstretcfgh = val & inh_avail_mask;
+ return RISCV_EXCP_NONE;
+}
+
static RISCVException read_mhpmevent(CPURISCVState *env, int csrno,
target_ulong *val)
{
@@ -5056,6 +5178,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
write_mcountinhibit,
.min_priv_ver = PRIV_VERSION_1_11_0 },
+ [CSR_MCYCLECFG] = { "mcyclecfg", smcntrpmf, read_mcyclecfg,
+ write_mcyclecfg,
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
+ [CSR_MINSTRETCFG] = { "minstretcfg", smcntrpmf, read_minstretcfg,
+ write_minstretcfg,
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
+
[CSR_MHPMEVENT3] = { "mhpmevent3", any, read_mhpmevent,
write_mhpmevent },
[CSR_MHPMEVENT4] = { "mhpmevent4", any, read_mhpmevent,
@@ -5115,6 +5244,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
[CSR_MHPMEVENT31] = { "mhpmevent31", any, read_mhpmevent,
write_mhpmevent },
+ [CSR_MCYCLECFGH] = { "mcyclecfgh", smcntrpmf_32, read_mcyclecfgh,
+ write_mcyclecfgh,
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
+ [CSR_MINSTRETCFGH] = { "minstretcfgh", smcntrpmf_32, read_minstretcfgh,
+ write_minstretcfgh,
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
+
[CSR_MHPMEVENT3H] = { "mhpmevent3h", sscofpmf_32, read_mhpmeventh,
write_mhpmeventh,
.min_priv_ver = PRIV_VERSION_1_12_0 },
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 20/30] target/riscv: Only set INH fields if priv mode is available
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (18 preceding siblings ...)
2024-07-18 2:10 ` [PULL 19/30] target/riscv: Add cycle & instret privilege mode filtering support Alistair Francis
@ 2024-07-18 2:10 ` Alistair Francis
2024-07-18 2:10 ` [PULL 21/30] target/riscv: Implement privilege mode filtering for cycle/instret Alistair Francis
` (10 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:10 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Atish Patra, Alistair Francis
From: Atish Patra <atishp@rivosinc.com>
Currently, the INH fields are set in mhpmevent uncoditionally
without checking if a particular priv mode is supported or not.
Suggested-by: Alistair Francis <alistair23@gmail.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240711-smcntrpmf_v7-v8-6-b7c38ae7b263@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/csr.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 8831d4f5ec..364583dc03 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -967,13 +967,24 @@ static RISCVException write_mhpmevent(CPURISCVState *env, int csrno,
{
int evt_index = csrno - CSR_MCOUNTINHIBIT;
uint64_t mhpmevt_val = val;
-
- env->mhpmevent_val[evt_index] = val;
+ uint64_t inh_avail_mask;
if (riscv_cpu_mxl(env) == MXL_RV32) {
+ env->mhpmevent_val[evt_index] = val;
mhpmevt_val = mhpmevt_val |
((uint64_t)env->mhpmeventh_val[evt_index] << 32);
+ } else {
+ inh_avail_mask = ~MHPMEVENT_FILTER_MASK | MHPMEVENT_BIT_MINH;
+ inh_avail_mask |= riscv_has_ext(env, RVU) ? MHPMEVENT_BIT_UINH : 0;
+ inh_avail_mask |= riscv_has_ext(env, RVS) ? MHPMEVENT_BIT_SINH : 0;
+ inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+ riscv_has_ext(env, RVU)) ? MHPMEVENT_BIT_VUINH : 0;
+ inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+ riscv_has_ext(env, RVS)) ? MHPMEVENT_BIT_VSINH : 0;
+ mhpmevt_val = val & inh_avail_mask;
+ env->mhpmevent_val[evt_index] = mhpmevt_val;
}
+
riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
return RISCV_EXCP_NONE;
@@ -993,11 +1004,21 @@ static RISCVException write_mhpmeventh(CPURISCVState *env, int csrno,
target_ulong val)
{
int evt_index = csrno - CSR_MHPMEVENT3H + 3;
- uint64_t mhpmevth_val = val;
+ uint64_t mhpmevth_val;
uint64_t mhpmevt_val = env->mhpmevent_val[evt_index];
+ target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
+ MHPMEVENTH_BIT_MINH);
+
+ inh_avail_mask |= riscv_has_ext(env, RVU) ? MHPMEVENTH_BIT_UINH : 0;
+ inh_avail_mask |= riscv_has_ext(env, RVS) ? MHPMEVENTH_BIT_SINH : 0;
+ inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+ riscv_has_ext(env, RVU)) ? MHPMEVENTH_BIT_VUINH : 0;
+ inh_avail_mask |= (riscv_has_ext(env, RVH) &&
+ riscv_has_ext(env, RVS)) ? MHPMEVENTH_BIT_VSINH : 0;
+ mhpmevth_val = val & inh_avail_mask;
mhpmevt_val = mhpmevt_val | (mhpmevth_val << 32);
- env->mhpmeventh_val[evt_index] = val;
+ env->mhpmeventh_val[evt_index] = mhpmevth_val;
riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 21/30] target/riscv: Implement privilege mode filtering for cycle/instret
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (19 preceding siblings ...)
2024-07-18 2:10 ` [PULL 20/30] target/riscv: Only set INH fields if priv mode is available Alistair Francis
@ 2024-07-18 2:10 ` Alistair Francis
2024-07-20 14:43 ` Peter Maydell
2025-08-21 9:25 ` Philippe Mathieu-Daudé
2024-07-18 2:10 ` [PULL 22/30] target/riscv: Save counter values during countinhibit update Alistair Francis
` (9 subsequent siblings)
30 siblings, 2 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:10 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Atish Patra, Rajnesh Kanwal, Daniel Henrique Barboza,
Alistair Francis
From: Atish Patra <atishp@rivosinc.com>
Privilege mode filtering can also be emulated for cycle/instret by
tracking host_ticks/icount during each privilege mode switch. This
patch implements that for both cycle/instret and mhpmcounters. The
first one requires Smcntrpmf while the other one requires Sscofpmf
to be enabled.
The cycle/instret are still computed using host ticks when icount
is not enabled. Otherwise, they are computed using raw icount which
is more accurate in icount mode.
Co-Developed-by: Rajnesh Kanwal <rkanwal@rivosinc.com>
Signed-off-by: Rajnesh Kanwal <rkanwal@rivosinc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Message-ID: <20240711-smcntrpmf_v7-v8-7-b7c38ae7b263@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 11 ++++
target/riscv/pmu.h | 2 +
target/riscv/cpu_helper.c | 9 ++-
target/riscv/csr.c | 117 ++++++++++++++++++++++++++------------
target/riscv/pmu.c | 92 ++++++++++++++++++++++++++++++
5 files changed, 194 insertions(+), 37 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 980e2154cd..f515ad072b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -181,6 +181,15 @@ typedef struct PMUCTRState {
target_ulong irq_overflow_left;
} PMUCTRState;
+typedef struct PMUFixedCtrState {
+ /* Track cycle and icount for each privilege mode */
+ uint64_t counter[4];
+ uint64_t counter_prev[4];
+ /* Track cycle and icount for each privilege mode when V = 1*/
+ uint64_t counter_virt[2];
+ uint64_t counter_virt_prev[2];
+} PMUFixedCtrState;
+
struct CPUArchState {
target_ulong gpr[32];
target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
@@ -377,6 +386,8 @@ struct CPUArchState {
/* PMU event selector configured values for RV32 */
target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
+ PMUFixedCtrState pmu_fixed_ctrs[2];
+
target_ulong sscratch;
target_ulong mscratch;
diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
index 7c0ad661e0..ca40cfeed6 100644
--- a/target/riscv/pmu.h
+++ b/target/riscv/pmu.h
@@ -34,5 +34,7 @@ int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx);
void riscv_pmu_generate_fdt_node(void *fdt, uint32_t cmask, char *pmu_name);
int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value,
uint32_t ctr_idx);
+void riscv_pmu_update_fixed_ctrs(CPURISCVState *env, target_ulong newpriv,
+ bool new_virt);
#endif /* RISCV_PMU_H */
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 10d3fdaed3..395a1d9140 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -695,9 +695,14 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en)
{
g_assert(newpriv <= PRV_M && newpriv != PRV_RESERVED);
- if (icount_enabled() && newpriv != env->priv) {
- riscv_itrigger_update_priv(env);
+ if (newpriv != env->priv || env->virt_enabled != virt_en) {
+ if (icount_enabled()) {
+ riscv_itrigger_update_priv(env);
+ }
+
+ riscv_pmu_update_fixed_ctrs(env, newpriv, virt_en);
}
+
/* tlb_flush is unnecessary as mode is contained in mmu_idx */
env->priv = newpriv;
env->xl = cpu_recompute_xl(env);
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 364583dc03..85d3f0aa3f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -787,36 +787,16 @@ static RISCVException write_vcsr(CPURISCVState *env, int csrno,
return RISCV_EXCP_NONE;
}
+#if defined(CONFIG_USER_ONLY)
/* User Timers and Counters */
-static target_ulong get_ticks(bool shift, bool instructions)
+static target_ulong get_ticks(bool shift)
{
- int64_t val;
- target_ulong result;
-
-#if !defined(CONFIG_USER_ONLY)
- if (icount_enabled()) {
- if (instructions) {
- val = icount_get_raw();
- } else {
- val = icount_get();
- }
- } else {
- val = cpu_get_host_ticks();
- }
-#else
- val = cpu_get_host_ticks();
-#endif
-
- if (shift) {
- result = val >> 32;
- } else {
- result = val;
- }
+ int64_t val = cpu_get_host_ticks();
+ target_ulong result = shift ? val >> 32 : val;
return result;
}
-#if defined(CONFIG_USER_ONLY)
static RISCVException read_time(CPURISCVState *env, int csrno,
target_ulong *val)
{
@@ -834,14 +814,14 @@ static RISCVException read_timeh(CPURISCVState *env, int csrno,
static RISCVException read_hpmcounter(CPURISCVState *env, int csrno,
target_ulong *val)
{
- *val = get_ticks(false, (csrno == CSR_INSTRET));
+ *val = get_ticks(false);
return RISCV_EXCP_NONE;
}
static RISCVException read_hpmcounterh(CPURISCVState *env, int csrno,
target_ulong *val)
{
- *val = get_ticks(true, (csrno == CSR_INSTRETH));
+ *val = get_ticks(true);
return RISCV_EXCP_NONE;
}
@@ -1025,17 +1005,82 @@ static RISCVException write_mhpmeventh(CPURISCVState *env, int csrno,
return RISCV_EXCP_NONE;
}
+static target_ulong riscv_pmu_ctr_get_fixed_counters_val(CPURISCVState *env,
+ int counter_idx,
+ bool upper_half)
+{
+ int inst = riscv_pmu_ctr_monitor_instructions(env, counter_idx);
+ uint64_t *counter_arr_virt = env->pmu_fixed_ctrs[inst].counter_virt;
+ uint64_t *counter_arr = env->pmu_fixed_ctrs[inst].counter;
+ target_ulong result = 0;
+ uint64_t curr_val = 0;
+ uint64_t cfg_val = 0;
+
+ if (counter_idx == 0) {
+ cfg_val = upper_half ? ((uint64_t)env->mcyclecfgh << 32) :
+ env->mcyclecfg;
+ } else if (counter_idx == 2) {
+ cfg_val = upper_half ? ((uint64_t)env->minstretcfgh << 32) :
+ env->minstretcfg;
+ } else {
+ cfg_val = upper_half ?
+ ((uint64_t)env->mhpmeventh_val[counter_idx] << 32) :
+ env->mhpmevent_val[counter_idx];
+ cfg_val &= MHPMEVENT_FILTER_MASK;
+ }
+
+ if (!cfg_val) {
+ if (icount_enabled()) {
+ curr_val = inst ? icount_get_raw() : icount_get();
+ } else {
+ curr_val = cpu_get_host_ticks();
+ }
+
+ goto done;
+ }
+
+ if (!(cfg_val & MCYCLECFG_BIT_MINH)) {
+ curr_val += counter_arr[PRV_M];
+ }
+
+ if (!(cfg_val & MCYCLECFG_BIT_SINH)) {
+ curr_val += counter_arr[PRV_S];
+ }
+
+ if (!(cfg_val & MCYCLECFG_BIT_UINH)) {
+ curr_val += counter_arr[PRV_U];
+ }
+
+ if (!(cfg_val & MCYCLECFG_BIT_VSINH)) {
+ curr_val += counter_arr_virt[PRV_S];
+ }
+
+ if (!(cfg_val & MCYCLECFG_BIT_VUINH)) {
+ curr_val += counter_arr_virt[PRV_U];
+ }
+
+done:
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ result = upper_half ? curr_val >> 32 : curr_val;
+ } else {
+ result = curr_val;
+ }
+
+ return result;
+}
+
static RISCVException write_mhpmcounter(CPURISCVState *env, int csrno,
target_ulong val)
{
int ctr_idx = csrno - CSR_MCYCLE;
PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
uint64_t mhpmctr_val = val;
- bool instr = riscv_pmu_ctr_monitor_instructions(env, ctr_idx);
counter->mhpmcounter_val = val;
- if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) || instr) {
- counter->mhpmcounter_prev = get_ticks(false, instr);
+ if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
+ riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
+ counter->mhpmcounter_prev = riscv_pmu_ctr_get_fixed_counters_val(env,
+ ctr_idx, false);
if (ctr_idx > 2) {
if (riscv_cpu_mxl(env) == MXL_RV32) {
mhpmctr_val = mhpmctr_val |
@@ -1058,12 +1103,13 @@ static RISCVException write_mhpmcounterh(CPURISCVState *env, int csrno,
PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
uint64_t mhpmctr_val = counter->mhpmcounter_val;
uint64_t mhpmctrh_val = val;
- bool instr = riscv_pmu_ctr_monitor_instructions(env, ctr_idx);
counter->mhpmcounterh_val = val;
mhpmctr_val = mhpmctr_val | (mhpmctrh_val << 32);
- if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) || instr) {
- counter->mhpmcounterh_prev = get_ticks(true, instr);
+ if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
+ riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
+ counter->mhpmcounterh_prev = riscv_pmu_ctr_get_fixed_counters_val(env,
+ ctr_idx, true);
if (ctr_idx > 2) {
riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
}
@@ -1082,7 +1128,6 @@ static RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
counter->mhpmcounter_prev;
target_ulong ctr_val = upper_half ? counter->mhpmcounterh_val :
counter->mhpmcounter_val;
- bool instr = riscv_pmu_ctr_monitor_instructions(env, ctr_idx);
if (get_field(env->mcountinhibit, BIT(ctr_idx))) {
/*
@@ -1103,8 +1148,10 @@ static RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
* The kernel computes the perf delta by subtracting the current value from
* the value it initialized previously (ctr_val).
*/
- if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) || instr) {
- *val = get_ticks(upper_half, instr) - ctr_prev + ctr_val;
+ if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
+ riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
+ *val = riscv_pmu_ctr_get_fixed_counters_val(env, ctr_idx, upper_half) -
+ ctr_prev + ctr_val;
} else {
*val = ctr_val;
}
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index 0e7d58b8a5..ac648cff8d 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -19,6 +19,7 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
+#include "qemu/timer.h"
#include "cpu.h"
#include "pmu.h"
#include "sysemu/cpu-timers.h"
@@ -176,6 +177,97 @@ static int riscv_pmu_incr_ctr_rv64(RISCVCPU *cpu, uint32_t ctr_idx)
return 0;
}
+/*
+ * Information needed to update counters:
+ * new_priv, new_virt: To correctly save starting snapshot for the newly
+ * started mode. Look at array being indexed with newprv.
+ * old_priv, old_virt: To correctly select previous snapshot for old priv
+ * and compute delta. Also to select correct counter
+ * to inc. Look at arrays being indexed with env->priv.
+ *
+ * To avoid the complexity of calling this function, we assume that
+ * env->priv and env->virt_enabled contain old priv and old virt and
+ * new priv and new virt values are passed in as arguments.
+ */
+static void riscv_pmu_icount_update_priv(CPURISCVState *env,
+ target_ulong newpriv, bool new_virt)
+{
+ uint64_t *snapshot_prev, *snapshot_new;
+ uint64_t current_icount;
+ uint64_t *counter_arr;
+ uint64_t delta;
+
+ if (icount_enabled()) {
+ current_icount = icount_get_raw();
+ } else {
+ current_icount = cpu_get_host_ticks();
+ }
+
+ if (env->virt_enabled) {
+ counter_arr = env->pmu_fixed_ctrs[1].counter_virt;
+ snapshot_prev = env->pmu_fixed_ctrs[1].counter_virt_prev;
+ } else {
+ counter_arr = env->pmu_fixed_ctrs[1].counter;
+ snapshot_prev = env->pmu_fixed_ctrs[1].counter_prev;
+ }
+
+ if (new_virt) {
+ snapshot_new = env->pmu_fixed_ctrs[1].counter_virt_prev;
+ } else {
+ snapshot_new = env->pmu_fixed_ctrs[1].counter_prev;
+ }
+
+ /*
+ * new_priv can be same as env->priv. So we need to calculate
+ * delta first before updating snapshot_new[new_priv].
+ */
+ delta = current_icount - snapshot_prev[env->priv];
+ snapshot_new[newpriv] = current_icount;
+
+ counter_arr[env->priv] += delta;
+}
+
+static void riscv_pmu_cycle_update_priv(CPURISCVState *env,
+ target_ulong newpriv, bool new_virt)
+{
+ uint64_t *snapshot_prev, *snapshot_new;
+ uint64_t current_ticks;
+ uint64_t *counter_arr;
+ uint64_t delta;
+
+ if (icount_enabled()) {
+ current_ticks = icount_get();
+ } else {
+ current_ticks = cpu_get_host_ticks();
+ }
+
+ if (env->virt_enabled) {
+ counter_arr = env->pmu_fixed_ctrs[0].counter_virt;
+ snapshot_prev = env->pmu_fixed_ctrs[0].counter_virt_prev;
+ } else {
+ counter_arr = env->pmu_fixed_ctrs[0].counter;
+ snapshot_prev = env->pmu_fixed_ctrs[0].counter_prev;
+ }
+
+ if (new_virt) {
+ snapshot_new = env->pmu_fixed_ctrs[0].counter_virt_prev;
+ } else {
+ snapshot_new = env->pmu_fixed_ctrs[0].counter_prev;
+ }
+
+ delta = current_ticks - snapshot_prev[env->priv];
+ snapshot_new[newpriv] = current_ticks;
+
+ counter_arr[env->priv] += delta;
+}
+
+void riscv_pmu_update_fixed_ctrs(CPURISCVState *env, target_ulong newpriv,
+ bool new_virt)
+{
+ riscv_pmu_cycle_update_priv(env, newpriv, new_virt);
+ riscv_pmu_icount_update_priv(env, newpriv, new_virt);
+}
+
int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx)
{
uint32_t ctr_idx;
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PULL 21/30] target/riscv: Implement privilege mode filtering for cycle/instret
2024-07-18 2:10 ` [PULL 21/30] target/riscv: Implement privilege mode filtering for cycle/instret Alistair Francis
@ 2024-07-20 14:43 ` Peter Maydell
2024-07-22 23:24 ` Atish Kumar Patra
2025-08-21 9:25 ` Philippe Mathieu-Daudé
1 sibling, 1 reply; 45+ messages in thread
From: Peter Maydell @ 2024-07-20 14:43 UTC (permalink / raw)
To: Alistair Francis
Cc: qemu-devel, Atish Patra, Rajnesh Kanwal, Daniel Henrique Barboza,
Alistair Francis
On Thu, 18 Jul 2024 at 03:12, Alistair Francis <alistair23@gmail.com> wrote:
>
> From: Atish Patra <atishp@rivosinc.com>
>
> Privilege mode filtering can also be emulated for cycle/instret by
> tracking host_ticks/icount during each privilege mode switch. This
> patch implements that for both cycle/instret and mhpmcounters. The
> first one requires Smcntrpmf while the other one requires Sscofpmf
> to be enabled.
>
> The cycle/instret are still computed using host ticks when icount
> is not enabled. Otherwise, they are computed using raw icount which
> is more accurate in icount mode.
Hi; Coverity points out some possible issues with this patch
(CID 1558459, 1558462):
> +typedef struct PMUFixedCtrState {
> + /* Track cycle and icount for each privilege mode */
> + uint64_t counter[4];
> + uint64_t counter_prev[4];
> + /* Track cycle and icount for each privilege mode when V = 1*/
> + uint64_t counter_virt[2];
> + uint64_t counter_virt_prev[2];
These two arrays are defined with size 2...
> +static void riscv_pmu_icount_update_priv(CPURISCVState *env,
> + target_ulong newpriv, bool new_virt)
> +{
> + uint64_t *snapshot_prev, *snapshot_new;
> + uint64_t current_icount;
> + uint64_t *counter_arr;
> + uint64_t delta;
> +
> + if (icount_enabled()) {
> + current_icount = icount_get_raw();
> + } else {
> + current_icount = cpu_get_host_ticks();
> + }
> +
> + if (env->virt_enabled) {
> + counter_arr = env->pmu_fixed_ctrs[1].counter_virt;
> + snapshot_prev = env->pmu_fixed_ctrs[1].counter_virt_prev;
> + } else {
> + counter_arr = env->pmu_fixed_ctrs[1].counter;
> + snapshot_prev = env->pmu_fixed_ctrs[1].counter_prev;
> + }
> +
> + if (new_virt) {
> + snapshot_new = env->pmu_fixed_ctrs[1].counter_virt_prev;
> + } else {
> + snapshot_new = env->pmu_fixed_ctrs[1].counter_prev;
> + }
> +
> + /*
> + * new_priv can be same as env->priv. So we need to calculate
> + * delta first before updating snapshot_new[new_priv].
> + */
> + delta = current_icount - snapshot_prev[env->priv];
> + snapshot_new[newpriv] = current_icount;
> +
> + counter_arr[env->priv] += delta;
...and in this function we may use those counter_virt and
counter_virt_prev arrays with newpriv and env->priv as indexes,
but in the callsites like riscv_cpu_set_mode() the assertions on
newpriv etc are things like
g_assert(newpriv <= PRV_M && newpriv != PRV_RESERVED);
so Coverity thinks newpriv might be PRV_M (because that's the only
explicit range guard it's seen) and we will overrun the array.
If this is a "can't happen" case I think we should have asserts in the
functions like riscv_pmu_icount_update_priv() and riscv_pmu_cycle_update_priv()
that might index into these arrays that the indexes can't be out of bounds
for these smaller arrays.
thanks
-- PMM
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PULL 21/30] target/riscv: Implement privilege mode filtering for cycle/instret
2024-07-20 14:43 ` Peter Maydell
@ 2024-07-22 23:24 ` Atish Kumar Patra
0 siblings, 0 replies; 45+ messages in thread
From: Atish Kumar Patra @ 2024-07-22 23:24 UTC (permalink / raw)
To: Peter Maydell
Cc: Alistair Francis, qemu-devel, Rajnesh Kanwal,
Daniel Henrique Barboza, Alistair Francis
On Sat, Jul 20, 2024 at 7:44 AM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Thu, 18 Jul 2024 at 03:12, Alistair Francis <alistair23@gmail.com> wrote:
> >
> > From: Atish Patra <atishp@rivosinc.com>
> >
> > Privilege mode filtering can also be emulated for cycle/instret by
> > tracking host_ticks/icount during each privilege mode switch. This
> > patch implements that for both cycle/instret and mhpmcounters. The
> > first one requires Smcntrpmf while the other one requires Sscofpmf
> > to be enabled.
> >
> > The cycle/instret are still computed using host ticks when icount
> > is not enabled. Otherwise, they are computed using raw icount which
> > is more accurate in icount mode.
>
> Hi; Coverity points out some possible issues with this patch
> (CID 1558459, 1558462):
>
>
> > +typedef struct PMUFixedCtrState {
> > + /* Track cycle and icount for each privilege mode */
> > + uint64_t counter[4];
> > + uint64_t counter_prev[4];
> > + /* Track cycle and icount for each privilege mode when V = 1*/
> > + uint64_t counter_virt[2];
> > + uint64_t counter_virt_prev[2];
>
> These two arrays are defined with size 2...
>
>
> > +static void riscv_pmu_icount_update_priv(CPURISCVState *env,
> > + target_ulong newpriv, bool new_virt)
> > +{
> > + uint64_t *snapshot_prev, *snapshot_new;
> > + uint64_t current_icount;
> > + uint64_t *counter_arr;
> > + uint64_t delta;
> > +
> > + if (icount_enabled()) {
> > + current_icount = icount_get_raw();
> > + } else {
> > + current_icount = cpu_get_host_ticks();
> > + }
> > +
> > + if (env->virt_enabled) {
> > + counter_arr = env->pmu_fixed_ctrs[1].counter_virt;
> > + snapshot_prev = env->pmu_fixed_ctrs[1].counter_virt_prev;
> > + } else {
> > + counter_arr = env->pmu_fixed_ctrs[1].counter;
> > + snapshot_prev = env->pmu_fixed_ctrs[1].counter_prev;
> > + }
> > +
> > + if (new_virt) {
> > + snapshot_new = env->pmu_fixed_ctrs[1].counter_virt_prev;
> > + } else {
> > + snapshot_new = env->pmu_fixed_ctrs[1].counter_prev;
> > + }
> > +
> > + /*
> > + * new_priv can be same as env->priv. So we need to calculate
> > + * delta first before updating snapshot_new[new_priv].
> > + */
> > + delta = current_icount - snapshot_prev[env->priv];
> > + snapshot_new[newpriv] = current_icount;
> > +
> > + counter_arr[env->priv] += delta;
>
> ...and in this function we may use those counter_virt and
> counter_virt_prev arrays with newpriv and env->priv as indexes,
> but in the callsites like riscv_cpu_set_mode() the assertions on
> newpriv etc are things like
> g_assert(newpriv <= PRV_M && newpriv != PRV_RESERVED);
>
> so Coverity thinks newpriv might be PRV_M (because that's the only
> explicit range guard it's seen) and we will overrun the array.
>
> If this is a "can't happen" case I think we should have asserts in the
Yes. Both these arrays are used when virt is enabled which can't
happen when PRV_M.
The separate array is required to distinguish between VS and HS mode
where both priv is PRV_S.
> functions like riscv_pmu_icount_update_priv() and riscv_pmu_cycle_update_priv()
> that might index into these arrays that the indexes can't be out of bounds
> for these smaller arrays.
>
Sure. I will add the asserts and send a fix patch.
>
> thanks
> -- PMM
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PULL 21/30] target/riscv: Implement privilege mode filtering for cycle/instret
2024-07-18 2:10 ` [PULL 21/30] target/riscv: Implement privilege mode filtering for cycle/instret Alistair Francis
2024-07-20 14:43 ` Peter Maydell
@ 2025-08-21 9:25 ` Philippe Mathieu-Daudé
2025-10-03 1:39 ` Alistair Francis
1 sibling, 1 reply; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-08-21 9:25 UTC (permalink / raw)
To: Alistair Francis, qemu-devel
Cc: Atish Patra, Rajnesh Kanwal, Daniel Henrique Barboza,
Alistair Francis
Hi,
(old patch merged as b2d7a7c7e4e30fb5341d38deac968de675f9419c)
On 18/7/24 04:10, Alistair Francis wrote:
> From: Atish Patra <atishp@rivosinc.com>
>
> Privilege mode filtering can also be emulated for cycle/instret by
> tracking host_ticks/icount during each privilege mode switch. This
> patch implements that for both cycle/instret and mhpmcounters. The
> first one requires Smcntrpmf while the other one requires Sscofpmf
> to be enabled.
>
> The cycle/instret are still computed using host ticks when icount
> is not enabled. Otherwise, they are computed using raw icount which
> is more accurate in icount mode.
>
> Co-Developed-by: Rajnesh Kanwal <rkanwal@rivosinc.com>
> Signed-off-by: Rajnesh Kanwal <rkanwal@rivosinc.com>
> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> Acked-by: Alistair Francis <alistair.francis@wdc.com>
> Signed-off-by: Atish Patra <atishp@rivosinc.com>
> Message-ID: <20240711-smcntrpmf_v7-v8-7-b7c38ae7b263@rivosinc.com>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/cpu.h | 11 ++++
> target/riscv/pmu.h | 2 +
> target/riscv/cpu_helper.c | 9 ++-
> target/riscv/csr.c | 117 ++++++++++++++++++++++++++------------
> target/riscv/pmu.c | 92 ++++++++++++++++++++++++++++++
> 5 files changed, 194 insertions(+), 37 deletions(-)
> +#if defined(CONFIG_USER_ONLY)
> /* User Timers and Counters */
> -static target_ulong get_ticks(bool shift, bool instructions)
> +static target_ulong get_ticks(bool shift)
> {
> - int64_t val;
> - target_ulong result;
> -
> -#if !defined(CONFIG_USER_ONLY)
> - if (icount_enabled()) {
> - if (instructions) {
> - val = icount_get_raw();
> - } else {
> - val = icount_get();
> - }
> - } else {
> - val = cpu_get_host_ticks();
> - }
I see this comes from old commit c7b95171881 ("RISC-V: Implement
modular CSR helper interface"), ...
> -#else
> - val = cpu_get_host_ticks();
> -#endif
> -
> - if (shift) {
> - result = val >> 32;
> - } else {
> - result = val;
> - }
> + int64_t val = cpu_get_host_ticks();
> + target_ulong result = shift ? val >> 32 : val;
>
> return result;
> }
> +{
> + uint64_t *snapshot_prev, *snapshot_new;
> + uint64_t current_ticks;
> + uint64_t *counter_arr;
> + uint64_t delta;
> +
> + if (icount_enabled()) {
> + current_ticks = icount_get();
> + } else {
> + current_ticks = cpu_get_host_ticks();
> + }
... but still I wonder, why not use cpus_get_elapsed_ticks()?
Regards,
Phil.
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PULL 21/30] target/riscv: Implement privilege mode filtering for cycle/instret
2025-08-21 9:25 ` Philippe Mathieu-Daudé
@ 2025-10-03 1:39 ` Alistair Francis
0 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2025-10-03 1:39 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: qemu-devel, Atish Patra, Rajnesh Kanwal, Daniel Henrique Barboza,
Alistair Francis
On Thu, Aug 21, 2025 at 7:25 PM Philippe Mathieu-Daudé
<philmd@linaro.org> wrote:
>
> Hi,
>
> (old patch merged as b2d7a7c7e4e30fb5341d38deac968de675f9419c)
>
> On 18/7/24 04:10, Alistair Francis wrote:
> > From: Atish Patra <atishp@rivosinc.com>
> >
> > Privilege mode filtering can also be emulated for cycle/instret by
> > tracking host_ticks/icount during each privilege mode switch. This
> > patch implements that for both cycle/instret and mhpmcounters. The
> > first one requires Smcntrpmf while the other one requires Sscofpmf
> > to be enabled.
> >
> > The cycle/instret are still computed using host ticks when icount
> > is not enabled. Otherwise, they are computed using raw icount which
> > is more accurate in icount mode.
> >
> > Co-Developed-by: Rajnesh Kanwal <rkanwal@rivosinc.com>
> > Signed-off-by: Rajnesh Kanwal <rkanwal@rivosinc.com>
> > Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> > Acked-by: Alistair Francis <alistair.francis@wdc.com>
> > Signed-off-by: Atish Patra <atishp@rivosinc.com>
> > Message-ID: <20240711-smcntrpmf_v7-v8-7-b7c38ae7b263@rivosinc.com>
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > ---
> > target/riscv/cpu.h | 11 ++++
> > target/riscv/pmu.h | 2 +
> > target/riscv/cpu_helper.c | 9 ++-
> > target/riscv/csr.c | 117 ++++++++++++++++++++++++++------------
> > target/riscv/pmu.c | 92 ++++++++++++++++++++++++++++++
> > 5 files changed, 194 insertions(+), 37 deletions(-)
>
>
> > +#if defined(CONFIG_USER_ONLY)
> > /* User Timers and Counters */
> > -static target_ulong get_ticks(bool shift, bool instructions)
> > +static target_ulong get_ticks(bool shift)
> > {
> > - int64_t val;
> > - target_ulong result;
> > -
> > -#if !defined(CONFIG_USER_ONLY)
> > - if (icount_enabled()) {
> > - if (instructions) {
> > - val = icount_get_raw();
> > - } else {
> > - val = icount_get();
> > - }
> > - } else {
> > - val = cpu_get_host_ticks();
> > - }
>
> I see this comes from old commit c7b95171881 ("RISC-V: Implement
> modular CSR helper interface"), ...
>
> > -#else
> > - val = cpu_get_host_ticks();
> > -#endif
> > -
> > - if (shift) {
> > - result = val >> 32;
> > - } else {
> > - result = val;
> > - }
> > + int64_t val = cpu_get_host_ticks();
> > + target_ulong result = shift ? val >> 32 : val;
> >
> > return result;
> > }
>
>
> > +{
> > + uint64_t *snapshot_prev, *snapshot_new;
> > + uint64_t current_ticks;
> > + uint64_t *counter_arr;
> > + uint64_t delta;
> > +
> > + if (icount_enabled()) {
> > + current_ticks = icount_get();
> > + } else {
> > + current_ticks = cpu_get_host_ticks();
> > + }
>
> ... but still I wonder, why not use cpus_get_elapsed_ticks()?
I don't think there is a specific reason, I didn't realised
cpus_get_elapsed_ticks() is the way to go. Should this be changed to
use cpus_get_elapsed_ticks()?
Alistair
>
> Regards,
>
> Phil.
>
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PULL 22/30] target/riscv: Save counter values during countinhibit update
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (20 preceding siblings ...)
2024-07-18 2:10 ` [PULL 21/30] target/riscv: Implement privilege mode filtering for cycle/instret Alistair Francis
@ 2024-07-18 2:10 ` Alistair Francis
2024-07-18 2:10 ` [PULL 23/30] target/riscv: Enforce WARL behavior for scounteren/hcounteren Alistair Francis
` (8 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:10 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Atish Patra, Alistair Francis,
Daniel Henrique Barboza
From: Atish Patra <atishp@rivosinc.com>
Currently, if a counter monitoring cycle/instret is stopped via
mcountinhibit we just update the state while the value is saved
during the next read. This is not accurate as the read may happen
many cycles after the counter is stopped. Ideally, the read should
return the value saved when the counter is stopped.
Thus, save the value of the counter during the inhibit update
operation and return that value during the read if corresponding bit
in mcountihibit is set.
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Message-ID: <20240711-smcntrpmf_v7-v8-8-b7c38ae7b263@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 1 -
target/riscv/csr.c | 34 ++++++++++++++++++++++------------
target/riscv/machine.c | 5 ++---
3 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index f515ad072b..093c86b8b9 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -176,7 +176,6 @@ typedef struct PMUCTRState {
target_ulong mhpmcounter_prev;
/* Snapshort value of a counter in RV32 */
target_ulong mhpmcounterh_prev;
- bool started;
/* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt trigger */
target_ulong irq_overflow_left;
} PMUCTRState;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 85d3f0aa3f..b7a24f9c60 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1131,17 +1131,11 @@ static RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
if (get_field(env->mcountinhibit, BIT(ctr_idx))) {
/*
- * Counter should not increment if inhibit bit is set. We can't really
- * stop the icount counting. Just return the counter value written by
- * the supervisor to indicate that counter was not incremented.
+ * Counter should not increment if inhibit bit is set. Just return the
+ * current counter value.
*/
- if (!counter->started) {
- *val = ctr_val;
- return RISCV_EXCP_NONE;
- } else {
- /* Mark that the counter has been stopped */
- counter->started = false;
- }
+ *val = ctr_val;
+ return RISCV_EXCP_NONE;
}
/*
@@ -2183,9 +2177,25 @@ static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
/* Check if any other counter is also monitoring cycles/instructions */
for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
- if (!get_field(env->mcountinhibit, BIT(cidx))) {
counter = &env->pmu_ctrs[cidx];
- counter->started = true;
+ if (get_field(env->mcountinhibit, BIT(cidx)) && (val & BIT(cidx))) {
+ /*
+ * Update the counter value for cycle/instret as we can't stop the
+ * host ticks. But we should show the current value at this moment.
+ */
+ if (riscv_pmu_ctr_monitor_cycles(env, cidx) ||
+ riscv_pmu_ctr_monitor_instructions(env, cidx)) {
+ counter->mhpmcounter_val =
+ riscv_pmu_ctr_get_fixed_counters_val(env, cidx, false) -
+ counter->mhpmcounter_prev +
+ counter->mhpmcounter_val;
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ counter->mhpmcounterh_val =
+ riscv_pmu_ctr_get_fixed_counters_val(env, cidx, true) -
+ counter->mhpmcounterh_prev +
+ counter->mhpmcounterh_val;
+ }
+ }
}
}
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 76f2150f78..492c2c6d9d 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -320,15 +320,14 @@ static bool pmu_needed(void *opaque)
static const VMStateDescription vmstate_pmu_ctr_state = {
.name = "cpu/pmu",
- .version_id = 1,
- .minimum_version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
.needed = pmu_needed,
.fields = (const VMStateField[]) {
VMSTATE_UINTTL(mhpmcounter_val, PMUCTRState),
VMSTATE_UINTTL(mhpmcounterh_val, PMUCTRState),
VMSTATE_UINTTL(mhpmcounter_prev, PMUCTRState),
VMSTATE_UINTTL(mhpmcounterh_prev, PMUCTRState),
- VMSTATE_BOOL(started, PMUCTRState),
VMSTATE_END_OF_LIST()
}
};
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 23/30] target/riscv: Enforce WARL behavior for scounteren/hcounteren
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (21 preceding siblings ...)
2024-07-18 2:10 ` [PULL 22/30] target/riscv: Save counter values during countinhibit update Alistair Francis
@ 2024-07-18 2:10 ` Alistair Francis
2024-07-18 2:10 ` [PULL 24/30] target/riscv: Start counters from both mhpmcounter and mcountinhibit Alistair Francis
` (7 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:10 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Atish Patra, Daniel Henrique Barboza,
Alistair Francis
From: Atish Patra <atishp@rivosinc.com>
scounteren/hcountern are also WARL registers similar to mcountern.
Only set the bits for the available counters during the write to
preserve the WARL behavior.
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240711-smcntrpmf_v7-v8-9-b7c38ae7b263@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/csr.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index b7a24f9c60..d6c5b73afd 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3063,7 +3063,11 @@ static RISCVException read_scounteren(CPURISCVState *env, int csrno,
static RISCVException write_scounteren(CPURISCVState *env, int csrno,
target_ulong val)
{
- env->scounteren = val;
+ RISCVCPU *cpu = env_archcpu(env);
+
+ /* WARL register - disable unavailable counters */
+ env->scounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
+ COUNTEREN_IR);
return RISCV_EXCP_NONE;
}
@@ -3722,7 +3726,11 @@ static RISCVException read_hcounteren(CPURISCVState *env, int csrno,
static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
target_ulong val)
{
- env->hcounteren = val;
+ RISCVCPU *cpu = env_archcpu(env);
+
+ /* WARL register - disable unavailable counters */
+ env->hcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
+ COUNTEREN_IR);
return RISCV_EXCP_NONE;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 24/30] target/riscv: Start counters from both mhpmcounter and mcountinhibit
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (22 preceding siblings ...)
2024-07-18 2:10 ` [PULL 23/30] target/riscv: Enforce WARL behavior for scounteren/hcounteren Alistair Francis
@ 2024-07-18 2:10 ` Alistair Francis
2024-07-18 2:10 ` [PULL 25/30] target/riscv: More accurately model priv mode filtering Alistair Francis
` (6 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:10 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Rajnesh Kanwal, Daniel Henrique Barboza,
Alistair Francis
From: Rajnesh Kanwal <rkanwal@rivosinc.com>
Currently we start timer counter from write_mhpmcounter path only
without checking for mcountinhibit bit. This changes adds mcountinhibit
check and also programs the counter from write_mcountinhibit as well.
When a counter is stopped using mcountinhibit we simply update
the value of the counter based on current host ticks and save
it for future reads.
We don't need to disable running timer as pmu_timer_trigger_irq
will discard the interrupt if the counter has been inhibited.
Signed-off-by: Rajnesh Kanwal <rkanwal@rivosinc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20240711-smcntrpmf_v7-v8-10-b7c38ae7b263@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/csr.c | 75 ++++++++++++++++++++++++++++++++--------------
target/riscv/pmu.c | 3 +-
2 files changed, 54 insertions(+), 24 deletions(-)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d6c5b73afd..bb6ac33ac2 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1077,8 +1077,9 @@ static RISCVException write_mhpmcounter(CPURISCVState *env, int csrno,
uint64_t mhpmctr_val = val;
counter->mhpmcounter_val = val;
- if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
- riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
+ if (!get_field(env->mcountinhibit, BIT(ctr_idx)) &&
+ (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
+ riscv_pmu_ctr_monitor_instructions(env, ctr_idx))) {
counter->mhpmcounter_prev = riscv_pmu_ctr_get_fixed_counters_val(env,
ctr_idx, false);
if (ctr_idx > 2) {
@@ -1106,8 +1107,9 @@ static RISCVException write_mhpmcounterh(CPURISCVState *env, int csrno,
counter->mhpmcounterh_val = val;
mhpmctr_val = mhpmctr_val | (mhpmctrh_val << 32);
- if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
- riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
+ if (!get_field(env->mcountinhibit, BIT(ctr_idx)) &&
+ (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
+ riscv_pmu_ctr_monitor_instructions(env, ctr_idx))) {
counter->mhpmcounterh_prev = riscv_pmu_ctr_get_fixed_counters_val(env,
ctr_idx, true);
if (ctr_idx > 2) {
@@ -2170,31 +2172,60 @@ static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
int cidx;
PMUCTRState *counter;
RISCVCPU *cpu = env_archcpu(env);
+ uint32_t present_ctrs = cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_IR;
+ target_ulong updated_ctrs = (env->mcountinhibit ^ val) & present_ctrs;
+ uint64_t mhpmctr_val, prev_count, curr_count;
/* WARL register - disable unavailable counters; TM bit is always 0 */
- env->mcountinhibit =
- val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_IR);
+ env->mcountinhibit = val & present_ctrs;
/* Check if any other counter is also monitoring cycles/instructions */
for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
- counter = &env->pmu_ctrs[cidx];
- if (get_field(env->mcountinhibit, BIT(cidx)) && (val & BIT(cidx))) {
- /*
- * Update the counter value for cycle/instret as we can't stop the
- * host ticks. But we should show the current value at this moment.
- */
- if (riscv_pmu_ctr_monitor_cycles(env, cidx) ||
- riscv_pmu_ctr_monitor_instructions(env, cidx)) {
- counter->mhpmcounter_val =
- riscv_pmu_ctr_get_fixed_counters_val(env, cidx, false) -
- counter->mhpmcounter_prev +
- counter->mhpmcounter_val;
+ if (!(updated_ctrs & BIT(cidx)) ||
+ (!riscv_pmu_ctr_monitor_cycles(env, cidx) &&
+ !riscv_pmu_ctr_monitor_instructions(env, cidx))) {
+ continue;
+ }
+
+ counter = &env->pmu_ctrs[cidx];
+
+ if (!get_field(env->mcountinhibit, BIT(cidx))) {
+ counter->mhpmcounter_prev =
+ riscv_pmu_ctr_get_fixed_counters_val(env, cidx, false);
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ counter->mhpmcounterh_prev =
+ riscv_pmu_ctr_get_fixed_counters_val(env, cidx, true);
+ }
+
+ if (cidx > 2) {
+ mhpmctr_val = counter->mhpmcounter_val;
if (riscv_cpu_mxl(env) == MXL_RV32) {
- counter->mhpmcounterh_val =
- riscv_pmu_ctr_get_fixed_counters_val(env, cidx, true) -
- counter->mhpmcounterh_prev +
- counter->mhpmcounterh_val;
+ mhpmctr_val = mhpmctr_val |
+ ((uint64_t)counter->mhpmcounterh_val << 32);
}
+ riscv_pmu_setup_timer(env, mhpmctr_val, cidx);
+ }
+ } else {
+ curr_count = riscv_pmu_ctr_get_fixed_counters_val(env, cidx, false);
+
+ mhpmctr_val = counter->mhpmcounter_val;
+ prev_count = counter->mhpmcounter_prev;
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ uint64_t tmp =
+ riscv_pmu_ctr_get_fixed_counters_val(env, cidx, true);
+
+ curr_count = curr_count | (tmp << 32);
+ mhpmctr_val = mhpmctr_val |
+ ((uint64_t)counter->mhpmcounterh_val << 32);
+ prev_count = prev_count |
+ ((uint64_t)counter->mhpmcounterh_prev << 32);
+ }
+
+ /* Adjust the counter for later reads. */
+ mhpmctr_val = curr_count - prev_count + mhpmctr_val;
+ counter->mhpmcounter_val = mhpmctr_val;
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ counter->mhpmcounterh_val = mhpmctr_val >> 32;
}
}
}
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index ac648cff8d..63420d9f36 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -285,8 +285,7 @@ int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx)
}
ctr_idx = GPOINTER_TO_UINT(value);
- if (!riscv_pmu_counter_enabled(cpu, ctr_idx) ||
- get_field(env->mcountinhibit, BIT(ctr_idx))) {
+ if (!riscv_pmu_counter_enabled(cpu, ctr_idx)) {
return -1;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 25/30] target/riscv: More accurately model priv mode filtering.
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (23 preceding siblings ...)
2024-07-18 2:10 ` [PULL 24/30] target/riscv: Start counters from both mhpmcounter and mcountinhibit Alistair Francis
@ 2024-07-18 2:10 ` Alistair Francis
2024-07-18 2:10 ` [PULL 26/30] target/riscv: Do not setup pmu timer if OF is disabled Alistair Francis
` (5 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:10 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Rajnesh Kanwal, Daniel Henrique Barboza,
Alistair Francis
From: Rajnesh Kanwal <rkanwal@rivosinc.com>
In case of programmable counters configured to count inst/cycles
we often end-up with counter not incrementing at all from kernel's
perspective.
For example:
- Kernel configures hpm3 to count instructions and sets hpmcounter
to -10000 and all modes except U mode are inhibited.
- In QEMU we configure a timer to expire after ~10000 instructions.
- Problem is, it's often the case that kernel might not even schedule
Umode task and we hit the timer callback in QEMU.
- In the timer callback we inject the interrupt into kernel, kernel
runs the handler and reads hpmcounter3 value.
- Given QEMU maintains individual counters to count for each privilege
mode, and given umode never ran, the umode counter didn't increment
and QEMU returns same value as was programmed by the kernel when
starting the counter.
- Kernel checks for overflow using previous and current value of the
counter and reprograms the counter given there wasn't an overflow
as per the counter value. (Which itself is a problem. We have QEMU
telling kernel that counter3 overflowed but the counter value
returned by QEMU doesn't seem to reflect that.).
This change makes sure that timer is reprogrammed from the handler
if the counter didn't overflow based on the counter value.
Second, this change makes sure that whenever the counter is read,
it's value is updated to reflect the latest count.
Signed-off-by: Rajnesh Kanwal <rkanwal@rivosinc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20240711-smcntrpmf_v7-v8-11-b7c38ae7b263@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/pmu.h | 2 ++
target/riscv/csr.c | 5 ++++-
target/riscv/pmu.c | 30 +++++++++++++++++++++++++++---
3 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
index ca40cfeed6..3853d0e262 100644
--- a/target/riscv/pmu.h
+++ b/target/riscv/pmu.h
@@ -36,5 +36,7 @@ int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value,
uint32_t ctr_idx);
void riscv_pmu_update_fixed_ctrs(CPURISCVState *env, target_ulong newpriv,
bool new_virt);
+RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
+ bool upper_half, uint32_t ctr_idx);
#endif /* RISCV_PMU_H */
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index bb6ac33ac2..781ef27eba 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1039,6 +1039,9 @@ static target_ulong riscv_pmu_ctr_get_fixed_counters_val(CPURISCVState *env,
goto done;
}
+ /* Update counter before reading. */
+ riscv_pmu_update_fixed_ctrs(env, env->priv, env->virt_enabled);
+
if (!(cfg_val & MCYCLECFG_BIT_MINH)) {
curr_val += counter_arr[PRV_M];
}
@@ -1122,7 +1125,7 @@ static RISCVException write_mhpmcounterh(CPURISCVState *env, int csrno,
return RISCV_EXCP_NONE;
}
-static RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
+RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
bool upper_half, uint32_t ctr_idx)
{
PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index 63420d9f36..a4729f6c53 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -425,6 +425,8 @@ static void pmu_timer_trigger_irq(RISCVCPU *cpu,
target_ulong *mhpmevent_val;
uint64_t of_bit_mask;
int64_t irq_trigger_at;
+ uint64_t curr_ctr_val, curr_ctrh_val;
+ uint64_t ctr_val;
if (evt_idx != RISCV_PMU_EVENT_HW_CPU_CYCLES &&
evt_idx != RISCV_PMU_EVENT_HW_INSTRUCTIONS) {
@@ -454,6 +456,26 @@ static void pmu_timer_trigger_irq(RISCVCPU *cpu,
return;
}
+ riscv_pmu_read_ctr(env, (target_ulong *)&curr_ctr_val, false, ctr_idx);
+ ctr_val = counter->mhpmcounter_val;
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ riscv_pmu_read_ctr(env, (target_ulong *)&curr_ctrh_val, true, ctr_idx);
+ curr_ctr_val = curr_ctr_val | (curr_ctrh_val << 32);
+ ctr_val = ctr_val |
+ ((uint64_t)counter->mhpmcounterh_val << 32);
+ }
+
+ /*
+ * We can not accommodate for inhibited modes when setting up timer. Check
+ * if the counter has actually overflowed or not by comparing current
+ * counter value (accommodated for inhibited modes) with software written
+ * counter value.
+ */
+ if (curr_ctr_val >= ctr_val) {
+ riscv_pmu_setup_timer(env, curr_ctr_val, ctr_idx);
+ return;
+ }
+
if (cpu->pmu_avail_ctrs & BIT(ctr_idx)) {
/* Generate interrupt only if OF bit is clear */
if (!(*mhpmevent_val & of_bit_mask)) {
@@ -475,7 +497,7 @@ void riscv_pmu_timer_cb(void *priv)
int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value, uint32_t ctr_idx)
{
- uint64_t overflow_delta, overflow_at;
+ uint64_t overflow_delta, overflow_at, curr_ns;
int64_t overflow_ns, overflow_left = 0;
RISCVCPU *cpu = env_archcpu(env);
PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
@@ -506,8 +528,10 @@ int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value, uint32_t ctr_idx)
} else {
return -1;
}
- overflow_at = (uint64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- overflow_ns;
+ curr_ns = (uint64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ overflow_at = curr_ns + overflow_ns;
+ if (overflow_at <= curr_ns)
+ overflow_at = UINT64_MAX;
if (overflow_at > INT64_MAX) {
overflow_left += overflow_at - INT64_MAX;
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 26/30] target/riscv: Do not setup pmu timer if OF is disabled
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (24 preceding siblings ...)
2024-07-18 2:10 ` [PULL 25/30] target/riscv: More accurately model priv mode filtering Alistair Francis
@ 2024-07-18 2:10 ` Alistair Francis
2024-07-20 15:19 ` Peter Maydell
2024-07-18 2:10 ` [PULL 27/30] target/riscv: Expose the Smcntrpmf config Alistair Francis
` (4 subsequent siblings)
30 siblings, 1 reply; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:10 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Atish Patra, Daniel Henrique Barboza,
Alistair Francis
From: Atish Patra <atishp@rivosinc.com>
The timer is setup function is invoked in both hpmcounter
write and mcountinhibit write path. If the OF bit set, the
LCOFI interrupt is disabled. There is no benefitting in
setting up the qemu timer until LCOFI is cleared to indicate
that interrupts can be fired again.
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Message-ID: <20240711-smcntrpmf_v7-v8-12-b7c38ae7b263@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/pmu.c | 56 ++++++++++++++++++++++++++++++++++++----------
1 file changed, 44 insertions(+), 12 deletions(-)
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index a4729f6c53..3cc0b3648c 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -416,14 +416,49 @@ int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
return 0;
}
+static bool pmu_hpmevent_is_of_set(CPURISCVState *env, uint32_t ctr_idx)
+{
+ target_ulong mhpmevent_val;
+ uint64_t of_bit_mask;
+
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ mhpmevent_val = env->mhpmeventh_val[ctr_idx];
+ of_bit_mask = MHPMEVENTH_BIT_OF;
+ } else {
+ mhpmevent_val = env->mhpmevent_val[ctr_idx];
+ of_bit_mask = MHPMEVENT_BIT_OF;
+ }
+
+ return get_field(mhpmevent_val, of_bit_mask);
+}
+
+static bool pmu_hpmevent_set_of_if_clear(CPURISCVState *env, uint32_t ctr_idx)
+{
+ target_ulong *mhpmevent_val;
+ uint64_t of_bit_mask;
+
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ mhpmevent_val = &env->mhpmeventh_val[ctr_idx];
+ of_bit_mask = MHPMEVENTH_BIT_OF;
+ } else {
+ mhpmevent_val = &env->mhpmevent_val[ctr_idx];
+ of_bit_mask = MHPMEVENT_BIT_OF;
+ }
+
+ if (!get_field(*mhpmevent_val, of_bit_mask)) {
+ *mhpmevent_val |= of_bit_mask;
+ return true;
+ }
+
+ return false;
+}
+
static void pmu_timer_trigger_irq(RISCVCPU *cpu,
enum riscv_pmu_event_idx evt_idx)
{
uint32_t ctr_idx;
CPURISCVState *env = &cpu->env;
PMUCTRState *counter;
- target_ulong *mhpmevent_val;
- uint64_t of_bit_mask;
int64_t irq_trigger_at;
uint64_t curr_ctr_val, curr_ctrh_val;
uint64_t ctr_val;
@@ -439,12 +474,9 @@ static void pmu_timer_trigger_irq(RISCVCPU *cpu,
return;
}
- if (riscv_cpu_mxl(env) == MXL_RV32) {
- mhpmevent_val = &env->mhpmeventh_val[ctr_idx];
- of_bit_mask = MHPMEVENTH_BIT_OF;
- } else {
- mhpmevent_val = &env->mhpmevent_val[ctr_idx];
- of_bit_mask = MHPMEVENT_BIT_OF;
+ /* Generate interrupt only if OF bit is clear */
+ if (pmu_hpmevent_is_of_set(env, ctr_idx)) {
+ return;
}
counter = &env->pmu_ctrs[ctr_idx];
@@ -477,9 +509,7 @@ static void pmu_timer_trigger_irq(RISCVCPU *cpu,
}
if (cpu->pmu_avail_ctrs & BIT(ctr_idx)) {
- /* Generate interrupt only if OF bit is clear */
- if (!(*mhpmevent_val & of_bit_mask)) {
- *mhpmevent_val |= of_bit_mask;
+ if (pmu_hpmevent_set_of_if_clear(env, ctr_idx)) {
riscv_cpu_update_mip(env, MIP_LCOFIP, BOOL_TO_MASK(1));
}
}
@@ -502,7 +532,9 @@ int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value, uint32_t ctr_idx)
RISCVCPU *cpu = env_archcpu(env);
PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
- if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->cfg.ext_sscofpmf) {
+ /* No need to setup a timer if LCOFI is disabled when OF is set */
+ if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->cfg.ext_sscofpmf ||
+ pmu_hpmevent_is_of_set(env, ctr_idx)) {
return -1;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PULL 26/30] target/riscv: Do not setup pmu timer if OF is disabled
2024-07-18 2:10 ` [PULL 26/30] target/riscv: Do not setup pmu timer if OF is disabled Alistair Francis
@ 2024-07-20 15:19 ` Peter Maydell
2024-07-22 23:33 ` Atish Kumar Patra
2024-07-25 14:05 ` Peter Maydell
0 siblings, 2 replies; 45+ messages in thread
From: Peter Maydell @ 2024-07-20 15:19 UTC (permalink / raw)
To: Alistair Francis
Cc: qemu-devel, Atish Patra, Daniel Henrique Barboza,
Alistair Francis
On Thu, 18 Jul 2024 at 03:15, Alistair Francis <alistair23@gmail.com> wrote:
>
> From: Atish Patra <atishp@rivosinc.com>
>
> The timer is setup function is invoked in both hpmcounter
> write and mcountinhibit write path. If the OF bit set, the
> LCOFI interrupt is disabled. There is no benefitting in
> setting up the qemu timer until LCOFI is cleared to indicate
> that interrupts can be fired again.
> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> Signed-off-by: Atish Patra <atishp@rivosinc.com>
> Message-ID: <20240711-smcntrpmf_v7-v8-12-b7c38ae7b263@rivosinc.com>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/pmu.c | 56 ++++++++++++++++++++++++++++++++++++----------
> 1 file changed, 44 insertions(+), 12 deletions(-)
>
> diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> index a4729f6c53..3cc0b3648c 100644
> --- a/target/riscv/pmu.c
> +++ b/target/riscv/pmu.c
> @@ -416,14 +416,49 @@ int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
> return 0;
> }
Hi; I was looking at an issue Coverity flagged up with this code (CID
1558461, 1558463):
> +static bool pmu_hpmevent_is_of_set(CPURISCVState *env, uint32_t ctr_idx)
> +{
> + target_ulong mhpmevent_val;
> + uint64_t of_bit_mask;
> +
> + if (riscv_cpu_mxl(env) == MXL_RV32) {
> + mhpmevent_val = env->mhpmeventh_val[ctr_idx];
> + of_bit_mask = MHPMEVENTH_BIT_OF;
> + } else {
> + mhpmevent_val = env->mhpmevent_val[ctr_idx];
> + of_bit_mask = MHPMEVENT_BIT_OF;
MHPMEVENT_BIT_OF is defined as BIT_ULL(63)...
> + }
> +
> + return get_field(mhpmevent_val, of_bit_mask);
...but we pass it to get_field(), whose definition is:
#define get_field(reg, mask) (((reg) & \
(uint64_t)(mask)) / ((mask) & ~((mask) << 1)))
Notice that part of this expression is "(mask) << 1". So Coverity complains
that we took a constant value and shifted it right off the top.
I think this is probably a false positive, but why is target/riscv
using its own ad-hoc macros for extracting bitfields? We have
a standard set of extract/deposit macros in bitops.h, and not
using them makes the riscv code harder to read for people who
are used to the rest of the codebase (e.g. to figure out if this
Coverity issue is a false positive I would need to look at these
macros to figure out what exactly they're doing).
thanks
-- PMM
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PULL 26/30] target/riscv: Do not setup pmu timer if OF is disabled
2024-07-20 15:19 ` Peter Maydell
@ 2024-07-22 23:33 ` Atish Kumar Patra
2024-07-23 0:43 ` Alistair Francis
2024-07-24 19:00 ` Daniel Henrique Barboza
2024-07-25 14:05 ` Peter Maydell
1 sibling, 2 replies; 45+ messages in thread
From: Atish Kumar Patra @ 2024-07-22 23:33 UTC (permalink / raw)
To: Peter Maydell
Cc: Alistair Francis, qemu-devel, Daniel Henrique Barboza,
Alistair Francis
On Sat, Jul 20, 2024 at 8:19 AM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Thu, 18 Jul 2024 at 03:15, Alistair Francis <alistair23@gmail.com> wrote:
> >
> > From: Atish Patra <atishp@rivosinc.com>
> >
> > The timer is setup function is invoked in both hpmcounter
> > write and mcountinhibit write path. If the OF bit set, the
> > LCOFI interrupt is disabled. There is no benefitting in
> > setting up the qemu timer until LCOFI is cleared to indicate
> > that interrupts can be fired again.
> > Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> > Signed-off-by: Atish Patra <atishp@rivosinc.com>
> > Message-ID: <20240711-smcntrpmf_v7-v8-12-b7c38ae7b263@rivosinc.com>
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > ---
> > target/riscv/pmu.c | 56 ++++++++++++++++++++++++++++++++++++----------
> > 1 file changed, 44 insertions(+), 12 deletions(-)
> >
> > diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> > index a4729f6c53..3cc0b3648c 100644
> > --- a/target/riscv/pmu.c
> > +++ b/target/riscv/pmu.c
> > @@ -416,14 +416,49 @@ int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
> > return 0;
> > }
>
> Hi; I was looking at an issue Coverity flagged up with this code (CID
> 1558461, 1558463):
>
> > +static bool pmu_hpmevent_is_of_set(CPURISCVState *env, uint32_t ctr_idx)
> > +{
> > + target_ulong mhpmevent_val;
> > + uint64_t of_bit_mask;
> > +
> > + if (riscv_cpu_mxl(env) == MXL_RV32) {
> > + mhpmevent_val = env->mhpmeventh_val[ctr_idx];
> > + of_bit_mask = MHPMEVENTH_BIT_OF;
> > + } else {
> > + mhpmevent_val = env->mhpmevent_val[ctr_idx];
> > + of_bit_mask = MHPMEVENT_BIT_OF;
>
> MHPMEVENT_BIT_OF is defined as BIT_ULL(63)...
>
> > + }
> > +
> > + return get_field(mhpmevent_val, of_bit_mask);
>
> ...but we pass it to get_field(), whose definition is:
>
> #define get_field(reg, mask) (((reg) & \
> (uint64_t)(mask)) / ((mask) & ~((mask) << 1)))
>
> Notice that part of this expression is "(mask) << 1". So Coverity complains
> that we took a constant value and shifted it right off the top.
>
> I think this is probably a false positive, but why is target/riscv
> using its own ad-hoc macros for extracting bitfields? We have
> a standard set of extract/deposit macros in bitops.h, and not
Thanks for pointing those out. I checked the get_field usage from the
beginning of riscv support 6 years back.
There are tons of users of get_field in a bunch of riscv sources. I
guess it was just added once and everybody kept using it
without switching to generic functions.
@Alistair Francis : Are there any other reasons ?
If not, I can take a stab at fixing those if nobody is looking at them already.
> using them makes the riscv code harder to read for people who
> are used to the rest of the codebase (e.g. to figure out if this
> Coverity issue is a false positive I would need to look at these
> macros to figure out what exactly they're doing).
>
> thanks
> -- PMM
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PULL 26/30] target/riscv: Do not setup pmu timer if OF is disabled
2024-07-22 23:33 ` Atish Kumar Patra
@ 2024-07-23 0:43 ` Alistair Francis
2024-07-23 0:49 ` Richard Henderson
2024-07-24 19:00 ` Daniel Henrique Barboza
1 sibling, 1 reply; 45+ messages in thread
From: Alistair Francis @ 2024-07-23 0:43 UTC (permalink / raw)
To: Atish Kumar Patra
Cc: Peter Maydell, qemu-devel, Daniel Henrique Barboza,
Alistair Francis
On Tue, Jul 23, 2024 at 9:33 AM Atish Kumar Patra <atishp@rivosinc.com> wrote:
>
> On Sat, Jul 20, 2024 at 8:19 AM Peter Maydell <peter.maydell@linaro.org> wrote:
> >
> > On Thu, 18 Jul 2024 at 03:15, Alistair Francis <alistair23@gmail.com> wrote:
> > >
> > > From: Atish Patra <atishp@rivosinc.com>
> > >
> > > The timer is setup function is invoked in both hpmcounter
> > > write and mcountinhibit write path. If the OF bit set, the
> > > LCOFI interrupt is disabled. There is no benefitting in
> > > setting up the qemu timer until LCOFI is cleared to indicate
> > > that interrupts can be fired again.
> > > Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> > > Signed-off-by: Atish Patra <atishp@rivosinc.com>
> > > Message-ID: <20240711-smcntrpmf_v7-v8-12-b7c38ae7b263@rivosinc.com>
> > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > > ---
> > > target/riscv/pmu.c | 56 ++++++++++++++++++++++++++++++++++++----------
> > > 1 file changed, 44 insertions(+), 12 deletions(-)
> > >
> > > diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> > > index a4729f6c53..3cc0b3648c 100644
> > > --- a/target/riscv/pmu.c
> > > +++ b/target/riscv/pmu.c
> > > @@ -416,14 +416,49 @@ int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
> > > return 0;
> > > }
> >
> > Hi; I was looking at an issue Coverity flagged up with this code (CID
> > 1558461, 1558463):
> >
> > > +static bool pmu_hpmevent_is_of_set(CPURISCVState *env, uint32_t ctr_idx)
> > > +{
> > > + target_ulong mhpmevent_val;
> > > + uint64_t of_bit_mask;
> > > +
> > > + if (riscv_cpu_mxl(env) == MXL_RV32) {
> > > + mhpmevent_val = env->mhpmeventh_val[ctr_idx];
> > > + of_bit_mask = MHPMEVENTH_BIT_OF;
> > > + } else {
> > > + mhpmevent_val = env->mhpmevent_val[ctr_idx];
> > > + of_bit_mask = MHPMEVENT_BIT_OF;
> >
> > MHPMEVENT_BIT_OF is defined as BIT_ULL(63)...
> >
> > > + }
> > > +
> > > + return get_field(mhpmevent_val, of_bit_mask);
> >
> > ...but we pass it to get_field(), whose definition is:
> >
> > #define get_field(reg, mask) (((reg) & \
> > (uint64_t)(mask)) / ((mask) & ~((mask) << 1)))
> >
> > Notice that part of this expression is "(mask) << 1". So Coverity complains
> > that we took a constant value and shifted it right off the top.
> >
> > I think this is probably a false positive, but why is target/riscv
> > using its own ad-hoc macros for extracting bitfields? We have
> > a standard set of extract/deposit macros in bitops.h, and not
>
> Thanks for pointing those out. I checked the get_field usage from the
> beginning of riscv support 6 years back.
> There are tons of users of get_field in a bunch of riscv sources. I
> guess it was just added once and everybody kept using it
> without switching to generic functions.
I think you are right about that
>
> @Alistair Francis : Are there any other reasons ?
Not that I know of
>
> If not, I can take a stab at fixing those if nobody is looking at them already.
That would be great!
Alistair
>
> > using them makes the riscv code harder to read for people who
> > are used to the rest of the codebase (e.g. to figure out if this
> > Coverity issue is a false positive I would need to look at these
> > macros to figure out what exactly they're doing).
> >
> > thanks
> > -- PMM
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PULL 26/30] target/riscv: Do not setup pmu timer if OF is disabled
2024-07-23 0:43 ` Alistair Francis
@ 2024-07-23 0:49 ` Richard Henderson
0 siblings, 0 replies; 45+ messages in thread
From: Richard Henderson @ 2024-07-23 0:49 UTC (permalink / raw)
To: Alistair Francis, Atish Kumar Patra
Cc: Peter Maydell, qemu-devel, Daniel Henrique Barboza,
Alistair Francis
On 7/23/24 10:43, Alistair Francis wrote:
>>> #define get_field(reg, mask) (((reg) & \
>>> (uint64_t)(mask)) / ((mask) & ~((mask) << 1)))
>>>
>>> Notice that part of this expression is "(mask) << 1". So Coverity complains
>>> that we took a constant value and shifted it right off the top.
>>>
>>> I think this is probably a false positive, but why is target/riscv
>>> using its own ad-hoc macros for extracting bitfields? We have
>>> a standard set of extract/deposit macros in bitops.h, and not
>>
>> Thanks for pointing those out. I checked the get_field usage from the
>> beginning of riscv support 6 years back.
>> There are tons of users of get_field in a bunch of riscv sources. I
>> guess it was just added once and everybody kept using it
>> without switching to generic functions.
>
> I think you are right about that
I think this macro comes from spike, and it was copied in with a bunch of other basic isa
defines at the start of the qemu port.
r~
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PULL 26/30] target/riscv: Do not setup pmu timer if OF is disabled
2024-07-22 23:33 ` Atish Kumar Patra
2024-07-23 0:43 ` Alistair Francis
@ 2024-07-24 19:00 ` Daniel Henrique Barboza
2024-07-24 21:30 ` Richard Henderson
1 sibling, 1 reply; 45+ messages in thread
From: Daniel Henrique Barboza @ 2024-07-24 19:00 UTC (permalink / raw)
To: Atish Kumar Patra, Peter Maydell
Cc: Alistair Francis, qemu-devel, Alistair Francis
On 7/22/24 8:33 PM, Atish Kumar Patra wrote:
> On Sat, Jul 20, 2024 at 8:19 AM Peter Maydell <peter.maydell@linaro.org> wrote:
>>
>> On Thu, 18 Jul 2024 at 03:15, Alistair Francis <alistair23@gmail.com> wrote:
>>>
>>> From: Atish Patra <atishp@rivosinc.com>
>>>
>>> The timer is setup function is invoked in both hpmcounter
>>> write and mcountinhibit write path. If the OF bit set, the
>>> LCOFI interrupt is disabled. There is no benefitting in
>>> setting up the qemu timer until LCOFI is cleared to indicate
>>> that interrupts can be fired again.
>>> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>>> Signed-off-by: Atish Patra <atishp@rivosinc.com>
>>> Message-ID: <20240711-smcntrpmf_v7-v8-12-b7c38ae7b263@rivosinc.com>
>>> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
>>> ---
>>> target/riscv/pmu.c | 56 ++++++++++++++++++++++++++++++++++++----------
>>> 1 file changed, 44 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
>>> index a4729f6c53..3cc0b3648c 100644
>>> --- a/target/riscv/pmu.c
>>> +++ b/target/riscv/pmu.c
>>> @@ -416,14 +416,49 @@ int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
>>> return 0;
>>> }
>>
>> Hi; I was looking at an issue Coverity flagged up with this code (CID
>> 1558461, 1558463):
>>
>>> +static bool pmu_hpmevent_is_of_set(CPURISCVState *env, uint32_t ctr_idx)
>>> +{
>>> + target_ulong mhpmevent_val;
>>> + uint64_t of_bit_mask;
>>> +
>>> + if (riscv_cpu_mxl(env) == MXL_RV32) {
>>> + mhpmevent_val = env->mhpmeventh_val[ctr_idx];
>>> + of_bit_mask = MHPMEVENTH_BIT_OF;
>>> + } else {
>>> + mhpmevent_val = env->mhpmevent_val[ctr_idx];
>>> + of_bit_mask = MHPMEVENT_BIT_OF;
>>
>> MHPMEVENT_BIT_OF is defined as BIT_ULL(63)...
>>
>>> + }
>>> +
>>> + return get_field(mhpmevent_val, of_bit_mask);
>>
>> ...but we pass it to get_field(), whose definition is:
>>
>> #define get_field(reg, mask) (((reg) & \
>> (uint64_t)(mask)) / ((mask) & ~((mask) << 1)))
>>
>> Notice that part of this expression is "(mask) << 1". So Coverity complains
>> that we took a constant value and shifted it right off the top.
>>
>> I think this is probably a false positive, but why is target/riscv
>> using its own ad-hoc macros for extracting bitfields? We have
>> a standard set of extract/deposit macros in bitops.h, and not
>
> Thanks for pointing those out. I checked the get_field usage from the
> beginning of riscv support 6 years back.
> There are tons of users of get_field in a bunch of riscv sources. I
> guess it was just added once and everybody kept using it
> without switching to generic functions.
I'm not sure about which generic functions we're supposed to use in replace of
get_field/set_field, at least as far as bitops.h goes. extract64/deposit64 has a
different API (it uses start bit + length, not a mask) and it would require
a lot of RISC-V code to be adapted to this format.
Looking a little further I see that registerfields.h has the equivalent of what
we're using here: FIELD_EX64 / FIELD_SEX64. But these macros seems to be tied with
the abstractions used in the header, i.e. registers created with REG32/REG64 and
fields/masks created with the FIELD() macro. The header smmuv3-internal.h makes
use of them so we could use that as a base.
Hopefully Peter/Richard can correct me if I'm wrong and point to the right
direction. Thanks,
Daniel
>
> @Alistair Francis : Are there any other reasons ?
>
> If not, I can take a stab at fixing those if nobody is looking at them already.
>
>> using them makes the riscv code harder to read for people who
>> are used to the rest of the codebase (e.g. to figure out if this
>> Coverity issue is a false positive I would need to look at these
>> macros to figure out what exactly they're doing).
>>
>> thanks
>> -- PMM
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PULL 26/30] target/riscv: Do not setup pmu timer if OF is disabled
2024-07-24 19:00 ` Daniel Henrique Barboza
@ 2024-07-24 21:30 ` Richard Henderson
0 siblings, 0 replies; 45+ messages in thread
From: Richard Henderson @ 2024-07-24 21:30 UTC (permalink / raw)
To: Daniel Henrique Barboza, Atish Kumar Patra, Peter Maydell
Cc: Alistair Francis, qemu-devel, Alistair Francis
On 7/25/24 05:00, Daniel Henrique Barboza wrote:
> I'm not sure about which generic functions we're supposed to use in replace of
> get_field/set_field, at least as far as bitops.h goes. extract64/deposit64 has a
> different API (it uses start bit + length, not a mask) and it would require
> a lot of RISC-V code to be adapted to this format.
>
> Looking a little further I see that registerfields.h has the equivalent of what
> we're using here: FIELD_EX64 / FIELD_SEX64. But these macros seems to be tied with
> the abstractions used in the header, i.e. registers created with REG32/REG64 and
> fields/masks created with the FIELD() macro. The header smmuv3-internal.h makes
> use of them so we could use that as a base.
>
> Hopefully Peter/Richard can correct me if I'm wrong and point to the right
> direction. Thanks,
Yes, registerfields.h is the proper replacement.
r~
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PULL 26/30] target/riscv: Do not setup pmu timer if OF is disabled
2024-07-20 15:19 ` Peter Maydell
2024-07-22 23:33 ` Atish Kumar Patra
@ 2024-07-25 14:05 ` Peter Maydell
1 sibling, 0 replies; 45+ messages in thread
From: Peter Maydell @ 2024-07-25 14:05 UTC (permalink / raw)
To: Alistair Francis
Cc: qemu-devel, Atish Patra, Daniel Henrique Barboza,
Alistair Francis
On Sat, 20 Jul 2024 at 16:19, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Thu, 18 Jul 2024 at 03:15, Alistair Francis <alistair23@gmail.com> wrote:
> >
> > From: Atish Patra <atishp@rivosinc.com>
> >
> > The timer is setup function is invoked in both hpmcounter
> > write and mcountinhibit write path. If the OF bit set, the
> > LCOFI interrupt is disabled. There is no benefitting in
> > setting up the qemu timer until LCOFI is cleared to indicate
> > that interrupts can be fired again.
> > Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> > Signed-off-by: Atish Patra <atishp@rivosinc.com>
> > Message-ID: <20240711-smcntrpmf_v7-v8-12-b7c38ae7b263@rivosinc.com>
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > ---
> > target/riscv/pmu.c | 56 ++++++++++++++++++++++++++++++++++++----------
> > 1 file changed, 44 insertions(+), 12 deletions(-)
> >
> > diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> > index a4729f6c53..3cc0b3648c 100644
> > --- a/target/riscv/pmu.c
> > +++ b/target/riscv/pmu.c
> > @@ -416,14 +416,49 @@ int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
> > return 0;
> > }
>
> Hi; I was looking at an issue Coverity flagged up with this code (CID
> 1558461, 1558463):
>
> > +static bool pmu_hpmevent_is_of_set(CPURISCVState *env, uint32_t ctr_idx)
> > +{
> > + target_ulong mhpmevent_val;
> > + uint64_t of_bit_mask;
> > +
> > + if (riscv_cpu_mxl(env) == MXL_RV32) {
> > + mhpmevent_val = env->mhpmeventh_val[ctr_idx];
> > + of_bit_mask = MHPMEVENTH_BIT_OF;
> > + } else {
> > + mhpmevent_val = env->mhpmevent_val[ctr_idx];
> > + of_bit_mask = MHPMEVENT_BIT_OF;
>
> MHPMEVENT_BIT_OF is defined as BIT_ULL(63)...
>
> > + }
> > +
> > + return get_field(mhpmevent_val, of_bit_mask);
>
> ...but we pass it to get_field(), whose definition is:
>
> #define get_field(reg, mask) (((reg) & \
> (uint64_t)(mask)) / ((mask) & ~((mask) << 1)))
>
> Notice that part of this expression is "(mask) << 1". So Coverity complains
> that we took a constant value and shifted it right off the top.
>
> I think this is probably a false positive
Having worked through some examples I'm happy that this is
a false positive and the expression used here does the
right thing even when the mask goes right up to bit 63.
So I've closed the Coverity issues as false positives;
whether we decide it's worth converting the riscv target to
use QEMU's more standard accessor macros is a separate issue.
If we do want to keep these get_field/set_field macros,
could we add a documentation comment that says what they
do, including description of what the arguments are?
thanks
-- PMM
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PULL 27/30] target/riscv: Expose the Smcntrpmf config
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (25 preceding siblings ...)
2024-07-18 2:10 ` [PULL 26/30] target/riscv: Do not setup pmu timer if OF is disabled Alistair Francis
@ 2024-07-18 2:10 ` Alistair Francis
2024-07-18 2:10 ` [PULL 28/30] target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR Alistair Francis
` (3 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:10 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Atish Patra, Alistair Francis
From: Atish Patra <atishp@rivosinc.com>
Create a new config for Smcntrpmf extension so that it can be enabled/
disabled from the qemu commandline.
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240711-smcntrpmf_v7-v8-13-b7c38ae7b263@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 4efe7ee3b0..a90808a3ba 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1472,6 +1472,7 @@ const char *riscv_get_misa_ext_description(uint32_t bit)
const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
/* Defaults for standard extensions */
MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
+ MULTI_EXT_CFG_BOOL("smcntrpmf", ext_smcntrpmf, false),
MULTI_EXT_CFG_BOOL("zifencei", ext_zifencei, true),
MULTI_EXT_CFG_BOOL("zicsr", ext_zicsr, true),
MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 28/30] target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (26 preceding siblings ...)
2024-07-18 2:10 ` [PULL 27/30] target/riscv: Expose the Smcntrpmf config Alistair Francis
@ 2024-07-18 2:10 ` Alistair Francis
2024-07-18 2:10 ` [PULL 29/30] hw/riscv/virt.c: re-insert and deprecate 'riscv, delegate' Alistair Francis
` (2 subsequent siblings)
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:10 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Yu-Ming Chang, Alvin Chang, Alistair Francis
From: Yu-Ming Chang <yumin686@andestech.com>
Both CSRRS and CSRRC always read the addressed CSR and cause any read side
effects regardless of rs1 and rd fields. Note that if rs1 specifies a register
holding a zero value other than x0, the instruction will still attempt to write
the unmodified value back to the CSR and will cause any attendant side effects.
So if CSRRS or CSRRC tries to write a read-only CSR with rs1 which specifies
a register holding a zero value, an illegal instruction exception should be
raised.
Signed-off-by: Yu-Ming Chang <yumin686@andestech.com>
Signed-off-by: Alvin Chang <alvinga@andestech.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <172100444279.18077.6893072378718059541-0@git.sr.ht>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 4 +++
target/riscv/csr.c | 57 ++++++++++++++++++++++++++++++++++++----
target/riscv/op_helper.c | 6 ++---
3 files changed, 58 insertions(+), 9 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 093c86b8b9..1619c3acb6 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -751,6 +751,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
void riscv_cpu_update_mask(CPURISCVState *env);
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
+ target_ulong *ret_value);
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
target_ulong *ret_value,
target_ulong new_value, target_ulong write_mask);
@@ -783,6 +785,8 @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
target_ulong new_value,
target_ulong write_mask);
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
+ Int128 *ret_value);
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
Int128 *ret_value,
Int128 new_value, Int128 write_mask);
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 781ef27eba..ea3560342c 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -4624,7 +4624,7 @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
int csrno,
- bool write_mask)
+ bool write)
{
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
bool read_only = get_field(csrno, 0xC00) == 3;
@@ -4646,7 +4646,7 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
}
/* read / write check */
- if (write_mask && read_only) {
+ if (write && read_only) {
return RISCV_EXCP_ILLEGAL_INST;
}
@@ -4733,11 +4733,22 @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
return RISCV_EXCP_NONE;
}
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
+ target_ulong *ret_value)
+{
+ RISCVException ret = riscv_csrrw_check(env, csrno, false);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
+ return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
+}
+
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
target_ulong *ret_value,
target_ulong new_value, target_ulong write_mask)
{
- RISCVException ret = riscv_csrrw_check(env, csrno, write_mask);
+ RISCVException ret = riscv_csrrw_check(env, csrno, true);
if (ret != RISCV_EXCP_NONE) {
return ret;
}
@@ -4785,13 +4796,45 @@ static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
return RISCV_EXCP_NONE;
}
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
+ Int128 *ret_value)
+{
+ RISCVException ret;
+
+ ret = riscv_csrrw_check(env, csrno, false);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
+ if (csr_ops[csrno].read128) {
+ return riscv_csrrw_do128(env, csrno, ret_value,
+ int128_zero(), int128_zero());
+ }
+
+ /*
+ * Fall back to 64-bit version for now, if the 128-bit alternative isn't
+ * at all defined.
+ * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
+ * significant), for those, this fallback is correctly handling the
+ * accesses
+ */
+ target_ulong old_value;
+ ret = riscv_csrrw_do64(env, csrno, &old_value,
+ (target_ulong)0,
+ (target_ulong)0);
+ if (ret == RISCV_EXCP_NONE && ret_value) {
+ *ret_value = int128_make64(old_value);
+ }
+ return ret;
+}
+
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
Int128 *ret_value,
Int128 new_value, Int128 write_mask)
{
RISCVException ret;
- ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask));
+ ret = riscv_csrrw_check(env, csrno, true);
if (ret != RISCV_EXCP_NONE) {
return ret;
}
@@ -4830,7 +4873,11 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
#if !defined(CONFIG_USER_ONLY)
env->debugger = true;
#endif
- ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
+ if (!write_mask) {
+ ret = riscv_csrr(env, csrno, ret_value);
+ } else {
+ ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
+ }
#if !defined(CONFIG_USER_ONLY)
env->debugger = false;
#endif
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index ec1408ba0f..25a5263573 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -51,7 +51,7 @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
}
target_ulong val = 0;
- RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
+ RISCVException ret = riscv_csrr(env, csr, &val);
if (ret != RISCV_EXCP_NONE) {
riscv_raise_exception(env, ret, GETPC());
@@ -84,9 +84,7 @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
target_ulong helper_csrr_i128(CPURISCVState *env, int csr)
{
Int128 rv = int128_zero();
- RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
- int128_zero(),
- int128_zero());
+ RISCVException ret = riscv_csrr_i128(env, csr, &rv);
if (ret != RISCV_EXCP_NONE) {
riscv_raise_exception(env, ret, GETPC());
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 29/30] hw/riscv/virt.c: re-insert and deprecate 'riscv, delegate'
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (27 preceding siblings ...)
2024-07-18 2:10 ` [PULL 28/30] target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR Alistair Francis
@ 2024-07-18 2:10 ` Alistair Francis
2024-07-18 2:10 ` [PULL 30/30] roms/opensbi: Update to v1.5 Alistair Francis
2024-07-18 21:01 ` [PULL 00/30] riscv-to-apply queue Richard Henderson
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:10 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Daniel Henrique Barboza, Conor Dooley, Anup Patel,
Alistair Francis
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Commit b1f1e9dcfa renamed 'riscv,delegate' to 'riscv,delegation' since
it is the correct name as per dt-bindings, and the absence of the
correct name will result in validation fails when dumping the dtb and
using dt-validate.
But this change has a side-effect: every other firmware available that
is AIA capable is using 'riscv,delegate', and it will fault/misbehave if
this property isn't present. The property was added back in QEMU 7.0,
meaning we have 2 years of firmware development using the wrong
property.
Re-introducing 'riscv,delegate' while keeping 'riscv,delegation' allows
older firmwares to keep booting with the 'virt' machine.
'riscv,delegate' is then marked for future deprecation with its use
being discouraged from now on.
Cc: Conor Dooley <conor@kernel.org>
Cc: Anup Patel <apatel@ventanamicro.com>
Fixes: b1f1e9dcfa ("hw/riscv/virt.c: aplic DT: rename prop to 'riscv, delegation'")
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240715090455.145888-1-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
docs/about/deprecated.rst | 11 +++++++++++
hw/riscv/virt.c | 9 +++++++++
2 files changed, 20 insertions(+)
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 20b7a17cf0..88f0f03786 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -479,6 +479,17 @@ versions, aliases will point to newer CPU model versions
depending on the machine type, so management software must
resolve CPU model aliases before starting a virtual machine.
+RISC-V "virt" board "riscv,delegate" DT property (since 9.1)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The "riscv,delegate" DT property was added in QEMU 7.0 as part of
+the AIA APLIC support. The property changed name during the review
+process in Linux and the correct name ended up being
+"riscv,delegation". Changing the DT property name will break all
+available firmwares that are using the current (wrong) name. The
+property is kept as is in 9.1, together with "riscv,delegation", to
+give more time for firmware developers to change their code.
+
Migration
---------
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index bc0893e087..9981e0f6c9 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -651,6 +651,15 @@ static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegation",
aplic_child_phandle, 0x1,
VIRT_IRQCHIP_NUM_SOURCES);
+ /*
+ * DEPRECATED_9.1: Compat property kept temporarily
+ * to allow old firmwares to work with AIA. Do *not*
+ * use 'riscv,delegate' in new code: use
+ * 'riscv,delegation' instead.
+ */
+ qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate",
+ aplic_child_phandle, 0x1,
+ VIRT_IRQCHIP_NUM_SOURCES);
}
riscv_socket_fdt_write_id(ms, aplic_name, socket);
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 30/30] roms/opensbi: Update to v1.5
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (28 preceding siblings ...)
2024-07-18 2:10 ` [PULL 29/30] hw/riscv/virt.c: re-insert and deprecate 'riscv, delegate' Alistair Francis
@ 2024-07-18 2:10 ` Alistair Francis
2024-07-18 21:01 ` [PULL 00/30] riscv-to-apply queue Richard Henderson
30 siblings, 0 replies; 45+ messages in thread
From: Alistair Francis @ 2024-07-18 2:10 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Daniel Henrique Barboza, Alistair Francis
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Update OpenSBI and the pre-built opensbi32 and opensbi64 images to
v1.5.
The following commits were included in v1.5:
455de67 include: Bump-up version to 1.5
23b7bad lib: sbi: check incoming dbtr shmem address
0e45b63 docs: Fix wrong filename
caae2f7 lib: sbi: fwft: return SBI_EINVAL rather than SBI_ERR_INVALID_PARAM
e8717d1 lib: sbi: fwft: check feature value to be exactly 1 or 0
ecef14d lib: sbi: implement SBI FWFT extension
e9ee967 lib: sbi: fwft: add support for SBI_FWFT_PTE_AD_HW_UPDATING
c97a1d5 lib: sbi: fwft: add support for SBI_FWFT_MISALIGNED_EXC_DELEG
aa5a859 lib: sbi: add support for firmware features extension
53844c9 lib: sbi: Add support for Svade and Svadu extensions
52dcf35 platform: generic: andes: Add support for RV32 to set up PMA
f09f164 platform: generic: andes: Refine Andes PMA related code
7830e98 lib: serial: fix RX path in litex-uart
62e178a lib: utils/reset: Try initializing all reset devices in dt
3a94a32 sbi: sbi_domain_context: Fix trap context for domain context switching
a73ff04 lib: utils/reset: Fix fdt_reset to search for more dt nodes
b5c984b lib: utils/reset: Skip initialize reset when dt is not enabled
86bbe6c lib: utils/serial: Fix fdt_serial to match more dt nodes
179e00a lib: utils/serial: Skip initialize serial when dt is not enabled
b1c7c75 lib: utils/irqchip: Skip initialize irqchip when dt is not enabled
5e3ad7d lib: utils/timer: Skip initialize timer when dt is not enabled
c5be0e1 lib: utils/ipi: Skip initialize ipi when dt is not enabled
df3db6a lib: utils/fdt: Fix DT property for APLIC delegation
d962db2 lib: utils/gpio: respect flag GPIO_FLAG_ACTIVE_LOW
ae5ef18 lib: sbi: sse: handle missing writable attributes
858754a lib: utils/irqchip: Add sanity checks in imsic_get_data() and imsic_get_target_file()
96f0a2e firmware: Bring back FW_TEXT_START as an optional parameter
e3a30a2 lib: utils/irqchip: Check before initializing imsic
2bed4c1 platform: generic: thead: add Sophgo CV18XX/SG200X series
533067d lib: sbi: Put event after use in sbi_sse_exit() loop
ea9cf6a utils/reset: Add SG2042 hwmon MCU support.
1cb792d lib: sbi: simplify inline function in sbi_dtbr.c
7b37da3 lib: sbi: fix return type of sbi_dbtr_shmem_disabled
e065c3c lib: sbi: Fixed memory permission check in sbi_dbtr_setup_shmem
7f54527 lib: sbi: fix DBTR_SHMEM_MAKE_PHYS for RV64
744f495 lib: sbi: Removal unnecessary check dbtr_thishart_state_ptr
4953bd7 lib: sbi: fix hart_shmem_base
019a8e6 platform: generic: thead: add Canaan Kendryte K230
33e21c9 platform: generic: thead: separate T-Head PMU Errata
2b93ce0 platform: andes: Change all occurrences of andes45 to andes
f68b3ae platform: andes: Rename files with the prefix andes45
17e8291 sbi: sbi_domain_context: Add spinlock for updating domain assigned_harts
1d89a9d lib: sbi: Refine the settings for switching to Virtual Supervisor Mode.
033104d lib: sbi: sse: check handler entry to belong to supervisor mode
bd00765 lib: sbi: sse: use PRV_S instead of hardcoded value for mode
ce3c82c lib: sbi: sse: call enable callback before sending IPI
d528dbf lib: sbi: sse: remove superfluous sbi_list_empty() check
22ff750 lib: sbi: sse: simplify 32bits overflow check
7aa80ea lib: sbi: sse: rename sse_hart_unlock() to sse_enabled_event_unlock()
c21c99d lib: sbi: sse: fix typos, comments and spacing errors
7b1ed96 lib: tests: Add test for spinlocks
7bdf41a lib: tests: Add test for atomic_t
f6243d9 lib: tests: Add test suite init function
d4d2582 firmware: remove FW_TEXT_START
73344d4 lib: utils: check correct value in fdt_node_offset_by_compatible
37e1544 lib: sbi: sse_event_get() may return NULL
68bc031 lib: sbi: Add missing sscrind and sscfg extensions in sbi_hart_ext[]
a7c5c2c Makefile: Remove unnecessary dependencies
268feab Makefile: Respect manual changes to .config
29ecda9 sbi: sbi_domain_context: Check privilege spec version before accessing S-mode CSRs
7862c24 lib: sbi: Wakeup non-coldboot HARTs early in the coldboot path
beb0cd1 lib: sbi: Simplify wait_for_coldboot() implementation
f5375bc platform: generic: allwinner: Optimize current hart scratch access
b94396c lib: utils/timer: Optimize current hart scratch access
5c9a735 include: sbi: Support byteorder macros in assembly
06fc453 lib: sbi: Add SSE support for PMU events
09ad214 lib: sbi: Implement SBI SSE extension
c8cdf01 lib: sbi: Add support for Supervisor Software Events extension
76d7e9b firmware: remove copy-base relocation
5186da6 platform: generic: allwinner: sun20i-d1: Remove duplicated CSR definitions
3b2f89e docs: writing_tests: Make docs correspond the latest changes
f7d0050 lib: sbi: Extend sbi_trap_error() to dump state in a nested trap
5b11f16 lib: sbi: Pass trap context pointer to sbi_ecall_handler()
43d346c lib: sbi: Remove regs parameter from trap irq handling functions
d84e7eb lib: sbi: Remove regs paramter of sbi_irqchip_process()
f414cf9 lib: sbi: Simplify parameters of sbi_illegal_insn_handler()
fea33a9 lib: sbi: Simplify parameters of misaligned and access fault handlers
abea949 lib: sbi: Introduce trap context
60ffc15 include: sbi: Add trap_context pointer in struct sbi_scratch
ebb697a lib: sbi: Remove sbi_trap_exit() and related code
2e85178 lib: sbi: Remove epc from struct sbi_trap_info
86224ec docs/writing_tests: Update tests paths
5c992a1 lib: tests: Move tests to a separate directory
81e3ba7 lib: sbi: call platform load/store emulators
ddf3b64 include: sbi: add emulate_load/store handler to platform ops
4c11265 lib: sbi: abstract out insn decoding to unify mem fault handlers
9221fe5 lib: sbi: change prototype of sbi_misaligned_load/store_handler
a17600c lib: sbi: change prototype of sbi_trap_redirect
2471cf2 include: sbi: rename sbi_misaligned_ldst.h to sbi_trap_ldst.h
c0a6320 lib: sbi: rename sbi_misaligned_ldst.c to sbi_trap_ldst.c
e11025c lib: sbi: Add initial domain context management support
87d8fe7 lib: tests: Add sbi_console test
e5f53fd lib: tests: Add a test for sbi_bitmap
874fcef lib: Add SBIUnit testing macros and functions
b9e4de0 docs: Add documentation about tests and SBIUnit
526b9ce firmware: fw_base.S: fix _reset_regs
8151105 firmware: fw_base.S: Remove _relocate_lottery
187397f firmware: fw_dynamic.S: Remove _bad_dynamic_info
b27b7c6 firmware: fw_base: Simplified setup trap handler
fdf5589 firmware: fw_base.S: Simplify address get
748bef1 lib: sbi_misaligned_ldst: Add handling of C.LHU/C.LH and C.SH
bc36678 platform: andes: Drop andes_pmu_setup()
6bb6b61 lib: sbi: Add support for smcsrind and smcdeleg
322b598 lib: sbi_hsm: Restor hart state to stop when fails to start
96a35db docs/firmware: document new options for jump and payload firmwares
2cff7f3 platform: Apply relocatable address
f056939 firmware: Add relocatable FW_PAYLOAD_FDT_ADDR
7227cdd firmware: Add relocatable FW_JUMP_ADDR and FW_JUMP_FDT_ADDR
741e941 platform: starfive: call starfive_jh7110_inst_init() in pm_reset_init()
3edf044 platform: starfive: return error if needed devices are not present
80ae046 platform: starfive: rename "stf,axp15060-regulator" -> "x-powers,axp15060"
5335340 platform: starfive: remove redundant compatibility check in pmic_ops
4d8569d platform: starfive: get I2C offset address from clocks property
034af1f platform: starfive: correct system clock device tree node
88273fe lib: sbi_pmu: Before using we should ensure PMU init done
46c8c65 docs: move documentation of system suspend test.
8df836d platform: generic: Parse system suspend test from config node.
23e7e48 docs: Add OpenSBI DT configuration guide.
67ce5a7 platform: generic: Add support for specify coldboot harts in DT
9c8b18e firmware: fw_base.S: remove _runtime_offset
4c6b7cb firmware: fw_base.S: Improve loading u32
92e8aff firmware: always create dynsym section
d1dad07 Makefile: check for --exclude-libs
4a76f79 Makefile: don't pass -mstrict-align if not supported
21caaa3 fw_base.S: Fix comment errors
1ec353d lib: sbi: Use mask to check the free bit during trigger allocation
bb90a9e lib: sbi: Print number of debug triggers found
76a2a15 lib: sbi: Implement SBI debug trigger extension
fa87ec9 include: sbi: Add SBI debug trigger extension related defines
97f234f lib: sbi: Introduce the SBI debug triggers extension support
40dac6b lib: sbi: Detect support of debug triggers
2499769 include: sbi: Introduce debug trigger register encodings
20ca19a include: sbi: Add TINFO debug trigger CSR
b752099 include: sbi: Introduce common endianess conversion macro
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240715171521.179517-1-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
.../opensbi-riscv32-generic-fw_dynamic.bin | Bin 267416 -> 268312 bytes
.../opensbi-riscv64-generic-fw_dynamic.bin | Bin 270808 -> 272504 bytes
roms/opensbi | 2 +-
3 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
index 60ca1165c8..7ec260ff40 100644
Binary files a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin differ
diff --git a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin
index bae158d457..090c0cf6ac 100644
Binary files a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin differ
diff --git a/roms/opensbi b/roms/opensbi
index a2b255b889..455de672dd 160000
--- a/roms/opensbi
+++ b/roms/opensbi
@@ -1 +1 @@
-Subproject commit a2b255b88918715173942f2c5e1f97ac9e90c877
+Subproject commit 455de672dd7c2aa1992df54dfb08dc11abbc1b1a
--
2.45.2
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PULL 00/30] riscv-to-apply queue
2024-07-18 2:09 [PULL 00/30] riscv-to-apply queue Alistair Francis
` (29 preceding siblings ...)
2024-07-18 2:10 ` [PULL 30/30] roms/opensbi: Update to v1.5 Alistair Francis
@ 2024-07-18 21:01 ` Richard Henderson
30 siblings, 0 replies; 45+ messages in thread
From: Richard Henderson @ 2024-07-18 21:01 UTC (permalink / raw)
To: qemu-devel
On 7/18/24 12:09, Alistair Francis wrote:
> The following changes since commit 58ee924b97d1c0898555647a31820c5a20d55a73:
>
> Merge tag 'for-upstream' ofhttps://gitlab.com/bonzini/qemu into staging (2024-07-17 15:40:28 +1000)
>
> are available in the Git repository at:
>
> https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240718-1
>
> for you to fetch changes up to daff9f7f7a457f78ce455e6abf19c2a37dfe7630:
>
> roms/opensbi: Update to v1.5 (2024-07-18 12:08:45 +1000)
>
> ----------------------------------------------------------------
> RISC-V PR for 9.1
>
> * Support the zimop, zcmop, zama16b and zabha extensions
> * Validate the mode when setting vstvec CSR
> * Add decode support for Zawrs extension
> * Update the KVM regs to Linux 6.10-rc5
> * Add smcntrpmf extension support
> * Raise an exception when CSRRS/CSRRC writes a read-only CSR
> * Re-insert and deprecate 'riscv,delegate' in virt machine device tree
> * roms/opensbi: Update to v1.5
Applied, thanks. Please update https://wiki.qemu.org/ChangeLog/9.1 as appropriate.
r~
^ permalink raw reply [flat|nested] 45+ messages in thread