1
From: Alistair Francis <alistair.francis@wdc.com>
1
The following changes since commit ad10b4badc1dd5b28305f9b9f1168cf0aa3ae946:
2
2
3
The following changes since commit 6661b8c7fe3f8b5687d2d90f7b4f3f23d70e3e8b:
3
Merge tag 'pull-error-2024-05-27' of https://repo.or.cz/qemu/armbru into staging (2024-05-27 06:40:42 -0700)
4
5
Merge tag 'pull-ppc-20230205' of https://gitlab.com/danielhb/qemu into staging (2023-02-05 16:49:09 +0000)
6
4
7
are available in the Git repository at:
5
are available in the Git repository at:
8
6
9
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20230207
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240528
10
8
11
for you to fetch changes up to 5474aa4f3e0a3e9c171db7c55b5baf15f2e2778c:
9
for you to fetch changes up to 1806da76cb81088ea026ca3441551782b850e393:
12
10
13
hw/riscv: virt: Simplify virt_{get,set}_aclint() (2023-02-07 08:21:32 +1000)
11
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR (2024-05-28 12:20:27 +1000)
14
12
15
----------------------------------------------------------------
13
----------------------------------------------------------------
16
Third RISC-V PR for QEMU 8.0
14
RISC-V PR for 9.1
17
15
18
* Update disas for xnor/orn/andn and slli.uw
16
* APLICs add child earlier than realize
19
* Update opentitan IRQs
17
* Fix exposure of Zkr
20
* Fix rom code when Zicsr is disabled
18
* Raise exceptions on wrs.nto
21
* Update VS timer whenever htimedelta changes
19
* Implement SBI debug console (DBCN) calls for KVM
22
* A collection of fixes for virtulisation
20
* Support 64-bit addresses for initrd
23
* Set tval for triggered watchpoints
21
* Change RISCV_EXCP_SEMIHOST exception number to 63
24
* Cleanups for board and FDT creation
22
* Tolerate KVM disable ext errors
25
* Add support for the T-Head vendor extensions
23
* Set tval in breakpoints
26
* A fix for virtual instr exception
24
* Add support for Zve32x extension
27
* Fix ctzw behavior
25
* Add support for Zve64x extension
28
* Fix SBI getchar handler for KVM
26
* Relax vector register check in RISCV gdbstub
27
* Fix the element agnostic Vector function problem
28
* Fix Zvkb extension config
29
* Implement dynamic establishment of custom decoder
30
* Add th.sxstatus CSR emulation
31
* Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions
32
* Check single width operator for vector fp widen instructions
33
* Check single width operator for vfncvt.rod.f.f.w
34
* Remove redudant SEW checking for vector fp narrow/widen instructions
35
* Prioritize pmp errors in raise_mmu_exception()
36
* Do not set mtval2 for non guest-page faults
37
* Remove experimental prefix from "B" extension
38
* Fixup CBO extension register calculation
39
* Fix the hart bit setting of AIA
40
* Fix reg_width in ricsv_gen_dynamic_vector_feature()
41
* Decode all of the pmpcfg and pmpaddr CSRs
42
* Raise an exception when CSRRS/CSRRC writes a read-only CSR
29
43
30
----------------------------------------------------------------
44
----------------------------------------------------------------
31
Alistair Francis (1):
45
Alexei Filippov (1):
32
hw/riscv: boot: Don't use CSRs if they are disabled
46
target/riscv: do not set mtval2 for non guest-page faults
33
47
34
Anup Patel (4):
48
Alistair Francis (2):
35
target/riscv: Update VS timer whenever htimedelta changes
49
target/riscv: rvzicbo: Fixup CBO extension register calculation
36
target/riscv: Don't clear mask in riscv_cpu_update_mip() for VSTIP
50
disas/riscv: Decode all of the pmpcfg and pmpaddr CSRs
37
target/riscv: No need to re-start QEMU timer when timecmp == UINT64_MAX
38
target/riscv: Ensure opcode is saved for all relevant instructions
39
51
40
Bin Meng (1):
52
Andrew Jones (2):
41
hw/riscv: virt: Simplify virt_{get,set}_aclint()
53
target/riscv/kvm: Fix exposure of Zkr
54
target/riscv: Raise exceptions on wrs.nto
42
55
43
Christoph Müllner (14):
56
Cheng Yang (1):
44
RISC-V: Adding XTheadCmo ISA extension
57
hw/riscv/boot.c: Support 64-bit address for initrd
45
RISC-V: Adding XTheadSync ISA extension
58
46
RISC-V: Adding XTheadBa ISA extension
59
Christoph Müllner (1):
47
RISC-V: Adding XTheadBb ISA extension
60
riscv: thead: Add th.sxstatus CSR emulation
48
RISC-V: Adding XTheadBs ISA extension
61
49
RISC-V: Adding XTheadCondMov ISA extension
62
Clément Léger (1):
50
RISC-V: Adding T-Head multiply-accumulate instructions
63
target/riscv: change RISCV_EXCP_SEMIHOST exception number to 63
51
RISC-V: Adding T-Head MemPair extension
52
RISC-V: Adding T-Head MemIdx extension
53
RISC-V: Adding T-Head FMemIdx extension
54
RISC-V: Set minimum priv version for Zfh to 1.11
55
RISC-V: Add initial support for T-Head C906
56
RISC-V: Adding XTheadFmv ISA extension
57
target/riscv: add a MAINTAINERS entry for XThead* extension support
58
64
59
Daniel Henrique Barboza (6):
65
Daniel Henrique Barboza (6):
60
hw/riscv/virt.c: calculate socket count once in create_fdt_imsic()
66
target/riscv/kvm: implement SBI debug console (DBCN) calls
61
hw/riscv/virt.c: rename MachineState 'mc' pointers to 'ms'
67
target/riscv/kvm: tolerate KVM disable ext errors
62
hw/riscv/spike.c: rename MachineState 'mc' pointers to' ms'
68
target/riscv/debug: set tval=pc in breakpoint exceptions
63
hw/riscv/boot.c: calculate fdt size after fdt_pack()
69
trans_privileged.c.inc: set (m|s)tval on ebreak breakpoint
64
hw/riscv: split fdt address calculation from fdt load
70
target/riscv: prioritize pmp errors in raise_mmu_exception()
65
hw/riscv: change riscv_compute_fdt_addr() semantics
71
riscv, gdbstub.c: fix reg_width in ricsv_gen_dynamic_vector_feature()
66
72
67
Deepak Gupta (1):
73
Huang Tao (2):
68
target/riscv: fix for virtual instr exception
74
target/riscv: Fix the element agnostic function problem
75
target/riscv: Implement dynamic establishment of custom decoder
69
76
70
Philipp Tomsich (1):
77
Jason Chien (3):
71
target/riscv: update disas.c for xnor/orn/andn and slli.uw
78
target/riscv: Add support for Zve32x extension
79
target/riscv: Add support for Zve64x extension
80
target/riscv: Relax vector register check in RISCV gdbstub
72
81
73
Sergey Matyukevich (1):
82
Max Chou (4):
74
target/riscv: set tval for triggered watchpoints
83
target/riscv: rvv: Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions
84
target/riscv: rvv: Check single width operator for vector fp widen instructions
85
target/riscv: rvv: Check single width operator for vfncvt.rod.f.f.w
86
target/riscv: rvv: Remove redudant SEW checking for vector fp narrow/widen instructions
75
87
76
Vladimir Isaev (2):
88
Rob Bradford (1):
77
target/riscv: fix ctzw behavior
89
target/riscv: Remove experimental prefix from "B" extension
78
target/riscv: fix SBI getchar handler for KVM
79
90
80
Wilfred Mallawa (1):
91
Yangyu Chen (1):
81
include/hw/riscv/opentitan: update opentitan IRQs
92
target/riscv/cpu.c: fix Zvkb extension config
82
93
83
MAINTAINERS | 8 +
94
Yong-Xuan Wang (1):
84
include/hw/riscv/boot.h | 4 +-
95
target/riscv/kvm.c: Fix the hart bit setting of AIA
85
include/hw/riscv/opentitan.h | 14 +-
96
86
target/riscv/cpu.h | 12 +
97
Yu-Ming Chang (1):
87
target/riscv/cpu_vendorid.h | 6 +
98
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR
88
target/riscv/helper.h | 1 +
99
89
target/riscv/xthead.decode | 185 +++++
100
yang.zhang (1):
90
disas/riscv.c | 8 +-
101
hw/intc/riscv_aplic: APLICs should add child earlier than realize
91
hw/riscv/boot.c | 62 +-
102
92
hw/riscv/microchip_pfsoc.c | 7 +-
103
MAINTAINERS | 1 +
93
hw/riscv/opentitan.c | 80 +-
104
target/riscv/cpu.h | 11 ++
94
hw/riscv/sifive_u.c | 8 +-
105
target/riscv/cpu_bits.h | 2 +-
95
hw/riscv/spike.c | 25 +-
106
target/riscv/cpu_cfg.h | 2 +
96
hw/riscv/virt.c | 476 ++++++------
107
target/riscv/helper.h | 1 +
97
target/riscv/cpu.c | 55 +-
108
target/riscv/sbi_ecall_interface.h | 17 +++
98
target/riscv/cpu_helper.c | 8 +-
109
target/riscv/tcg/tcg-cpu.h | 15 +++
99
target/riscv/csr.c | 16 +
110
disas/riscv.c | 65 +++++++++-
100
target/riscv/debug.c | 1 -
111
hw/intc/riscv_aplic.c | 8 +-
101
target/riscv/kvm.c | 5 +-
112
hw/riscv/boot.c | 4 +-
102
target/riscv/op_helper.c | 6 +
113
target/riscv/cpu.c | 10 +-
103
target/riscv/time_helper.c | 36 +-
114
target/riscv/cpu_helper.c | 37 +++---
104
target/riscv/translate.c | 32 +
115
target/riscv/csr.c | 71 +++++++++--
105
target/riscv/insn_trans/trans_rva.c.inc | 10 +-
116
target/riscv/debug.c | 3 +
106
target/riscv/insn_trans/trans_rvb.c.inc | 1 +
117
target/riscv/gdbstub.c | 8 +-
107
target/riscv/insn_trans/trans_rvd.c.inc | 2 +
118
target/riscv/kvm/kvm-cpu.c | 157 ++++++++++++++++++++++++-
108
target/riscv/insn_trans/trans_rvf.c.inc | 2 +
119
target/riscv/op_helper.c | 17 ++-
109
target/riscv/insn_trans/trans_rvh.c.inc | 3 +
120
target/riscv/tcg/tcg-cpu.c | 50 +++++---
110
target/riscv/insn_trans/trans_rvi.c.inc | 2 +
121
target/riscv/th_csr.c | 79 +++++++++++++
111
target/riscv/insn_trans/trans_rvzfh.c.inc | 2 +
122
target/riscv/translate.c | 31 +++--
112
target/riscv/insn_trans/trans_svinval.c.inc | 3 +
123
target/riscv/vector_internals.c | 22 ++++
113
target/riscv/insn_trans/trans_xthead.c.inc | 1094 +++++++++++++++++++++++++++
124
target/riscv/insn_trans/trans_privileged.c.inc | 2 +
114
target/riscv/meson.build | 1 +
125
target/riscv/insn_trans/trans_rvv.c.inc | 46 +++++---
115
32 files changed, 1847 insertions(+), 328 deletions(-)
126
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 +++--
116
create mode 100644 target/riscv/cpu_vendorid.h
127
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++-
117
create mode 100644 target/riscv/xthead.decode
128
target/riscv/meson.build | 1 +
118
create mode 100644 target/riscv/insn_trans/trans_xthead.c.inc
129
26 files changed, 596 insertions(+), 109 deletions(-)
130
create mode 100644 target/riscv/th_csr.c
131
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: "yang.zhang" <yang.zhang@hexintek.com>
2
2
3
This patch adds support for the T-Head FMemIdx instructions.
3
Since only root APLICs can have hw IRQ lines, aplic->parent should
4
The patch uses the T-Head specific decoder and translation.
4
be initialized first.
5
5
6
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
Fixes: e8f79343cf ("hw/intc: Add RISC-V AIA APLIC device emulation")
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
8
Signed-off-by: yang.zhang <yang.zhang@hexintek.com>
9
Message-Id: <20230131202013.2541053-11-christoph.muellner@vrull.eu>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
10
Message-ID: <20240409014445.278-1-gaoshanliukou@163.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
---
12
target/riscv/cpu.h | 1 +
13
hw/intc/riscv_aplic.c | 8 ++++----
13
target/riscv/xthead.decode | 10 ++
14
1 file changed, 4 insertions(+), 4 deletions(-)
14
target/riscv/cpu.c | 2 +
15
target/riscv/translate.c | 3 +-
16
target/riscv/insn_trans/trans_xthead.c.inc | 108 +++++++++++++++++++++
17
5 files changed, 123 insertions(+), 1 deletion(-)
18
15
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
16
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.h
18
--- a/hw/intc/riscv_aplic.c
22
+++ b/target/riscv/cpu.h
19
+++ b/hw/intc/riscv_aplic.c
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
20
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
24
bool ext_xtheadbs;
21
qdev_prop_set_bit(dev, "msimode", msimode);
25
bool ext_xtheadcmo;
22
qdev_prop_set_bit(dev, "mmode", mmode);
26
bool ext_xtheadcondmov;
23
27
+ bool ext_xtheadfmemidx;
24
+ if (parent) {
28
bool ext_xtheadmac;
25
+ riscv_aplic_add_child(parent, dev);
29
bool ext_xtheadmemidx;
30
bool ext_xtheadmempair;
31
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/xthead.decode
34
+++ b/target/riscv/xthead.decode
35
@@ -XXX,XX +XXX,XX @@ th_l2cache_iall 0000000 10110 00000 000 00000 0001011
36
th_mveqz 0100000 ..... ..... 001 ..... 0001011 @r
37
th_mvnez 0100001 ..... ..... 001 ..... 0001011 @r
38
39
+# XTheadFMemIdx
40
+th_flrd 01100 .. ..... ..... 110 ..... 0001011 @th_memidx
41
+th_flrw 01000 .. ..... ..... 110 ..... 0001011 @th_memidx
42
+th_flurd 01110 .. ..... ..... 110 ..... 0001011 @th_memidx
43
+th_flurw 01010 .. ..... ..... 110 ..... 0001011 @th_memidx
44
+th_fsrd 01100 .. ..... ..... 111 ..... 0001011 @th_memidx
45
+th_fsrw 01000 .. ..... ..... 111 ..... 0001011 @th_memidx
46
+th_fsurd 01110 .. ..... ..... 111 ..... 0001011 @th_memidx
47
+th_fsurw 01010 .. ..... ..... 111 ..... 0001011 @th_memidx
48
+
49
# XTheadMac
50
th_mula 00100 00 ..... ..... 001 ..... 0001011 @r
51
th_mulah 00101 00 ..... ..... 001 ..... 0001011 @r
52
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/riscv/cpu.c
55
+++ b/target/riscv/cpu.c
56
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
57
ISA_EXT_DATA_ENTRY(xtheadbs, true, PRIV_VERSION_1_11_0, ext_xtheadbs),
58
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
59
ISA_EXT_DATA_ENTRY(xtheadcondmov, true, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
60
+ ISA_EXT_DATA_ENTRY(xtheadfmemidx, true, PRIV_VERSION_1_11_0, ext_xtheadfmemidx),
61
ISA_EXT_DATA_ENTRY(xtheadmac, true, PRIV_VERSION_1_11_0, ext_xtheadmac),
62
ISA_EXT_DATA_ENTRY(xtheadmemidx, true, PRIV_VERSION_1_11_0, ext_xtheadmemidx),
63
ISA_EXT_DATA_ENTRY(xtheadmempair, true, PRIV_VERSION_1_11_0, ext_xtheadmempair),
64
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
65
DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
66
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
67
DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
68
+ DEFINE_PROP_BOOL("xtheadfmemidx", RISCVCPU, cfg.ext_xtheadfmemidx, false),
69
DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false),
70
DEFINE_PROP_BOOL("xtheadmemidx", RISCVCPU, cfg.ext_xtheadmemidx, false),
71
DEFINE_PROP_BOOL("xtheadmempair", RISCVCPU, cfg.ext_xtheadmempair, false),
72
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/riscv/translate.c
75
+++ b/target/riscv/translate.c
76
@@ -XXX,XX +XXX,XX @@ static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
77
{
78
return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
79
ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
80
- ctx->cfg_ptr->ext_xtheadcondmov || ctx->cfg_ptr->ext_xtheadmac ||
81
+ ctx->cfg_ptr->ext_xtheadcondmov ||
82
+ ctx->cfg_ptr->ext_xtheadfmemidx || ctx->cfg_ptr->ext_xtheadmac ||
83
ctx->cfg_ptr->ext_xtheadmemidx || ctx->cfg_ptr->ext_xtheadmempair ||
84
ctx->cfg_ptr->ext_xtheadsync;
85
}
86
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/riscv/insn_trans/trans_xthead.c.inc
89
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
90
@@ -XXX,XX +XXX,XX @@
91
} \
92
} while (0)
93
94
+#define REQUIRE_XTHEADFMEMIDX(ctx) do { \
95
+ if (!ctx->cfg_ptr->ext_xtheadfmemidx) { \
96
+ return false; \
97
+ } \
98
+} while (0)
99
+
100
#define REQUIRE_XTHEADMAC(ctx) do { \
101
if (!ctx->cfg_ptr->ext_xtheadmac) { \
102
return false; \
103
@@ -XXX,XX +XXX,XX @@ static bool trans_th_mvnez(DisasContext *ctx, arg_th_mveqz *a)
104
return gen_th_condmove(ctx, a, TCG_COND_NE);
105
}
106
107
+/* XTheadFMem */
108
+
109
+/*
110
+ * Load 64-bit float from indexed address.
111
+ * If !zext_offs, then address is rs1 + (rs2 << imm2).
112
+ * If zext_offs, then address is rs1 + (zext(rs2[31:0]) << imm2).
113
+ */
114
+static bool gen_fload_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop,
115
+ bool zext_offs)
116
+{
117
+ TCGv_i64 rd = cpu_fpr[a->rd];
118
+ TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs);
119
+
120
+ tcg_gen_qemu_ld_i64(rd, addr, ctx->mem_idx, memop);
121
+ if ((memop & MO_SIZE) == MO_32) {
122
+ gen_nanbox_s(rd, rd);
123
+ }
26
+ }
124
+
27
+
125
+ mark_fs_dirty(ctx);
28
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
126
+ return true;
29
127
+}
30
if (!is_kvm_aia(msimode)) {
128
+
31
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
129
+/*
32
}
130
+ * Store 64-bit float to indexed address.
33
131
+ * If !zext_offs, then address is rs1 + (rs2 << imm2).
34
- if (parent) {
132
+ * If zext_offs, then address is rs1 + (zext(rs2[31:0]) << imm2).
35
- riscv_aplic_add_child(parent, dev);
133
+ */
36
- }
134
+static bool gen_fstore_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop,
37
-
135
+ bool zext_offs)
38
if (!msimode) {
136
+{
39
for (i = 0; i < num_harts; i++) {
137
+ TCGv_i64 rd = cpu_fpr[a->rd];
40
CPUState *cpu = cpu_by_arch_id(hartid_base + i);
138
+ TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs);
139
+
140
+ tcg_gen_qemu_st_i64(rd, addr, ctx->mem_idx, memop);
141
+
142
+ return true;
143
+}
144
+
145
+static bool trans_th_flrd(DisasContext *ctx, arg_th_memidx *a)
146
+{
147
+ REQUIRE_XTHEADFMEMIDX(ctx);
148
+ REQUIRE_FPU;
149
+ REQUIRE_EXT(ctx, RVD);
150
+ return gen_fload_idx(ctx, a, MO_TEUQ, false);
151
+}
152
+
153
+static bool trans_th_flrw(DisasContext *ctx, arg_th_memidx *a)
154
+{
155
+ REQUIRE_XTHEADFMEMIDX(ctx);
156
+ REQUIRE_FPU;
157
+ REQUIRE_EXT(ctx, RVF);
158
+ return gen_fload_idx(ctx, a, MO_TEUL, false);
159
+}
160
+
161
+static bool trans_th_flurd(DisasContext *ctx, arg_th_memidx *a)
162
+{
163
+ REQUIRE_XTHEADFMEMIDX(ctx);
164
+ REQUIRE_FPU;
165
+ REQUIRE_EXT(ctx, RVD);
166
+ return gen_fload_idx(ctx, a, MO_TEUQ, true);
167
+}
168
+
169
+static bool trans_th_flurw(DisasContext *ctx, arg_th_memidx *a)
170
+{
171
+ REQUIRE_XTHEADFMEMIDX(ctx);
172
+ REQUIRE_FPU;
173
+ REQUIRE_EXT(ctx, RVF);
174
+ return gen_fload_idx(ctx, a, MO_TEUL, true);
175
+}
176
+
177
+static bool trans_th_fsrd(DisasContext *ctx, arg_th_memidx *a)
178
+{
179
+ REQUIRE_XTHEADFMEMIDX(ctx);
180
+ REQUIRE_FPU;
181
+ REQUIRE_EXT(ctx, RVD);
182
+ return gen_fstore_idx(ctx, a, MO_TEUQ, false);
183
+}
184
+
185
+static bool trans_th_fsrw(DisasContext *ctx, arg_th_memidx *a)
186
+{
187
+ REQUIRE_XTHEADFMEMIDX(ctx);
188
+ REQUIRE_FPU;
189
+ REQUIRE_EXT(ctx, RVF);
190
+ return gen_fstore_idx(ctx, a, MO_TEUL, false);
191
+}
192
+
193
+static bool trans_th_fsurd(DisasContext *ctx, arg_th_memidx *a)
194
+{
195
+ REQUIRE_XTHEADFMEMIDX(ctx);
196
+ REQUIRE_FPU;
197
+ REQUIRE_EXT(ctx, RVD);
198
+ return gen_fstore_idx(ctx, a, MO_TEUQ, true);
199
+}
200
+
201
+static bool trans_th_fsurw(DisasContext *ctx, arg_th_memidx *a)
202
+{
203
+ REQUIRE_XTHEADFMEMIDX(ctx);
204
+ REQUIRE_FPU;
205
+ REQUIRE_EXT(ctx, RVF);
206
+ return gen_fstore_idx(ctx, a, MO_TEUL, true);
207
+}
208
+
209
/* XTheadMac */
210
211
static bool gen_th_mac(DisasContext *ctx, arg_r *a,
212
--
41
--
213
2.39.1
42
2.45.1
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Andrew Jones <ajones@ventanamicro.com>
2
2
3
This patch adds support for the T-Head MemIdx instructions.
3
The Zkr extension may only be exposed to KVM guests if the VMM
4
The patch uses the T-Head specific decoder and translation.
4
implements the SEED CSR. Use the same implementation as TCG.
5
5
6
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
Without this patch, running with a KVM which does not forward the
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
SEED CSR access to QEMU will result in an ILL exception being
8
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
8
injected into the guest (this results in Linux guests crashing on
9
Message-Id: <20230131202013.2541053-10-christoph.muellner@vrull.eu>
9
boot). And, when running with a KVM which does forward the access,
10
QEMU will crash, since QEMU doesn't know what to do with the exit.
11
12
Fixes: 3108e2f1c69d ("target/riscv/kvm: update KVM exts to Linux 6.8")
13
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Cc: qemu-stable <qemu-stable@nongnu.org>
16
Message-ID: <20240422134605.534207-2-ajones@ventanamicro.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
18
---
12
target/riscv/cpu.h | 1 +
19
target/riscv/cpu.h | 3 +++
13
target/riscv/xthead.decode | 54 +++
20
target/riscv/csr.c | 18 ++++++++++++++----
14
target/riscv/cpu.c | 2 +
21
target/riscv/kvm/kvm-cpu.c | 25 +++++++++++++++++++++++++
15
target/riscv/translate.c | 21 +-
22
3 files changed, 42 insertions(+), 4 deletions(-)
16
target/riscv/insn_trans/trans_xthead.c.inc | 387 +++++++++++++++++++++
17
5 files changed, 464 insertions(+), 1 deletion(-)
18
23
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.h
26
--- a/target/riscv/cpu.h
22
+++ b/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
28
@@ -XXX,XX +XXX,XX @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
24
bool ext_xtheadcmo;
29
25
bool ext_xtheadcondmov;
30
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
26
bool ext_xtheadmac;
31
27
+ bool ext_xtheadmemidx;
32
+target_ulong riscv_new_csr_seed(target_ulong new_value,
28
bool ext_xtheadmempair;
33
+ target_ulong write_mask);
29
bool ext_xtheadsync;
34
+
30
bool ext_XVentanaCondOps;
35
uint8_t satp_mode_max_from_map(uint32_t map);
31
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
36
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
37
38
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
32
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/xthead.decode
40
--- a/target/riscv/csr.c
34
+++ b/target/riscv/xthead.decode
41
+++ b/target/riscv/csr.c
35
@@ -XXX,XX +XXX,XX @@
42
@@ -XXX,XX +XXX,XX @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
36
%rd2 20:5
43
#endif
37
%rs2 20:5
44
38
%sh5 20:5
45
/* Crypto Extension */
39
+%imm5 20:s5
46
-static RISCVException rmw_seed(CPURISCVState *env, int csrno,
40
%sh6 20:6
47
- target_ulong *ret_value,
41
%sh2 25:2
48
- target_ulong new_value,
42
+%imm2 25:2
49
- target_ulong write_mask)
43
50
+target_ulong riscv_new_csr_seed(target_ulong new_value,
44
# Argument sets
51
+ target_ulong write_mask)
45
&r rd rs1 rs2 !extern
52
{
46
@@ -XXX,XX +XXX,XX @@
53
uint16_t random_v;
47
&shift shamt rs1 rd !extern
54
Error *random_e = NULL;
48
&th_bfext msb lsb rs1 rd
55
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
49
&th_pair rd1 rs rd2 sh2
56
rval = random_v | SEED_OPST_ES16;
50
+&th_memidx rd rs1 rs2 imm2
57
}
51
+&th_meminc rd rs1 imm5 imm2
58
52
59
+ return rval;
53
# Formats
54
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
55
@@ -XXX,XX +XXX,XX @@
56
@sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd
57
@sh6 ...... ...... ..... ... ..... ....... &shift shamt=%sh6 %rs1 %rd
58
@th_pair ..... .. ..... ..... ... ..... ....... &th_pair %rd1 %rs %rd2 %sh2
59
+@th_memidx ..... .. ..... ..... ... ..... ....... &th_memidx %rd %rs1 %rs2 %imm2
60
+@th_meminc ..... .. ..... ..... ... ..... ....... &th_meminc %rd %rs1 %imm5 %imm2
61
62
# XTheadBa
63
# Instead of defining a new encoding, we simply use the decoder to
64
@@ -XXX,XX +XXX,XX @@ th_muls 00100 01 ..... ..... 001 ..... 0001011 @r
65
th_mulsh 00101 01 ..... ..... 001 ..... 0001011 @r
66
th_mulsw 00100 11 ..... ..... 001 ..... 0001011 @r
67
68
+# XTheadMemIdx
69
+th_ldia 01111 .. ..... ..... 100 ..... 0001011 @th_meminc
70
+th_ldib 01101 .. ..... ..... 100 ..... 0001011 @th_meminc
71
+th_lwia 01011 .. ..... ..... 100 ..... 0001011 @th_meminc
72
+th_lwib 01001 .. ..... ..... 100 ..... 0001011 @th_meminc
73
+th_lwuia 11011 .. ..... ..... 100 ..... 0001011 @th_meminc
74
+th_lwuib 11001 .. ..... ..... 100 ..... 0001011 @th_meminc
75
+th_lhia 00111 .. ..... ..... 100 ..... 0001011 @th_meminc
76
+th_lhib 00101 .. ..... ..... 100 ..... 0001011 @th_meminc
77
+th_lhuia 10111 .. ..... ..... 100 ..... 0001011 @th_meminc
78
+th_lhuib 10101 .. ..... ..... 100 ..... 0001011 @th_meminc
79
+th_lbia 00011 .. ..... ..... 100 ..... 0001011 @th_meminc
80
+th_lbib 00001 .. ..... ..... 100 ..... 0001011 @th_meminc
81
+th_lbuia 10011 .. ..... ..... 100 ..... 0001011 @th_meminc
82
+th_lbuib 10001 .. ..... ..... 100 ..... 0001011 @th_meminc
83
+th_sdia 01111 .. ..... ..... 101 ..... 0001011 @th_meminc
84
+th_sdib 01101 .. ..... ..... 101 ..... 0001011 @th_meminc
85
+th_swia 01011 .. ..... ..... 101 ..... 0001011 @th_meminc
86
+th_swib 01001 .. ..... ..... 101 ..... 0001011 @th_meminc
87
+th_shia 00111 .. ..... ..... 101 ..... 0001011 @th_meminc
88
+th_shib 00101 .. ..... ..... 101 ..... 0001011 @th_meminc
89
+th_sbia 00011 .. ..... ..... 101 ..... 0001011 @th_meminc
90
+th_sbib 00001 .. ..... ..... 101 ..... 0001011 @th_meminc
91
+
92
+th_lrd 01100 .. ..... ..... 100 ..... 0001011 @th_memidx
93
+th_lrw 01000 .. ..... ..... 100 ..... 0001011 @th_memidx
94
+th_lrwu 11000 .. ..... ..... 100 ..... 0001011 @th_memidx
95
+th_lrh 00100 .. ..... ..... 100 ..... 0001011 @th_memidx
96
+th_lrhu 10100 .. ..... ..... 100 ..... 0001011 @th_memidx
97
+th_lrb 00000 .. ..... ..... 100 ..... 0001011 @th_memidx
98
+th_lrbu 10000 .. ..... ..... 100 ..... 0001011 @th_memidx
99
+th_srd 01100 .. ..... ..... 101 ..... 0001011 @th_memidx
100
+th_srw 01000 .. ..... ..... 101 ..... 0001011 @th_memidx
101
+th_srh 00100 .. ..... ..... 101 ..... 0001011 @th_memidx
102
+th_srb 00000 .. ..... ..... 101 ..... 0001011 @th_memidx
103
+
104
+th_lurd 01110 .. ..... ..... 100 ..... 0001011 @th_memidx
105
+th_lurw 01010 .. ..... ..... 100 ..... 0001011 @th_memidx
106
+th_lurwu 11010 .. ..... ..... 100 ..... 0001011 @th_memidx
107
+th_lurh 00110 .. ..... ..... 100 ..... 0001011 @th_memidx
108
+th_lurhu 10110 .. ..... ..... 100 ..... 0001011 @th_memidx
109
+th_lurb 00010 .. ..... ..... 100 ..... 0001011 @th_memidx
110
+th_lurbu 10010 .. ..... ..... 100 ..... 0001011 @th_memidx
111
+th_surd 01110 .. ..... ..... 101 ..... 0001011 @th_memidx
112
+th_surw 01010 .. ..... ..... 101 ..... 0001011 @th_memidx
113
+th_surh 00110 .. ..... ..... 101 ..... 0001011 @th_memidx
114
+th_surb 00010 .. ..... ..... 101 ..... 0001011 @th_memidx
115
+
116
# XTheadMemPair
117
th_ldd 11111 .. ..... ..... 100 ..... 0001011 @th_pair
118
th_lwd 11100 .. ..... ..... 100 ..... 0001011 @th_pair
119
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/target/riscv/cpu.c
122
+++ b/target/riscv/cpu.c
123
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
124
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
125
ISA_EXT_DATA_ENTRY(xtheadcondmov, true, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
126
ISA_EXT_DATA_ENTRY(xtheadmac, true, PRIV_VERSION_1_11_0, ext_xtheadmac),
127
+ ISA_EXT_DATA_ENTRY(xtheadmemidx, true, PRIV_VERSION_1_11_0, ext_xtheadmemidx),
128
ISA_EXT_DATA_ENTRY(xtheadmempair, true, PRIV_VERSION_1_11_0, ext_xtheadmempair),
129
ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
130
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
131
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
132
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
133
DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
134
DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false),
135
+ DEFINE_PROP_BOOL("xtheadmemidx", RISCVCPU, cfg.ext_xtheadmemidx, false),
136
DEFINE_PROP_BOOL("xtheadmempair", RISCVCPU, cfg.ext_xtheadmempair, false),
137
DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
138
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
139
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/target/riscv/translate.c
142
+++ b/target/riscv/translate.c
143
@@ -XXX,XX +XXX,XX @@ static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
144
return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
145
ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
146
ctx->cfg_ptr->ext_xtheadcondmov || ctx->cfg_ptr->ext_xtheadmac ||
147
- ctx->cfg_ptr->ext_xtheadmempair || ctx->cfg_ptr->ext_xtheadsync;
148
+ ctx->cfg_ptr->ext_xtheadmemidx || ctx->cfg_ptr->ext_xtheadmempair ||
149
+ ctx->cfg_ptr->ext_xtheadsync;
150
}
151
152
#define MATERIALISE_EXT_PREDICATE(ext) \
153
@@ -XXX,XX +XXX,XX @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm)
154
return addr;
155
}
156
157
+/* Compute a canonical address from a register plus reg offset. */
158
+static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs)
159
+{
160
+ TCGv addr = temp_new(ctx);
161
+ TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
162
+
163
+ tcg_gen_add_tl(addr, src1, offs);
164
+ if (ctx->pm_mask_enabled) {
165
+ tcg_gen_andc_tl(addr, addr, pm_mask);
166
+ } else if (get_xl(ctx) == MXL_RV32) {
167
+ tcg_gen_ext32u_tl(addr, addr);
168
+ }
169
+ if (ctx->pm_base_enabled) {
170
+ tcg_gen_or_tl(addr, addr, pm_base);
171
+ }
172
+ return addr;
173
+}
60
+}
174
+
61
+
175
#ifndef CONFIG_USER_ONLY
62
+static RISCVException rmw_seed(CPURISCVState *env, int csrno,
176
/* The states of mstatus_fs are:
63
+ target_ulong *ret_value,
177
* 0 = disabled, 1 = initial, 2 = clean, 3 = dirty
64
+ target_ulong new_value,
178
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
65
+ target_ulong write_mask)
66
+{
67
+ target_ulong rval;
68
+
69
+ rval = riscv_new_csr_seed(new_value, write_mask);
70
+
71
if (ret_value) {
72
*ret_value = rval;
73
}
74
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
179
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
180
--- a/target/riscv/insn_trans/trans_xthead.c.inc
76
--- a/target/riscv/kvm/kvm-cpu.c
181
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
77
+++ b/target/riscv/kvm/kvm-cpu.c
182
@@ -XXX,XX +XXX,XX @@
78
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
183
} \
79
return ret;
184
} while (0)
80
}
185
81
186
+#define REQUIRE_XTHEADMEMIDX(ctx) do { \
82
+static int kvm_riscv_handle_csr(CPUState *cs, struct kvm_run *run)
187
+ if (!ctx->cfg_ptr->ext_xtheadmemidx) { \
83
+{
188
+ return false; \
84
+ target_ulong csr_num = run->riscv_csr.csr_num;
189
+ } \
85
+ target_ulong new_value = run->riscv_csr.new_value;
190
+} while (0)
86
+ target_ulong write_mask = run->riscv_csr.write_mask;
87
+ int ret = 0;
191
+
88
+
192
#define REQUIRE_XTHEADMEMPAIR(ctx) do { \
89
+ switch (csr_num) {
193
if (!ctx->cfg_ptr->ext_xtheadmempair) { \
90
+ case CSR_SEED:
194
return false; \
91
+ run->riscv_csr.ret_value = riscv_new_csr_seed(new_value, write_mask);
195
@@ -XXX,XX +XXX,XX @@
92
+ break;
196
} \
93
+ default:
197
} while (0)
94
+ qemu_log_mask(LOG_UNIMP,
198
95
+ "%s: un-handled CSR EXIT for CSR %lx\n",
199
+/*
96
+ __func__, csr_num);
200
+ * Calculate and return the address for indexed mem operations:
97
+ ret = -1;
201
+ * If !zext_offs, then the address is rs1 + (rs2 << imm2).
98
+ break;
202
+ * If zext_offs, then the address is rs1 + (zext(rs2[31:0]) << imm2).
203
+ */
204
+static TCGv get_th_address_indexed(DisasContext *ctx, int rs1, int rs2,
205
+ int imm2, bool zext_offs)
206
+{
207
+ TCGv src2 = get_gpr(ctx, rs2, EXT_NONE);
208
+ TCGv offs = tcg_temp_new();
209
+
210
+ if (zext_offs) {
211
+ tcg_gen_extract_tl(offs, src2, 0, 32);
212
+ tcg_gen_shli_tl(offs, offs, imm2);
213
+ } else {
214
+ tcg_gen_shli_tl(offs, src2, imm2);
215
+ }
99
+ }
216
+
100
+
217
+ TCGv addr = get_address_indexed(ctx, rs1, offs);
101
+ return ret;
218
+
219
+ tcg_temp_free(offs);
220
+ return addr;
221
+}
102
+}
222
+
103
+
223
/* XTheadBa */
104
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
224
105
{
225
/*
106
int ret = 0;
226
@@ -XXX,XX +XXX,XX @@ static bool trans_th_mulsw(DisasContext *ctx, arg_th_mulsw *a)
107
@@ -XXX,XX +XXX,XX @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
227
return gen_th_mac(ctx, a, tcg_gen_sub_tl, NULL);
108
case KVM_EXIT_RISCV_SBI:
228
}
109
ret = kvm_riscv_handle_sbi(cs, run);
229
110
break;
230
+/* XTheadMemIdx */
111
+ case KVM_EXIT_RISCV_CSR:
231
+
112
+ ret = kvm_riscv_handle_csr(cs, run);
232
+/*
113
+ break;
233
+ * Load with memop from indexed address and add (imm5 << imm2) to rs1.
114
default:
234
+ * If !preinc, then the load address is rs1.
115
qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
235
+ * If preinc, then the load address is rs1 + (imm5) << imm2).
116
__func__, run->exit_reason);
236
+ */
237
+static bool gen_load_inc(DisasContext *ctx, arg_th_meminc *a, MemOp memop,
238
+ bool preinc)
239
+{
240
+ if (a->rs1 == a->rd) {
241
+ return false;
242
+ }
243
+
244
+ int imm = a->imm5 << a->imm2;
245
+ TCGv addr = get_address(ctx, a->rs1, preinc ? imm : 0);
246
+ TCGv rd = dest_gpr(ctx, a->rd);
247
+ TCGv rs1 = get_gpr(ctx, a->rs1, EXT_NONE);
248
+
249
+ tcg_gen_qemu_ld_tl(rd, addr, ctx->mem_idx, memop);
250
+ tcg_gen_addi_tl(rs1, rs1, imm);
251
+ gen_set_gpr(ctx, a->rd, rd);
252
+ gen_set_gpr(ctx, a->rs1, rs1);
253
+
254
+ tcg_temp_free(addr);
255
+ return true;
256
+}
257
+
258
+/*
259
+ * Store with memop to indexed address and add (imm5 << imm2) to rs1.
260
+ * If !preinc, then the store address is rs1.
261
+ * If preinc, then the store address is rs1 + (imm5) << imm2).
262
+ */
263
+static bool gen_store_inc(DisasContext *ctx, arg_th_meminc *a, MemOp memop,
264
+ bool preinc)
265
+{
266
+ int imm = a->imm5 << a->imm2;
267
+ TCGv addr = get_address(ctx, a->rs1, preinc ? imm : 0);
268
+ TCGv data = get_gpr(ctx, a->rd, EXT_NONE);
269
+ TCGv rs1 = get_gpr(ctx, a->rs1, EXT_NONE);
270
+
271
+ tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
272
+ tcg_gen_addi_tl(rs1, rs1, imm);
273
+ gen_set_gpr(ctx, a->rs1, rs1);
274
+
275
+ tcg_temp_free(addr);
276
+ return true;
277
+}
278
+
279
+static bool trans_th_ldia(DisasContext *ctx, arg_th_meminc *a)
280
+{
281
+ REQUIRE_XTHEADMEMIDX(ctx);
282
+ REQUIRE_64BIT(ctx);
283
+ return gen_load_inc(ctx, a, MO_TESQ, false);
284
+}
285
+
286
+static bool trans_th_ldib(DisasContext *ctx, arg_th_meminc *a)
287
+{
288
+ REQUIRE_XTHEADMEMIDX(ctx);
289
+ REQUIRE_64BIT(ctx);
290
+ return gen_load_inc(ctx, a, MO_TESQ, true);
291
+}
292
+
293
+static bool trans_th_lwia(DisasContext *ctx, arg_th_meminc *a)
294
+{
295
+ REQUIRE_XTHEADMEMIDX(ctx);
296
+ return gen_load_inc(ctx, a, MO_TESL, false);
297
+}
298
+
299
+static bool trans_th_lwib(DisasContext *ctx, arg_th_meminc *a)
300
+{
301
+ REQUIRE_XTHEADMEMIDX(ctx);
302
+ return gen_load_inc(ctx, a, MO_TESL, true);
303
+}
304
+
305
+static bool trans_th_lwuia(DisasContext *ctx, arg_th_meminc *a)
306
+{
307
+ REQUIRE_XTHEADMEMIDX(ctx);
308
+ REQUIRE_64BIT(ctx);
309
+ return gen_load_inc(ctx, a, MO_TEUL, false);
310
+}
311
+
312
+static bool trans_th_lwuib(DisasContext *ctx, arg_th_meminc *a)
313
+{
314
+ REQUIRE_XTHEADMEMIDX(ctx);
315
+ REQUIRE_64BIT(ctx);
316
+ return gen_load_inc(ctx, a, MO_TEUL, true);
317
+}
318
+
319
+static bool trans_th_lhia(DisasContext *ctx, arg_th_meminc *a)
320
+{
321
+ REQUIRE_XTHEADMEMIDX(ctx);
322
+ return gen_load_inc(ctx, a, MO_TESW, false);
323
+}
324
+
325
+static bool trans_th_lhib(DisasContext *ctx, arg_th_meminc *a)
326
+{
327
+ REQUIRE_XTHEADMEMIDX(ctx);
328
+ return gen_load_inc(ctx, a, MO_TESW, true);
329
+}
330
+
331
+static bool trans_th_lhuia(DisasContext *ctx, arg_th_meminc *a)
332
+{
333
+ REQUIRE_XTHEADMEMIDX(ctx);
334
+ return gen_load_inc(ctx, a, MO_TEUW, false);
335
+}
336
+
337
+static bool trans_th_lhuib(DisasContext *ctx, arg_th_meminc *a)
338
+{
339
+ REQUIRE_XTHEADMEMIDX(ctx);
340
+ return gen_load_inc(ctx, a, MO_TEUW, true);
341
+}
342
+
343
+static bool trans_th_lbia(DisasContext *ctx, arg_th_meminc *a)
344
+{
345
+ REQUIRE_XTHEADMEMIDX(ctx);
346
+ return gen_load_inc(ctx, a, MO_SB, false);
347
+}
348
+
349
+static bool trans_th_lbib(DisasContext *ctx, arg_th_meminc *a)
350
+{
351
+ REQUIRE_XTHEADMEMIDX(ctx);
352
+ return gen_load_inc(ctx, a, MO_SB, true);
353
+}
354
+
355
+static bool trans_th_lbuia(DisasContext *ctx, arg_th_meminc *a)
356
+{
357
+ REQUIRE_XTHEADMEMIDX(ctx);
358
+ return gen_load_inc(ctx, a, MO_UB, false);
359
+}
360
+
361
+static bool trans_th_lbuib(DisasContext *ctx, arg_th_meminc *a)
362
+{
363
+ REQUIRE_XTHEADMEMIDX(ctx);
364
+ return gen_load_inc(ctx, a, MO_UB, true);
365
+}
366
+
367
+static bool trans_th_sdia(DisasContext *ctx, arg_th_meminc *a)
368
+{
369
+ REQUIRE_XTHEADMEMIDX(ctx);
370
+ REQUIRE_64BIT(ctx);
371
+ return gen_store_inc(ctx, a, MO_TESQ, false);
372
+}
373
+
374
+static bool trans_th_sdib(DisasContext *ctx, arg_th_meminc *a)
375
+{
376
+ REQUIRE_XTHEADMEMIDX(ctx);
377
+ REQUIRE_64BIT(ctx);
378
+ return gen_store_inc(ctx, a, MO_TESQ, true);
379
+}
380
+
381
+static bool trans_th_swia(DisasContext *ctx, arg_th_meminc *a)
382
+{
383
+ REQUIRE_XTHEADMEMIDX(ctx);
384
+ return gen_store_inc(ctx, a, MO_TESL, false);
385
+}
386
+
387
+static bool trans_th_swib(DisasContext *ctx, arg_th_meminc *a)
388
+{
389
+ REQUIRE_XTHEADMEMIDX(ctx);
390
+ return gen_store_inc(ctx, a, MO_TESL, true);
391
+}
392
+
393
+static bool trans_th_shia(DisasContext *ctx, arg_th_meminc *a)
394
+{
395
+ REQUIRE_XTHEADMEMIDX(ctx);
396
+ return gen_store_inc(ctx, a, MO_TESW, false);
397
+}
398
+
399
+static bool trans_th_shib(DisasContext *ctx, arg_th_meminc *a)
400
+{
401
+ REQUIRE_XTHEADMEMIDX(ctx);
402
+ return gen_store_inc(ctx, a, MO_TESW, true);
403
+}
404
+
405
+static bool trans_th_sbia(DisasContext *ctx, arg_th_meminc *a)
406
+{
407
+ REQUIRE_XTHEADMEMIDX(ctx);
408
+ return gen_store_inc(ctx, a, MO_SB, false);
409
+}
410
+
411
+static bool trans_th_sbib(DisasContext *ctx, arg_th_meminc *a)
412
+{
413
+ REQUIRE_XTHEADMEMIDX(ctx);
414
+ return gen_store_inc(ctx, a, MO_SB, true);
415
+}
416
+
417
+/*
418
+ * Load with memop from indexed address.
419
+ * If !zext_offs, then address is rs1 + (rs2 << imm2).
420
+ * If zext_offs, then address is rs1 + (zext(rs2[31:0]) << imm2).
421
+ */
422
+static bool gen_load_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop,
423
+ bool zext_offs)
424
+{
425
+ TCGv rd = dest_gpr(ctx, a->rd);
426
+ TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs);
427
+
428
+ tcg_gen_qemu_ld_tl(rd, addr, ctx->mem_idx, memop);
429
+ gen_set_gpr(ctx, a->rd, rd);
430
+
431
+ return true;
432
+}
433
+
434
+/*
435
+ * Store with memop to indexed address.
436
+ * If !zext_offs, then address is rs1 + (rs2 << imm2).
437
+ * If zext_offs, then address is rs1 + (zext(rs2[31:0]) << imm2).
438
+ */
439
+static bool gen_store_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop,
440
+ bool zext_offs)
441
+{
442
+ TCGv data = get_gpr(ctx, a->rd, EXT_NONE);
443
+ TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs);
444
+
445
+ tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
446
+
447
+ return true;
448
+}
449
+
450
+static bool trans_th_lrd(DisasContext *ctx, arg_th_memidx *a)
451
+{
452
+ REQUIRE_XTHEADMEMIDX(ctx);
453
+ REQUIRE_64BIT(ctx);
454
+ return gen_load_idx(ctx, a, MO_TESQ, false);
455
+}
456
+
457
+static bool trans_th_lrw(DisasContext *ctx, arg_th_memidx *a)
458
+{
459
+ REQUIRE_XTHEADMEMIDX(ctx);
460
+ return gen_load_idx(ctx, a, MO_TESL, false);
461
+}
462
+
463
+static bool trans_th_lrwu(DisasContext *ctx, arg_th_memidx *a)
464
+{
465
+ REQUIRE_XTHEADMEMIDX(ctx);
466
+ REQUIRE_64BIT(ctx);
467
+ return gen_load_idx(ctx, a, MO_TEUL, false);
468
+}
469
+
470
+static bool trans_th_lrh(DisasContext *ctx, arg_th_memidx *a)
471
+{
472
+ REQUIRE_XTHEADMEMIDX(ctx);
473
+ return gen_load_idx(ctx, a, MO_TESW, false);
474
+}
475
+
476
+static bool trans_th_lrhu(DisasContext *ctx, arg_th_memidx *a)
477
+{
478
+ REQUIRE_XTHEADMEMIDX(ctx);
479
+ return gen_load_idx(ctx, a, MO_TEUW, false);
480
+}
481
+
482
+static bool trans_th_lrb(DisasContext *ctx, arg_th_memidx *a)
483
+{
484
+ REQUIRE_XTHEADMEMIDX(ctx);
485
+ return gen_load_idx(ctx, a, MO_SB, false);
486
+}
487
+
488
+static bool trans_th_lrbu(DisasContext *ctx, arg_th_memidx *a)
489
+{
490
+ REQUIRE_XTHEADMEMIDX(ctx);
491
+ return gen_load_idx(ctx, a, MO_UB, false);
492
+}
493
+
494
+static bool trans_th_srd(DisasContext *ctx, arg_th_memidx *a)
495
+{
496
+ REQUIRE_XTHEADMEMIDX(ctx);
497
+ REQUIRE_64BIT(ctx);
498
+ return gen_store_idx(ctx, a, MO_TESQ, false);
499
+}
500
+
501
+static bool trans_th_srw(DisasContext *ctx, arg_th_memidx *a)
502
+{
503
+ REQUIRE_XTHEADMEMIDX(ctx);
504
+ return gen_store_idx(ctx, a, MO_TESL, false);
505
+}
506
+
507
+static bool trans_th_srh(DisasContext *ctx, arg_th_memidx *a)
508
+{
509
+ REQUIRE_XTHEADMEMIDX(ctx);
510
+ return gen_store_idx(ctx, a, MO_TESW, false);
511
+}
512
+
513
+static bool trans_th_srb(DisasContext *ctx, arg_th_memidx *a)
514
+{
515
+ REQUIRE_XTHEADMEMIDX(ctx);
516
+ return gen_store_idx(ctx, a, MO_SB, false);
517
+}
518
+static bool trans_th_lurd(DisasContext *ctx, arg_th_memidx *a)
519
+{
520
+ REQUIRE_XTHEADMEMIDX(ctx);
521
+ REQUIRE_64BIT(ctx);
522
+ return gen_load_idx(ctx, a, MO_TESQ, true);
523
+}
524
+
525
+static bool trans_th_lurw(DisasContext *ctx, arg_th_memidx *a)
526
+{
527
+ REQUIRE_XTHEADMEMIDX(ctx);
528
+ return gen_load_idx(ctx, a, MO_TESL, true);
529
+}
530
+
531
+static bool trans_th_lurwu(DisasContext *ctx, arg_th_memidx *a)
532
+{
533
+ REQUIRE_XTHEADMEMIDX(ctx);
534
+ REQUIRE_64BIT(ctx);
535
+ return gen_load_idx(ctx, a, MO_TEUL, true);
536
+}
537
+
538
+static bool trans_th_lurh(DisasContext *ctx, arg_th_memidx *a)
539
+{
540
+ REQUIRE_XTHEADMEMIDX(ctx);
541
+ return gen_load_idx(ctx, a, MO_TESW, true);
542
+}
543
+
544
+static bool trans_th_lurhu(DisasContext *ctx, arg_th_memidx *a)
545
+{
546
+ REQUIRE_XTHEADMEMIDX(ctx);
547
+ return gen_load_idx(ctx, a, MO_TEUW, true);
548
+}
549
+
550
+static bool trans_th_lurb(DisasContext *ctx, arg_th_memidx *a)
551
+{
552
+ REQUIRE_XTHEADMEMIDX(ctx);
553
+ return gen_load_idx(ctx, a, MO_SB, true);
554
+}
555
+
556
+static bool trans_th_lurbu(DisasContext *ctx, arg_th_memidx *a)
557
+{
558
+ REQUIRE_XTHEADMEMIDX(ctx);
559
+ return gen_load_idx(ctx, a, MO_UB, true);
560
+}
561
+
562
+static bool trans_th_surd(DisasContext *ctx, arg_th_memidx *a)
563
+{
564
+ REQUIRE_XTHEADMEMIDX(ctx);
565
+ REQUIRE_64BIT(ctx);
566
+ return gen_store_idx(ctx, a, MO_TESQ, true);
567
+}
568
+
569
+static bool trans_th_surw(DisasContext *ctx, arg_th_memidx *a)
570
+{
571
+ REQUIRE_XTHEADMEMIDX(ctx);
572
+ return gen_store_idx(ctx, a, MO_TESL, true);
573
+}
574
+
575
+static bool trans_th_surh(DisasContext *ctx, arg_th_memidx *a)
576
+{
577
+ REQUIRE_XTHEADMEMIDX(ctx);
578
+ return gen_store_idx(ctx, a, MO_TESW, true);
579
+}
580
+
581
+static bool trans_th_surb(DisasContext *ctx, arg_th_memidx *a)
582
+{
583
+ REQUIRE_XTHEADMEMIDX(ctx);
584
+ return gen_store_idx(ctx, a, MO_SB, true);
585
+}
586
+
587
/* XTheadMemPair */
588
589
static bool gen_loadpair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop,
590
--
117
--
591
2.39.1
118
2.45.1
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Andrew Jones <ajones@ventanamicro.com>
2
2
3
This patch adds support for the XTheadSync ISA extension.
3
Implementing wrs.nto to always just return is consistent with the
4
The patch uses the T-Head specific decoder and translation.
4
specification, as the instruction is permitted to terminate the
5
stall for any reason, but it's not useful for virtualization, where
6
we'd like the guest to trap to the hypervisor in order to allow
7
scheduling of the lock holding VCPU. Change to always immediately
8
raise exceptions when the appropriate conditions are present,
9
otherwise continue to just return. Note, immediately raising
10
exceptions is also consistent with the specification since the
11
time limit that should expire prior to the exception is
12
implementation-specific.
5
13
6
The implementation introduces a helper to execute synchronization tasks:
14
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
7
helper_tlb_flush_all() performs a synchronized TLB flush on all CPUs.
15
Reviewed-by: Christoph Müllner <christoph.muellner@vrull.eu>
8
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
18
Message-ID: <20240424142808.62936-2-ajones@ventanamicro.com>
12
Message-Id: <20230131202013.2541053-3-christoph.muellner@vrull.eu>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
20
---
15
target/riscv/cpu.h | 1 +
21
target/riscv/helper.h | 1 +
16
target/riscv/helper.h | 1 +
22
target/riscv/op_helper.c | 11 ++++++++
17
target/riscv/xthead.decode | 9 +++
23
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 ++++++++++++++-------
18
target/riscv/cpu.c | 2 +
24
3 files changed, 32 insertions(+), 9 deletions(-)
19
target/riscv/op_helper.c | 6 ++
20
target/riscv/translate.c | 2 +-
21
target/riscv/insn_trans/trans_xthead.c.inc | 85 ++++++++++++++++++++++
22
7 files changed, 105 insertions(+), 1 deletion(-)
23
25
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
29
30
/* Vendor-specific custom extensions */
31
bool ext_xtheadcmo;
32
+ bool ext_xtheadsync;
33
bool ext_XVentanaCondOps;
34
35
uint8_t pmu_num;
36
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
26
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
37
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/helper.h
28
--- a/target/riscv/helper.h
39
+++ b/target/riscv/helper.h
29
+++ b/target/riscv/helper.h
40
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(sret, tl, env)
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
31
DEF_HELPER_1(sret, tl, env)
41
DEF_HELPER_1(mret, tl, env)
32
DEF_HELPER_1(mret, tl, env)
42
DEF_HELPER_1(wfi, void, env)
33
DEF_HELPER_1(wfi, void, env)
34
+DEF_HELPER_1(wrs_nto, void, env)
43
DEF_HELPER_1(tlb_flush, void, env)
35
DEF_HELPER_1(tlb_flush, void, env)
44
+DEF_HELPER_1(tlb_flush_all, void, env)
36
DEF_HELPER_1(tlb_flush_all, void, env)
45
/* Native Debug */
37
/* Native Debug */
46
DEF_HELPER_1(itrigger_match, void, env)
47
#endif
48
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/xthead.decode
51
+++ b/target/riscv/xthead.decode
52
@@ -XXX,XX +XXX,XX @@
53
54
# Fields:
55
%rs1 15:5
56
+%rs2 20:5
57
58
# Formats
59
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
60
+@rs2_s ....... ..... ..... ... ..... ....... %rs2 %rs1
61
62
# XTheadCmo
63
th_dcache_call 0000000 00001 00000 000 00000 0001011
64
@@ -XXX,XX +XXX,XX @@ th_icache_iva 0000001 10000 ..... 000 00000 0001011 @sfence_vm
65
th_l2cache_call 0000000 10101 00000 000 00000 0001011
66
th_l2cache_ciall 0000000 10111 00000 000 00000 0001011
67
th_l2cache_iall 0000000 10110 00000 000 00000 0001011
68
+
69
+# XTheadSync
70
+th_sfence_vmas 0000010 ..... ..... 000 00000 0001011 @rs2_s
71
+th_sync 0000000 11000 00000 000 00000 0001011
72
+th_sync_i 0000000 11010 00000 000 00000 0001011
73
+th_sync_is 0000000 11011 00000 000 00000 0001011
74
+th_sync_s 0000000 11001 00000 000 00000 0001011
75
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/riscv/cpu.c
78
+++ b/target/riscv/cpu.c
79
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
80
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
81
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
82
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
83
+ ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
84
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
85
};
86
87
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
88
89
/* Vendor-specific custom extensions */
90
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
91
+ DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
92
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
93
94
/* These are experimental so mark with 'x-' */
95
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
38
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
96
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
97
--- a/target/riscv/op_helper.c
40
--- a/target/riscv/op_helper.c
98
+++ b/target/riscv/op_helper.c
41
+++ b/target/riscv/op_helper.c
99
@@ -XXX,XX +XXX,XX @@ void helper_tlb_flush(CPURISCVState *env)
42
@@ -XXX,XX +XXX,XX @@ void helper_wfi(CPURISCVState *env)
100
}
43
}
101
}
44
}
102
45
103
+void helper_tlb_flush_all(CPURISCVState *env)
46
+void helper_wrs_nto(CPURISCVState *env)
104
+{
47
+{
105
+ CPUState *cs = env_cpu(env);
48
+ if (env->virt_enabled && (env->priv == PRV_S || env->priv == PRV_U) &&
106
+ tlb_flush_all_cpus_synced(cs);
49
+ get_field(env->hstatus, HSTATUS_VTW) &&
50
+ !get_field(env->mstatus, MSTATUS_TW)) {
51
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
52
+ } else if (env->priv != PRV_M && get_field(env->mstatus, MSTATUS_TW)) {
53
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
54
+ }
107
+}
55
+}
108
+
56
+
109
void helper_hyp_tlb_flush(CPURISCVState *env)
57
void helper_tlb_flush(CPURISCVState *env)
110
{
58
{
111
CPUState *cs = env_cpu(env);
59
CPUState *cs = env_cpu(env);
112
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
60
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc
113
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
114
--- a/target/riscv/translate.c
62
--- a/target/riscv/insn_trans/trans_rvzawrs.c.inc
115
+++ b/target/riscv/translate.c
63
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
116
@@ -XXX,XX +XXX,XX @@ static bool always_true_p(DisasContext *ctx __attribute__((__unused__)))
64
@@ -XXX,XX +XXX,XX @@
117
65
* this program. If not, see <http://www.gnu.org/licenses/>.
118
static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
66
*/
67
68
-static bool trans_wrs(DisasContext *ctx)
69
+static bool trans_wrs_sto(DisasContext *ctx, arg_wrs_sto *a)
119
{
70
{
120
- return ctx->cfg_ptr->ext_xtheadcmo;
71
if (!ctx->cfg_ptr->ext_zawrs) {
121
+ return ctx->cfg_ptr->ext_xtheadcmo || ctx->cfg_ptr->ext_xtheadsync;
72
return false;
73
@@ -XXX,XX +XXX,XX @@ static bool trans_wrs(DisasContext *ctx)
74
return true;
122
}
75
}
123
76
124
#define MATERIALISE_EXT_PREDICATE(ext) \
77
-#define GEN_TRANS_WRS(insn) \
125
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
78
-static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn *a) \
126
index XXXXXXX..XXXXXXX 100644
79
-{ \
127
--- a/target/riscv/insn_trans/trans_xthead.c.inc
80
- (void)a; \
128
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
81
- return trans_wrs(ctx); \
129
@@ -XXX,XX +XXX,XX @@
82
-}
130
} \
83
+static bool trans_wrs_nto(DisasContext *ctx, arg_wrs_nto *a)
131
} while (0)
132
133
+#define REQUIRE_XTHEADSYNC(ctx) do { \
134
+ if (!ctx->cfg_ptr->ext_xtheadsync) { \
135
+ return false; \
136
+ } \
137
+} while (0)
138
+
139
/* XTheadCmo */
140
141
static inline int priv_level(DisasContext *ctx)
142
@@ -XXX,XX +XXX,XX @@ NOP_PRIVCHECK(th_icache_iva, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
143
NOP_PRIVCHECK(th_l2cache_call, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
144
NOP_PRIVCHECK(th_l2cache_ciall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
145
NOP_PRIVCHECK(th_l2cache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
146
+
147
+/* XTheadSync */
148
+
149
+static bool trans_th_sfence_vmas(DisasContext *ctx, arg_th_sfence_vmas *a)
150
+{
84
+{
151
+ (void) a;
85
+ if (!ctx->cfg_ptr->ext_zawrs) {
152
+ REQUIRE_XTHEADSYNC(ctx);
86
+ return false;
153
+
87
+ }
88
89
-GEN_TRANS_WRS(wrs_nto)
90
-GEN_TRANS_WRS(wrs_sto)
91
+ /*
92
+ * Depending on the mode of execution, mstatus.TW and hstatus.VTW, wrs.nto
93
+ * should raise an exception when the implementation-specific bounded time
94
+ * limit has expired. Our time limit is zero, so we either return
95
+ * immediately, as does our implementation of wrs.sto, or raise an
96
+ * exception, as handled by the wrs.nto helper.
97
+ */
154
+#ifndef CONFIG_USER_ONLY
98
+#ifndef CONFIG_USER_ONLY
155
+ REQUIRE_PRIV_MS(ctx);
99
+ gen_helper_wrs_nto(tcg_env);
156
+ gen_helper_tlb_flush_all(cpu_env);
157
+ return true;
158
+#else
159
+ return false;
160
+#endif
161
+}
162
+
163
+#ifndef CONFIG_USER_ONLY
164
+static void gen_th_sync_local(DisasContext *ctx)
165
+{
166
+ /*
167
+ * Emulate out-of-order barriers with pipeline flush
168
+ * by exiting the translation block.
169
+ */
170
+ gen_set_pc_imm(ctx, ctx->pc_succ_insn);
171
+ tcg_gen_exit_tb(NULL, 0);
172
+ ctx->base.is_jmp = DISAS_NORETURN;
173
+}
174
+#endif
100
+#endif
175
+
101
+
176
+static bool trans_th_sync(DisasContext *ctx, arg_th_sync *a)
102
+ /* We only get here when helper_wrs_nto() doesn't raise an exception. */
177
+{
103
+ return trans_wrs_sto(ctx, NULL);
178
+ (void) a;
179
+ REQUIRE_XTHEADSYNC(ctx);
180
+
181
+#ifndef CONFIG_USER_ONLY
182
+ REQUIRE_PRIV_MSU(ctx);
183
+
184
+ /*
185
+ * th.sync is an out-of-order barrier.
186
+ */
187
+ gen_th_sync_local(ctx);
188
+
189
+ return true;
190
+#else
191
+ return false;
192
+#endif
193
+}
194
+
195
+static bool trans_th_sync_i(DisasContext *ctx, arg_th_sync_i *a)
196
+{
197
+ (void) a;
198
+ REQUIRE_XTHEADSYNC(ctx);
199
+
200
+#ifndef CONFIG_USER_ONLY
201
+ REQUIRE_PRIV_MSU(ctx);
202
+
203
+ /*
204
+ * th.sync.i is th.sync plus pipeline flush.
205
+ */
206
+ gen_th_sync_local(ctx);
207
+
208
+ return true;
209
+#else
210
+ return false;
211
+#endif
212
+}
213
+
214
+static bool trans_th_sync_is(DisasContext *ctx, arg_th_sync_is *a)
215
+{
216
+ /* This instruction has the same behaviour like th.sync.i. */
217
+ return trans_th_sync_i(ctx, a);
218
+}
219
+
220
+static bool trans_th_sync_s(DisasContext *ctx, arg_th_sync_s *a)
221
+{
222
+ /* This instruction has the same behaviour like th.sync. */
223
+ return trans_th_sync(ctx, a);
224
+}
104
+}
225
--
105
--
226
2.39.1
106
2.45.1
107
108
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
This patch adds support for the XTheadCondMov ISA extension.
3
SBI defines a Debug Console extension "DBCN" that will, in time, replace
4
The patch uses the T-Head specific decoder and translation.
4
the legacy console putchar and getchar SBI extensions.
5
5
6
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
The appeal of the DBCN extension is that it allows multiple bytes to be
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
read/written in the SBI console in a single SBI call.
8
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
8
9
Message-Id: <20230131202013.2541053-7-christoph.muellner@vrull.eu>
9
As far as KVM goes, the DBCN calls are forwarded by an in-kernel KVM
10
module to userspace. But this will only happens if the KVM module
11
actually supports this SBI extension and we activate it.
12
13
We'll check for DBCN support during init time, checking if get-reg-list
14
is advertising KVM_RISCV_SBI_EXT_DBCN. In that case, we'll enable it via
15
kvm_set_one_reg() during kvm_arch_init_vcpu().
16
17
Finally, change kvm_riscv_handle_sbi() to handle the incoming calls for
18
SBI_EXT_DBCN, reading and writing as required.
19
20
A simple KVM guest with 'earlycon=sbi', running in an emulated RISC-V
21
host, takes around 20 seconds to boot without using DBCN. With this
22
patch we're taking around 14 seconds to boot due to the speed-up in the
23
terminal output. There's no change in boot time if the guest isn't
24
using earlycon.
25
26
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
27
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
28
Message-ID: <20240425155012.581366-1-dbarboza@ventanamicro.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
30
---
12
target/riscv/cpu.h | 1 +
31
target/riscv/sbi_ecall_interface.h | 17 +++++
13
target/riscv/xthead.decode | 4 +++
32
target/riscv/kvm/kvm-cpu.c | 111 +++++++++++++++++++++++++++++
14
target/riscv/cpu.c | 2 ++
33
2 files changed, 128 insertions(+)
15
target/riscv/translate.c | 2 +-
34
16
target/riscv/insn_trans/trans_xthead.c.inc | 35 ++++++++++++++++++++++
35
diff --git a/target/riscv/sbi_ecall_interface.h b/target/riscv/sbi_ecall_interface.h
17
5 files changed, 43 insertions(+), 1 deletion(-)
18
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
20
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.h
37
--- a/target/riscv/sbi_ecall_interface.h
22
+++ b/target/riscv/cpu.h
38
+++ b/target/riscv/sbi_ecall_interface.h
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
39
@@ -XXX,XX +XXX,XX @@
24
bool ext_xtheadbb;
40
25
bool ext_xtheadbs;
41
/* clang-format off */
26
bool ext_xtheadcmo;
42
27
+ bool ext_xtheadcondmov;
43
+#define SBI_SUCCESS 0
28
bool ext_xtheadsync;
44
+#define SBI_ERR_FAILED -1
29
bool ext_XVentanaCondOps;
45
+#define SBI_ERR_NOT_SUPPORTED -2
30
46
+#define SBI_ERR_INVALID_PARAM -3
31
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
47
+#define SBI_ERR_DENIED -4
48
+#define SBI_ERR_INVALID_ADDRESS -5
49
+#define SBI_ERR_ALREADY_AVAILABLE -6
50
+#define SBI_ERR_ALREADY_STARTED -7
51
+#define SBI_ERR_ALREADY_STOPPED -8
52
+#define SBI_ERR_NO_SHMEM -9
53
+
54
/* SBI Extension IDs */
55
#define SBI_EXT_0_1_SET_TIMER 0x0
56
#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
57
@@ -XXX,XX +XXX,XX @@
58
#define SBI_EXT_IPI 0x735049
59
#define SBI_EXT_RFENCE 0x52464E43
60
#define SBI_EXT_HSM 0x48534D
61
+#define SBI_EXT_DBCN 0x4442434E
62
63
/* SBI function IDs for BASE extension */
64
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
65
@@ -XXX,XX +XXX,XX @@
66
#define SBI_EXT_HSM_HART_STOP 0x1
67
#define SBI_EXT_HSM_HART_GET_STATUS 0x2
68
69
+/* SBI function IDs for DBCN extension */
70
+#define SBI_EXT_DBCN_CONSOLE_WRITE 0x0
71
+#define SBI_EXT_DBCN_CONSOLE_READ 0x1
72
+#define SBI_EXT_DBCN_CONSOLE_WRITE_BYTE 0x2
73
+
74
#define SBI_HSM_HART_STATUS_STARTED 0x0
75
#define SBI_HSM_HART_STATUS_STOPPED 0x1
76
#define SBI_HSM_HART_STATUS_START_PENDING 0x2
77
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
32
index XXXXXXX..XXXXXXX 100644
78
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/xthead.decode
79
--- a/target/riscv/kvm/kvm-cpu.c
34
+++ b/target/riscv/xthead.decode
80
+++ b/target/riscv/kvm/kvm-cpu.c
35
@@ -XXX,XX +XXX,XX @@ th_l2cache_call 0000000 10101 00000 000 00000 0001011
81
@@ -XXX,XX +XXX,XX @@ static KVMCPUConfig kvm_v_vlenb = {
36
th_l2cache_ciall 0000000 10111 00000 000 00000 0001011
82
KVM_REG_RISCV_VECTOR_CSR_REG(vlenb)
37
th_l2cache_iall 0000000 10110 00000 000 00000 0001011
38
39
+# XTheadCondMov
40
+th_mveqz 0100000 ..... ..... 001 ..... 0001011 @r
41
+th_mvnez 0100001 ..... ..... 001 ..... 0001011 @r
42
+
43
# XTheadSync
44
th_sfence_vmas 0000010 ..... ..... 000 00000 0001011 @rs2_s
45
th_sync 0000000 11000 00000 000 00000 0001011
46
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/cpu.c
49
+++ b/target/riscv/cpu.c
50
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
51
ISA_EXT_DATA_ENTRY(xtheadbb, true, PRIV_VERSION_1_11_0, ext_xtheadbb),
52
ISA_EXT_DATA_ENTRY(xtheadbs, true, PRIV_VERSION_1_11_0, ext_xtheadbs),
53
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
54
+ ISA_EXT_DATA_ENTRY(xtheadcondmov, true, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
55
ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
56
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
57
};
83
};
58
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
84
59
DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false),
85
+static KVMCPUConfig kvm_sbi_dbcn = {
60
DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
86
+ .name = "sbi_dbcn",
61
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
87
+ .kvm_reg_id = KVM_REG_RISCV | KVM_REG_SIZE_U64 |
62
+ DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
88
+ KVM_REG_RISCV_SBI_EXT | KVM_RISCV_SBI_EXT_DBCN
63
DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
89
+};
64
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
90
+
65
91
static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
66
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
92
{
67
index XXXXXXX..XXXXXXX 100644
93
CPURISCVState *env = &cpu->env;
68
--- a/target/riscv/translate.c
94
@@ -XXX,XX +XXX,XX @@ static int uint64_cmp(const void *a, const void *b)
69
+++ b/target/riscv/translate.c
95
return 0;
70
@@ -XXX,XX +XXX,XX @@ static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
96
}
71
{
97
72
return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
98
+static void kvm_riscv_check_sbi_dbcn_support(RISCVCPU *cpu,
73
ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
99
+ KVMScratchCPU *kvmcpu,
74
- ctx->cfg_ptr->ext_xtheadsync;
100
+ struct kvm_reg_list *reglist)
75
+ ctx->cfg_ptr->ext_xtheadcondmov || ctx->cfg_ptr->ext_xtheadsync;
76
}
77
78
#define MATERIALISE_EXT_PREDICATE(ext) \
79
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/riscv/insn_trans/trans_xthead.c.inc
82
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
83
@@ -XXX,XX +XXX,XX @@
84
} \
85
} while (0)
86
87
+#define REQUIRE_XTHEADCONDMOV(ctx) do { \
88
+ if (!ctx->cfg_ptr->ext_xtheadcondmov) { \
89
+ return false; \
90
+ } \
91
+} while (0)
92
+
93
#define REQUIRE_XTHEADSYNC(ctx) do { \
94
if (!ctx->cfg_ptr->ext_xtheadsync) { \
95
return false; \
96
@@ -XXX,XX +XXX,XX @@ NOP_PRIVCHECK(th_l2cache_call, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
97
NOP_PRIVCHECK(th_l2cache_ciall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
98
NOP_PRIVCHECK(th_l2cache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
99
100
+/* XTheadCondMov */
101
+
102
+static bool gen_th_condmove(DisasContext *ctx, arg_r *a, TCGCond cond)
103
+{
101
+{
104
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
102
+ struct kvm_reg_list *reg_search;
105
+ TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
103
+
106
+ TCGv old = get_gpr(ctx, a->rd, EXT_NONE);
104
+ reg_search = bsearch(&kvm_sbi_dbcn.kvm_reg_id, reglist->reg, reglist->n,
107
+ TCGv dest = dest_gpr(ctx, a->rd);
105
+ sizeof(uint64_t), uint64_cmp);
108
+
106
+
109
+ tcg_gen_movcond_tl(cond, dest, src2, ctx->zero, src1, old);
107
+ if (reg_search) {
110
+
108
+ kvm_sbi_dbcn.supported = true;
111
+ gen_set_gpr(ctx, a->rd, dest);
109
+ }
112
+ return true;
113
+}
110
+}
114
+
111
+
115
+/* th.mveqz: "if (rs2 == 0) rd = rs1;" */
112
static void kvm_riscv_read_vlenb(RISCVCPU *cpu, KVMScratchCPU *kvmcpu,
116
+static bool trans_th_mveqz(DisasContext *ctx, arg_th_mveqz *a)
113
struct kvm_reg_list *reglist)
114
{
115
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
116
if (riscv_has_ext(&cpu->env, RVV)) {
117
kvm_riscv_read_vlenb(cpu, kvmcpu, reglist);
118
}
119
+
120
+ kvm_riscv_check_sbi_dbcn_support(cpu, kvmcpu, reglist);
121
}
122
123
static void riscv_init_kvm_registers(Object *cpu_obj)
124
@@ -XXX,XX +XXX,XX @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs)
125
return ret;
126
}
127
128
+static int kvm_vcpu_enable_sbi_dbcn(RISCVCPU *cpu, CPUState *cs)
117
+{
129
+{
118
+ REQUIRE_XTHEADCONDMOV(ctx);
130
+ target_ulong reg = 1;
119
+ return gen_th_condmove(ctx, a, TCG_COND_EQ);
131
+
132
+ if (!kvm_sbi_dbcn.supported) {
133
+ return 0;
134
+ }
135
+
136
+ return kvm_set_one_reg(cs, kvm_sbi_dbcn.kvm_reg_id, &reg);
120
+}
137
+}
121
+
138
+
122
+/* th.mvnez: "if (rs2 != 0) rd = rs1;" */
139
int kvm_arch_init_vcpu(CPUState *cs)
123
+static bool trans_th_mvnez(DisasContext *ctx, arg_th_mveqz *a)
140
{
141
int ret = 0;
142
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
143
kvm_riscv_update_cpu_misa_ext(cpu, cs);
144
kvm_riscv_update_cpu_cfg_isa_ext(cpu, cs);
145
146
+ ret = kvm_vcpu_enable_sbi_dbcn(cpu, cs);
147
+
148
return ret;
149
}
150
151
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
152
return true;
153
}
154
155
+static void kvm_riscv_handle_sbi_dbcn(CPUState *cs, struct kvm_run *run)
124
+{
156
+{
125
+ REQUIRE_XTHEADCONDMOV(ctx);
157
+ g_autofree uint8_t *buf = NULL;
126
+ return gen_th_condmove(ctx, a, TCG_COND_NE);
158
+ RISCVCPU *cpu = RISCV_CPU(cs);
159
+ target_ulong num_bytes;
160
+ uint64_t addr;
161
+ unsigned char ch;
162
+ int ret;
163
+
164
+ switch (run->riscv_sbi.function_id) {
165
+ case SBI_EXT_DBCN_CONSOLE_READ:
166
+ case SBI_EXT_DBCN_CONSOLE_WRITE:
167
+ num_bytes = run->riscv_sbi.args[0];
168
+
169
+ if (num_bytes == 0) {
170
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
171
+ run->riscv_sbi.ret[1] = 0;
172
+ break;
173
+ }
174
+
175
+ addr = run->riscv_sbi.args[1];
176
+
177
+ /*
178
+ * Handle the case where a 32 bit CPU is running in a
179
+ * 64 bit addressing env.
180
+ */
181
+ if (riscv_cpu_mxl(&cpu->env) == MXL_RV32) {
182
+ addr |= (uint64_t)run->riscv_sbi.args[2] << 32;
183
+ }
184
+
185
+ buf = g_malloc0(num_bytes);
186
+
187
+ if (run->riscv_sbi.function_id == SBI_EXT_DBCN_CONSOLE_READ) {
188
+ ret = qemu_chr_fe_read_all(serial_hd(0)->be, buf, num_bytes);
189
+ if (ret < 0) {
190
+ error_report("SBI_EXT_DBCN_CONSOLE_READ: error when "
191
+ "reading chardev");
192
+ exit(1);
193
+ }
194
+
195
+ cpu_physical_memory_write(addr, buf, ret);
196
+ } else {
197
+ cpu_physical_memory_read(addr, buf, num_bytes);
198
+
199
+ ret = qemu_chr_fe_write_all(serial_hd(0)->be, buf, num_bytes);
200
+ if (ret < 0) {
201
+ error_report("SBI_EXT_DBCN_CONSOLE_WRITE: error when "
202
+ "writing chardev");
203
+ exit(1);
204
+ }
205
+ }
206
+
207
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
208
+ run->riscv_sbi.ret[1] = ret;
209
+ break;
210
+ case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE:
211
+ ch = run->riscv_sbi.args[0];
212
+ ret = qemu_chr_fe_write(serial_hd(0)->be, &ch, sizeof(ch));
213
+
214
+ if (ret < 0) {
215
+ error_report("SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: error when "
216
+ "writing chardev");
217
+ exit(1);
218
+ }
219
+
220
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
221
+ run->riscv_sbi.ret[1] = 0;
222
+ break;
223
+ default:
224
+ run->riscv_sbi.ret[0] = SBI_ERR_NOT_SUPPORTED;
225
+ }
127
+}
226
+}
128
+
227
+
129
/* XTheadSync */
228
static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
130
229
{
131
static bool trans_th_sfence_vmas(DisasContext *ctx, arg_th_sfence_vmas *a)
230
int ret = 0;
231
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
232
}
233
ret = 0;
234
break;
235
+ case SBI_EXT_DBCN:
236
+ kvm_riscv_handle_sbi_dbcn(cs, run);
237
+ break;
238
default:
239
qemu_log_mask(LOG_UNIMP,
240
"%s: un-handled SBI EXIT, specific reasons is %lu\n",
132
--
241
--
133
2.39.1
242
2.45.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Cheng Yang <yangcheng.work@foxmail.com>
2
2
3
fdt_pack() can change the fdt size, meaning that fdt_totalsize() can
3
Use qemu_fdt_setprop_u64() instead of qemu_fdt_setprop_cell()
4
contain a now deprecated (bigger) value.
4
to set the address of initrd in FDT to support 64-bit address.
5
5
6
Signed-off-by: Cheng Yang <yangcheng.work@foxmail.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Message-ID: <tencent_A4482251DD0890F312758FA6B33F60815609@qq.com>
8
Message-Id: <20230201171212.1219375-2-dbarboza@ventanamicro.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
10
---
11
hw/riscv/boot.c | 10 ++++++----
11
hw/riscv/boot.c | 4 ++--
12
1 file changed, 6 insertions(+), 4 deletions(-)
12
1 file changed, 2 insertions(+), 2 deletions(-)
13
13
14
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
14
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/boot.c
16
--- a/hw/riscv/boot.c
17
+++ b/hw/riscv/boot.c
17
+++ b/hw/riscv/boot.c
18
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
18
@@ -XXX,XX +XXX,XX @@ static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
19
{
19
/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
20
uint64_t temp, fdt_addr;
20
if (fdt) {
21
hwaddr dram_end = dram_base + mem_size;
21
end = start + size;
22
- int ret, fdtsize = fdt_totalsize(fdt);
22
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
23
+ int ret = fdt_pack(fdt);
23
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
24
+ int fdtsize;
24
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-start", start);
25
25
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-end", end);
26
+ /* Should only fail if we've built a corrupted tree */
26
}
27
+ g_assert(ret == 0);
27
}
28
+
29
+ fdtsize = fdt_totalsize(fdt);
30
if (fdtsize <= 0) {
31
error_report("invalid device-tree");
32
exit(1);
33
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
34
temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end;
35
fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB);
36
37
- ret = fdt_pack(fdt);
38
- /* Should only fail if we've built a corrupted tree */
39
- g_assert(ret == 0);
40
/* copy in the device tree */
41
qemu_fdt_dumpdtb(fdt, fdtsize);
42
28
43
--
29
--
44
2.39.1
30
2.45.1
diff view generated by jsdifflib
1
From: Vladimir Isaev <vladimir.isaev@syntacore.com>
1
From: Clément Léger <cleger@rivosinc.com>
2
2
3
Character must be returned via ret[0] field (copied to a0 by KVM).
3
The current semihost exception number (16) is a reserved number (range
4
[16-17]). The upcoming double trap specification uses that number for
5
the double trap exception. Since the privileged spec (Table 22) defines
6
ranges for custom uses change the semihosting exception number to 63
7
which belongs to the range [48-63] in order to avoid any future
8
collisions with reserved exception.
4
9
5
Return value should be set to 0 to indicate successful processing.
10
Signed-off-by: Clément Léger <cleger@rivosinc.com>
6
11
7
Signed-off-by: Vladimir Isaev <vladimir.isaev@syntacore.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20230203135155.12449-1-vladimir.isaev@syntacore.com>
13
Message-ID: <20240422135840.1959967-1-cleger@rivosinc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
15
---
12
target/riscv/kvm.c | 5 +++--
16
target/riscv/cpu_bits.h | 2 +-
13
1 file changed, 3 insertions(+), 2 deletions(-)
17
1 file changed, 1 insertion(+), 1 deletion(-)
14
18
15
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
19
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/kvm.c
21
--- a/target/riscv/cpu_bits.h
18
+++ b/target/riscv/kvm.c
22
+++ b/target/riscv/cpu_bits.h
19
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
23
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
20
case SBI_EXT_0_1_CONSOLE_GETCHAR:
24
RISCV_EXCP_INST_PAGE_FAULT = 0xc, /* since: priv-1.10.0 */
21
ret = qemu_chr_fe_read_all(serial_hd(0)->be, &ch, sizeof(ch));
25
RISCV_EXCP_LOAD_PAGE_FAULT = 0xd, /* since: priv-1.10.0 */
22
if (ret == sizeof(ch)) {
26
RISCV_EXCP_STORE_PAGE_FAULT = 0xf, /* since: priv-1.10.0 */
23
- run->riscv_sbi.args[0] = ch;
27
- RISCV_EXCP_SEMIHOST = 0x10,
24
+ run->riscv_sbi.ret[0] = ch;
28
RISCV_EXCP_INST_GUEST_PAGE_FAULT = 0x14,
25
} else {
29
RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT = 0x15,
26
- run->riscv_sbi.args[0] = -1;
30
RISCV_EXCP_VIRT_INSTRUCTION_FAULT = 0x16,
27
+ run->riscv_sbi.ret[0] = -1;
31
RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT = 0x17,
28
}
32
+ RISCV_EXCP_SEMIHOST = 0x3f,
29
+ ret = 0;
33
} RISCVException;
30
break;
34
31
default:
35
#define RISCV_EXCP_INT_FLAG 0x80000000
32
qemu_log_mask(LOG_UNIMP,
33
--
36
--
34
2.39.1
37
2.45.1
38
39
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
We have a convention in other QEMU boards/archs to name MachineState
3
Running a KVM guest using a 6.9-rc3 kernel, in a 6.8 host that has zkr
4
pointers as either 'machine' or 'ms'. MachineClass pointers are usually
4
enabled, will fail with a kernel oops SIGILL right at the start. The
5
called 'mc'.
5
reason is that we can't expose zkr without implementing the SEED CSR.
6
Disabling zkr in the guest would be a workaround, but if the KVM doesn't
7
allow it we'll error out and never boot.
6
8
7
The 'virt' RISC-V machine has a lot of instances where MachineState
9
In hindsight this is too strict. If we keep proceeding, despite not
8
pointers are named 'mc'. There is nothing wrong with that, but we gain
10
disabling the extension in the KVM vcpu, we'll not add the extension in
9
more compatibility with the rest of the QEMU code base, and easier
11
the riscv,isa. The guest kernel will be unaware of the extension, i.e.
10
reviews, if we follow QEMU conventions.
12
it doesn't matter if the KVM vcpu has it enabled underneath or not. So
13
it's ok to keep booting in this case.
11
14
12
Rename all 'mc' MachineState pointers to 'ms'. This is a very tedious
15
Change our current logic to not error out if we fail to disable an
13
and mechanical patch that was produced by doing the following:
16
extension in kvm_set_one_reg(), but show a warning and keep booting. It
17
is important to throw a warning because we must make the user aware that
18
the extension is still available in the vcpu, meaning that an
19
ill-behaved guest can ignore the riscv,isa settings and use the
20
extension.
14
21
15
- find/replace all 'MachineState *mc' to 'MachineState *ms';
22
The case we're handling happens with an EINVAL error code. If we fail to
16
- find/replace all 'mc->fdt' to 'ms->fdt';
23
disable the extension in KVM for any other reason, error out.
17
- find/replace all 'mc->smp.cpus' to 'ms->smp.cpus';
18
- replace any remaining occurrences of 'mc' that the compiler complained
19
about.
20
24
21
Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
25
We'll also keep erroring out when we fail to enable an extension in KVM,
22
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
26
since adding the extension in riscv,isa at this point will cause a guest
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
27
malfunction because the extension isn't enabled in the vcpu.
28
29
Suggested-by: Andrew Jones <ajones@ventanamicro.com>
24
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
30
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
25
Message-Id: <20230124212234.412630-3-dbarboza@ventanamicro.com>
31
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
33
Message-ID: <20240422171425.333037-2-dbarboza@ventanamicro.com>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
34
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
---
35
---
28
hw/riscv/virt.c | 434 ++++++++++++++++++++++++------------------------
36
target/riscv/kvm/kvm-cpu.c | 12 ++++++++----
29
1 file changed, 217 insertions(+), 217 deletions(-)
37
1 file changed, 8 insertions(+), 4 deletions(-)
30
38
31
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
39
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
32
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/riscv/virt.c
41
--- a/target/riscv/kvm/kvm-cpu.c
34
+++ b/hw/riscv/virt.c
42
+++ b/target/riscv/kvm/kvm-cpu.c
35
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
43
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
36
{
44
reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
37
int cpu;
45
ret = kvm_set_one_reg(cs, id, &reg);
38
uint32_t cpu_phandle;
46
if (ret != 0) {
39
- MachineState *mc = MACHINE(s);
47
- error_report("Unable to %s extension %s in KVM, error %d",
40
+ MachineState *ms = MACHINE(s);
48
- reg ? "enable" : "disable",
41
char *name, *cpu_name, *core_name, *intc_name;
49
- multi_ext_cfg->name, ret);
42
bool is_32_bit = riscv_is_32bit(&s->soc[0]);
50
- exit(EXIT_FAILURE);
43
51
+ if (!reg && ret == -EINVAL) {
44
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
52
+ warn_report("KVM cannot disable extension %s",
45
53
+ multi_ext_cfg->name);
46
cpu_name = g_strdup_printf("/cpus/cpu@%d",
54
+ } else {
47
s->soc[socket].hartid_base + cpu);
55
+ error_report("Unable to enable extension %s in KVM, error %d",
48
- qemu_fdt_add_subnode(mc->fdt, cpu_name);
56
+ multi_ext_cfg->name, ret);
49
+ qemu_fdt_add_subnode(ms->fdt, cpu_name);
57
+ exit(EXIT_FAILURE);
50
if (riscv_feature(&s->soc[socket].harts[cpu].env,
58
+ }
51
RISCV_FEATURE_MMU)) {
52
- qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type",
53
+ qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type",
54
(is_32_bit) ? "riscv,sv32" : "riscv,sv48");
55
} else {
56
- qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type",
57
+ qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type",
58
"riscv,none");
59
}
60
name = riscv_isa_string(&s->soc[socket].harts[cpu]);
61
- qemu_fdt_setprop_string(mc->fdt, cpu_name, "riscv,isa", name);
62
+ qemu_fdt_setprop_string(ms->fdt, cpu_name, "riscv,isa", name);
63
g_free(name);
64
- qemu_fdt_setprop_string(mc->fdt, cpu_name, "compatible", "riscv");
65
- qemu_fdt_setprop_string(mc->fdt, cpu_name, "status", "okay");
66
- qemu_fdt_setprop_cell(mc->fdt, cpu_name, "reg",
67
+ qemu_fdt_setprop_string(ms->fdt, cpu_name, "compatible", "riscv");
68
+ qemu_fdt_setprop_string(ms->fdt, cpu_name, "status", "okay");
69
+ qemu_fdt_setprop_cell(ms->fdt, cpu_name, "reg",
70
s->soc[socket].hartid_base + cpu);
71
- qemu_fdt_setprop_string(mc->fdt, cpu_name, "device_type", "cpu");
72
- riscv_socket_fdt_write_id(mc, cpu_name, socket);
73
- qemu_fdt_setprop_cell(mc->fdt, cpu_name, "phandle", cpu_phandle);
74
+ qemu_fdt_setprop_string(ms->fdt, cpu_name, "device_type", "cpu");
75
+ riscv_socket_fdt_write_id(ms, cpu_name, socket);
76
+ qemu_fdt_setprop_cell(ms->fdt, cpu_name, "phandle", cpu_phandle);
77
78
intc_phandles[cpu] = (*phandle)++;
79
80
intc_name = g_strdup_printf("%s/interrupt-controller", cpu_name);
81
- qemu_fdt_add_subnode(mc->fdt, intc_name);
82
- qemu_fdt_setprop_cell(mc->fdt, intc_name, "phandle",
83
+ qemu_fdt_add_subnode(ms->fdt, intc_name);
84
+ qemu_fdt_setprop_cell(ms->fdt, intc_name, "phandle",
85
intc_phandles[cpu]);
86
- qemu_fdt_setprop_string(mc->fdt, intc_name, "compatible",
87
+ qemu_fdt_setprop_string(ms->fdt, intc_name, "compatible",
88
"riscv,cpu-intc");
89
- qemu_fdt_setprop(mc->fdt, intc_name, "interrupt-controller", NULL, 0);
90
- qemu_fdt_setprop_cell(mc->fdt, intc_name, "#interrupt-cells", 1);
91
+ qemu_fdt_setprop(ms->fdt, intc_name, "interrupt-controller", NULL, 0);
92
+ qemu_fdt_setprop_cell(ms->fdt, intc_name, "#interrupt-cells", 1);
93
94
core_name = g_strdup_printf("%s/core%d", clust_name, cpu);
95
- qemu_fdt_add_subnode(mc->fdt, core_name);
96
- qemu_fdt_setprop_cell(mc->fdt, core_name, "cpu", cpu_phandle);
97
+ qemu_fdt_add_subnode(ms->fdt, core_name);
98
+ qemu_fdt_setprop_cell(ms->fdt, core_name, "cpu", cpu_phandle);
99
100
g_free(core_name);
101
g_free(intc_name);
102
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_memory(RISCVVirtState *s,
103
{
104
char *mem_name;
105
uint64_t addr, size;
106
- MachineState *mc = MACHINE(s);
107
+ MachineState *ms = MACHINE(s);
108
109
- addr = memmap[VIRT_DRAM].base + riscv_socket_mem_offset(mc, socket);
110
- size = riscv_socket_mem_size(mc, socket);
111
+ addr = memmap[VIRT_DRAM].base + riscv_socket_mem_offset(ms, socket);
112
+ size = riscv_socket_mem_size(ms, socket);
113
mem_name = g_strdup_printf("/memory@%lx", (long)addr);
114
- qemu_fdt_add_subnode(mc->fdt, mem_name);
115
- qemu_fdt_setprop_cells(mc->fdt, mem_name, "reg",
116
+ qemu_fdt_add_subnode(ms->fdt, mem_name);
117
+ qemu_fdt_setprop_cells(ms->fdt, mem_name, "reg",
118
addr >> 32, addr, size >> 32, size);
119
- qemu_fdt_setprop_string(mc->fdt, mem_name, "device_type", "memory");
120
- riscv_socket_fdt_write_id(mc, mem_name, socket);
121
+ qemu_fdt_setprop_string(ms->fdt, mem_name, "device_type", "memory");
122
+ riscv_socket_fdt_write_id(ms, mem_name, socket);
123
g_free(mem_name);
124
}
125
126
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_clint(RISCVVirtState *s,
127
char *clint_name;
128
uint32_t *clint_cells;
129
unsigned long clint_addr;
130
- MachineState *mc = MACHINE(s);
131
+ MachineState *ms = MACHINE(s);
132
static const char * const clint_compat[2] = {
133
"sifive,clint0", "riscv,clint0"
134
};
135
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_clint(RISCVVirtState *s,
136
137
clint_addr = memmap[VIRT_CLINT].base + (memmap[VIRT_CLINT].size * socket);
138
clint_name = g_strdup_printf("/soc/clint@%lx", clint_addr);
139
- qemu_fdt_add_subnode(mc->fdt, clint_name);
140
- qemu_fdt_setprop_string_array(mc->fdt, clint_name, "compatible",
141
+ qemu_fdt_add_subnode(ms->fdt, clint_name);
142
+ qemu_fdt_setprop_string_array(ms->fdt, clint_name, "compatible",
143
(char **)&clint_compat,
144
ARRAY_SIZE(clint_compat));
145
- qemu_fdt_setprop_cells(mc->fdt, clint_name, "reg",
146
+ qemu_fdt_setprop_cells(ms->fdt, clint_name, "reg",
147
0x0, clint_addr, 0x0, memmap[VIRT_CLINT].size);
148
- qemu_fdt_setprop(mc->fdt, clint_name, "interrupts-extended",
149
+ qemu_fdt_setprop(ms->fdt, clint_name, "interrupts-extended",
150
clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
151
- riscv_socket_fdt_write_id(mc, clint_name, socket);
152
+ riscv_socket_fdt_write_id(ms, clint_name, socket);
153
g_free(clint_name);
154
155
g_free(clint_cells);
156
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aclint(RISCVVirtState *s,
157
uint32_t *aclint_mswi_cells;
158
uint32_t *aclint_sswi_cells;
159
uint32_t *aclint_mtimer_cells;
160
- MachineState *mc = MACHINE(s);
161
+ MachineState *ms = MACHINE(s);
162
163
aclint_mswi_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
164
aclint_mtimer_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
165
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aclint(RISCVVirtState *s,
166
if (s->aia_type != VIRT_AIA_TYPE_APLIC_IMSIC) {
167
addr = memmap[VIRT_CLINT].base + (memmap[VIRT_CLINT].size * socket);
168
name = g_strdup_printf("/soc/mswi@%lx", addr);
169
- qemu_fdt_add_subnode(mc->fdt, name);
170
- qemu_fdt_setprop_string(mc->fdt, name, "compatible",
171
+ qemu_fdt_add_subnode(ms->fdt, name);
172
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible",
173
"riscv,aclint-mswi");
174
- qemu_fdt_setprop_cells(mc->fdt, name, "reg",
175
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg",
176
0x0, addr, 0x0, RISCV_ACLINT_SWI_SIZE);
177
- qemu_fdt_setprop(mc->fdt, name, "interrupts-extended",
178
+ qemu_fdt_setprop(ms->fdt, name, "interrupts-extended",
179
aclint_mswi_cells, aclint_cells_size);
180
- qemu_fdt_setprop(mc->fdt, name, "interrupt-controller", NULL, 0);
181
- qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells", 0);
182
- riscv_socket_fdt_write_id(mc, name, socket);
183
+ qemu_fdt_setprop(ms->fdt, name, "interrupt-controller", NULL, 0);
184
+ qemu_fdt_setprop_cell(ms->fdt, name, "#interrupt-cells", 0);
185
+ riscv_socket_fdt_write_id(ms, name, socket);
186
g_free(name);
187
}
188
189
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aclint(RISCVVirtState *s,
190
size = memmap[VIRT_CLINT].size - RISCV_ACLINT_SWI_SIZE;
191
}
192
name = g_strdup_printf("/soc/mtimer@%lx", addr);
193
- qemu_fdt_add_subnode(mc->fdt, name);
194
- qemu_fdt_setprop_string(mc->fdt, name, "compatible",
195
+ qemu_fdt_add_subnode(ms->fdt, name);
196
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible",
197
"riscv,aclint-mtimer");
198
- qemu_fdt_setprop_cells(mc->fdt, name, "reg",
199
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg",
200
0x0, addr + RISCV_ACLINT_DEFAULT_MTIME,
201
0x0, size - RISCV_ACLINT_DEFAULT_MTIME,
202
0x0, addr + RISCV_ACLINT_DEFAULT_MTIMECMP,
203
0x0, RISCV_ACLINT_DEFAULT_MTIME);
204
- qemu_fdt_setprop(mc->fdt, name, "interrupts-extended",
205
+ qemu_fdt_setprop(ms->fdt, name, "interrupts-extended",
206
aclint_mtimer_cells, aclint_cells_size);
207
- riscv_socket_fdt_write_id(mc, name, socket);
208
+ riscv_socket_fdt_write_id(ms, name, socket);
209
g_free(name);
210
211
if (s->aia_type != VIRT_AIA_TYPE_APLIC_IMSIC) {
212
addr = memmap[VIRT_ACLINT_SSWI].base +
213
(memmap[VIRT_ACLINT_SSWI].size * socket);
214
name = g_strdup_printf("/soc/sswi@%lx", addr);
215
- qemu_fdt_add_subnode(mc->fdt, name);
216
- qemu_fdt_setprop_string(mc->fdt, name, "compatible",
217
+ qemu_fdt_add_subnode(ms->fdt, name);
218
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible",
219
"riscv,aclint-sswi");
220
- qemu_fdt_setprop_cells(mc->fdt, name, "reg",
221
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg",
222
0x0, addr, 0x0, memmap[VIRT_ACLINT_SSWI].size);
223
- qemu_fdt_setprop(mc->fdt, name, "interrupts-extended",
224
+ qemu_fdt_setprop(ms->fdt, name, "interrupts-extended",
225
aclint_sswi_cells, aclint_cells_size);
226
- qemu_fdt_setprop(mc->fdt, name, "interrupt-controller", NULL, 0);
227
- qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells", 0);
228
- riscv_socket_fdt_write_id(mc, name, socket);
229
+ qemu_fdt_setprop(ms->fdt, name, "interrupt-controller", NULL, 0);
230
+ qemu_fdt_setprop_cell(ms->fdt, name, "#interrupt-cells", 0);
231
+ riscv_socket_fdt_write_id(ms, name, socket);
232
g_free(name);
233
}
234
235
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s,
236
char *plic_name;
237
uint32_t *plic_cells;
238
unsigned long plic_addr;
239
- MachineState *mc = MACHINE(s);
240
+ MachineState *ms = MACHINE(s);
241
static const char * const plic_compat[2] = {
242
"sifive,plic-1.0.0", "riscv,plic0"
243
};
244
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s,
245
plic_phandles[socket] = (*phandle)++;
246
plic_addr = memmap[VIRT_PLIC].base + (memmap[VIRT_PLIC].size * socket);
247
plic_name = g_strdup_printf("/soc/plic@%lx", plic_addr);
248
- qemu_fdt_add_subnode(mc->fdt, plic_name);
249
- qemu_fdt_setprop_cell(mc->fdt, plic_name,
250
+ qemu_fdt_add_subnode(ms->fdt, plic_name);
251
+ qemu_fdt_setprop_cell(ms->fdt, plic_name,
252
"#interrupt-cells", FDT_PLIC_INT_CELLS);
253
- qemu_fdt_setprop_cell(mc->fdt, plic_name,
254
+ qemu_fdt_setprop_cell(ms->fdt, plic_name,
255
"#address-cells", FDT_PLIC_ADDR_CELLS);
256
- qemu_fdt_setprop_string_array(mc->fdt, plic_name, "compatible",
257
+ qemu_fdt_setprop_string_array(ms->fdt, plic_name, "compatible",
258
(char **)&plic_compat,
259
ARRAY_SIZE(plic_compat));
260
- qemu_fdt_setprop(mc->fdt, plic_name, "interrupt-controller", NULL, 0);
261
- qemu_fdt_setprop(mc->fdt, plic_name, "interrupts-extended",
262
+ qemu_fdt_setprop(ms->fdt, plic_name, "interrupt-controller", NULL, 0);
263
+ qemu_fdt_setprop(ms->fdt, plic_name, "interrupts-extended",
264
plic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
265
- qemu_fdt_setprop_cells(mc->fdt, plic_name, "reg",
266
+ qemu_fdt_setprop_cells(ms->fdt, plic_name, "reg",
267
0x0, plic_addr, 0x0, memmap[VIRT_PLIC].size);
268
- qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev",
269
+ qemu_fdt_setprop_cell(ms->fdt, plic_name, "riscv,ndev",
270
VIRT_IRQCHIP_NUM_SOURCES - 1);
271
- riscv_socket_fdt_write_id(mc, plic_name, socket);
272
- qemu_fdt_setprop_cell(mc->fdt, plic_name, "phandle",
273
+ riscv_socket_fdt_write_id(ms, plic_name, socket);
274
+ qemu_fdt_setprop_cell(ms->fdt, plic_name, "phandle",
275
plic_phandles[socket]);
276
277
if (!socket) {
278
- platform_bus_add_all_fdt_nodes(mc->fdt, plic_name,
279
+ platform_bus_add_all_fdt_nodes(ms->fdt, plic_name,
280
memmap[VIRT_PLATFORM_BUS].base,
281
memmap[VIRT_PLATFORM_BUS].size,
282
VIRT_PLATFORM_BUS_IRQ);
283
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
284
{
285
int cpu, socket;
286
char *imsic_name;
287
- MachineState *mc = MACHINE(s);
288
- int socket_count = riscv_socket_count(mc);
289
+ MachineState *ms = MACHINE(s);
290
+ int socket_count = riscv_socket_count(ms);
291
uint32_t imsic_max_hart_per_socket, imsic_guest_bits;
292
uint32_t *imsic_cells, *imsic_regs, imsic_addr, imsic_size;
293
294
*msi_m_phandle = (*phandle)++;
295
*msi_s_phandle = (*phandle)++;
296
- imsic_cells = g_new0(uint32_t, mc->smp.cpus * 2);
297
+ imsic_cells = g_new0(uint32_t, ms->smp.cpus * 2);
298
imsic_regs = g_new0(uint32_t, socket_count * 4);
299
300
/* M-level IMSIC node */
301
- for (cpu = 0; cpu < mc->smp.cpus; cpu++) {
302
+ for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
303
imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
304
imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
305
}
306
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
307
}
308
imsic_name = g_strdup_printf("/soc/imsics@%lx",
309
(unsigned long)memmap[VIRT_IMSIC_M].base);
310
- qemu_fdt_add_subnode(mc->fdt, imsic_name);
311
- qemu_fdt_setprop_string(mc->fdt, imsic_name, "compatible",
312
+ qemu_fdt_add_subnode(ms->fdt, imsic_name);
313
+ qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
314
"riscv,imsics");
315
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "#interrupt-cells",
316
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
317
FDT_IMSIC_INT_CELLS);
318
- qemu_fdt_setprop(mc->fdt, imsic_name, "interrupt-controller",
319
+ qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
320
NULL, 0);
321
- qemu_fdt_setprop(mc->fdt, imsic_name, "msi-controller",
322
+ qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
323
NULL, 0);
324
- qemu_fdt_setprop(mc->fdt, imsic_name, "interrupts-extended",
325
- imsic_cells, mc->smp.cpus * sizeof(uint32_t) * 2);
326
- qemu_fdt_setprop(mc->fdt, imsic_name, "reg", imsic_regs,
327
+ qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
328
+ imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
329
+ qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
330
socket_count * sizeof(uint32_t) * 4);
331
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
332
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
333
VIRT_IRQCHIP_NUM_MSIS);
334
if (socket_count > 1) {
335
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits",
336
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
337
imsic_num_bits(imsic_max_hart_per_socket));
338
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-bits",
339
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
340
imsic_num_bits(socket_count));
341
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-shift",
342
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
343
IMSIC_MMIO_GROUP_MIN_SHIFT);
344
}
345
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "phandle", *msi_m_phandle);
346
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_m_phandle);
347
348
g_free(imsic_name);
349
350
/* S-level IMSIC node */
351
- for (cpu = 0; cpu < mc->smp.cpus; cpu++) {
352
+ for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
353
imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
354
imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
355
}
356
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
357
}
358
imsic_name = g_strdup_printf("/soc/imsics@%lx",
359
(unsigned long)memmap[VIRT_IMSIC_S].base);
360
- qemu_fdt_add_subnode(mc->fdt, imsic_name);
361
- qemu_fdt_setprop_string(mc->fdt, imsic_name, "compatible",
362
+ qemu_fdt_add_subnode(ms->fdt, imsic_name);
363
+ qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
364
"riscv,imsics");
365
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "#interrupt-cells",
366
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
367
FDT_IMSIC_INT_CELLS);
368
- qemu_fdt_setprop(mc->fdt, imsic_name, "interrupt-controller",
369
+ qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
370
NULL, 0);
371
- qemu_fdt_setprop(mc->fdt, imsic_name, "msi-controller",
372
+ qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
373
NULL, 0);
374
- qemu_fdt_setprop(mc->fdt, imsic_name, "interrupts-extended",
375
- imsic_cells, mc->smp.cpus * sizeof(uint32_t) * 2);
376
- qemu_fdt_setprop(mc->fdt, imsic_name, "reg", imsic_regs,
377
+ qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
378
+ imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
379
+ qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
380
socket_count * sizeof(uint32_t) * 4);
381
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
382
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
383
VIRT_IRQCHIP_NUM_MSIS);
384
if (imsic_guest_bits) {
385
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,guest-index-bits",
386
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,guest-index-bits",
387
imsic_guest_bits);
388
}
389
if (socket_count > 1) {
390
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits",
391
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
392
imsic_num_bits(imsic_max_hart_per_socket));
393
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-bits",
394
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
395
imsic_num_bits(socket_count));
396
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-shift",
397
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
398
IMSIC_MMIO_GROUP_MIN_SHIFT);
399
}
400
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "phandle", *msi_s_phandle);
401
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_s_phandle);
402
g_free(imsic_name);
403
404
g_free(imsic_regs);
405
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
406
char *aplic_name;
407
uint32_t *aplic_cells;
408
unsigned long aplic_addr;
409
- MachineState *mc = MACHINE(s);
410
+ MachineState *ms = MACHINE(s);
411
uint32_t aplic_m_phandle, aplic_s_phandle;
412
413
aplic_m_phandle = (*phandle)++;
414
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
415
aplic_addr = memmap[VIRT_APLIC_M].base +
416
(memmap[VIRT_APLIC_M].size * socket);
417
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
418
- qemu_fdt_add_subnode(mc->fdt, aplic_name);
419
- qemu_fdt_setprop_string(mc->fdt, aplic_name, "compatible", "riscv,aplic");
420
- qemu_fdt_setprop_cell(mc->fdt, aplic_name,
421
+ qemu_fdt_add_subnode(ms->fdt, aplic_name);
422
+ qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
423
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name,
424
"#interrupt-cells", FDT_APLIC_INT_CELLS);
425
- qemu_fdt_setprop(mc->fdt, aplic_name, "interrupt-controller", NULL, 0);
426
+ qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
427
if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
428
- qemu_fdt_setprop(mc->fdt, aplic_name, "interrupts-extended",
429
+ qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
430
aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2);
431
} else {
432
- qemu_fdt_setprop_cell(mc->fdt, aplic_name, "msi-parent",
433
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent",
434
msi_m_phandle);
435
}
436
- qemu_fdt_setprop_cells(mc->fdt, aplic_name, "reg",
437
+ qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
438
0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_M].size);
439
- qemu_fdt_setprop_cell(mc->fdt, aplic_name, "riscv,num-sources",
440
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
441
VIRT_IRQCHIP_NUM_SOURCES);
442
- qemu_fdt_setprop_cell(mc->fdt, aplic_name, "riscv,children",
443
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,children",
444
aplic_s_phandle);
445
- qemu_fdt_setprop_cells(mc->fdt, aplic_name, "riscv,delegate",
446
+ qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate",
447
aplic_s_phandle, 0x1, VIRT_IRQCHIP_NUM_SOURCES);
448
- riscv_socket_fdt_write_id(mc, aplic_name, socket);
449
- qemu_fdt_setprop_cell(mc->fdt, aplic_name, "phandle", aplic_m_phandle);
450
+ riscv_socket_fdt_write_id(ms, aplic_name, socket);
451
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_m_phandle);
452
g_free(aplic_name);
453
454
/* S-level APLIC node */
455
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
456
aplic_addr = memmap[VIRT_APLIC_S].base +
457
(memmap[VIRT_APLIC_S].size * socket);
458
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
459
- qemu_fdt_add_subnode(mc->fdt, aplic_name);
460
- qemu_fdt_setprop_string(mc->fdt, aplic_name, "compatible", "riscv,aplic");
461
- qemu_fdt_setprop_cell(mc->fdt, aplic_name,
462
+ qemu_fdt_add_subnode(ms->fdt, aplic_name);
463
+ qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
464
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name,
465
"#interrupt-cells", FDT_APLIC_INT_CELLS);
466
- qemu_fdt_setprop(mc->fdt, aplic_name, "interrupt-controller", NULL, 0);
467
+ qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
468
if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
469
- qemu_fdt_setprop(mc->fdt, aplic_name, "interrupts-extended",
470
+ qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
471
aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2);
472
} else {
473
- qemu_fdt_setprop_cell(mc->fdt, aplic_name, "msi-parent",
474
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent",
475
msi_s_phandle);
476
}
477
- qemu_fdt_setprop_cells(mc->fdt, aplic_name, "reg",
478
+ qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
479
0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_S].size);
480
- qemu_fdt_setprop_cell(mc->fdt, aplic_name, "riscv,num-sources",
481
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
482
VIRT_IRQCHIP_NUM_SOURCES);
483
- riscv_socket_fdt_write_id(mc, aplic_name, socket);
484
- qemu_fdt_setprop_cell(mc->fdt, aplic_name, "phandle", aplic_s_phandle);
485
+ riscv_socket_fdt_write_id(ms, aplic_name, socket);
486
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_s_phandle);
487
488
if (!socket) {
489
- platform_bus_add_all_fdt_nodes(mc->fdt, aplic_name,
490
+ platform_bus_add_all_fdt_nodes(ms->fdt, aplic_name,
491
memmap[VIRT_PLATFORM_BUS].base,
492
memmap[VIRT_PLATFORM_BUS].size,
493
VIRT_PLATFORM_BUS_IRQ);
494
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
495
static void create_fdt_pmu(RISCVVirtState *s)
496
{
497
char *pmu_name;
498
- MachineState *mc = MACHINE(s);
499
+ MachineState *ms = MACHINE(s);
500
RISCVCPU hart = s->soc[0].harts[0];
501
502
pmu_name = g_strdup_printf("/soc/pmu");
503
- qemu_fdt_add_subnode(mc->fdt, pmu_name);
504
- qemu_fdt_setprop_string(mc->fdt, pmu_name, "compatible", "riscv,pmu");
505
- riscv_pmu_generate_fdt_node(mc->fdt, hart.cfg.pmu_num, pmu_name);
506
+ qemu_fdt_add_subnode(ms->fdt, pmu_name);
507
+ qemu_fdt_setprop_string(ms->fdt, pmu_name, "compatible", "riscv,pmu");
508
+ riscv_pmu_generate_fdt_node(ms->fdt, hart.cfg.pmu_num, pmu_name);
509
510
g_free(pmu_name);
511
}
512
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
513
{
514
char *clust_name;
515
int socket, phandle_pos;
516
- MachineState *mc = MACHINE(s);
517
+ MachineState *ms = MACHINE(s);
518
uint32_t msi_m_phandle = 0, msi_s_phandle = 0;
519
uint32_t *intc_phandles, xplic_phandles[MAX_NODES];
520
- int socket_count = riscv_socket_count(mc);
521
+ int socket_count = riscv_socket_count(ms);
522
523
- qemu_fdt_add_subnode(mc->fdt, "/cpus");
524
- qemu_fdt_setprop_cell(mc->fdt, "/cpus", "timebase-frequency",
525
+ qemu_fdt_add_subnode(ms->fdt, "/cpus");
526
+ qemu_fdt_setprop_cell(ms->fdt, "/cpus", "timebase-frequency",
527
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);
528
- qemu_fdt_setprop_cell(mc->fdt, "/cpus", "#size-cells", 0x0);
529
- qemu_fdt_setprop_cell(mc->fdt, "/cpus", "#address-cells", 0x1);
530
- qemu_fdt_add_subnode(mc->fdt, "/cpus/cpu-map");
531
+ qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
532
+ qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
533
+ qemu_fdt_add_subnode(ms->fdt, "/cpus/cpu-map");
534
535
- intc_phandles = g_new0(uint32_t, mc->smp.cpus);
536
+ intc_phandles = g_new0(uint32_t, ms->smp.cpus);
537
538
- phandle_pos = mc->smp.cpus;
539
+ phandle_pos = ms->smp.cpus;
540
for (socket = (socket_count - 1); socket >= 0; socket--) {
541
phandle_pos -= s->soc[socket].num_harts;
542
543
clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket);
544
- qemu_fdt_add_subnode(mc->fdt, clust_name);
545
+ qemu_fdt_add_subnode(ms->fdt, clust_name);
546
547
create_fdt_socket_cpus(s, socket, clust_name, phandle,
548
&intc_phandles[phandle_pos]);
549
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
550
*msi_pcie_phandle = msi_s_phandle;
551
}
552
553
- phandle_pos = mc->smp.cpus;
554
+ phandle_pos = ms->smp.cpus;
555
for (socket = (socket_count - 1); socket >= 0; socket--) {
556
phandle_pos -= s->soc[socket].num_harts;
557
558
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
559
}
59
}
560
}
60
}
561
562
- riscv_socket_fdt_write_distance_matrix(mc);
563
+ riscv_socket_fdt_write_distance_matrix(ms);
564
}
565
566
static void create_fdt_virtio(RISCVVirtState *s, const MemMapEntry *memmap,
567
@@ -XXX,XX +XXX,XX @@ static void create_fdt_virtio(RISCVVirtState *s, const MemMapEntry *memmap,
568
{
569
int i;
570
char *name;
571
- MachineState *mc = MACHINE(s);
572
+ MachineState *ms = MACHINE(s);
573
574
for (i = 0; i < VIRTIO_COUNT; i++) {
575
name = g_strdup_printf("/soc/virtio_mmio@%lx",
576
(long)(memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size));
577
- qemu_fdt_add_subnode(mc->fdt, name);
578
- qemu_fdt_setprop_string(mc->fdt, name, "compatible", "virtio,mmio");
579
- qemu_fdt_setprop_cells(mc->fdt, name, "reg",
580
+ qemu_fdt_add_subnode(ms->fdt, name);
581
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible", "virtio,mmio");
582
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg",
583
0x0, memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size,
584
0x0, memmap[VIRT_VIRTIO].size);
585
- qemu_fdt_setprop_cell(mc->fdt, name, "interrupt-parent",
586
+ qemu_fdt_setprop_cell(ms->fdt, name, "interrupt-parent",
587
irq_virtio_phandle);
588
if (s->aia_type == VIRT_AIA_TYPE_NONE) {
589
- qemu_fdt_setprop_cell(mc->fdt, name, "interrupts",
590
+ qemu_fdt_setprop_cell(ms->fdt, name, "interrupts",
591
VIRTIO_IRQ + i);
592
} else {
593
- qemu_fdt_setprop_cells(mc->fdt, name, "interrupts",
594
+ qemu_fdt_setprop_cells(ms->fdt, name, "interrupts",
595
VIRTIO_IRQ + i, 0x4);
596
}
597
g_free(name);
598
@@ -XXX,XX +XXX,XX @@ static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap,
599
uint32_t msi_pcie_phandle)
600
{
601
char *name;
602
- MachineState *mc = MACHINE(s);
603
+ MachineState *ms = MACHINE(s);
604
605
name = g_strdup_printf("/soc/pci@%lx",
606
(long) memmap[VIRT_PCIE_ECAM].base);
607
- qemu_fdt_add_subnode(mc->fdt, name);
608
- qemu_fdt_setprop_cell(mc->fdt, name, "#address-cells",
609
+ qemu_fdt_add_subnode(ms->fdt, name);
610
+ qemu_fdt_setprop_cell(ms->fdt, name, "#address-cells",
611
FDT_PCI_ADDR_CELLS);
612
- qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells",
613
+ qemu_fdt_setprop_cell(ms->fdt, name, "#interrupt-cells",
614
FDT_PCI_INT_CELLS);
615
- qemu_fdt_setprop_cell(mc->fdt, name, "#size-cells", 0x2);
616
- qemu_fdt_setprop_string(mc->fdt, name, "compatible",
617
+ qemu_fdt_setprop_cell(ms->fdt, name, "#size-cells", 0x2);
618
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible",
619
"pci-host-ecam-generic");
620
- qemu_fdt_setprop_string(mc->fdt, name, "device_type", "pci");
621
- qemu_fdt_setprop_cell(mc->fdt, name, "linux,pci-domain", 0);
622
- qemu_fdt_setprop_cells(mc->fdt, name, "bus-range", 0,
623
+ qemu_fdt_setprop_string(ms->fdt, name, "device_type", "pci");
624
+ qemu_fdt_setprop_cell(ms->fdt, name, "linux,pci-domain", 0);
625
+ qemu_fdt_setprop_cells(ms->fdt, name, "bus-range", 0,
626
memmap[VIRT_PCIE_ECAM].size / PCIE_MMCFG_SIZE_MIN - 1);
627
- qemu_fdt_setprop(mc->fdt, name, "dma-coherent", NULL, 0);
628
+ qemu_fdt_setprop(ms->fdt, name, "dma-coherent", NULL, 0);
629
if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) {
630
- qemu_fdt_setprop_cell(mc->fdt, name, "msi-parent", msi_pcie_phandle);
631
+ qemu_fdt_setprop_cell(ms->fdt, name, "msi-parent", msi_pcie_phandle);
632
}
633
- qemu_fdt_setprop_cells(mc->fdt, name, "reg", 0,
634
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg", 0,
635
memmap[VIRT_PCIE_ECAM].base, 0, memmap[VIRT_PCIE_ECAM].size);
636
- qemu_fdt_setprop_sized_cells(mc->fdt, name, "ranges",
637
+ qemu_fdt_setprop_sized_cells(ms->fdt, name, "ranges",
638
1, FDT_PCI_RANGE_IOPORT, 2, 0,
639
2, memmap[VIRT_PCIE_PIO].base, 2, memmap[VIRT_PCIE_PIO].size,
640
1, FDT_PCI_RANGE_MMIO,
641
@@ -XXX,XX +XXX,XX @@ static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap,
642
2, virt_high_pcie_memmap.base,
643
2, virt_high_pcie_memmap.base, 2, virt_high_pcie_memmap.size);
644
645
- create_pcie_irq_map(s, mc->fdt, name, irq_pcie_phandle);
646
+ create_pcie_irq_map(s, ms->fdt, name, irq_pcie_phandle);
647
g_free(name);
648
}
649
650
@@ -XXX,XX +XXX,XX @@ static void create_fdt_reset(RISCVVirtState *s, const MemMapEntry *memmap,
651
{
652
char *name;
653
uint32_t test_phandle;
654
- MachineState *mc = MACHINE(s);
655
+ MachineState *ms = MACHINE(s);
656
657
test_phandle = (*phandle)++;
658
name = g_strdup_printf("/soc/test@%lx",
659
(long)memmap[VIRT_TEST].base);
660
- qemu_fdt_add_subnode(mc->fdt, name);
661
+ qemu_fdt_add_subnode(ms->fdt, name);
662
{
663
static const char * const compat[3] = {
664
"sifive,test1", "sifive,test0", "syscon"
665
};
666
- qemu_fdt_setprop_string_array(mc->fdt, name, "compatible",
667
+ qemu_fdt_setprop_string_array(ms->fdt, name, "compatible",
668
(char **)&compat, ARRAY_SIZE(compat));
669
}
670
- qemu_fdt_setprop_cells(mc->fdt, name, "reg",
671
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg",
672
0x0, memmap[VIRT_TEST].base, 0x0, memmap[VIRT_TEST].size);
673
- qemu_fdt_setprop_cell(mc->fdt, name, "phandle", test_phandle);
674
- test_phandle = qemu_fdt_get_phandle(mc->fdt, name);
675
+ qemu_fdt_setprop_cell(ms->fdt, name, "phandle", test_phandle);
676
+ test_phandle = qemu_fdt_get_phandle(ms->fdt, name);
677
g_free(name);
678
679
name = g_strdup_printf("/reboot");
680
- qemu_fdt_add_subnode(mc->fdt, name);
681
- qemu_fdt_setprop_string(mc->fdt, name, "compatible", "syscon-reboot");
682
- qemu_fdt_setprop_cell(mc->fdt, name, "regmap", test_phandle);
683
- qemu_fdt_setprop_cell(mc->fdt, name, "offset", 0x0);
684
- qemu_fdt_setprop_cell(mc->fdt, name, "value", FINISHER_RESET);
685
+ qemu_fdt_add_subnode(ms->fdt, name);
686
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-reboot");
687
+ qemu_fdt_setprop_cell(ms->fdt, name, "regmap", test_phandle);
688
+ qemu_fdt_setprop_cell(ms->fdt, name, "offset", 0x0);
689
+ qemu_fdt_setprop_cell(ms->fdt, name, "value", FINISHER_RESET);
690
g_free(name);
691
692
name = g_strdup_printf("/poweroff");
693
- qemu_fdt_add_subnode(mc->fdt, name);
694
- qemu_fdt_setprop_string(mc->fdt, name, "compatible", "syscon-poweroff");
695
- qemu_fdt_setprop_cell(mc->fdt, name, "regmap", test_phandle);
696
- qemu_fdt_setprop_cell(mc->fdt, name, "offset", 0x0);
697
- qemu_fdt_setprop_cell(mc->fdt, name, "value", FINISHER_PASS);
698
+ qemu_fdt_add_subnode(ms->fdt, name);
699
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-poweroff");
700
+ qemu_fdt_setprop_cell(ms->fdt, name, "regmap", test_phandle);
701
+ qemu_fdt_setprop_cell(ms->fdt, name, "offset", 0x0);
702
+ qemu_fdt_setprop_cell(ms->fdt, name, "value", FINISHER_PASS);
703
g_free(name);
704
}
705
706
@@ -XXX,XX +XXX,XX @@ static void create_fdt_uart(RISCVVirtState *s, const MemMapEntry *memmap,
707
uint32_t irq_mmio_phandle)
708
{
709
char *name;
710
- MachineState *mc = MACHINE(s);
711
+ MachineState *ms = MACHINE(s);
712
713
name = g_strdup_printf("/soc/serial@%lx", (long)memmap[VIRT_UART0].base);
714
- qemu_fdt_add_subnode(mc->fdt, name);
715
- qemu_fdt_setprop_string(mc->fdt, name, "compatible", "ns16550a");
716
- qemu_fdt_setprop_cells(mc->fdt, name, "reg",
717
+ qemu_fdt_add_subnode(ms->fdt, name);
718
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible", "ns16550a");
719
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg",
720
0x0, memmap[VIRT_UART0].base,
721
0x0, memmap[VIRT_UART0].size);
722
- qemu_fdt_setprop_cell(mc->fdt, name, "clock-frequency", 3686400);
723
- qemu_fdt_setprop_cell(mc->fdt, name, "interrupt-parent", irq_mmio_phandle);
724
+ qemu_fdt_setprop_cell(ms->fdt, name, "clock-frequency", 3686400);
725
+ qemu_fdt_setprop_cell(ms->fdt, name, "interrupt-parent", irq_mmio_phandle);
726
if (s->aia_type == VIRT_AIA_TYPE_NONE) {
727
- qemu_fdt_setprop_cell(mc->fdt, name, "interrupts", UART0_IRQ);
728
+ qemu_fdt_setprop_cell(ms->fdt, name, "interrupts", UART0_IRQ);
729
} else {
730
- qemu_fdt_setprop_cells(mc->fdt, name, "interrupts", UART0_IRQ, 0x4);
731
+ qemu_fdt_setprop_cells(ms->fdt, name, "interrupts", UART0_IRQ, 0x4);
732
}
733
734
- qemu_fdt_add_subnode(mc->fdt, "/chosen");
735
- qemu_fdt_setprop_string(mc->fdt, "/chosen", "stdout-path", name);
736
+ qemu_fdt_add_subnode(ms->fdt, "/chosen");
737
+ qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", name);
738
g_free(name);
739
}
740
741
@@ -XXX,XX +XXX,XX @@ static void create_fdt_rtc(RISCVVirtState *s, const MemMapEntry *memmap,
742
uint32_t irq_mmio_phandle)
743
{
744
char *name;
745
- MachineState *mc = MACHINE(s);
746
+ MachineState *ms = MACHINE(s);
747
748
name = g_strdup_printf("/soc/rtc@%lx", (long)memmap[VIRT_RTC].base);
749
- qemu_fdt_add_subnode(mc->fdt, name);
750
- qemu_fdt_setprop_string(mc->fdt, name, "compatible",
751
+ qemu_fdt_add_subnode(ms->fdt, name);
752
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible",
753
"google,goldfish-rtc");
754
- qemu_fdt_setprop_cells(mc->fdt, name, "reg",
755
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg",
756
0x0, memmap[VIRT_RTC].base, 0x0, memmap[VIRT_RTC].size);
757
- qemu_fdt_setprop_cell(mc->fdt, name, "interrupt-parent",
758
+ qemu_fdt_setprop_cell(ms->fdt, name, "interrupt-parent",
759
irq_mmio_phandle);
760
if (s->aia_type == VIRT_AIA_TYPE_NONE) {
761
- qemu_fdt_setprop_cell(mc->fdt, name, "interrupts", RTC_IRQ);
762
+ qemu_fdt_setprop_cell(ms->fdt, name, "interrupts", RTC_IRQ);
763
} else {
764
- qemu_fdt_setprop_cells(mc->fdt, name, "interrupts", RTC_IRQ, 0x4);
765
+ qemu_fdt_setprop_cells(ms->fdt, name, "interrupts", RTC_IRQ, 0x4);
766
}
767
g_free(name);
768
}
769
@@ -XXX,XX +XXX,XX @@ static void create_fdt_rtc(RISCVVirtState *s, const MemMapEntry *memmap,
770
static void create_fdt_flash(RISCVVirtState *s, const MemMapEntry *memmap)
771
{
772
char *name;
773
- MachineState *mc = MACHINE(s);
774
+ MachineState *ms = MACHINE(s);
775
hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2;
776
hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
777
778
name = g_strdup_printf("/flash@%" PRIx64, flashbase);
779
- qemu_fdt_add_subnode(mc->fdt, name);
780
- qemu_fdt_setprop_string(mc->fdt, name, "compatible", "cfi-flash");
781
- qemu_fdt_setprop_sized_cells(mc->fdt, name, "reg",
782
+ qemu_fdt_add_subnode(ms->fdt, name);
783
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible", "cfi-flash");
784
+ qemu_fdt_setprop_sized_cells(ms->fdt, name, "reg",
785
2, flashbase, 2, flashsize,
786
2, flashbase + flashsize, 2, flashsize);
787
- qemu_fdt_setprop_cell(mc->fdt, name, "bank-width", 4);
788
+ qemu_fdt_setprop_cell(ms->fdt, name, "bank-width", 4);
789
g_free(name);
790
}
791
792
static void create_fdt_fw_cfg(RISCVVirtState *s, const MemMapEntry *memmap)
793
{
794
char *nodename;
795
- MachineState *mc = MACHINE(s);
796
+ MachineState *ms = MACHINE(s);
797
hwaddr base = memmap[VIRT_FW_CFG].base;
798
hwaddr size = memmap[VIRT_FW_CFG].size;
799
800
nodename = g_strdup_printf("/fw-cfg@%" PRIx64, base);
801
- qemu_fdt_add_subnode(mc->fdt, nodename);
802
- qemu_fdt_setprop_string(mc->fdt, nodename,
803
+ qemu_fdt_add_subnode(ms->fdt, nodename);
804
+ qemu_fdt_setprop_string(ms->fdt, nodename,
805
"compatible", "qemu,fw-cfg-mmio");
806
- qemu_fdt_setprop_sized_cells(mc->fdt, nodename, "reg",
807
+ qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
808
2, base, 2, size);
809
- qemu_fdt_setprop(mc->fdt, nodename, "dma-coherent", NULL, 0);
810
+ qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0);
811
g_free(nodename);
812
}
813
814
static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap)
815
{
816
- MachineState *mc = MACHINE(s);
817
+ MachineState *ms = MACHINE(s);
818
uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1;
819
uint32_t irq_pcie_phandle = 1, irq_virtio_phandle = 1;
820
uint8_t rng_seed[32];
821
822
- if (mc->dtb) {
823
- mc->fdt = load_device_tree(mc->dtb, &s->fdt_size);
824
- if (!mc->fdt) {
825
+ if (ms->dtb) {
826
+ ms->fdt = load_device_tree(ms->dtb, &s->fdt_size);
827
+ if (!ms->fdt) {
828
error_report("load_device_tree() failed");
829
exit(1);
830
}
831
} else {
832
- mc->fdt = create_device_tree(&s->fdt_size);
833
- if (!mc->fdt) {
834
+ ms->fdt = create_device_tree(&s->fdt_size);
835
+ if (!ms->fdt) {
836
error_report("create_device_tree() failed");
837
exit(1);
838
}
839
}
840
841
- qemu_fdt_setprop_string(mc->fdt, "/", "model", "riscv-virtio,qemu");
842
- qemu_fdt_setprop_string(mc->fdt, "/", "compatible", "riscv-virtio");
843
- qemu_fdt_setprop_cell(mc->fdt, "/", "#size-cells", 0x2);
844
- qemu_fdt_setprop_cell(mc->fdt, "/", "#address-cells", 0x2);
845
+ qemu_fdt_setprop_string(ms->fdt, "/", "model", "riscv-virtio,qemu");
846
+ qemu_fdt_setprop_string(ms->fdt, "/", "compatible", "riscv-virtio");
847
+ qemu_fdt_setprop_cell(ms->fdt, "/", "#size-cells", 0x2);
848
+ qemu_fdt_setprop_cell(ms->fdt, "/", "#address-cells", 0x2);
849
850
- qemu_fdt_add_subnode(mc->fdt, "/soc");
851
- qemu_fdt_setprop(mc->fdt, "/soc", "ranges", NULL, 0);
852
- qemu_fdt_setprop_string(mc->fdt, "/soc", "compatible", "simple-bus");
853
- qemu_fdt_setprop_cell(mc->fdt, "/soc", "#size-cells", 0x2);
854
- qemu_fdt_setprop_cell(mc->fdt, "/soc", "#address-cells", 0x2);
855
+ qemu_fdt_add_subnode(ms->fdt, "/soc");
856
+ qemu_fdt_setprop(ms->fdt, "/soc", "ranges", NULL, 0);
857
+ qemu_fdt_setprop_string(ms->fdt, "/soc", "compatible", "simple-bus");
858
+ qemu_fdt_setprop_cell(ms->fdt, "/soc", "#size-cells", 0x2);
859
+ qemu_fdt_setprop_cell(ms->fdt, "/soc", "#address-cells", 0x2);
860
861
create_fdt_sockets(s, memmap, &phandle, &irq_mmio_phandle,
862
&irq_pcie_phandle, &irq_virtio_phandle,
863
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap)
864
865
/* Pass seed to RNG */
866
qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
867
- qemu_fdt_setprop(mc->fdt, "/chosen", "rng-seed",
868
+ qemu_fdt_setprop(ms->fdt, "/chosen", "rng-seed",
869
rng_seed, sizeof(rng_seed));
870
}
871
872
@@ -XXX,XX +XXX,XX @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
873
return dev;
874
}
875
876
-static FWCfgState *create_fw_cfg(const MachineState *mc)
877
+static FWCfgState *create_fw_cfg(const MachineState *ms)
878
{
879
hwaddr base = virt_memmap[VIRT_FW_CFG].base;
880
FWCfgState *fw_cfg;
881
882
fw_cfg = fw_cfg_init_mem_wide(base + 8, base, 8, base + 16,
883
&address_space_memory);
884
- fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)mc->smp.cpus);
885
+ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)ms->smp.cpus);
886
887
return fw_cfg;
888
}
61
}
889
--
62
--
890
2.39.1
63
2.45.1
diff view generated by jsdifflib
1
From: Sergey Matyukevich <sergey.matyukevich@syntacore.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
According to privileged spec, if [sm]tval is written with a nonzero
3
We're not setting (s/m)tval when triggering breakpoints of type 2
4
value when a breakpoint exception occurs, then [sm]tval will contain
4
(mcontrol) and 6 (mcontrol6). According to the debug spec section
5
the faulting virtual address. Set tval to hit address when breakpoint
5
5.7.12, "Match Control Type 6":
6
exception is triggered by hardware watchpoint.
7
6
8
Signed-off-by: Sergey Matyukevich <sergey.matyukevich@syntacore.com>
7
"The Privileged Spec says that breakpoint exceptions that occur on
9
Reviewed-by: Bin Meng <bmeng@tinylab.org>
8
instruction fetches, loads, or stores update the tval CSR with either
9
zero or the faulting virtual address. The faulting virtual address for
10
an mcontrol6 trigger with action = 0 is the address being accessed and
11
which caused that trigger to fire."
12
13
A similar text is also found in the Debug spec section 5.7.11 w.r.t.
14
mcontrol.
15
16
Note that what we're doing ATM is not violating the spec, but it's
17
simple enough to set mtval/stval and it makes life easier for any
18
software that relies on this info.
19
20
Given that we always use action = 0, save the faulting address for the
21
mcontrol and mcontrol6 trigger breakpoints into env->badaddr, which is
22
used as as scratch area for traps with address information. 'tval' is
23
then set during riscv_cpu_do_interrupt().
24
25
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
26
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20230131170955.752743-1-geomatsi@gmail.com>
27
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
28
Message-ID: <20240416230437.1869024-2-dbarboza@ventanamicro.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
30
---
14
target/riscv/cpu_helper.c | 6 ++++++
31
target/riscv/cpu_helper.c | 1 +
15
target/riscv/debug.c | 1 -
32
target/riscv/debug.c | 3 +++
16
2 files changed, 6 insertions(+), 1 deletion(-)
33
2 files changed, 4 insertions(+)
17
34
18
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
35
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
19
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/cpu_helper.c
37
--- a/target/riscv/cpu_helper.c
21
+++ b/target/riscv/cpu_helper.c
38
+++ b/target/riscv/cpu_helper.c
22
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
23
case RISCV_EXCP_VIRT_INSTRUCTION_FAULT:
24
tval = env->bins;
40
tval = env->bins;
25
break;
41
break;
26
+ case RISCV_EXCP_BREAKPOINT:
42
case RISCV_EXCP_BREAKPOINT:
27
+ if (cs->watchpoint_hit) {
43
+ tval = env->badaddr;
28
+ tval = cs->watchpoint_hit->hitaddr;
44
if (cs->watchpoint_hit) {
29
+ cs->watchpoint_hit = NULL;
45
tval = cs->watchpoint_hit->hitaddr;
30
+ }
46
cs->watchpoint_hit = NULL;
31
+ break;
32
default:
33
break;
34
}
35
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
47
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
36
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/debug.c
49
--- a/target/riscv/debug.c
38
+++ b/target/riscv/debug.c
50
+++ b/target/riscv/debug.c
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_debug_excp_handler(CPUState *cs)
51
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
40
52
if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
41
if (cs->watchpoint_hit) {
53
/* check U/S/M bit against current privilege level */
42
if (cs->watchpoint_hit->flags & BP_CPU) {
54
if ((ctrl >> 3) & BIT(env->priv)) {
43
- cs->watchpoint_hit = NULL;
55
+ env->badaddr = pc;
44
do_trigger_action(env, DBG_ACTION_BP);
56
return true;
45
}
57
}
46
} else {
58
}
59
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
60
if (env->virt_enabled) {
61
/* check VU/VS bit against current privilege level */
62
if ((ctrl >> 23) & BIT(env->priv)) {
63
+ env->badaddr = pc;
64
return true;
65
}
66
} else {
67
/* check U/S/M bit against current privilege level */
68
if ((ctrl >> 3) & BIT(env->priv)) {
69
+ env->badaddr = pc;
70
return true;
71
}
72
}
47
--
73
--
48
2.39.1
74
2.45.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
As it is now, riscv_compute_fdt_addr() is receiving a dram_base, a
3
Privileged spec section 4.1.9 mentions:
4
mem_size (which is defaulted to MachineState::ram_size in all boards)
5
and the FDT pointer. And it makes a very important assumption: the DRAM
6
interval dram_base + mem_size is contiguous. This is indeed the case for
7
most boards that use a FDT.
8
4
9
The Icicle Kit board works with 2 distinct RAM banks that are separated
5
"When a trap is taken into S-mode, stval is written with
10
by a gap. We have a lower bank with 1GiB size, a gap follows, then at
6
exception-specific information to assist software in handling the trap.
11
64GiB the high memory starts. MachineClass::default_ram_size for this
7
(...)
12
board is set to 1.5Gb, and machine_init() is enforcing it as minimal RAM
13
size, meaning that there we'll always have at least 512 MiB in the Hi
14
RAM area.
15
8
16
Using riscv_compute_fdt_addr() in this board is weird because not only
9
If stval is written with a nonzero value when a breakpoint,
17
the board has sparse RAM, and it's calling it using the base address of
10
address-misaligned, access-fault, or page-fault exception occurs on an
18
the Lo RAM area, but it's also using a mem_size that we have guarantees
11
instruction fetch, load, or store, then stval will contain the faulting
19
that it will go up to the Hi RAM. All the function assumptions doesn't
12
virtual address."
20
work for this board.
21
13
22
In fact, what makes the function works at all in this case is a
14
A similar text is found for mtval in section 3.1.16.
23
coincidence. Commit 1a475d39ef54 introduced a 3GB boundary for the FDT,
24
down from 4Gb, that is enforced if dram_base is lower than 3072 MiB. For
25
the Icicle Kit board, memmap[MICROCHIP_PFSOC_DRAM_LO].base is 0x80000000
26
(2 Gb) and it has a 1Gb size, so it will fall in the conditions to put
27
the FDT under a 3Gb address, which happens to be exactly at the end of
28
DRAM_LO. If the base address of the Lo area started later than 3Gb this
29
function would be unusable by the board. Changing any assumptions inside
30
riscv_compute_fdt_addr() can also break it by accident as well.
31
15
32
Let's change riscv_compute_fdt_addr() semantics to be appropriate to the
16
Setting mtval/stval in this scenario is optional, but some softwares read
33
Icicle Kit board and for future boards that might have sparse RAM
17
these regs when handling ebreaks.
34
topologies to worry about:
35
18
36
- relieve the condition that the dram_base + mem_size area is contiguous,
19
Write 'badaddr' in all ebreak breakpoints to write the appropriate
37
since this is already not the case today;
20
'tval' during riscv_do_cpu_interrrupt().
38
39
- receive an extra 'dram_size' size attribute that refers to a contiguous
40
RAM block that the board wants the FDT to reside on.
41
42
Together with 'mem_size' and 'fdt', which are now now being consumed by a
43
MachineState pointer, we're able to make clear assumptions based on the
44
DRAM block and total mem_size available to ensure that the FDT will be put
45
in a valid RAM address.
46
21
47
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
48
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
49
Message-Id: <20230201171212.1219375-4-dbarboza@ventanamicro.com>
24
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-ID: <20240416230437.1869024-3-dbarboza@ventanamicro.com>
50
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
51
---
28
---
52
include/hw/riscv/boot.h | 2 +-
29
target/riscv/insn_trans/trans_privileged.c.inc | 2 ++
53
hw/riscv/boot.c | 35 +++++++++++++++++++++++------------
30
1 file changed, 2 insertions(+)
54
hw/riscv/microchip_pfsoc.c | 3 ++-
55
hw/riscv/sifive_u.c | 3 ++-
56
hw/riscv/spike.c | 3 ++-
57
hw/riscv/virt.c | 3 ++-
58
6 files changed, 32 insertions(+), 17 deletions(-)
59
31
60
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
32
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
61
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
62
--- a/include/hw/riscv/boot.h
34
--- a/target/riscv/insn_trans/trans_privileged.c.inc
63
+++ b/include/hw/riscv/boot.h
35
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
64
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(MachineState *machine,
36
@@ -XXX,XX +XXX,XX @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
65
symbol_fn_t sym_cb);
37
if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) {
66
void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry);
38
generate_exception(ctx, RISCV_EXCP_SEMIHOST);
67
uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size,
39
} else {
68
- void *fdt);
40
+ tcg_gen_st_tl(tcg_constant_tl(ebreak_addr), tcg_env,
69
+ MachineState *ms);
41
+ offsetof(CPURISCVState, badaddr));
70
void riscv_load_fdt(hwaddr fdt_addr, void *fdt);
42
generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
71
void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts,
72
hwaddr saddr,
73
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/riscv/boot.c
76
+++ b/hw/riscv/boot.c
77
@@ -XXX,XX +XXX,XX @@ void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
78
}
79
80
/*
81
- * The FDT should be put at the farthest point possible to
82
- * avoid overwriting it with the kernel/initrd.
83
+ * This function makes an assumption that the DRAM interval
84
+ * 'dram_base' + 'dram_size' is contiguous.
85
*
86
- * This function makes an assumption that the DRAM is
87
- * contiguous. It also cares about 32-bit systems and
88
- * will limit fdt_addr to be addressable by them even for
89
- * 64-bit CPUs.
90
+ * Considering that 'dram_end' is the lowest value between
91
+ * the end of the DRAM block and MachineState->ram_size, the
92
+ * FDT location will vary according to 'dram_base':
93
+ *
94
+ * - if 'dram_base' is less that 3072 MiB, the FDT will be
95
+ * put at the lowest value between 3072 MiB and 'dram_end';
96
+ *
97
+ * - if 'dram_base' is higher than 3072 MiB, the FDT will be
98
+ * put at 'dram_end'.
99
*
100
* The FDT is fdt_packed() during the calculation.
101
*/
102
-uint64_t riscv_compute_fdt_addr(hwaddr dram_base, uint64_t mem_size,
103
- void *fdt)
104
+uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size,
105
+ MachineState *ms)
106
{
107
- uint64_t temp;
108
- hwaddr dram_end = dram_base + mem_size;
109
- int ret = fdt_pack(fdt);
110
+ int ret = fdt_pack(ms->fdt);
111
+ hwaddr dram_end, temp;
112
int fdtsize;
113
114
/* Should only fail if we've built a corrupted tree */
115
g_assert(ret == 0);
116
117
- fdtsize = fdt_totalsize(fdt);
118
+ fdtsize = fdt_totalsize(ms->fdt);
119
if (fdtsize <= 0) {
120
error_report("invalid device-tree");
121
exit(1);
122
}
43
}
123
44
return true;
124
+ /*
125
+ * A dram_size == 0, usually from a MemMapEntry[].size element,
126
+ * means that the DRAM block goes all the way to ms->ram_size.
127
+ */
128
+ dram_end = dram_base;
129
+ dram_end += dram_size ? MIN(ms->ram_size, dram_size) : ms->ram_size;
130
+
131
/*
132
* We should put fdt as far as possible to avoid kernel/initrd overwriting
133
* its content. But it should be addressable by 32 bit system as well.
134
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
135
index XXXXXXX..XXXXXXX 100644
136
--- a/hw/riscv/microchip_pfsoc.c
137
+++ b/hw/riscv/microchip_pfsoc.c
138
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
139
140
/* Compute the fdt load address in dram */
141
fdt_load_addr = riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base,
142
- machine->ram_size, machine->fdt);
143
+ memmap[MICROCHIP_PFSOC_DRAM_LO].size,
144
+ machine);
145
riscv_load_fdt(fdt_load_addr, machine->fdt);
146
147
/* Load the reset vector */
148
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/hw/riscv/sifive_u.c
151
+++ b/hw/riscv/sifive_u.c
152
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
153
}
154
155
fdt_load_addr = riscv_compute_fdt_addr(memmap[SIFIVE_U_DEV_DRAM].base,
156
- machine->ram_size, machine->fdt);
157
+ memmap[SIFIVE_U_DEV_DRAM].size,
158
+ machine);
159
riscv_load_fdt(fdt_load_addr, machine->fdt);
160
161
if (!riscv_is_32bit(&s->soc.u_cpus)) {
162
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
163
index XXXXXXX..XXXXXXX 100644
164
--- a/hw/riscv/spike.c
165
+++ b/hw/riscv/spike.c
166
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
167
}
168
169
fdt_load_addr = riscv_compute_fdt_addr(memmap[SPIKE_DRAM].base,
170
- machine->ram_size, machine->fdt);
171
+ memmap[SPIKE_DRAM].size,
172
+ machine);
173
riscv_load_fdt(fdt_load_addr, machine->fdt);
174
175
/* load the reset vector */
176
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
177
index XXXXXXX..XXXXXXX 100644
178
--- a/hw/riscv/virt.c
179
+++ b/hw/riscv/virt.c
180
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
181
}
182
183
fdt_load_addr = riscv_compute_fdt_addr(memmap[VIRT_DRAM].base,
184
- machine->ram_size, machine->fdt);
185
+ memmap[VIRT_DRAM].size,
186
+ machine);
187
riscv_load_fdt(fdt_load_addr, machine->fdt);
188
189
/* load the reset vector */
190
--
45
--
191
2.39.1
46
2.45.1
diff view generated by jsdifflib
1
From: Anup Patel <apatel@ventanamicro.com>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
The htimedelta[h] CSR has impact on the VS timer comparison so we
3
Add support for Zve32x extension and replace some checks for Zve32f with
4
should call riscv_timer_write_timecmp() whenever htimedelta changes.
4
Zve32x, since Zve32f depends on Zve32x.
5
5
6
Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
6
Signed-off-by: Jason Chien <jason.chien@sifive.com>
7
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Max Chou <max.chou@sifive.com>
9
Message-Id: <20230120125950.2246378-2-apatel@ventanamicro.com>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Message-ID: <20240328022343.6871-2-jason.chien@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
---
12
target/riscv/csr.c | 16 ++++++++++++++++
13
target/riscv/cpu_cfg.h | 1 +
13
1 file changed, 16 insertions(+)
14
target/riscv/cpu.c | 2 ++
15
target/riscv/cpu_helper.c | 2 +-
16
target/riscv/csr.c | 2 +-
17
target/riscv/tcg/tcg-cpu.c | 16 ++++++++--------
18
target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
19
6 files changed, 15 insertions(+), 12 deletions(-)
14
20
21
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu_cfg.h
24
+++ b/target/riscv/cpu_cfg.h
25
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
26
bool ext_zhinx;
27
bool ext_zhinxmin;
28
bool ext_zve32f;
29
+ bool ext_zve32x;
30
bool ext_zve64f;
31
bool ext_zve64d;
32
bool ext_zvbb;
33
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/riscv/cpu.c
36
+++ b/target/riscv/cpu.c
37
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
38
ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
39
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
40
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
41
+ ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
42
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
43
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
44
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
45
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
46
MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false),
47
MULTI_EXT_CFG_BOOL("zfhmin", ext_zfhmin, false),
48
MULTI_EXT_CFG_BOOL("zve32f", ext_zve32f, false),
49
+ MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
50
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
51
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
52
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
53
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/riscv/cpu_helper.c
56
+++ b/target/riscv/cpu_helper.c
57
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
58
*pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
59
*cs_base = 0;
60
61
- if (cpu->cfg.ext_zve32f) {
62
+ if (cpu->cfg.ext_zve32x) {
63
/*
64
* If env->vl equals to VLMAX, we can use generic vector operation
65
* expanders (GVEC) to accerlate the vector operations.
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
66
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
16
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/csr.c
68
--- a/target/riscv/csr.c
18
+++ b/target/riscv/csr.c
69
+++ b/target/riscv/csr.c
19
@@ -XXX,XX +XXX,XX @@ static RISCVException read_htimedelta(CPURISCVState *env, int csrno,
70
@@ -XXX,XX +XXX,XX @@ static RISCVException fs(CPURISCVState *env, int csrno)
20
static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
71
21
target_ulong val)
72
static RISCVException vs(CPURISCVState *env, int csrno)
22
{
73
{
23
+ RISCVCPU *cpu = env_archcpu(env);
74
- if (riscv_cpu_cfg(env)->ext_zve32f) {
24
+
75
+ if (riscv_cpu_cfg(env)->ext_zve32x) {
25
if (!env->rdtime_fn) {
76
#if !defined(CONFIG_USER_ONLY)
26
return RISCV_EXCP_ILLEGAL_INST;
77
if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
78
return RISCV_EXCP_ILLEGAL_INST;
79
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/riscv/tcg/tcg-cpu.c
82
+++ b/target/riscv/tcg/tcg-cpu.c
83
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
84
return;
27
}
85
}
28
@@ -XXX,XX +XXX,XX @@ static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
86
29
} else {
87
- if (cpu->cfg.ext_zve32f && !riscv_has_ext(env, RVF)) {
30
env->htimedelta = val;
88
- error_setg(errp, "Zve32f/Zve64f extensions require F extension");
89
- return;
90
+ /* The Zve32f extension depends on the Zve32x extension */
91
+ if (cpu->cfg.ext_zve32f) {
92
+ if (!riscv_has_ext(env, RVF)) {
93
+ error_setg(errp, "Zve32f/Zve64f extensions require F extension");
94
+ return;
95
+ }
96
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
31
}
97
}
32
+
98
33
+ if (cpu->cfg.ext_sstc && env->rdtime_fn) {
99
if (cpu->cfg.ext_zvfh) {
34
+ riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
100
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
35
+ env->htimedelta, MIP_VSTIP);
101
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zvbc), true);
36
+ }
102
}
37
+
103
38
return RISCV_EXCP_NONE;
104
- /*
39
}
105
- * In principle Zve*x would also suffice here, were they supported
40
106
- * in qemu
41
@@ -XXX,XX +XXX,XX @@ static RISCVException read_htimedeltah(CPURISCVState *env, int csrno,
107
- */
42
static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
108
if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkg ||
43
target_ulong val)
109
cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed ||
110
- cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
111
+ cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32x) {
112
error_setg(errp,
113
"Vector crypto extensions require V or Zve* extensions");
114
return;
115
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
116
index XXXXXXX..XXXXXXX 100644
117
--- a/target/riscv/insn_trans/trans_rvv.c.inc
118
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
119
@@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
44
{
120
{
45
+ RISCVCPU *cpu = env_archcpu(env);
121
TCGv s1, dst;
46
+
122
47
if (!env->rdtime_fn) {
123
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
48
return RISCV_EXCP_ILLEGAL_INST;
124
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
125
return false;
49
}
126
}
50
127
51
env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
128
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
52
+
129
{
53
+ if (cpu->cfg.ext_sstc && env->rdtime_fn) {
130
TCGv dst;
54
+ riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
131
55
+ env->htimedelta, MIP_VSTIP);
132
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
56
+ }
133
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
57
+
134
return false;
58
return RISCV_EXCP_NONE;
135
}
59
}
60
136
61
--
137
--
62
2.39.1
138
2.45.1
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
This patch adds the T-Head C906 to the list of known CPUs.
3
Add support for Zve64x extension. Enabling Zve64f enables Zve64x and
4
Selecting this CPUs will automatically enable the available
4
enabling Zve64x enables Zve32x according to their dependency.
5
ISA extensions of the CPUs (incl. vendor extensions).
6
5
7
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2107
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
9
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
10
Message-Id: <20230131202013.2541053-13-christoph.muellner@vrull.eu>
9
Reviewed-by: Max Chou <max.chou@sifive.com>
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Message-ID: <20240328022343.6871-3-jason.chien@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
---
13
target/riscv/cpu.h | 1 +
14
target/riscv/cpu_cfg.h | 1 +
14
target/riscv/cpu_vendorid.h | 6 ++++++
15
target/riscv/cpu.c | 2 ++
15
target/riscv/cpu.c | 31 +++++++++++++++++++++++++++++++
16
target/riscv/tcg/tcg-cpu.c | 17 +++++++++++------
16
3 files changed, 38 insertions(+)
17
3 files changed, 14 insertions(+), 6 deletions(-)
17
create mode 100644 target/riscv/cpu_vendorid.h
18
18
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
19
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.h
21
--- a/target/riscv/cpu_cfg.h
22
+++ b/target/riscv/cpu.h
22
+++ b/target/riscv/cpu_cfg.h
23
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
24
#define TYPE_RISCV_CPU_SIFIVE_E51 RISCV_CPU_TYPE_NAME("sifive-e51")
24
bool ext_zve32x;
25
#define TYPE_RISCV_CPU_SIFIVE_U34 RISCV_CPU_TYPE_NAME("sifive-u34")
25
bool ext_zve64f;
26
#define TYPE_RISCV_CPU_SIFIVE_U54 RISCV_CPU_TYPE_NAME("sifive-u54")
26
bool ext_zve64d;
27
+#define TYPE_RISCV_CPU_THEAD_C906 RISCV_CPU_TYPE_NAME("thead-c906")
27
+ bool ext_zve64x;
28
#define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host")
28
bool ext_zvbb;
29
29
bool ext_zvbc;
30
#if defined(TARGET_RISCV32)
30
bool ext_zvkb;
31
diff --git a/target/riscv/cpu_vendorid.h b/target/riscv/cpu_vendorid.h
32
new file mode 100644
33
index XXXXXXX..XXXXXXX
34
--- /dev/null
35
+++ b/target/riscv/cpu_vendorid.h
36
@@ -XXX,XX +XXX,XX @@
37
+#ifndef TARGET_RISCV_CPU_VENDORID_H
38
+#define TARGET_RISCV_CPU_VENDORID_H
39
+
40
+#define THEAD_VENDOR_ID 0x5b7
41
+
42
+#endif /* TARGET_RISCV_CPU_VENDORID_H */
43
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
44
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/cpu.c
33
--- a/target/riscv/cpu.c
46
+++ b/target/riscv/cpu.c
34
+++ b/target/riscv/cpu.c
47
@@ -XXX,XX +XXX,XX @@
35
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
48
#include "qemu/ctype.h"
36
ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
49
#include "qemu/log.h"
37
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
50
#include "cpu.h"
38
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
51
+#include "cpu_vendorid.h"
39
+ ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x),
52
#include "pmu.h"
40
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
53
#include "internals.h"
41
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
54
#include "time_helper.h"
42
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
55
@@ -XXX,XX +XXX,XX @@ static void rv64_sifive_e_cpu_init(Object *obj)
43
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
56
cpu->cfg.mmu = false;
44
MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
57
}
45
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
58
46
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
59
+static void rv64_thead_c906_cpu_init(Object *obj)
47
+ MULTI_EXT_CFG_BOOL("zve64x", ext_zve64x, false),
60
+{
48
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
61
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
49
MULTI_EXT_CFG_BOOL("zvfbfwma", ext_zvfbfwma, false),
62
+ RISCVCPU *cpu = RISCV_CPU(obj);
50
MULTI_EXT_CFG_BOOL("zvfh", ext_zvfh, false),
63
+
51
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
64
+ set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
52
index XXXXXXX..XXXXXXX 100644
65
+ set_priv_version(env, PRIV_VERSION_1_11_0);
53
--- a/target/riscv/tcg/tcg-cpu.c
66
+
54
+++ b/target/riscv/tcg/tcg-cpu.c
67
+ cpu->cfg.ext_g = true;
55
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
68
+ cpu->cfg.ext_c = true;
56
69
+ cpu->cfg.ext_u = true;
57
/* The Zve64d extension depends on the Zve64f extension */
70
+ cpu->cfg.ext_s = true;
58
if (cpu->cfg.ext_zve64d) {
71
+ cpu->cfg.ext_icsr = true;
59
+ if (!riscv_has_ext(env, RVD)) {
72
+ cpu->cfg.ext_zfh = true;
60
+ error_setg(errp, "Zve64d/V extensions require D extension");
73
+ cpu->cfg.mmu = true;
61
+ return;
74
+ cpu->cfg.ext_xtheadba = true;
62
+ }
75
+ cpu->cfg.ext_xtheadbb = true;
63
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64f), true);
76
+ cpu->cfg.ext_xtheadbs = true;
64
}
77
+ cpu->cfg.ext_xtheadcmo = true;
65
78
+ cpu->cfg.ext_xtheadcondmov = true;
66
- /* The Zve64f extension depends on the Zve32f extension */
79
+ cpu->cfg.ext_xtheadfmemidx = true;
67
+ /* The Zve64f extension depends on the Zve64x and Zve32f extensions */
80
+ cpu->cfg.ext_xtheadmac = true;
68
if (cpu->cfg.ext_zve64f) {
81
+ cpu->cfg.ext_xtheadmemidx = true;
69
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64x), true);
82
+ cpu->cfg.ext_xtheadmempair = true;
70
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32f), true);
83
+ cpu->cfg.ext_xtheadsync = true;
71
}
84
+
72
85
+ cpu->cfg.mvendorid = THEAD_VENDOR_ID;
73
- if (cpu->cfg.ext_zve64d && !riscv_has_ext(env, RVD)) {
86
+}
74
- error_setg(errp, "Zve64d/V extensions require D extension");
87
+
75
- return;
88
static void rv128_base_cpu_init(Object *obj)
76
+ /* The Zve64x extension depends on the Zve32x extension */
89
{
77
+ if (cpu->cfg.ext_zve64x) {
90
if (qemu_tcg_mttcg_enabled()) {
78
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
91
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
79
}
92
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init),
80
93
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init),
81
/* The Zve32f extension depends on the Zve32x extension */
94
DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
82
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
95
+ DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C906, rv64_thead_c906_cpu_init),
83
return;
96
DEFINE_CPU(TYPE_RISCV_CPU_BASE128, rv128_base_cpu_init),
84
}
97
#endif
85
98
};
86
- if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
87
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64x) {
88
error_setg(
89
errp,
90
- "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
91
+ "Zvbc and Zvknhb extensions require V or Zve64x extensions");
92
return;
93
}
94
99
--
95
--
100
2.39.1
96
2.45.1
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
The XThead* extensions are maintained by T-Head and VRULL.
3
In current implementation, the gdbstub allows reading vector registers
4
Adding a point of contact from both companies.
4
only if V extension is supported. However, all vector extensions and
5
vector crypto extensions have the vector registers and they all depend
6
on Zve32x. The gdbstub should check for Zve32x instead.
5
7
6
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
Signed-off-by: Jason Chien <jason.chien@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
10
Reviewed-by: Max Chou <max.chou@sifive.com>
9
Message-Id: <20230131202013.2541053-15-christoph.muellner@vrull.eu>
11
Message-ID: <20240328022343.6871-4-jason.chien@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
13
---
12
MAINTAINERS | 8 ++++++++
14
target/riscv/gdbstub.c | 2 +-
13
1 file changed, 8 insertions(+)
15
1 file changed, 1 insertion(+), 1 deletion(-)
14
16
15
diff --git a/MAINTAINERS b/MAINTAINERS
17
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/MAINTAINERS
19
--- a/target/riscv/gdbstub.c
18
+++ b/MAINTAINERS
20
+++ b/target/riscv/gdbstub.c
19
@@ -XXX,XX +XXX,XX @@ F: include/hw/riscv/
21
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
20
F: linux-user/host/riscv32/
22
gdb_find_static_feature("riscv-32bit-fpu.xml"),
21
F: linux-user/host/riscv64/
23
0);
22
24
}
23
+RISC-V XThead* extensions
25
- if (env->misa_ext & RVV) {
24
+M: Christoph Muellner <christoph.muellner@vrull.eu>
26
+ if (cpu->cfg.ext_zve32x) {
25
+M: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
27
gdb_register_coprocessor(cs, riscv_gdb_get_vector,
26
+L: qemu-riscv@nongnu.org
28
riscv_gdb_set_vector,
27
+S: Supported
29
ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs),
28
+F: target/riscv/insn_trans/trans_xthead.c.inc
29
+F: target/riscv/xthead*.decode
30
+
31
RISC-V XVentanaCondOps extension
32
M: Philipp Tomsich <philipp.tomsich@vrull.eu>
33
L: qemu-riscv@nongnu.org
34
--
30
--
35
2.39.1
31
2.45.1
diff view generated by jsdifflib
1
From: Vladimir Isaev <vladimir.isaev@syntacore.com>
1
From: Huang Tao <eric.huang@linux.alibaba.com>
2
2
3
According to spec, ctzw should work with 32-bit register, not 64.
3
In RVV and vcrypto instructions, the masked and tail elements are set to 1s
4
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
5
agnostic policy.
4
6
5
For example, previous implementation returns 33 for (1<<33) input
7
However, this function can't deal the big endian situation. This patch fixes
6
when the new one returns 32.
8
the problem by adding handling of such case.
7
9
8
Signed-off-by: Vladimir Isaev <vladimir.isaev@syntacore.com>
10
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
11
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-Id: <20230204082312.43557-1-vladimir.isaev@syntacore.com>
12
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20240325021654.6594-1-eric.huang@linux.alibaba.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
16
---
14
target/riscv/insn_trans/trans_rvb.c.inc | 1 +
17
target/riscv/vector_internals.c | 22 ++++++++++++++++++++++
15
1 file changed, 1 insertion(+)
18
1 file changed, 22 insertions(+)
16
19
17
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
20
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/insn_trans/trans_rvb.c.inc
22
--- a/target/riscv/vector_internals.c
20
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
23
+++ b/target/riscv/vector_internals.c
21
@@ -XXX,XX +XXX,XX @@ static bool trans_ctzw(DisasContext *ctx, arg_ctzw *a)
24
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
22
{
25
if (tot - cnt == 0) {
23
REQUIRE_64BIT(ctx);
26
return ;
24
REQUIRE_ZBB(ctx);
27
}
25
+ ctx->ol = MXL_RV32;
28
+
26
return gen_unary(ctx, a, EXT_ZERO, gen_ctzw);
29
+ if (HOST_BIG_ENDIAN) {
30
+ /*
31
+ * Deal the situation when the elements are insdie
32
+ * only one uint64 block including setting the
33
+ * masked-off element.
34
+ */
35
+ if (((tot - 1) ^ cnt) < 8) {
36
+ memset(base + H1(tot - 1), -1, tot - cnt);
37
+ return;
38
+ }
39
+ /*
40
+ * Otherwise, at least cross two uint64_t blocks.
41
+ * Set first unaligned block.
42
+ */
43
+ if (cnt % 8 != 0) {
44
+ uint32_t j = ROUND_UP(cnt, 8);
45
+ memset(base + H1(j - 1), -1, j - cnt);
46
+ cnt = j;
47
+ }
48
+ /* Set other 64bit aligend blocks */
49
+ }
50
memset(base + cnt, -1, tot - cnt);
27
}
51
}
28
52
29
--
53
--
30
2.39.1
54
2.45.1
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Yangyu Chen <cyy@cyyself.name>
2
2
3
There are no differences for floating point instructions in priv version 1.11
3
This code has a typo that writes zvkb to zvkg, causing users can't
4
and 1.12. There is also no dependency for Zfh to priv version 1.12.
4
enable zvkb through the config. This patch gets this fixed.
5
Therefore allow Zfh to be enabled for priv version 1.11.
6
5
7
Acked-by: Alistair Francis <alistair.francis@wdc.com>
6
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
8
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
7
Fixes: ea61ef7097d0 ("target/riscv: Move vector crypto extensions to riscv_cpu_extensions")
9
Message-Id: <20230131202013.2541053-12-christoph.muellner@vrull.eu>
8
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Max Chou <max.chou@sifive.com>
11
Reviewed-by:  Weiwei Li <liwei1518@gmail.com>
12
Message-ID: <tencent_7E34EEF0F90B9A68BF38BEE09EC6D4877C0A@qq.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
15
---
12
target/riscv/cpu.c | 2 +-
16
target/riscv/cpu.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
17
1 file changed, 1 insertion(+), 1 deletion(-)
14
18
15
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
19
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu.c
21
--- a/target/riscv/cpu.c
18
+++ b/target/riscv/cpu.c
22
+++ b/target/riscv/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
23
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
20
ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
24
/* Vector cryptography extensions */
21
ISA_EXT_DATA_ENTRY(zihintpause, true, PRIV_VERSION_1_10_0, ext_zihintpause),
25
MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false),
22
ISA_EXT_DATA_ENTRY(zawrs, true, PRIV_VERSION_1_12_0, ext_zawrs),
26
MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false),
23
- ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_12_0, ext_zfh),
27
- MULTI_EXT_CFG_BOOL("zvkb", ext_zvkg, false),
24
+ ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_11_0, ext_zfh),
28
+ MULTI_EXT_CFG_BOOL("zvkb", ext_zvkb, false),
25
ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
29
MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false),
26
ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
30
MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false),
27
ISA_EXT_DATA_ENTRY(zdinx, true, PRIV_VERSION_1_12_0, ext_zdinx),
31
MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false),
28
--
32
--
29
2.39.1
33
2.45.1
34
35
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Huang Tao <eric.huang@linux.alibaba.com>
2
2
3
This patch adds support for the XTheadFmv ISA extension.
3
In this patch, we modify the decoder to be a freely composable data
4
The patch uses the T-Head specific decoder and translation.
4
structure instead of a hardcoded one. It can be dynamically builded up
5
according to the extensions.
6
This approach has several benefits:
7
1. Provides support for heterogeneous cpu architectures. As we add decoder in
8
RISCVCPU, each cpu can have their own decoder, and the decoders can be
9
different due to cpu's features.
10
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
11
can be added to the dynamic_decoder when building up the decoder. Therefore,
12
there is no need to run the guard_func when decoding each instruction. It can
13
improve the decoding efficiency
14
3. For vendor or dynamic cpus, it allows them to customize their own decoder
15
functions to improve decoding efficiency, especially when vendor-defined
16
instruction sets increase. Because of dynamic building up, it can skip the other
17
decoder guard functions when decoding.
18
4. Pre patch for allowing adding a vendor decoder before decode_insn32() with minimal
19
overhead for users that don't need this particular vendor decoder.
5
20
6
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
21
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
22
Suggested-by: Christoph Muellner <christoph.muellner@vrull.eu>
23
Co-authored-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
25
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
26
Message-ID: <20240506023607.29544-1-eric.huang@linux.alibaba.com>
9
Message-Id: <20230131202013.2541053-14-christoph.muellner@vrull.eu>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
28
---
12
target/riscv/cpu.h | 1 +
29
target/riscv/cpu.h | 1 +
13
target/riscv/xthead.decode | 4 ++
30
target/riscv/tcg/tcg-cpu.h | 15 +++++++++++++++
14
target/riscv/cpu.c | 2 +
31
target/riscv/cpu.c | 1 +
15
target/riscv/translate.c | 6 +--
32
target/riscv/tcg/tcg-cpu.c | 15 +++++++++++++++
16
target/riscv/insn_trans/trans_xthead.c.inc | 45 ++++++++++++++++++++++
33
target/riscv/translate.c | 31 +++++++++++++++----------------
17
5 files changed, 55 insertions(+), 3 deletions(-)
34
5 files changed, 47 insertions(+), 16 deletions(-)
18
35
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
36
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
20
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.h
38
--- a/target/riscv/cpu.h
22
+++ b/target/riscv/cpu.h
39
+++ b/target/riscv/cpu.h
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
40
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
24
bool ext_xtheadcmo;
41
uint32_t pmu_avail_ctrs;
25
bool ext_xtheadcondmov;
42
/* Mapping of events to counters */
26
bool ext_xtheadfmemidx;
43
GHashTable *pmu_event_ctr_map;
27
+ bool ext_xtheadfmv;
44
+ const GPtrArray *decoders;
28
bool ext_xtheadmac;
45
};
29
bool ext_xtheadmemidx;
46
30
bool ext_xtheadmempair;
47
/**
31
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
48
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
32
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/xthead.decode
50
--- a/target/riscv/tcg/tcg-cpu.h
34
+++ b/target/riscv/xthead.decode
51
+++ b/target/riscv/tcg/tcg-cpu.h
35
@@ -XXX,XX +XXX,XX @@ th_fsrw 01000 .. ..... ..... 111 ..... 0001011 @th_memidx
52
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
36
th_fsurd 01110 .. ..... ..... 111 ..... 0001011 @th_memidx
53
void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
37
th_fsurw 01010 .. ..... ..... 111 ..... 0001011 @th_memidx
54
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
38
55
39
+# XTheadFmv
56
+struct DisasContext;
40
+th_fmv_hw_x 1010000 00000 ..... 001 ..... 0001011 @r2
57
+struct RISCVCPUConfig;
41
+th_fmv_x_hw 1100000 00000 ..... 001 ..... 0001011 @r2
58
+typedef struct RISCVDecoder {
59
+ bool (*guard_func)(const struct RISCVCPUConfig *);
60
+ bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
61
+} RISCVDecoder;
42
+
62
+
43
# XTheadMac
63
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
44
th_mula 00100 00 ..... ..... 001 ..... 0001011 @r
64
+
45
th_mulah 00101 00 ..... ..... 001 ..... 0001011 @r
65
+extern const size_t decoder_table_size;
66
+
67
+extern const RISCVDecoder decoder_table[];
68
+
69
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
70
+
71
#endif
46
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
72
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
47
index XXXXXXX..XXXXXXX 100644
73
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/cpu.c
74
--- a/target/riscv/cpu.c
49
+++ b/target/riscv/cpu.c
75
+++ b/target/riscv/cpu.c
50
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
76
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
51
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
77
error_propagate(errp, local_err);
52
ISA_EXT_DATA_ENTRY(xtheadcondmov, true, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
78
return;
53
ISA_EXT_DATA_ENTRY(xtheadfmemidx, true, PRIV_VERSION_1_11_0, ext_xtheadfmemidx),
79
}
54
+ ISA_EXT_DATA_ENTRY(xtheadfmv, true, PRIV_VERSION_1_11_0, ext_xtheadfmv),
80
+ riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
55
ISA_EXT_DATA_ENTRY(xtheadmac, true, PRIV_VERSION_1_11_0, ext_xtheadmac),
81
} else if (kvm_enabled()) {
56
ISA_EXT_DATA_ENTRY(xtheadmemidx, true, PRIV_VERSION_1_11_0, ext_xtheadmemidx),
82
riscv_kvm_cpu_finalize_features(cpu, &local_err);
57
ISA_EXT_DATA_ENTRY(xtheadmempair, true, PRIV_VERSION_1_11_0, ext_xtheadmempair),
83
if (local_err != NULL) {
58
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
84
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
59
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
85
index XXXXXXX..XXXXXXX 100644
60
DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
86
--- a/target/riscv/tcg/tcg-cpu.c
61
DEFINE_PROP_BOOL("xtheadfmemidx", RISCVCPU, cfg.ext_xtheadfmemidx, false),
87
+++ b/target/riscv/tcg/tcg-cpu.c
62
+ DEFINE_PROP_BOOL("xtheadfmv", RISCVCPU, cfg.ext_xtheadfmv, false),
88
@@ -XXX,XX +XXX,XX @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
63
DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false),
89
}
64
DEFINE_PROP_BOOL("xtheadmemidx", RISCVCPU, cfg.ext_xtheadmemidx, false),
90
}
65
DEFINE_PROP_BOOL("xtheadmempair", RISCVCPU, cfg.ext_xtheadmempair, false),
91
92
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
93
+{
94
+ GPtrArray *dynamic_decoders;
95
+ dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
96
+ for (size_t i = 0; i < decoder_table_size; ++i) {
97
+ if (decoder_table[i].guard_func &&
98
+ decoder_table[i].guard_func(&cpu->cfg)) {
99
+ g_ptr_array_add(dynamic_decoders,
100
+ (gpointer)decoder_table[i].riscv_cpu_decode_fn);
101
+ }
102
+ }
103
+
104
+ cpu->decoders = dynamic_decoders;
105
+}
106
+
107
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
108
{
109
return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
66
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
110
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
67
index XXXXXXX..XXXXXXX 100644
111
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/translate.c
112
--- a/target/riscv/translate.c
69
+++ b/target/riscv/translate.c
113
+++ b/target/riscv/translate.c
70
@@ -XXX,XX +XXX,XX @@ static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
114
@@ -XXX,XX +XXX,XX @@
71
return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
115
#include "exec/helper-info.c.inc"
72
ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
116
#undef HELPER_H
73
ctx->cfg_ptr->ext_xtheadcondmov ||
117
74
- ctx->cfg_ptr->ext_xtheadfmemidx || ctx->cfg_ptr->ext_xtheadmac ||
118
+#include "tcg/tcg-cpu.h"
75
- ctx->cfg_ptr->ext_xtheadmemidx || ctx->cfg_ptr->ext_xtheadmempair ||
119
+
76
- ctx->cfg_ptr->ext_xtheadsync;
120
/* global register indices */
77
+ ctx->cfg_ptr->ext_xtheadfmemidx || ctx->cfg_ptr->ext_xtheadfmv ||
121
static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
78
+ ctx->cfg_ptr->ext_xtheadmac || ctx->cfg_ptr->ext_xtheadmemidx ||
122
static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
79
+ ctx->cfg_ptr->ext_xtheadmempair || ctx->cfg_ptr->ext_xtheadsync;
123
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
124
/* FRM is known to contain a valid value. */
125
bool frm_valid;
126
bool insn_start_updated;
127
+ const GPtrArray *decoders;
128
} DisasContext;
129
130
static inline bool has_ext(DisasContext *ctx, uint32_t ext)
131
@@ -XXX,XX +XXX,XX @@ static inline int insn_len(uint16_t first_word)
132
return (first_word & 3) == 3 ? 4 : 2;
80
}
133
}
81
134
82
#define MATERIALISE_EXT_PREDICATE(ext) \
135
+const RISCVDecoder decoder_table[] = {
83
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
136
+ { always_true_p, decode_insn32 },
84
index XXXXXXX..XXXXXXX 100644
137
+ { has_xthead_p, decode_xthead},
85
--- a/target/riscv/insn_trans/trans_xthead.c.inc
138
+ { has_XVentanaCondOps_p, decode_XVentanaCodeOps},
86
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
139
+};
87
@@ -XXX,XX +XXX,XX @@
88
} \
89
} while (0)
90
91
+#define REQUIRE_XTHEADFMV(ctx) do { \
92
+ if (!ctx->cfg_ptr->ext_xtheadfmv) { \
93
+ return false; \
94
+ } \
95
+} while (0)
96
+
140
+
97
#define REQUIRE_XTHEADMAC(ctx) do { \
141
+const size_t decoder_table_size = ARRAY_SIZE(decoder_table);
98
if (!ctx->cfg_ptr->ext_xtheadmac) { \
142
+
99
return false; \
143
static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
100
@@ -XXX,XX +XXX,XX @@ static bool trans_th_fsurw(DisasContext *ctx, arg_th_memidx *a)
144
{
101
return gen_fstore_idx(ctx, a, MO_TEUL, true);
145
- /*
146
- * A table with predicate (i.e., guard) functions and decoder functions
147
- * that are tested in-order until a decoder matches onto the opcode.
148
- */
149
- static const struct {
150
- bool (*guard_func)(const RISCVCPUConfig *);
151
- bool (*decode_func)(DisasContext *, uint32_t);
152
- } decoders[] = {
153
- { always_true_p, decode_insn32 },
154
- { has_xthead_p, decode_xthead },
155
- { has_XVentanaCondOps_p, decode_XVentanaCodeOps },
156
- };
157
-
158
ctx->virt_inst_excp = false;
159
ctx->cur_insn_len = insn_len(opcode);
160
/* Check for compressed insn */
161
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
162
ctx->base.pc_next + 2));
163
ctx->opcode = opcode32;
164
165
- for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) {
166
- if (decoders[i].guard_func(ctx->cfg_ptr) &&
167
- decoders[i].decode_func(ctx, opcode32)) {
168
+ for (guint i = 0; i < ctx->decoders->len; ++i) {
169
+ riscv_cpu_decode_fn func = g_ptr_array_index(ctx->decoders, i);
170
+ if (func(ctx, opcode32)) {
171
return;
172
}
173
}
174
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
175
ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
176
ctx->zero = tcg_constant_tl(0);
177
ctx->virt_inst_excp = false;
178
+ ctx->decoders = cpu->decoders;
102
}
179
}
103
180
104
+/* XTheadFmv */
181
static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
105
+
106
+static bool trans_th_fmv_hw_x(DisasContext *ctx, arg_th_fmv_hw_x *a)
107
+{
108
+ REQUIRE_XTHEADFMV(ctx);
109
+ REQUIRE_32BIT(ctx);
110
+ REQUIRE_FPU;
111
+ REQUIRE_EXT(ctx, RVD);
112
+
113
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
114
+ TCGv_i64 t1 = tcg_temp_new_i64();
115
+
116
+ tcg_gen_extu_tl_i64(t1, src1);
117
+ tcg_gen_deposit_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], t1, 32, 32);
118
+ tcg_temp_free_i64(t1);
119
+ mark_fs_dirty(ctx);
120
+ return true;
121
+}
122
+
123
+static bool trans_th_fmv_x_hw(DisasContext *ctx, arg_th_fmv_x_hw *a)
124
+{
125
+ REQUIRE_XTHEADFMV(ctx);
126
+ REQUIRE_32BIT(ctx);
127
+ REQUIRE_FPU;
128
+ REQUIRE_EXT(ctx, RVD);
129
+ TCGv dst;
130
+ TCGv_i64 t1;
131
+
132
+ dst = dest_gpr(ctx, a->rd);
133
+ t1 = tcg_temp_new_i64();
134
+
135
+ tcg_gen_extract_i64(t1, cpu_fpr[a->rs1], 32, 32);
136
+ tcg_gen_trunc_i64_tl(dst, t1);
137
+ gen_set_gpr(ctx, a->rd, dst);
138
+ tcg_temp_free_i64(t1);
139
+ mark_fs_dirty(ctx);
140
+ return true;
141
+}
142
+
143
/* XTheadMac */
144
145
static bool gen_th_mac(DisasContext *ctx, arg_r *a,
146
--
182
--
147
2.39.1
183
2.45.1
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
2
2
3
This patch adds support for the XTheadCmo ISA extension.
3
The th.sxstatus CSR can be used to identify available custom extension
4
To avoid interfering with standard extensions, decoder and translation
4
on T-Head CPUs. The CSR is documented here:
5
are in its own xthead* specific files.
5
https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadsxstatus.adoc
6
Future patches should be able to easily add additional T-Head extension.
7
6
8
The implementation does not have much functionality (besides accepting
7
An important property of this patch is, that the th.sxstatus MAEE field
9
the instructions and not qualifying them as illegal instructions if
8
is not set (indicating that XTheadMae is not available).
10
the hart executes in the required privilege level for the instruction),
9
XTheadMae is a memory attribute extension (similar to Svpbmt) which is
11
as QEMU does not model CPU caches and instructions are documented
10
implemented in many T-Head CPUs (C906, C910, etc.) and utilizes bits
12
to not raise any exceptions.
11
in PTEs that are marked as reserved. QEMU maintainers prefer to not
12
implement XTheadMae, so we need give kernels a mechanism to identify
13
if XTheadMae is available in a system or not. And this patch introduces
14
this mechanism in QEMU in a way that's compatible with real HW
15
(i.e., probing the th.sxstatus.MAEE bit).
13
16
14
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
17
Further context can be found on the list:
18
https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg00775.html
19
20
Reviewed-by: LIU Zhiwei <zhiwe_liu@linux.alibaba.com>
21
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
22
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Message-ID: <20240429073656.2486732-1-christoph.muellner@vrull.eu>
17
Message-Id: <20230131202013.2541053-2-christoph.muellner@vrull.eu>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
25
---
20
target/riscv/cpu.h | 1 +
26
MAINTAINERS | 1 +
21
target/riscv/xthead.decode | 38 ++++++++++
27
target/riscv/cpu.h | 3 ++
22
target/riscv/cpu.c | 2 +
28
target/riscv/cpu.c | 1 +
23
target/riscv/translate.c | 8 +++
29
target/riscv/th_csr.c | 79 ++++++++++++++++++++++++++++++++++++++++
24
target/riscv/insn_trans/trans_xthead.c.inc | 81 ++++++++++++++++++++++
30
target/riscv/meson.build | 1 +
25
target/riscv/meson.build | 1 +
31
5 files changed, 85 insertions(+)
26
6 files changed, 131 insertions(+)
32
create mode 100644 target/riscv/th_csr.c
27
create mode 100644 target/riscv/xthead.decode
28
create mode 100644 target/riscv/insn_trans/trans_xthead.c.inc
29
33
34
diff --git a/MAINTAINERS b/MAINTAINERS
35
index XXXXXXX..XXXXXXX 100644
36
--- a/MAINTAINERS
37
+++ b/MAINTAINERS
38
@@ -XXX,XX +XXX,XX @@ L: qemu-riscv@nongnu.org
39
S: Supported
40
F: target/riscv/insn_trans/trans_xthead.c.inc
41
F: target/riscv/xthead*.decode
42
+F: target/riscv/th_*
43
F: disas/riscv-xthead*
44
45
RISC-V XVentanaCondOps extension
30
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
46
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
31
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
32
--- a/target/riscv/cpu.h
48
--- a/target/riscv/cpu.h
33
+++ b/target/riscv/cpu.h
49
+++ b/target/riscv/cpu.h
34
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
50
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_new_csr_seed(target_ulong new_value,
35
uint64_t mimpid;
51
uint8_t satp_mode_max_from_map(uint32_t map);
36
52
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
37
/* Vendor-specific custom extensions */
53
38
+ bool ext_xtheadcmo;
54
+/* Implemented in th_csr.c */
39
bool ext_XVentanaCondOps;
55
+void th_register_custom_csrs(RISCVCPU *cpu);
40
41
uint8_t pmu_num;
42
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
43
new file mode 100644
44
index XXXXXXX..XXXXXXX
45
--- /dev/null
46
+++ b/target/riscv/xthead.decode
47
@@ -XXX,XX +XXX,XX @@
48
+#
49
+# Translation routines for the instructions of the XThead* ISA extensions
50
+#
51
+# Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.eu
52
+#
53
+# SPDX-License-Identifier: LGPL-2.1-or-later
54
+#
55
+# The documentation of the ISA extensions can be found here:
56
+# https://github.com/T-head-Semi/thead-extension-spec/releases/latest
57
+
56
+
58
+# Fields:
57
#endif /* RISCV_CPU_H */
59
+%rs1 15:5
60
+
61
+# Formats
62
+@sfence_vm ....... ..... ..... ... ..... ....... %rs1
63
+
64
+# XTheadCmo
65
+th_dcache_call 0000000 00001 00000 000 00000 0001011
66
+th_dcache_ciall 0000000 00011 00000 000 00000 0001011
67
+th_dcache_iall 0000000 00010 00000 000 00000 0001011
68
+th_dcache_cpa 0000001 01001 ..... 000 00000 0001011 @sfence_vm
69
+th_dcache_cipa 0000001 01011 ..... 000 00000 0001011 @sfence_vm
70
+th_dcache_ipa 0000001 01010 ..... 000 00000 0001011 @sfence_vm
71
+th_dcache_cva 0000001 00101 ..... 000 00000 0001011 @sfence_vm
72
+th_dcache_civa 0000001 00111 ..... 000 00000 0001011 @sfence_vm
73
+th_dcache_iva 0000001 00110 ..... 000 00000 0001011 @sfence_vm
74
+th_dcache_csw 0000001 00001 ..... 000 00000 0001011 @sfence_vm
75
+th_dcache_cisw 0000001 00011 ..... 000 00000 0001011 @sfence_vm
76
+th_dcache_isw 0000001 00010 ..... 000 00000 0001011 @sfence_vm
77
+th_dcache_cpal1 0000001 01000 ..... 000 00000 0001011 @sfence_vm
78
+th_dcache_cval1 0000001 00100 ..... 000 00000 0001011 @sfence_vm
79
+th_icache_iall 0000000 10000 00000 000 00000 0001011
80
+th_icache_ialls 0000000 10001 00000 000 00000 0001011
81
+th_icache_ipa 0000001 11000 ..... 000 00000 0001011 @sfence_vm
82
+th_icache_iva 0000001 10000 ..... 000 00000 0001011 @sfence_vm
83
+th_l2cache_call 0000000 10101 00000 000 00000 0001011
84
+th_l2cache_ciall 0000000 10111 00000 000 00000 0001011
85
+th_l2cache_iall 0000000 10110 00000 000 00000 0001011
86
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
58
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
87
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
88
--- a/target/riscv/cpu.c
60
--- a/target/riscv/cpu.c
89
+++ b/target/riscv/cpu.c
61
+++ b/target/riscv/cpu.c
90
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
62
@@ -XXX,XX +XXX,XX @@ static void rv64_thead_c906_cpu_init(Object *obj)
91
ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
63
cpu->cfg.mvendorid = THEAD_VENDOR_ID;
92
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
64
#ifndef CONFIG_USER_ONLY
93
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
65
set_satp_mode_max_supported(cpu, VM_1_10_SV39);
94
+ ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
66
+ th_register_custom_csrs(cpu);
95
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
67
#endif
96
};
68
97
69
/* inherited from parent obj via riscv_cpu_init() */
98
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
70
diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
99
DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false),
100
101
/* Vendor-specific custom extensions */
102
+ DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
103
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
104
105
/* These are experimental so mark with 'x-' */
106
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/riscv/translate.c
109
+++ b/target/riscv/translate.c
110
@@ -XXX,XX +XXX,XX @@ static bool always_true_p(DisasContext *ctx __attribute__((__unused__)))
111
return true;
112
}
113
114
+static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
115
+{
116
+ return ctx->cfg_ptr->ext_xtheadcmo;
117
+}
118
+
119
#define MATERIALISE_EXT_PREDICATE(ext) \
120
static bool has_ ## ext ## _p(DisasContext *ctx) \
121
{ \
122
@@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
123
#include "insn_trans/trans_rvk.c.inc"
124
#include "insn_trans/trans_privileged.c.inc"
125
#include "insn_trans/trans_svinval.c.inc"
126
+#include "decode-xthead.c.inc"
127
+#include "insn_trans/trans_xthead.c.inc"
128
#include "insn_trans/trans_xventanacondops.c.inc"
129
130
/* Include the auto-generated decoder for 16 bit insn */
131
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
132
bool (*decode_func)(DisasContext *, uint32_t);
133
} decoders[] = {
134
{ always_true_p, decode_insn32 },
135
+ { has_xthead_p, decode_xthead },
136
{ has_XVentanaCondOps_p, decode_XVentanaCodeOps },
137
};
138
139
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
140
new file mode 100644
71
new file mode 100644
141
index XXXXXXX..XXXXXXX
72
index XXXXXXX..XXXXXXX
142
--- /dev/null
73
--- /dev/null
143
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
74
+++ b/target/riscv/th_csr.c
144
@@ -XXX,XX +XXX,XX @@
75
@@ -XXX,XX +XXX,XX @@
145
+/*
76
+/*
146
+ * RISC-V translation routines for the T-Head vendor extensions (xthead*).
77
+ * T-Head-specific CSRs.
147
+ *
78
+ *
148
+ * Copyright (c) 2022 VRULL GmbH.
79
+ * Copyright (c) 2024 VRULL GmbH
149
+ *
80
+ *
150
+ * This program is free software; you can redistribute it and/or modify it
81
+ * This program is free software; you can redistribute it and/or modify it
151
+ * under the terms and conditions of the GNU General Public License,
82
+ * under the terms and conditions of the GNU General Public License,
152
+ * version 2 or later, as published by the Free Software Foundation.
83
+ * version 2 or later, as published by the Free Software Foundation.
153
+ *
84
+ *
...
...
158
+ *
89
+ *
159
+ * You should have received a copy of the GNU General Public License along with
90
+ * You should have received a copy of the GNU General Public License along with
160
+ * this program. If not, see <http://www.gnu.org/licenses/>.
91
+ * this program. If not, see <http://www.gnu.org/licenses/>.
161
+ */
92
+ */
162
+
93
+
163
+#define REQUIRE_XTHEADCMO(ctx) do { \
94
+#include "qemu/osdep.h"
164
+ if (!ctx->cfg_ptr->ext_xtheadcmo) { \
95
+#include "cpu.h"
165
+ return false; \
96
+#include "cpu_vendorid.h"
166
+ } \
167
+} while (0)
168
+
97
+
169
+/* XTheadCmo */
98
+#define CSR_TH_SXSTATUS 0x5c0
170
+
99
+
171
+static inline int priv_level(DisasContext *ctx)
100
+/* TH_SXSTATUS bits */
101
+#define TH_SXSTATUS_UCME BIT(16)
102
+#define TH_SXSTATUS_MAEE BIT(21)
103
+#define TH_SXSTATUS_THEADISAEE BIT(22)
104
+
105
+typedef struct {
106
+ int csrno;
107
+ int (*insertion_test)(RISCVCPU *cpu);
108
+ riscv_csr_operations csr_ops;
109
+} riscv_csr;
110
+
111
+static RISCVException smode(CPURISCVState *env, int csrno)
172
+{
112
+{
173
+#ifdef CONFIG_USER_ONLY
113
+ if (riscv_has_ext(env, RVS)) {
174
+ return PRV_U;
114
+ return RISCV_EXCP_NONE;
175
+#else
115
+ }
176
+ /* Priv level is part of mem_idx. */
116
+
177
+ return ctx->mem_idx & TB_FLAGS_PRIV_MMU_MASK;
117
+ return RISCV_EXCP_ILLEGAL_INST;
178
+#endif
179
+}
118
+}
180
+
119
+
181
+/* Test if priv level is M, S, or U (cannot fail). */
120
+static int test_thead_mvendorid(RISCVCPU *cpu)
182
+#define REQUIRE_PRIV_MSU(ctx)
121
+{
122
+ if (cpu->cfg.mvendorid != THEAD_VENDOR_ID) {
123
+ return -1;
124
+ }
183
+
125
+
184
+/* Test if priv level is M or S. */
126
+ return 0;
185
+#define REQUIRE_PRIV_MS(ctx) \
186
+do { \
187
+ int priv = priv_level(ctx); \
188
+ if (!(priv == PRV_M || \
189
+ priv == PRV_S)) { \
190
+ return false; \
191
+ } \
192
+} while (0)
193
+
194
+#define NOP_PRIVCHECK(insn, extcheck, privcheck) \
195
+static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn * a) \
196
+{ \
197
+ (void) a; \
198
+ extcheck(ctx); \
199
+ privcheck(ctx); \
200
+ return true; \
201
+}
127
+}
202
+
128
+
203
+NOP_PRIVCHECK(th_dcache_call, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
129
+static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
204
+NOP_PRIVCHECK(th_dcache_ciall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
130
+ target_ulong *val)
205
+NOP_PRIVCHECK(th_dcache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
131
+{
206
+NOP_PRIVCHECK(th_dcache_cpa, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
132
+ /* We don't set MAEE here, because QEMU does not implement MAEE. */
207
+NOP_PRIVCHECK(th_dcache_cipa, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
133
+ *val = TH_SXSTATUS_UCME | TH_SXSTATUS_THEADISAEE;
208
+NOP_PRIVCHECK(th_dcache_ipa, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
134
+ return RISCV_EXCP_NONE;
209
+NOP_PRIVCHECK(th_dcache_cva, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
135
+}
210
+NOP_PRIVCHECK(th_dcache_civa, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
211
+NOP_PRIVCHECK(th_dcache_iva, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
212
+NOP_PRIVCHECK(th_dcache_csw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
213
+NOP_PRIVCHECK(th_dcache_cisw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
214
+NOP_PRIVCHECK(th_dcache_isw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
215
+NOP_PRIVCHECK(th_dcache_cpal1, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
216
+NOP_PRIVCHECK(th_dcache_cval1, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
217
+
136
+
218
+NOP_PRIVCHECK(th_icache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
137
+static riscv_csr th_csr_list[] = {
219
+NOP_PRIVCHECK(th_icache_ialls, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
138
+ {
220
+NOP_PRIVCHECK(th_icache_ipa, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
139
+ .csrno = CSR_TH_SXSTATUS,
221
+NOP_PRIVCHECK(th_icache_iva, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
140
+ .insertion_test = test_thead_mvendorid,
141
+ .csr_ops = { "th.sxstatus", smode, read_th_sxstatus }
142
+ }
143
+};
222
+
144
+
223
+NOP_PRIVCHECK(th_l2cache_call, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
145
+void th_register_custom_csrs(RISCVCPU *cpu)
224
+NOP_PRIVCHECK(th_l2cache_ciall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
146
+{
225
+NOP_PRIVCHECK(th_l2cache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
147
+ for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
148
+ int csrno = th_csr_list[i].csrno;
149
+ riscv_csr_operations *csr_ops = &th_csr_list[i].csr_ops;
150
+ if (!th_csr_list[i].insertion_test(cpu)) {
151
+ riscv_set_csr_ops(csrno, csr_ops);
152
+ }
153
+ }
154
+}
226
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
155
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
227
index XXXXXXX..XXXXXXX 100644
156
index XXXXXXX..XXXXXXX 100644
228
--- a/target/riscv/meson.build
157
--- a/target/riscv/meson.build
229
+++ b/target/riscv/meson.build
158
+++ b/target/riscv/meson.build
230
@@ -XXX,XX +XXX,XX @@
159
@@ -XXX,XX +XXX,XX @@ riscv_system_ss.add(files(
231
gen = [
160
'monitor.c',
232
decodetree.process('insn16.decode', extra_args: ['--static-decode=decode_insn16', '--insnwidth=16']),
161
'machine.c',
233
decodetree.process('insn32.decode', extra_args: '--static-decode=decode_insn32'),
162
'pmu.c',
234
+ decodetree.process('xthead.decode', extra_args: '--static-decode=decode_xthead'),
163
+ 'th_csr.c',
235
decodetree.process('XVentanaCondOps.decode', extra_args: '--static-decode=decode_XVentanaCodeOps'),
164
'time_helper.c',
236
]
165
'riscv-qmp-cmds.c',
237
166
))
238
--
167
--
239
2.39.1
168
2.45.1
169
170
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
This patch adds support for the T-Head MemPair instructions.
3
According v spec 18.4, only the vfwcvt.f.f.v and vfncvt.f.f.w
4
The patch uses the T-Head specific decoder and translation.
4
instructions will be affected by Zvfhmin extension.
5
And the vfwcvt.f.f.v and vfncvt.f.f.w instructions only support the
6
conversions of
5
7
6
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
* From 1*SEW(16/32) to 2*SEW(32/64)
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
* From 2*SEW(32/64) to 1*SEW(16/32)
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
9
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
10
Message-Id: <20230131202013.2541053-9-christoph.muellner@vrull.eu>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20240322092600.1198921-2-max.chou@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
16
---
13
target/riscv/cpu.h | 1 +
17
target/riscv/insn_trans/trans_rvv.c.inc | 20 ++++++++++++++++++--
14
target/riscv/xthead.decode | 13 +++
18
1 file changed, 18 insertions(+), 2 deletions(-)
15
target/riscv/cpu.c | 2 +
16
target/riscv/translate.c | 2 +-
17
target/riscv/insn_trans/trans_xthead.c.inc | 92 ++++++++++++++++++++++
18
5 files changed, 109 insertions(+), 1 deletion(-)
19
19
20
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
21
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/cpu.h
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
23
+++ b/target/riscv/cpu.h
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
24
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
24
@@ -XXX,XX +XXX,XX @@ static bool require_rvf(DisasContext *s)
25
bool ext_xtheadcmo;
25
}
26
bool ext_xtheadcondmov;
27
bool ext_xtheadmac;
28
+ bool ext_xtheadmempair;
29
bool ext_xtheadsync;
30
bool ext_XVentanaCondOps;
31
32
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/xthead.decode
35
+++ b/target/riscv/xthead.decode
36
@@ -XXX,XX +XXX,XX @@
37
38
# Fields:
39
%rd 7:5
40
+%rd1 7:5
41
+%rs 15:5
42
%rs1 15:5
43
+%rd2 20:5
44
%rs2 20:5
45
%sh5 20:5
46
%sh6 20:6
47
+%sh2 25:2
48
49
# Argument sets
50
&r rd rs1 rs2 !extern
51
&r2 rd rs1 !extern
52
&shift shamt rs1 rd !extern
53
&th_bfext msb lsb rs1 rd
54
+&th_pair rd1 rs rd2 sh2
55
56
# Formats
57
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
58
@@ -XXX,XX +XXX,XX @@
59
@th_bfext msb:6 lsb:6 ..... ... ..... ....... &th_bfext %rs1 %rd
60
@sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd
61
@sh6 ...... ...... ..... ... ..... ....... &shift shamt=%sh6 %rs1 %rd
62
+@th_pair ..... .. ..... ..... ... ..... ....... &th_pair %rd1 %rs %rd2 %sh2
63
64
# XTheadBa
65
# Instead of defining a new encoding, we simply use the decoder to
66
@@ -XXX,XX +XXX,XX @@ th_muls 00100 01 ..... ..... 001 ..... 0001011 @r
67
th_mulsh 00101 01 ..... ..... 001 ..... 0001011 @r
68
th_mulsw 00100 11 ..... ..... 001 ..... 0001011 @r
69
70
+# XTheadMemPair
71
+th_ldd 11111 .. ..... ..... 100 ..... 0001011 @th_pair
72
+th_lwd 11100 .. ..... ..... 100 ..... 0001011 @th_pair
73
+th_lwud 11110 .. ..... ..... 100 ..... 0001011 @th_pair
74
+th_sdd 11111 .. ..... ..... 101 ..... 0001011 @th_pair
75
+th_swd 11100 .. ..... ..... 101 ..... 0001011 @th_pair
76
+
77
# XTheadSync
78
th_sfence_vmas 0000010 ..... ..... 000 00000 0001011 @rs2_s
79
th_sync 0000000 11000 00000 000 00000 0001011
80
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/riscv/cpu.c
83
+++ b/target/riscv/cpu.c
84
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
85
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
86
ISA_EXT_DATA_ENTRY(xtheadcondmov, true, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
87
ISA_EXT_DATA_ENTRY(xtheadmac, true, PRIV_VERSION_1_11_0, ext_xtheadmac),
88
+ ISA_EXT_DATA_ENTRY(xtheadmempair, true, PRIV_VERSION_1_11_0, ext_xtheadmempair),
89
ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
90
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
91
};
92
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
93
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
94
DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
95
DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false),
96
+ DEFINE_PROP_BOOL("xtheadmempair", RISCVCPU, cfg.ext_xtheadmempair, false),
97
DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
98
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
99
100
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/riscv/translate.c
103
+++ b/target/riscv/translate.c
104
@@ -XXX,XX +XXX,XX @@ static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
105
return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
106
ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
107
ctx->cfg_ptr->ext_xtheadcondmov || ctx->cfg_ptr->ext_xtheadmac ||
108
- ctx->cfg_ptr->ext_xtheadsync;
109
+ ctx->cfg_ptr->ext_xtheadmempair || ctx->cfg_ptr->ext_xtheadsync;
110
}
26
}
111
27
112
#define MATERIALISE_EXT_PREDICATE(ext) \
28
+static bool require_rvfmin(DisasContext *s)
113
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/riscv/insn_trans/trans_xthead.c.inc
116
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
117
@@ -XXX,XX +XXX,XX @@
118
} \
119
} while (0)
120
121
+#define REQUIRE_XTHEADMEMPAIR(ctx) do { \
122
+ if (!ctx->cfg_ptr->ext_xtheadmempair) { \
123
+ return false; \
124
+ } \
125
+} while (0)
126
+
127
#define REQUIRE_XTHEADSYNC(ctx) do { \
128
if (!ctx->cfg_ptr->ext_xtheadsync) { \
129
return false; \
130
@@ -XXX,XX +XXX,XX @@ static bool trans_th_mulsw(DisasContext *ctx, arg_th_mulsw *a)
131
return gen_th_mac(ctx, a, tcg_gen_sub_tl, NULL);
132
}
133
134
+/* XTheadMemPair */
135
+
136
+static bool gen_loadpair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop,
137
+ int shamt)
138
+{
29
+{
139
+ if (a->rs == a->rd1 || a->rs == a->rd2 || a->rd1 == a->rd2) {
30
+ if (s->mstatus_fs == EXT_STATUS_DISABLED) {
140
+ return false;
31
+ return false;
141
+ }
32
+ }
142
+
33
+
143
+ TCGv t1 = tcg_temp_new();
34
+ switch (s->sew) {
144
+ TCGv t2 = tcg_temp_new();
35
+ case MO_16:
145
+ TCGv addr1 = tcg_temp_new();
36
+ return s->cfg_ptr->ext_zvfhmin;
146
+ TCGv addr2 = tcg_temp_new();
37
+ case MO_32:
147
+ int imm = a->sh2 << shamt;
38
+ return s->cfg_ptr->ext_zve32f;
148
+
39
+ default:
149
+ addr1 = get_address(ctx, a->rs, imm);
40
+ return false;
150
+ addr2 = get_address(ctx, a->rs, memop_size(memop) + imm);
41
+ }
151
+
152
+ tcg_gen_qemu_ld_tl(t1, addr1, ctx->mem_idx, memop);
153
+ tcg_gen_qemu_ld_tl(t2, addr2, ctx->mem_idx, memop);
154
+ gen_set_gpr(ctx, a->rd1, t1);
155
+ gen_set_gpr(ctx, a->rd2, t2);
156
+
157
+ tcg_temp_free(t1);
158
+ tcg_temp_free(t2);
159
+ tcg_temp_free(addr1);
160
+ tcg_temp_free(addr2);
161
+ return true;
162
+}
42
+}
163
+
43
+
164
+static bool trans_th_ldd(DisasContext *ctx, arg_th_pair *a)
44
static bool require_scale_rvf(DisasContext *s)
165
+{
45
{
166
+ REQUIRE_XTHEADMEMPAIR(ctx);
46
if (s->mstatus_fs == EXT_STATUS_DISABLED) {
167
+ REQUIRE_64BIT(ctx);
47
@@ -XXX,XX +XXX,XX @@ static bool require_scale_rvfmin(DisasContext *s)
168
+ return gen_loadpair_tl(ctx, a, MO_TESQ, 4);
48
}
169
+}
49
170
+
50
switch (s->sew) {
171
+static bool trans_th_lwd(DisasContext *ctx, arg_th_pair *a)
51
- case MO_8:
172
+{
52
- return s->cfg_ptr->ext_zvfhmin;
173
+ REQUIRE_XTHEADMEMPAIR(ctx);
53
case MO_16:
174
+ return gen_loadpair_tl(ctx, a, MO_TESL, 3);
54
return s->cfg_ptr->ext_zve32f;
175
+}
55
case MO_32:
176
+
56
@@ -XXX,XX +XXX,XX @@ static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
177
+static bool trans_th_lwud(DisasContext *ctx, arg_th_pair *a)
57
static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
178
+{
58
{
179
+ REQUIRE_XTHEADMEMPAIR(ctx);
59
return opfv_widen_check(s, a) &&
180
+ return gen_loadpair_tl(ctx, a, MO_TEUL, 3);
60
+ require_rvfmin(s) &&
181
+}
61
require_scale_rvfmin(s) &&
182
+
62
(s->sew != MO_8);
183
+static bool gen_storepair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop,
63
}
184
+ int shamt)
64
@@ -XXX,XX +XXX,XX @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
185
+{
65
static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
186
+ if (a->rs == a->rd1 || a->rs == a->rd2 || a->rd1 == a->rd2) {
66
{
187
+ return false;
67
return opfv_narrow_check(s, a) &&
188
+ }
68
+ require_rvfmin(s) &&
189
+
69
require_scale_rvfmin(s) &&
190
+ TCGv data1 = get_gpr(ctx, a->rd1, EXT_NONE);
70
(s->sew != MO_8);
191
+ TCGv data2 = get_gpr(ctx, a->rd2, EXT_NONE);
71
}
192
+ TCGv addr1 = tcg_temp_new();
193
+ TCGv addr2 = tcg_temp_new();
194
+ int imm = a->sh2 << shamt;
195
+
196
+ addr1 = get_address(ctx, a->rs, imm);
197
+ addr2 = get_address(ctx, a->rs, memop_size(memop) + imm);
198
+
199
+ tcg_gen_qemu_st_tl(data1, addr1, ctx->mem_idx, memop);
200
+ tcg_gen_qemu_st_tl(data2, addr2, ctx->mem_idx, memop);
201
+
202
+ tcg_temp_free(addr1);
203
+ tcg_temp_free(addr2);
204
+ return true;
205
+}
206
+
207
+static bool trans_th_sdd(DisasContext *ctx, arg_th_pair *a)
208
+{
209
+ REQUIRE_XTHEADMEMPAIR(ctx);
210
+ REQUIRE_64BIT(ctx);
211
+ return gen_storepair_tl(ctx, a, MO_TESQ, 4);
212
+}
213
+
214
+static bool trans_th_swd(DisasContext *ctx, arg_th_pair *a)
215
+{
216
+ REQUIRE_XTHEADMEMPAIR(ctx);
217
+ return gen_storepair_tl(ctx, a, MO_TESL, 3);
218
+}
219
+
220
/* XTheadSync */
221
222
static bool trans_th_sfence_vmas(DisasContext *ctx, arg_th_sfence_vmas *a)
223
--
72
--
224
2.39.1
73
2.45.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
There is no need to declare an intermediate "MachineState *ms".
3
The require_scale_rvf function only checks the double width operator for
4
the vector floating point widen instructions, so most of the widen
5
checking functions need to add require_rvf for single width operator.
4
6
5
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
The vfwcvt.f.x.v and vfwcvt.f.xu.v instructions convert single width
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
integer to double width float, so the opfxv_widen_check function doesn’t
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
need require_rvf for the single width operator(integer).
8
Message-Id: <20230206085007.3618715-1-bmeng@tinylab.org>
10
11
Signed-off-by: Max Chou <max.chou@sifive.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20240322092600.1198921-3-max.chou@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
16
---
11
hw/riscv/virt.c | 6 ++----
17
target/riscv/insn_trans/trans_rvv.c.inc | 5 +++++
12
1 file changed, 2 insertions(+), 4 deletions(-)
18
1 file changed, 5 insertions(+)
13
19
14
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/virt.c
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
17
+++ b/hw/riscv/virt.c
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
18
@@ -XXX,XX +XXX,XX @@ static void virt_set_aia(Object *obj, const char *val, Error **errp)
24
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check)
19
25
static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
20
static bool virt_get_aclint(Object *obj, Error **errp)
21
{
26
{
22
- MachineState *ms = MACHINE(obj);
27
return require_rvv(s) &&
23
- RISCVVirtState *s = RISCV_VIRT_MACHINE(ms);
28
+ require_rvf(s) &&
24
+ RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
29
require_scale_rvf(s) &&
25
30
(s->sew != MO_8) &&
26
return s->have_aclint;
31
vext_check_isa_ill(s) &&
27
}
32
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check)
28
33
static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
29
static void virt_set_aclint(Object *obj, bool value, Error **errp)
30
{
34
{
31
- MachineState *ms = MACHINE(obj);
35
return require_rvv(s) &&
32
- RISCVVirtState *s = RISCV_VIRT_MACHINE(ms);
36
+ require_rvf(s) &&
33
+ RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
37
require_scale_rvf(s) &&
34
38
(s->sew != MO_8) &&
35
s->have_aclint = value;
39
vext_check_isa_ill(s) &&
40
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_WIDEN_TRANS(vfwsub_vf)
41
static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
42
{
43
return require_rvv(s) &&
44
+ require_rvf(s) &&
45
require_scale_rvf(s) &&
46
(s->sew != MO_8) &&
47
vext_check_isa_ill(s) &&
48
@@ -XXX,XX +XXX,XX @@ GEN_OPFWV_WIDEN_TRANS(vfwsub_wv)
49
static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
50
{
51
return require_rvv(s) &&
52
+ require_rvf(s) &&
53
require_scale_rvf(s) &&
54
(s->sew != MO_8) &&
55
vext_check_isa_ill(s) &&
56
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
57
static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
58
{
59
return reduction_widen_check(s, a) &&
60
+ require_rvf(s) &&
61
require_scale_rvf(s) &&
62
(s->sew != MO_8);
36
}
63
}
37
--
64
--
38
2.39.1
65
2.45.1
66
67
diff view generated by jsdifflib
1
From: Deepak Gupta <debug@rivosinc.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
commit fb3f3730e4 added mechanism to generate virtual instruction
3
The opfv_narrow_check needs to check the single width float operator by
4
exception during instruction decode when virt is enabled.
4
require_rvf.
5
5
6
However in some situations, illegal instruction exception can be raised
6
Signed-off-by: Max Chou <max.chou@sifive.com>
7
due to state of CPU. One such situation is implementing branch tracking.
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
[1] An indirect branch if doesn't land on a landing pad instruction, then
8
Cc: qemu-stable <qemu-stable@nongnu.org>
9
cpu must raise an illegal instruction exception.
9
Message-ID: <20240322092600.1198921-4-max.chou@sifive.com>
10
Implementation would raise such expcetion due to missing landing pad inst
11
and not due to decode. Thus DisasContext must have `virt_inst_excp`
12
initialized to false during DisasContxt initialization for TB.
13
14
[1] - https://github.com/riscv/riscv-cfi
15
16
Signed-off-by: Deepak Gupta <debug@rivosinc.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-Id: <20230127191758.755844-1-debug@rivosinc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
11
---
21
target/riscv/translate.c | 1 +
12
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
22
1 file changed, 1 insertion(+)
13
1 file changed, 1 insertion(+)
23
14
24
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
25
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/translate.c
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
27
+++ b/target/riscv/translate.c
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
28
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
19
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
29
ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
20
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
30
ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
21
{
31
ctx->zero = tcg_constant_tl(0);
22
return opfv_narrow_check(s, a) &&
32
+ ctx->virt_inst_excp = false;
23
+ require_rvf(s) &&
24
require_scale_rvf(s) &&
25
(s->sew != MO_8);
33
}
26
}
34
35
static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
36
--
27
--
37
2.39.1
28
2.45.1
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
This patch adds support for the XTheadBs ISA extension.
3
If the checking functions check both the single and double width
4
The patch uses the T-Head specific decoder and translation.
4
operators at the same time, then the single width operator checking
5
functions (require_rvf[min]) will check whether the SEW is 8.
5
6
6
Co-developed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
7
Signed-off-by: Max Chou <max.chou@sifive.com>
7
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
9
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
10
Message-ID: <20240322092600.1198921-5-max.chou@sifive.com>
10
Message-Id: <20230131202013.2541053-6-christoph.muellner@vrull.eu>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
12
---
13
target/riscv/cpu.h | 1 +
13
target/riscv/insn_trans/trans_rvv.c.inc | 16 ++++------------
14
target/riscv/xthead.decode | 3 +++
14
1 file changed, 4 insertions(+), 12 deletions(-)
15
target/riscv/cpu.c | 2 ++
16
target/riscv/translate.c | 3 ++-
17
target/riscv/insn_trans/trans_xthead.c.inc | 15 +++++++++++++++
18
5 files changed, 23 insertions(+), 1 deletion(-)
19
15
20
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
16
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/cpu.h
18
--- a/target/riscv/insn_trans/trans_rvv.c.inc
23
+++ b/target/riscv/cpu.h
19
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
24
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
20
@@ -XXX,XX +XXX,XX @@ static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
25
/* Vendor-specific custom extensions */
21
return require_rvv(s) &&
26
bool ext_xtheadba;
22
require_rvf(s) &&
27
bool ext_xtheadbb;
23
require_scale_rvf(s) &&
28
+ bool ext_xtheadbs;
24
- (s->sew != MO_8) &&
29
bool ext_xtheadcmo;
25
vext_check_isa_ill(s) &&
30
bool ext_xtheadsync;
26
vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
31
bool ext_XVentanaCondOps;
27
}
32
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
28
@@ -XXX,XX +XXX,XX @@ static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
33
index XXXXXXX..XXXXXXX 100644
29
return require_rvv(s) &&
34
--- a/target/riscv/xthead.decode
30
require_rvf(s) &&
35
+++ b/target/riscv/xthead.decode
31
require_scale_rvf(s) &&
36
@@ -XXX,XX +XXX,XX @@ th_rev 1000001 00000 ..... 001 ..... 0001011 @r2
32
- (s->sew != MO_8) &&
37
th_revw 1001000 00000 ..... 001 ..... 0001011 @r2
33
vext_check_isa_ill(s) &&
38
th_tstnbz 1000000 00000 ..... 001 ..... 0001011 @r2
34
vext_check_ds(s, a->rd, a->rs2, a->vm);
39
35
}
40
+# XTheadBs
36
@@ -XXX,XX +XXX,XX @@ static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
41
+th_tst 100010 ...... ..... 001 ..... 0001011 @sh6
37
return require_rvv(s) &&
42
+
38
require_rvf(s) &&
43
# XTheadCmo
39
require_scale_rvf(s) &&
44
th_dcache_call 0000000 00001 00000 000 00000 0001011
40
- (s->sew != MO_8) &&
45
th_dcache_ciall 0000000 00011 00000 000 00000 0001011
41
vext_check_isa_ill(s) &&
46
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
42
vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
47
index XXXXXXX..XXXXXXX 100644
43
}
48
--- a/target/riscv/cpu.c
44
@@ -XXX,XX +XXX,XX @@ static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
49
+++ b/target/riscv/cpu.c
45
return require_rvv(s) &&
50
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
46
require_rvf(s) &&
51
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
47
require_scale_rvf(s) &&
52
ISA_EXT_DATA_ENTRY(xtheadba, true, PRIV_VERSION_1_11_0, ext_xtheadba),
48
- (s->sew != MO_8) &&
53
ISA_EXT_DATA_ENTRY(xtheadbb, true, PRIV_VERSION_1_11_0, ext_xtheadbb),
49
vext_check_isa_ill(s) &&
54
+ ISA_EXT_DATA_ENTRY(xtheadbs, true, PRIV_VERSION_1_11_0, ext_xtheadbs),
50
vext_check_dd(s, a->rd, a->rs2, a->vm);
55
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
51
}
56
ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
52
@@ -XXX,XX +XXX,XX @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
57
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
58
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
59
/* Vendor-specific custom extensions */
60
DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
61
DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false),
62
+ DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
63
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
64
DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
65
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
66
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/translate.c
69
+++ b/target/riscv/translate.c
70
@@ -XXX,XX +XXX,XX @@ static bool always_true_p(DisasContext *ctx __attribute__((__unused__)))
71
static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
72
{
53
{
73
return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
54
return opfv_widen_check(s, a) &&
74
- ctx->cfg_ptr->ext_xtheadcmo || ctx->cfg_ptr->ext_xtheadsync;
55
require_rvfmin(s) &&
75
+ ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
56
- require_scale_rvfmin(s) &&
76
+ ctx->cfg_ptr->ext_xtheadsync;
57
- (s->sew != MO_8);
58
+ require_scale_rvfmin(s);
77
}
59
}
78
60
79
#define MATERIALISE_EXT_PREDICATE(ext) \
61
#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
80
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
62
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
81
index XXXXXXX..XXXXXXX 100644
63
{
82
--- a/target/riscv/insn_trans/trans_xthead.c.inc
64
return opfv_narrow_check(s, a) &&
83
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
65
require_rvfmin(s) &&
84
@@ -XXX,XX +XXX,XX @@
66
- require_scale_rvfmin(s) &&
85
} \
67
- (s->sew != MO_8);
86
} while (0)
68
+ require_scale_rvfmin(s);
87
88
+#define REQUIRE_XTHEADBS(ctx) do { \
89
+ if (!ctx->cfg_ptr->ext_xtheadbs) { \
90
+ return false; \
91
+ } \
92
+} while (0)
93
+
94
#define REQUIRE_XTHEADCMO(ctx) do { \
95
if (!ctx->cfg_ptr->ext_xtheadcmo) { \
96
return false; \
97
@@ -XXX,XX +XXX,XX @@ static bool trans_th_tstnbz(DisasContext *ctx, arg_th_tstnbz *a)
98
return gen_unary(ctx, a, EXT_ZERO, gen_th_tstnbz);
99
}
69
}
100
70
101
+/* XTheadBs */
71
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
102
+
72
{
103
+/* th.tst is an alternate encoding for bexti (from Zbs) */
73
return opfv_narrow_check(s, a) &&
104
+static bool trans_th_tst(DisasContext *ctx, arg_th_tst *a)
74
require_rvf(s) &&
105
+{
75
- require_scale_rvf(s) &&
106
+ REQUIRE_XTHEADBS(ctx);
76
- (s->sew != MO_8);
107
+ return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bext);
77
+ require_scale_rvf(s);
108
+}
78
}
109
+
79
110
/* XTheadCmo */
80
#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \
111
81
@@ -XXX,XX +XXX,XX @@ static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
112
static inline int priv_level(DisasContext *ctx)
82
{
83
return reduction_widen_check(s, a) &&
84
require_rvf(s) &&
85
- require_scale_rvf(s) &&
86
- (s->sew != MO_8);
87
+ require_scale_rvf(s);
88
}
89
90
GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check)
113
--
91
--
114
2.39.1
92
2.45.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
riscv_socket_count() returns either ms->numa_state->num_nodes or 1
3
raise_mmu_exception(), as is today, is prioritizing guest page faults by
4
depending on NUMA support. In any case the value can be retrieved only
4
checking first if virt_enabled && !first_stage, and then considering the
5
once and used in the rest of the function.
5
regular inst/load/store faults.
6
6
7
This will also alleviate the rename we're going to do next by reducing
7
There's no mention in the spec about guest page fault being a higher
8
the instances of MachineState 'mc' inside hw/riscv/virt.c.
8
priority that PMP faults. In fact, privileged spec section 3.7.1 says:
9
9
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
"Attempting to fetch an instruction from a PMP region that does not have
11
execute permissions raises an instruction access-fault exception.
12
Attempting to execute a load or load-reserved instruction which accesses
13
a physical address within a PMP region without read permissions raises a
14
load access-fault exception. Attempting to execute a store,
15
store-conditional, or AMO instruction which accesses a physical address
16
within a PMP region without write permissions raises a store
17
access-fault exception."
18
19
So, in fact, we're doing it wrong - PMP faults should always be thrown,
20
regardless of also being a first or second stage fault.
21
22
The way riscv_cpu_tlb_fill() and get_physical_address() work is
23
adequate: a TRANSLATE_PMP_FAIL error is immediately reported and
24
reflected in the 'pmp_violation' flag. What we need is to change
25
raise_mmu_exception() to prioritize it.
26
27
Reported-by: Joseph Chan <jchan@ventanamicro.com>
28
Fixes: 82d53adfbb ("target/riscv/cpu_helper.c: Invalid exception on MMU translation stage")
29
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
30
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
31
Message-ID: <20240413105929.7030-1-alexei.filippov@syntacore.com>
13
Message-Id: <20230124212234.412630-2-dbarboza@ventanamicro.com>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
34
---
16
hw/riscv/virt.c | 34 +++++++++++++++++++---------------
35
target/riscv/cpu_helper.c | 22 ++++++++++++----------
17
1 file changed, 19 insertions(+), 15 deletions(-)
36
1 file changed, 12 insertions(+), 10 deletions(-)
18
37
19
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
20
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/riscv/virt.c
40
--- a/target/riscv/cpu_helper.c
22
+++ b/hw/riscv/virt.c
41
+++ b/target/riscv/cpu_helper.c
23
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
42
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
24
int cpu, socket;
43
25
char *imsic_name;
44
switch (access_type) {
26
MachineState *mc = MACHINE(s);
45
case MMU_INST_FETCH:
27
+ int socket_count = riscv_socket_count(mc);
46
- if (env->virt_enabled && !first_stage) {
28
uint32_t imsic_max_hart_per_socket, imsic_guest_bits;
47
+ if (pmp_violation) {
29
uint32_t *imsic_cells, *imsic_regs, imsic_addr, imsic_size;
48
+ cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT;
30
49
+ } else if (env->virt_enabled && !first_stage) {
31
*msi_m_phandle = (*phandle)++;
50
cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT;
32
*msi_s_phandle = (*phandle)++;
51
} else {
33
imsic_cells = g_new0(uint32_t, mc->smp.cpus * 2);
52
- cs->exception_index = pmp_violation ?
34
- imsic_regs = g_new0(uint32_t, riscv_socket_count(mc) * 4);
53
- RISCV_EXCP_INST_ACCESS_FAULT : RISCV_EXCP_INST_PAGE_FAULT;
35
+ imsic_regs = g_new0(uint32_t, socket_count * 4);
54
+ cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT;
36
55
}
37
/* M-level IMSIC node */
56
break;
38
for (cpu = 0; cpu < mc->smp.cpus; cpu++) {
57
case MMU_DATA_LOAD:
39
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
58
- if (two_stage && !first_stage) {
40
imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
59
+ if (pmp_violation) {
41
}
60
+ cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT;
42
imsic_max_hart_per_socket = 0;
61
+ } else if (two_stage && !first_stage) {
43
- for (socket = 0; socket < riscv_socket_count(mc); socket++) {
62
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
44
+ for (socket = 0; socket < socket_count; socket++) {
63
} else {
45
imsic_addr = memmap[VIRT_IMSIC_M].base +
64
- cs->exception_index = pmp_violation ?
46
socket * VIRT_IMSIC_GROUP_MAX_SIZE;
65
- RISCV_EXCP_LOAD_ACCESS_FAULT : RISCV_EXCP_LOAD_PAGE_FAULT;
47
imsic_size = IMSIC_HART_SIZE(0) * s->soc[socket].num_harts;
66
+ cs->exception_index = RISCV_EXCP_LOAD_PAGE_FAULT;
48
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
67
}
49
qemu_fdt_setprop(mc->fdt, imsic_name, "interrupts-extended",
68
break;
50
imsic_cells, mc->smp.cpus * sizeof(uint32_t) * 2);
69
case MMU_DATA_STORE:
51
qemu_fdt_setprop(mc->fdt, imsic_name, "reg", imsic_regs,
70
- if (two_stage && !first_stage) {
52
- riscv_socket_count(mc) * sizeof(uint32_t) * 4);
71
+ if (pmp_violation) {
53
+ socket_count * sizeof(uint32_t) * 4);
72
+ cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
54
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
73
+ } else if (two_stage && !first_stage) {
55
VIRT_IRQCHIP_NUM_MSIS);
74
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
56
- if (riscv_socket_count(mc) > 1) {
75
} else {
57
+ if (socket_count > 1) {
76
- cs->exception_index = pmp_violation ?
58
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits",
77
- RISCV_EXCP_STORE_AMO_ACCESS_FAULT :
59
imsic_num_bits(imsic_max_hart_per_socket));
78
- RISCV_EXCP_STORE_PAGE_FAULT;
60
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-bits",
79
+ cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
61
- imsic_num_bits(riscv_socket_count(mc)));
80
}
62
+ imsic_num_bits(socket_count));
81
break;
63
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-shift",
82
default:
64
IMSIC_MMIO_GROUP_MIN_SHIFT);
65
}
66
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
67
}
68
imsic_guest_bits = imsic_num_bits(s->aia_guests + 1);
69
imsic_max_hart_per_socket = 0;
70
- for (socket = 0; socket < riscv_socket_count(mc); socket++) {
71
+ for (socket = 0; socket < socket_count; socket++) {
72
imsic_addr = memmap[VIRT_IMSIC_S].base +
73
socket * VIRT_IMSIC_GROUP_MAX_SIZE;
74
imsic_size = IMSIC_HART_SIZE(imsic_guest_bits) *
75
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
76
qemu_fdt_setprop(mc->fdt, imsic_name, "interrupts-extended",
77
imsic_cells, mc->smp.cpus * sizeof(uint32_t) * 2);
78
qemu_fdt_setprop(mc->fdt, imsic_name, "reg", imsic_regs,
79
- riscv_socket_count(mc) * sizeof(uint32_t) * 4);
80
+ socket_count * sizeof(uint32_t) * 4);
81
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
82
VIRT_IRQCHIP_NUM_MSIS);
83
if (imsic_guest_bits) {
84
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,guest-index-bits",
85
imsic_guest_bits);
86
}
87
- if (riscv_socket_count(mc) > 1) {
88
+ if (socket_count > 1) {
89
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits",
90
imsic_num_bits(imsic_max_hart_per_socket));
91
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-bits",
92
- imsic_num_bits(riscv_socket_count(mc)));
93
+ imsic_num_bits(socket_count));
94
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-shift",
95
IMSIC_MMIO_GROUP_MIN_SHIFT);
96
}
97
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
98
MachineState *mc = MACHINE(s);
99
uint32_t msi_m_phandle = 0, msi_s_phandle = 0;
100
uint32_t *intc_phandles, xplic_phandles[MAX_NODES];
101
+ int socket_count = riscv_socket_count(mc);
102
103
qemu_fdt_add_subnode(mc->fdt, "/cpus");
104
qemu_fdt_setprop_cell(mc->fdt, "/cpus", "timebase-frequency",
105
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
106
intc_phandles = g_new0(uint32_t, mc->smp.cpus);
107
108
phandle_pos = mc->smp.cpus;
109
- for (socket = (riscv_socket_count(mc) - 1); socket >= 0; socket--) {
110
+ for (socket = (socket_count - 1); socket >= 0; socket--) {
111
phandle_pos -= s->soc[socket].num_harts;
112
113
clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket);
114
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
115
}
116
117
phandle_pos = mc->smp.cpus;
118
- for (socket = (riscv_socket_count(mc) - 1); socket >= 0; socket--) {
119
+ for (socket = (socket_count - 1); socket >= 0; socket--) {
120
phandle_pos -= s->soc[socket].num_harts;
121
122
if (s->aia_type == VIRT_AIA_TYPE_NONE) {
123
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
124
125
g_free(intc_phandles);
126
127
- for (socket = 0; socket < riscv_socket_count(mc); socket++) {
128
+ for (socket = 0; socket < socket_count; socket++) {
129
if (socket == 0) {
130
*irq_mmio_phandle = xplic_phandles[socket];
131
*irq_virtio_phandle = xplic_phandles[socket];
132
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap)
133
134
/* Pass seed to RNG */
135
qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
136
- qemu_fdt_setprop(mc->fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed));
137
+ qemu_fdt_setprop(mc->fdt, "/chosen", "rng-seed",
138
+ rng_seed, sizeof(rng_seed));
139
}
140
141
static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
142
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
143
char *soc_name;
144
DeviceState *mmio_irqchip, *virtio_irqchip, *pcie_irqchip;
145
int i, base_hartid, hart_count;
146
+ int socket_count = riscv_socket_count(machine);
147
148
/* Check socket count limit */
149
- if (VIRT_SOCKETS_MAX < riscv_socket_count(machine)) {
150
+ if (VIRT_SOCKETS_MAX < socket_count) {
151
error_report("number of sockets/nodes should be less than %d",
152
VIRT_SOCKETS_MAX);
153
exit(1);
154
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
155
156
/* Initialize sockets */
157
mmio_irqchip = virtio_irqchip = pcie_irqchip = NULL;
158
- for (i = 0; i < riscv_socket_count(machine); i++) {
159
+ for (i = 0; i < socket_count; i++) {
160
if (!riscv_socket_check_hartids(machine, i)) {
161
error_report("discontinuous hartids in socket%d", i);
162
exit(1);
163
--
83
--
164
2.39.1
84
2.45.1
diff view generated by jsdifflib
1
From: Anup Patel <apatel@ventanamicro.com>
1
From: Alexei Filippov <alexei.filippov@syntacore.com>
2
2
3
Instead of clearing mask in riscv_cpu_update_mip() for VSTIP, we
3
Previous patch fixed the PMP priority in raise_mmu_exception() but we're still
4
should call riscv_cpu_update_mip() with mask == 0 from timer_helper.c
4
setting mtval2 incorrectly. In riscv_cpu_tlb_fill(), after pmp check in 2 stage
5
for VSTIP.
5
translation part, mtval2 will be set in case of successes 2 stage translation but
6
failed pmp check.
6
7
7
Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
8
In this case we gonna set mtval2 via env->guest_phys_fault_addr in context of
8
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
9
riscv_cpu_tlb_fill(), as this was a guest-page-fault, but it didn't and mtval2
10
should be zero, according to RISCV privileged spec sect. 9.4.4: When a guest
11
page-fault is taken into M-mode, mtval2 is written with either zero or guest
12
physical address that faulted, shifted by 2 bits. *For other traps, mtval2
13
is set to zero...*
14
15
Signed-off-by: Alexei Filippov <alexei.filippov@syntacore.com>
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20230120125950.2246378-3-apatel@ventanamicro.com>
18
Message-ID: <20240503103052.6819-1-alexei.filippov@syntacore.com>
19
Cc: qemu-stable <qemu-stable@nongnu.org>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
21
---
13
target/riscv/cpu_helper.c | 2 --
22
target/riscv/cpu_helper.c | 12 ++++++------
14
target/riscv/time_helper.c | 12 ++++++++----
23
1 file changed, 6 insertions(+), 6 deletions(-)
15
2 files changed, 8 insertions(+), 6 deletions(-)
16
24
17
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
25
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
18
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu_helper.c
27
--- a/target/riscv/cpu_helper.c
20
+++ b/target/riscv/cpu_helper.c
28
+++ b/target/riscv/cpu_helper.c
21
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value)
29
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
22
vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
30
__func__, pa, ret, prot_pmp, tlb_size);
23
}
31
24
32
prot &= prot_pmp;
25
- /* No need to update mip for VSTIP */
33
- }
26
- mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask;
34
-
27
vstip = env->vstime_irq ? MIP_VSTIP : 0;
35
- if (ret != TRANSLATE_SUCCESS) {
28
36
+ } else {
29
QEMU_IOTHREAD_LOCK_GUARD();
37
/*
30
diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
38
* Guest physical address translation failed, this is a HS
31
index XXXXXXX..XXXXXXX 100644
39
* level exception
32
--- a/target/riscv/time_helper.c
40
*/
33
+++ b/target/riscv/time_helper.c
41
first_stage_error = false;
34
@@ -XXX,XX +XXX,XX @@ static void riscv_vstimer_cb(void *opaque)
42
- env->guest_phys_fault_addr = (im_address |
35
RISCVCPU *cpu = opaque;
43
- (address &
36
CPURISCVState *env = &cpu->env;
44
- (TARGET_PAGE_SIZE - 1))) >> 2;
37
env->vstime_irq = 1;
45
+ if (ret != TRANSLATE_PMP_FAIL) {
38
- riscv_cpu_update_mip(cpu, MIP_VSTIP, BOOL_TO_MASK(1));
46
+ env->guest_phys_fault_addr = (im_address |
39
+ riscv_cpu_update_mip(cpu, 0, BOOL_TO_MASK(1));
47
+ (address &
40
}
48
+ (TARGET_PAGE_SIZE - 1))) >> 2;
41
49
+ }
42
static void riscv_stimer_cb(void *opaque)
50
}
43
@@ -XXX,XX +XXX,XX @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer,
44
*/
45
if (timer_irq == MIP_VSTIP) {
46
env->vstime_irq = 1;
47
+ riscv_cpu_update_mip(cpu, 0, BOOL_TO_MASK(1));
48
+ } else {
49
+ riscv_cpu_update_mip(cpu, MIP_STIP, BOOL_TO_MASK(1));
50
}
51
}
51
- riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(1));
52
} else {
52
return;
53
}
54
55
+ /* Clear the [VS|S]TIP bit in mip */
56
if (timer_irq == MIP_VSTIP) {
57
env->vstime_irq = 0;
58
+ riscv_cpu_update_mip(cpu, 0, BOOL_TO_MASK(0));
59
+ } else {
60
+ riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
61
}
62
- /* Clear the [V]STIP bit in mip */
63
- riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
64
65
/* otherwise, set up the future timer interrupt */
66
diff = timecmp - rtc_r;
67
--
53
--
68
2.39.1
54
2.45.1
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Rob Bradford <rbradford@rivosinc.com>
2
2
3
This patch adds support for the XTheadBb ISA extension.
3
This extension has now been ratified:
4
The patch uses the T-Head specific decoder and translation.
4
https://jira.riscv.org/browse/RVS-2006 so the "x-" prefix can be
5
removed.
5
6
6
Co-developed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
7
Since this is now a ratified extension add it to the list of extensions
7
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
included in the "max" CPU variant.
9
10
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
11
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
13
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Message-Id: <20230131202013.2541053-5-christoph.muellner@vrull.eu>
14
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
15
Message-ID: <20240514110217.22516-1-rbradford@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
17
---
13
target/riscv/cpu.h | 1 +
18
target/riscv/cpu.c | 2 +-
14
target/riscv/xthead.decode | 20 ++++
19
target/riscv/tcg/tcg-cpu.c | 2 +-
15
target/riscv/cpu.c | 2 +
20
2 files changed, 2 insertions(+), 2 deletions(-)
16
target/riscv/translate.c | 4 +-
17
target/riscv/insn_trans/trans_xthead.c.inc | 124 +++++++++++++++++++++
18
5 files changed, 149 insertions(+), 2 deletions(-)
19
21
20
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/cpu.h
23
+++ b/target/riscv/cpu.h
24
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
25
26
/* Vendor-specific custom extensions */
27
bool ext_xtheadba;
28
+ bool ext_xtheadbb;
29
bool ext_xtheadcmo;
30
bool ext_xtheadsync;
31
bool ext_XVentanaCondOps;
32
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/xthead.decode
35
+++ b/target/riscv/xthead.decode
36
@@ -XXX,XX +XXX,XX @@
37
%rd 7:5
38
%rs1 15:5
39
%rs2 20:5
40
+%sh5 20:5
41
+%sh6 20:6
42
43
# Argument sets
44
&r rd rs1 rs2 !extern
45
+&r2 rd rs1 !extern
46
+&shift shamt rs1 rd !extern
47
+&th_bfext msb lsb rs1 rd
48
49
# Formats
50
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
51
@rs2_s ....... ..... ..... ... ..... ....... %rs2 %rs1
52
@r ....... ..... ..... ... ..... ....... &r %rs2 %rs1 %rd
53
+@r2 ....... ..... ..... ... ..... ....... &r2 %rs1 %rd
54
+@th_bfext msb:6 lsb:6 ..... ... ..... ....... &th_bfext %rs1 %rd
55
+@sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd
56
+@sh6 ...... ...... ..... ... ..... ....... &shift shamt=%sh6 %rs1 %rd
57
58
# XTheadBa
59
# Instead of defining a new encoding, we simply use the decoder to
60
@@ -XXX,XX +XXX,XX @@ th_addsl1 0000001 ..... ..... 001 ..... 0001011 @r
61
th_addsl2 0000010 ..... ..... 001 ..... 0001011 @r
62
th_addsl3 0000011 ..... ..... 001 ..... 0001011 @r
63
64
+# XTheadBb
65
+th_ext ...... ...... ..... 010 ..... 0001011 @th_bfext
66
+th_extu ...... ...... ..... 011 ..... 0001011 @th_bfext
67
+th_ff0 1000010 00000 ..... 001 ..... 0001011 @r2
68
+th_ff1 1000011 00000 ..... 001 ..... 0001011 @r2
69
+th_srri 000100 ...... ..... 001 ..... 0001011 @sh6
70
+th_srriw 0001010 ..... ..... 001 ..... 0001011 @sh5
71
+th_rev 1000001 00000 ..... 001 ..... 0001011 @r2
72
+th_revw 1001000 00000 ..... 001 ..... 0001011 @r2
73
+th_tstnbz 1000000 00000 ..... 001 ..... 0001011 @r2
74
+
75
# XTheadCmo
76
th_dcache_call 0000000 00001 00000 000 00000 0001011
77
th_dcache_ciall 0000000 00011 00000 000 00000 0001011
78
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
22
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
79
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
80
--- a/target/riscv/cpu.c
24
--- a/target/riscv/cpu.c
81
+++ b/target/riscv/cpu.c
25
+++ b/target/riscv/cpu.c
82
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
26
@@ -XXX,XX +XXX,XX @@ static const MISAExtInfo misa_ext_info_arr[] = {
83
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
27
MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
84
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
28
MISA_EXT_INFO(RVV, "v", "Vector operations"),
85
ISA_EXT_DATA_ENTRY(xtheadba, true, PRIV_VERSION_1_11_0, ext_xtheadba),
29
MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
86
+ ISA_EXT_DATA_ENTRY(xtheadbb, true, PRIV_VERSION_1_11_0, ext_xtheadbb),
30
- MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)")
87
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
31
+ MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
88
ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
32
};
89
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
33
90
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
34
static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc)
91
35
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
92
/* Vendor-specific custom extensions */
93
DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
94
+ DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false),
95
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
96
DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
97
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
98
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
99
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
100
--- a/target/riscv/translate.c
37
--- a/target/riscv/tcg/tcg-cpu.c
101
+++ b/target/riscv/translate.c
38
+++ b/target/riscv/tcg/tcg-cpu.c
102
@@ -XXX,XX +XXX,XX @@ static bool always_true_p(DisasContext *ctx __attribute__((__unused__)))
39
@@ -XXX,XX +XXX,XX @@ static void riscv_init_max_cpu_extensions(Object *obj)
103
40
const RISCVCPUMultiExtConfig *prop;
104
static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
41
105
{
42
/* Enable RVG, RVJ and RVV that are disabled by default */
106
- return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadcmo ||
43
- riscv_cpu_set_misa_ext(env, env->misa_ext | RVG | RVJ | RVV);
107
- ctx->cfg_ptr->ext_xtheadsync;
44
+ riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVJ | RVV);
108
+ return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
45
109
+ ctx->cfg_ptr->ext_xtheadcmo || ctx->cfg_ptr->ext_xtheadsync;
46
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
110
}
47
isa_ext_update_enabled(cpu, prop->offset, true);
111
112
#define MATERIALISE_EXT_PREDICATE(ext) \
113
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/riscv/insn_trans/trans_xthead.c.inc
116
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
117
@@ -XXX,XX +XXX,XX @@
118
} \
119
} while (0)
120
121
+#define REQUIRE_XTHEADBB(ctx) do { \
122
+ if (!ctx->cfg_ptr->ext_xtheadbb) { \
123
+ return false; \
124
+ } \
125
+} while (0)
126
+
127
#define REQUIRE_XTHEADCMO(ctx) do { \
128
if (!ctx->cfg_ptr->ext_xtheadcmo) { \
129
return false; \
130
@@ -XXX,XX +XXX,XX @@ GEN_TRANS_TH_ADDSL(1)
131
GEN_TRANS_TH_ADDSL(2)
132
GEN_TRANS_TH_ADDSL(3)
133
134
+/* XTheadBb */
135
+
136
+/* th.srri is an alternate encoding for rori (from Zbb) */
137
+static bool trans_th_srri(DisasContext *ctx, arg_th_srri * a)
138
+{
139
+ REQUIRE_XTHEADBB(ctx);
140
+ return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE,
141
+ tcg_gen_rotri_tl, gen_roriw, NULL);
142
+}
143
+
144
+/* th.srriw is an alternate encoding for roriw (from Zbb) */
145
+static bool trans_th_srriw(DisasContext *ctx, arg_th_srriw *a)
146
+{
147
+ REQUIRE_XTHEADBB(ctx);
148
+ REQUIRE_64BIT(ctx);
149
+ ctx->ol = MXL_RV32;
150
+ return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_roriw, NULL);
151
+}
152
+
153
+/* th.ext and th.extu perform signed/unsigned bitfield extraction */
154
+static bool gen_th_bfextract(DisasContext *ctx, arg_th_bfext *a,
155
+ void (*f)(TCGv, TCGv, unsigned int, unsigned int))
156
+{
157
+ TCGv dest = dest_gpr(ctx, a->rd);
158
+ TCGv source = get_gpr(ctx, a->rs1, EXT_ZERO);
159
+
160
+ if (a->lsb <= a->msb) {
161
+ f(dest, source, a->lsb, a->msb - a->lsb + 1);
162
+ gen_set_gpr(ctx, a->rd, dest);
163
+ }
164
+ return true;
165
+}
166
+
167
+static bool trans_th_ext(DisasContext *ctx, arg_th_ext *a)
168
+{
169
+ REQUIRE_XTHEADBB(ctx);
170
+ return gen_th_bfextract(ctx, a, tcg_gen_sextract_tl);
171
+}
172
+
173
+static bool trans_th_extu(DisasContext *ctx, arg_th_extu *a)
174
+{
175
+ REQUIRE_XTHEADBB(ctx);
176
+ return gen_th_bfextract(ctx, a, tcg_gen_extract_tl);
177
+}
178
+
179
+/* th.ff0: find first zero (clz on an inverted input) */
180
+static bool gen_th_ff0(DisasContext *ctx, arg_th_ff0 *a, DisasExtend ext)
181
+{
182
+ TCGv dest = dest_gpr(ctx, a->rd);
183
+ TCGv src1 = get_gpr(ctx, a->rs1, ext);
184
+
185
+ int olen = get_olen(ctx);
186
+ TCGv t = tcg_temp_new();
187
+
188
+ tcg_gen_not_tl(t, src1);
189
+ if (olen != TARGET_LONG_BITS) {
190
+ if (olen == 32) {
191
+ gen_clzw(dest, t);
192
+ } else {
193
+ g_assert_not_reached();
194
+ }
195
+ } else {
196
+ gen_clz(dest, t);
197
+ }
198
+
199
+ tcg_temp_free(t);
200
+ gen_set_gpr(ctx, a->rd, dest);
201
+
202
+ return true;
203
+}
204
+
205
+static bool trans_th_ff0(DisasContext *ctx, arg_th_ff0 *a)
206
+{
207
+ REQUIRE_XTHEADBB(ctx);
208
+ return gen_th_ff0(ctx, a, EXT_NONE);
209
+}
210
+
211
+/* th.ff1 is an alternate encoding for clz (from Zbb) */
212
+static bool trans_th_ff1(DisasContext *ctx, arg_th_ff1 *a)
213
+{
214
+ REQUIRE_XTHEADBB(ctx);
215
+ return gen_unary_per_ol(ctx, a, EXT_NONE, gen_clz, gen_clzw);
216
+}
217
+
218
+static void gen_th_revw(TCGv ret, TCGv arg1)
219
+{
220
+ tcg_gen_bswap32_tl(ret, arg1, TCG_BSWAP_OS);
221
+}
222
+
223
+/* th.rev is an alternate encoding for the RV64 rev8 (from Zbb) */
224
+static bool trans_th_rev(DisasContext *ctx, arg_th_rev *a)
225
+{
226
+ REQUIRE_XTHEADBB(ctx);
227
+
228
+ return gen_unary_per_ol(ctx, a, EXT_NONE, tcg_gen_bswap_tl, gen_th_revw);
229
+}
230
+
231
+/* th.revw is a sign-extended byte-swap of the lower word */
232
+static bool trans_th_revw(DisasContext *ctx, arg_th_revw *a)
233
+{
234
+ REQUIRE_XTHEADBB(ctx);
235
+ REQUIRE_64BIT(ctx);
236
+ return gen_unary(ctx, a, EXT_NONE, gen_th_revw);
237
+}
238
+
239
+/* th.tstnbz is equivalent to an orc.b (from Zbb) with inverted result */
240
+static void gen_th_tstnbz(TCGv ret, TCGv source1)
241
+{
242
+ gen_orc_b(ret, source1);
243
+ tcg_gen_not_tl(ret, ret);
244
+}
245
+
246
+static bool trans_th_tstnbz(DisasContext *ctx, arg_th_tstnbz *a)
247
+{
248
+ REQUIRE_XTHEADBB(ctx);
249
+ return gen_unary(ctx, a, EXT_ZERO, gen_th_tstnbz);
250
+}
251
+
252
/* XTheadCmo */
253
254
static inline int priv_level(DisasContext *ctx)
255
--
48
--
256
2.39.1
49
2.45.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Alistair Francis <alistair23@gmail.com>
2
2
3
A common trend in other archs is to calculate the fdt address, which is
3
When running the instruction
4
usually straightforward, and then calling a function that loads the
5
fdt/dtb by using that address.
6
4
7
riscv_load_fdt() is doing a bit too much in comparison. It's calculating
5
```
8
the fdt address via an elaborated heuristic to put the FDT at the bottom
6
cbo.flush 0(x0)
9
of DRAM, and "bottom of DRAM" will vary across boards and
7
```
10
configurations, then it's actually loading the fdt, and finally it's
11
returning the fdt address used to the caller.
12
8
13
Reduce the existing complexity of riscv_load_fdt() by splitting its code
9
QEMU would segfault.
14
into a new function, riscv_compute_fdt_addr(), that will take care of
15
all fdt address logic. riscv_load_fdt() can then be a simple function
16
that just loads a fdt at the given fdt address.
17
10
18
We're also taken the opportunity to clarify the intentions and
11
The issue was in cpu_gpr[a->rs1] as QEMU does not have cpu_gpr[0]
19
assumptions made by these functions. riscv_load_fdt() is now receiving a
12
allocated.
20
hwaddr as fdt_addr because there is no restriction of having to load the
21
fdt in higher addresses that doesn't fit in an uint32_t.
22
13
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
In order to fix this let's use the existing get_address()
24
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
helper. This also has the benefit of performing pointer mask
25
Message-Id: <20230201171212.1219375-3-dbarboza@ventanamicro.com>
16
calculations on the address specified in rs1.
17
18
The pointer masking specificiation specifically states:
19
20
"""
21
Cache Management Operations: All instructions in Zicbom, Zicbop and Zicboz
22
"""
23
24
So this is the correct behaviour and we previously have been incorrectly
25
not masking the address.
26
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
Reported-by: Fabian Thomas <fabian.thomas@cispa.de>
29
Fixes: e05da09b7cfd ("target/riscv: implement Zicbom extension")
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Cc: qemu-stable <qemu-stable@nongnu.org>
32
Message-ID: <20240514023910.301766-1-alistair.francis@wdc.com>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
---
34
---
28
include/hw/riscv/boot.h | 4 +++-
35
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++++++++++++----
29
hw/riscv/boot.c | 30 +++++++++++++++++++++++++-----
36
1 file changed, 12 insertions(+), 4 deletions(-)
30
hw/riscv/microchip_pfsoc.c | 6 ++++--
31
hw/riscv/sifive_u.c | 7 ++++---
32
hw/riscv/spike.c | 6 +++---
33
hw/riscv/virt.c | 7 ++++---
34
6 files changed, 43 insertions(+), 17 deletions(-)
35
37
36
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
38
diff --git a/target/riscv/insn_trans/trans_rvzicbo.c.inc b/target/riscv/insn_trans/trans_rvzicbo.c.inc
37
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
38
--- a/include/hw/riscv/boot.h
40
--- a/target/riscv/insn_trans/trans_rvzicbo.c.inc
39
+++ b/include/hw/riscv/boot.h
41
+++ b/target/riscv/insn_trans/trans_rvzicbo.c.inc
40
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(MachineState *machine,
42
@@ -XXX,XX +XXX,XX @@
41
target_ulong firmware_end_addr,
43
static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a)
42
symbol_fn_t sym_cb);
44
{
43
void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry);
45
REQUIRE_ZICBOM(ctx);
44
-uint64_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt);
46
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
45
+uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size,
47
+ TCGv src = get_address(ctx, a->rs1, 0);
46
+ void *fdt);
48
+
47
+void riscv_load_fdt(hwaddr fdt_addr, void *fdt);
49
+ gen_helper_cbo_clean_flush(tcg_env, src);
48
void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts,
50
return true;
49
hwaddr saddr,
50
hwaddr rom_base, hwaddr rom_size,
51
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/riscv/boot.c
54
+++ b/hw/riscv/boot.c
55
@@ -XXX,XX +XXX,XX @@ void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
56
}
57
}
51
}
58
52
59
-uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
53
static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a)
60
+/*
61
+ * The FDT should be put at the farthest point possible to
62
+ * avoid overwriting it with the kernel/initrd.
63
+ *
64
+ * This function makes an assumption that the DRAM is
65
+ * contiguous. It also cares about 32-bit systems and
66
+ * will limit fdt_addr to be addressable by them even for
67
+ * 64-bit CPUs.
68
+ *
69
+ * The FDT is fdt_packed() during the calculation.
70
+ */
71
+uint64_t riscv_compute_fdt_addr(hwaddr dram_base, uint64_t mem_size,
72
+ void *fdt)
73
{
54
{
74
- uint64_t temp, fdt_addr;
55
REQUIRE_ZICBOM(ctx);
75
+ uint64_t temp;
56
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
76
hwaddr dram_end = dram_base + mem_size;
57
+ TCGv src = get_address(ctx, a->rs1, 0);
77
int ret = fdt_pack(fdt);
78
int fdtsize;
79
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
80
* end of dram or 3GB whichever is lesser.
81
*/
82
temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end;
83
- fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB);
84
+
58
+
85
+ return QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB);
59
+ gen_helper_cbo_clean_flush(tcg_env, src);
86
+}
60
return true;
61
}
62
63
static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a)
64
{
65
REQUIRE_ZICBOM(ctx);
66
- gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]);
67
+ TCGv src = get_address(ctx, a->rs1, 0);
87
+
68
+
88
+/*
69
+ gen_helper_cbo_inval(tcg_env, src);
89
+ * 'fdt_addr' is received as hwaddr because boards might put
70
return true;
90
+ * the FDT beyond 32-bit addressing boundary.
91
+ */
92
+void riscv_load_fdt(hwaddr fdt_addr, void *fdt)
93
+{
94
+ uint32_t fdtsize = fdt_totalsize(fdt);
95
96
/* copy in the device tree */
97
qemu_fdt_dumpdtb(fdt, fdtsize);
98
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
99
&address_space_memory);
100
qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
101
rom_ptr_for_as(&address_space_memory, fdt_addr, fdtsize));
102
-
103
- return fdt_addr;
104
}
71
}
105
72
106
void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base,
73
static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)
107
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
74
{
108
index XXXXXXX..XXXXXXX 100644
75
REQUIRE_ZICBOZ(ctx);
109
--- a/hw/riscv/microchip_pfsoc.c
76
- gen_helper_cbo_zero(tcg_env, cpu_gpr[a->rs1]);
110
+++ b/hw/riscv/microchip_pfsoc.c
77
+ TCGv src = get_address(ctx, a->rs1, 0);
111
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
112
}
113
114
/* Compute the fdt load address in dram */
115
- fdt_load_addr = riscv_load_fdt(memmap[MICROCHIP_PFSOC_DRAM_LO].base,
116
- machine->ram_size, machine->fdt);
117
+ fdt_load_addr = riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base,
118
+ machine->ram_size, machine->fdt);
119
+ riscv_load_fdt(fdt_load_addr, machine->fdt);
120
+
78
+
121
/* Load the reset vector */
79
+ gen_helper_cbo_zero(tcg_env, src);
122
riscv_setup_rom_reset_vec(machine, &s->soc.u_cpus, firmware_load_addr,
80
return true;
123
memmap[MICROCHIP_PFSOC_ENVM_DATA].base,
81
}
124
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
125
index XXXXXXX..XXXXXXX 100644
126
--- a/hw/riscv/sifive_u.c
127
+++ b/hw/riscv/sifive_u.c
128
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
129
kernel_entry = 0;
130
}
131
132
- /* Compute the fdt load address in dram */
133
- fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DEV_DRAM].base,
134
- machine->ram_size, machine->fdt);
135
+ fdt_load_addr = riscv_compute_fdt_addr(memmap[SIFIVE_U_DEV_DRAM].base,
136
+ machine->ram_size, machine->fdt);
137
+ riscv_load_fdt(fdt_load_addr, machine->fdt);
138
+
139
if (!riscv_is_32bit(&s->soc.u_cpus)) {
140
start_addr_hi32 = (uint64_t)start_addr >> 32;
141
}
142
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
143
index XXXXXXX..XXXXXXX 100644
144
--- a/hw/riscv/spike.c
145
+++ b/hw/riscv/spike.c
146
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
147
kernel_entry = 0;
148
}
149
150
- /* Compute the fdt load address in dram */
151
- fdt_load_addr = riscv_load_fdt(memmap[SPIKE_DRAM].base,
152
- machine->ram_size, machine->fdt);
153
+ fdt_load_addr = riscv_compute_fdt_addr(memmap[SPIKE_DRAM].base,
154
+ machine->ram_size, machine->fdt);
155
+ riscv_load_fdt(fdt_load_addr, machine->fdt);
156
157
/* load the reset vector */
158
riscv_setup_rom_reset_vec(machine, &s->soc[0], memmap[SPIKE_DRAM].base,
159
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/hw/riscv/virt.c
162
+++ b/hw/riscv/virt.c
163
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
164
start_addr = virt_memmap[VIRT_FLASH].base;
165
}
166
167
- /* Compute the fdt load address in dram */
168
- fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
169
- machine->ram_size, machine->fdt);
170
+ fdt_load_addr = riscv_compute_fdt_addr(memmap[VIRT_DRAM].base,
171
+ machine->ram_size, machine->fdt);
172
+ riscv_load_fdt(fdt_load_addr, machine->fdt);
173
+
174
/* load the reset vector */
175
riscv_setup_rom_reset_vec(machine, &s->soc[0], start_addr,
176
virt_memmap[VIRT_MROM].base,
177
--
82
--
178
2.39.1
83
2.45.1
diff view generated by jsdifflib
1
From: Anup Patel <apatel@ventanamicro.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
The time CSR will wrap-around immediately after reaching UINT64_MAX
3
In AIA spec, each hart (or each hart within a group) has a unique hart
4
so we don't need to re-start QEMU timer when timecmp == UINT64_MAX
4
number to locate the memory pages of interrupt files in the address
5
in riscv_timer_write_timecmp().
5
space. The number of bits required to represent any hart number is equal
6
to ceil(log2(hmax + 1)), where hmax is the largest hart number among
7
groups.
6
8
7
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
9
However, if the largest hart number among groups is a power of 2, QEMU
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
will pass an inaccurate hart-index-bit setting to Linux. For example, when
9
Message-Id: <20230120125950.2246378-4-apatel@ventanamicro.com>
11
the guest OS has 4 harts, only ceil(log2(3 + 1)) = 2 bits are sufficient
12
to represent 4 harts, but we passes 3 to Linux. The code needs to be
13
updated to ensure accurate hart-index-bit settings.
14
15
Additionally, a Linux patch[1] is necessary to correctly recover the hart
16
index when the guest OS has only 1 hart, where the hart-index-bit is 0.
17
18
[1] https://lore.kernel.org/lkml/20240415064905.25184-1-yongxuan.wang@sifive.com/t/
19
20
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
21
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
22
Cc: qemu-stable <qemu-stable@nongnu.org>
23
Message-ID: <20240515091129.28116-1-yongxuan.wang@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
25
---
12
target/riscv/time_helper.c | 24 ++++++++++++++++++++++++
26
target/riscv/kvm/kvm-cpu.c | 9 ++++++++-
13
1 file changed, 24 insertions(+)
27
1 file changed, 8 insertions(+), 1 deletion(-)
14
28
15
diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
29
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
16
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/time_helper.c
31
--- a/target/riscv/kvm/kvm-cpu.c
18
+++ b/target/riscv/time_helper.c
32
+++ b/target/riscv/kvm/kvm-cpu.c
19
@@ -XXX,XX +XXX,XX @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer,
33
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
20
riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
34
}
21
}
35
}
22
36
23
+ /*
37
- hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
24
+ * Sstc specification says the following about timer interrupt:
38
+
25
+ * "A supervisor timer interrupt becomes pending - as reflected in
39
+ if (max_hart_per_socket > 1) {
26
+ * the STIP bit in the mip and sip registers - whenever time contains
40
+ max_hart_per_socket--;
27
+ * a value greater than or equal to stimecmp, treating the values
41
+ hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
28
+ * as unsigned integers. Writes to stimecmp are guaranteed to be
42
+ } else {
29
+ * reflected in STIP eventually, but not necessarily immediately.
43
+ hart_bits = 0;
30
+ * The interrupt remains posted until stimecmp becomes greater
31
+ * than time - typically as a result of writing stimecmp."
32
+ *
33
+ * When timecmp = UINT64_MAX, the time CSR will eventually reach
34
+ * timecmp value but on next timer tick the time CSR will wrap-around
35
+ * and become zero which is less than UINT64_MAX. Now, the timer
36
+ * interrupt behaves like a level triggered interrupt so it will
37
+ * become 1 when time = timecmp = UINT64_MAX and next timer tick
38
+ * it will become 0 again because time = 0 < timecmp = UINT64_MAX.
39
+ *
40
+ * Based on above, we don't re-start the QEMU timer when timecmp
41
+ * equals UINT64_MAX.
42
+ */
43
+ if (timecmp == UINT64_MAX) {
44
+ return;
45
+ }
44
+ }
46
+
45
+
47
/* otherwise, set up the future timer interrupt */
46
ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
48
diff = timecmp - rtc_r;
47
KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
49
/* back to ns (note args switched in muldiv64) */
48
&hart_bits, true, NULL);
50
--
49
--
51
2.39.1
50
2.45.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Follow the QEMU convention of naming MachineState pointers as 'ms' by
3
Commit 33a24910ae changed 'reg_width' to use 'vlenb', i.e. vector length
4
renaming the instances where we're calling it 'mc'.
4
in bytes, when in this context we want 'reg_width' as the length in
5
bits.
5
6
6
Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Fix 'reg_width' back to the value in bits like 7cb59921c05a
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
("target/riscv/gdbstub.c: use 'vlenb' instead of shifting 'vlen'") set
9
beforehand.
10
11
While we're at it, rename 'reg_width' to 'bitsize' to provide a bit more
12
clarity about what the variable represents. 'bitsize' is also used in
13
riscv_gen_dynamic_csr_feature() with the same purpose, i.e. as an input to
14
gdb_feature_builder_append_reg().
15
16
Cc: Akihiko Odaki <akihiko.odaki@daynix.com>
17
Cc: Alex Bennée <alex.bennee@linaro.org>
18
Reported-by: Robin Dapp <rdapp.gcc@gmail.com>
19
Fixes: 33a24910ae ("target/riscv: Use GDBFeature for dynamic XML")
20
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
22
Acked-by: Alex Bennée <alex.bennee@linaro.org>
23
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
24
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
25
Cc: qemu-stable <qemu-stable@nongnu.org>
10
Message-Id: <20230124212234.412630-4-dbarboza@ventanamicro.com>
26
Message-ID: <20240517203054.880861-2-dbarboza@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
28
---
13
hw/riscv/spike.c | 18 +++++++++---------
29
target/riscv/gdbstub.c | 6 +++---
14
1 file changed, 9 insertions(+), 9 deletions(-)
30
1 file changed, 3 insertions(+), 3 deletions(-)
15
31
16
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
32
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
17
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/spike.c
34
--- a/target/riscv/gdbstub.c
19
+++ b/hw/riscv/spike.c
35
+++ b/target/riscv/gdbstub.c
20
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
36
@@ -XXX,XX +XXX,XX @@ static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg)
21
uint64_t addr, size;
37
static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
22
unsigned long clint_addr;
38
{
23
int cpu, socket;
39
RISCVCPU *cpu = RISCV_CPU(cs);
24
- MachineState *mc = MACHINE(s);
40
- int reg_width = cpu->cfg.vlenb;
25
+ MachineState *ms = MACHINE(s);
41
+ int bitsize = cpu->cfg.vlenb << 3;
26
uint32_t *clint_cells;
42
GDBFeatureBuilder builder;
27
uint32_t cpu_phandle, intc_phandle, phandle = 1;
43
int i;
28
char *name, *mem_name, *clint_name, *clust_name;
44
29
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
45
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
30
"sifive,clint0", "riscv,clint0"
46
31
};
47
/* First define types and totals in a whole VL */
32
48
for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
33
- fdt = mc->fdt = create_device_tree(&fdt_size);
49
- int count = reg_width / vec_lanes[i].size;
34
+ fdt = ms->fdt = create_device_tree(&fdt_size);
50
+ int count = bitsize / vec_lanes[i].size;
35
if (!fdt) {
51
gdb_feature_builder_append_tag(
36
error_report("create_device_tree() failed");
52
&builder, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
37
exit(1);
53
vec_lanes[i].id, vec_lanes[i].gdb_type, count);
38
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
54
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
39
qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
55
/* Define vector registers */
40
qemu_fdt_add_subnode(fdt, "/cpus/cpu-map");
56
for (i = 0; i < 32; i++) {
41
57
gdb_feature_builder_append_reg(&builder, g_strdup_printf("v%d", i),
42
- for (socket = (riscv_socket_count(mc) - 1); socket >= 0; socket--) {
58
- reg_width, i, "riscv_vector", "vector");
43
+ for (socket = (riscv_socket_count(ms) - 1); socket >= 0; socket--) {
59
+ bitsize, i, "riscv_vector", "vector");
44
clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket);
45
qemu_fdt_add_subnode(fdt, clust_name);
46
47
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
48
qemu_fdt_setprop_cell(fdt, cpu_name, "reg",
49
s->soc[socket].hartid_base + cpu);
50
qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu");
51
- riscv_socket_fdt_write_id(mc, cpu_name, socket);
52
+ riscv_socket_fdt_write_id(ms, cpu_name, socket);
53
qemu_fdt_setprop_cell(fdt, cpu_name, "phandle", cpu_phandle);
54
55
intc_name = g_strdup_printf("%s/interrupt-controller", cpu_name);
56
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
57
g_free(cpu_name);
58
}
59
60
- addr = memmap[SPIKE_DRAM].base + riscv_socket_mem_offset(mc, socket);
61
- size = riscv_socket_mem_size(mc, socket);
62
+ addr = memmap[SPIKE_DRAM].base + riscv_socket_mem_offset(ms, socket);
63
+ size = riscv_socket_mem_size(ms, socket);
64
mem_name = g_strdup_printf("/memory@%lx", (long)addr);
65
qemu_fdt_add_subnode(fdt, mem_name);
66
qemu_fdt_setprop_cells(fdt, mem_name, "reg",
67
addr >> 32, addr, size >> 32, size);
68
qemu_fdt_setprop_string(fdt, mem_name, "device_type", "memory");
69
- riscv_socket_fdt_write_id(mc, mem_name, socket);
70
+ riscv_socket_fdt_write_id(ms, mem_name, socket);
71
g_free(mem_name);
72
73
clint_addr = memmap[SPIKE_CLINT].base +
74
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
75
0x0, clint_addr, 0x0, memmap[SPIKE_CLINT].size);
76
qemu_fdt_setprop(fdt, clint_name, "interrupts-extended",
77
clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
78
- riscv_socket_fdt_write_id(mc, clint_name, socket);
79
+ riscv_socket_fdt_write_id(ms, clint_name, socket);
80
81
g_free(clint_name);
82
g_free(clint_cells);
83
g_free(clust_name);
84
}
60
}
85
61
86
- riscv_socket_fdt_write_distance_matrix(mc);
62
gdb_feature_builder_end(&builder);
87
+ riscv_socket_fdt_write_distance_matrix(ms);
88
89
qemu_fdt_add_subnode(fdt, "/chosen");
90
qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", "/htif");
91
--
63
--
92
2.39.1
64
2.45.1
65
66
diff view generated by jsdifflib
1
From: Philipp Tomsich <philipp.tomsich@vrull.eu>
1
From: Alistair Francis <alistair23@gmail.com>
2
2
3
The decoding of the following instructions from Zb[abcs] currently
3
Previously we only listed a single pmpcfg CSR and the first 16 pmpaddr
4
contains decoding/printing errors:
4
CSRs. This patch fixes this to list all 16 pmpcfg and all 64 pmpaddr
5
* xnor,orn,andn: the rs2 operand is not being printed
5
CSRs are part of the disassembly.
6
* slli.uw: decodes and prints the immediate shift-amount as a
7
register (e.g. 'shift-by-2' becomes 'sp') instead of
8
     interpreting this as an immediate
9
6
10
This commit updates the instruction descriptions to use the
7
Reported-by: Eric DeVolder <eric_devolder@yahoo.com>
11
appropriate decoding/printing formats.
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
9
Fixes: ea10325917 ("RISC-V Disassembler")
13
Signed-off-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Cc: qemu-stable <qemu-stable@nongnu.org>
15
Message-Id: <20230120151551.1022761-1-philipp.tomsich@vrull.eu>
12
Message-ID: <20240514051615.330979-1-alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
14
---
18
disas/riscv.c | 8 ++++----
15
disas/riscv.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-
19
1 file changed, 4 insertions(+), 4 deletions(-)
16
1 file changed, 64 insertions(+), 1 deletion(-)
20
17
21
diff --git a/disas/riscv.c b/disas/riscv.c
18
diff --git a/disas/riscv.c b/disas/riscv.c
22
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
23
--- a/disas/riscv.c
20
--- a/disas/riscv.c
24
+++ b/disas/riscv.c
21
+++ b/disas/riscv.c
25
@@ -XXX,XX +XXX,XX @@ const rv_opcode_data opcode_data[] = {
22
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
26
{ "cpop", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
23
case 0x0383: return "mibound";
27
{ "sext.h", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
24
case 0x0384: return "mdbase";
28
{ "sext.b", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
25
case 0x0385: return "mdbound";
29
- { "xnor", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
26
- case 0x03a0: return "pmpcfg3";
30
- { "orn", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
27
+ case 0x03a0: return "pmpcfg0";
31
- { "andn", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
28
+ case 0x03a1: return "pmpcfg1";
32
+ { "xnor", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
29
+ case 0x03a2: return "pmpcfg2";
33
+ { "orn", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
30
+ case 0x03a3: return "pmpcfg3";
34
+ { "andn", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
31
+ case 0x03a4: return "pmpcfg4";
35
{ "rol", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
32
+ case 0x03a5: return "pmpcfg5";
36
{ "ror", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
33
+ case 0x03a6: return "pmpcfg6";
37
{ "sh1add", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
34
+ case 0x03a7: return "pmpcfg7";
38
@@ -XXX,XX +XXX,XX @@ const rv_opcode_data opcode_data[] = {
35
+ case 0x03a8: return "pmpcfg8";
39
{ "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
36
+ case 0x03a9: return "pmpcfg9";
40
{ "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
37
+ case 0x03aa: return "pmpcfg10";
41
{ "cpopw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
38
+ case 0x03ab: return "pmpcfg11";
42
- { "slli.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
39
+ case 0x03ac: return "pmpcfg12";
43
+ { "slli.uw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
40
+ case 0x03ad: return "pmpcfg13";
44
{ "add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
41
+ case 0x03ae: return "pmpcfg14";
45
{ "rolw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
42
+ case 0x03af: return "pmpcfg15";
46
{ "rorw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
43
case 0x03b0: return "pmpaddr0";
44
case 0x03b1: return "pmpaddr1";
45
case 0x03b2: return "pmpaddr2";
46
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
47
case 0x03bd: return "pmpaddr13";
48
case 0x03be: return "pmpaddr14";
49
case 0x03bf: return "pmpaddr15";
50
+ case 0x03c0: return "pmpaddr16";
51
+ case 0x03c1: return "pmpaddr17";
52
+ case 0x03c2: return "pmpaddr18";
53
+ case 0x03c3: return "pmpaddr19";
54
+ case 0x03c4: return "pmpaddr20";
55
+ case 0x03c5: return "pmpaddr21";
56
+ case 0x03c6: return "pmpaddr22";
57
+ case 0x03c7: return "pmpaddr23";
58
+ case 0x03c8: return "pmpaddr24";
59
+ case 0x03c9: return "pmpaddr25";
60
+ case 0x03ca: return "pmpaddr26";
61
+ case 0x03cb: return "pmpaddr27";
62
+ case 0x03cc: return "pmpaddr28";
63
+ case 0x03cd: return "pmpaddr29";
64
+ case 0x03ce: return "pmpaddr30";
65
+ case 0x03cf: return "pmpaddr31";
66
+ case 0x03d0: return "pmpaddr32";
67
+ case 0x03d1: return "pmpaddr33";
68
+ case 0x03d2: return "pmpaddr34";
69
+ case 0x03d3: return "pmpaddr35";
70
+ case 0x03d4: return "pmpaddr36";
71
+ case 0x03d5: return "pmpaddr37";
72
+ case 0x03d6: return "pmpaddr38";
73
+ case 0x03d7: return "pmpaddr39";
74
+ case 0x03d8: return "pmpaddr40";
75
+ case 0x03d9: return "pmpaddr41";
76
+ case 0x03da: return "pmpaddr42";
77
+ case 0x03db: return "pmpaddr43";
78
+ case 0x03dc: return "pmpaddr44";
79
+ case 0x03dd: return "pmpaddr45";
80
+ case 0x03de: return "pmpaddr46";
81
+ case 0x03df: return "pmpaddr47";
82
+ case 0x03e0: return "pmpaddr48";
83
+ case 0x03e1: return "pmpaddr49";
84
+ case 0x03e2: return "pmpaddr50";
85
+ case 0x03e3: return "pmpaddr51";
86
+ case 0x03e4: return "pmpaddr52";
87
+ case 0x03e5: return "pmpaddr53";
88
+ case 0x03e6: return "pmpaddr54";
89
+ case 0x03e7: return "pmpaddr55";
90
+ case 0x03e8: return "pmpaddr56";
91
+ case 0x03e9: return "pmpaddr57";
92
+ case 0x03ea: return "pmpaddr58";
93
+ case 0x03eb: return "pmpaddr59";
94
+ case 0x03ec: return "pmpaddr60";
95
+ case 0x03ed: return "pmpaddr61";
96
+ case 0x03ee: return "pmpaddr62";
97
+ case 0x03ef: return "pmpaddr63";
98
case 0x0780: return "mtohost";
99
case 0x0781: return "mfromhost";
100
case 0x0782: return "mreset";
47
--
101
--
48
2.39.1
102
2.45.1
diff view generated by jsdifflib
Deleted patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
2
1
3
Updates the opentitan IRQs to match the latest supported commit of
4
Opentitan from TockOS.
5
6
OPENTITAN_SUPPORTED_SHA := 565e4af39760a123c59a184aa2f5812a961fde47
7
8
Memory layout as per [1]
9
10
[1] https://github.com/lowRISC/opentitan/blob/565e4af39760a123c59a184aa2f5812a961fde47/hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
11
12
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-Id: <20230123063619.222459-1-wilfred.mallawa@opensource.wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
include/hw/riscv/opentitan.h | 14 +++----
18
hw/riscv/opentitan.c | 80 ++++++++++++++++++------------------
19
2 files changed, 47 insertions(+), 47 deletions(-)
20
21
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/riscv/opentitan.h
24
+++ b/include/hw/riscv/opentitan.h
25
@@ -XXX,XX +XXX,XX @@ enum {
26
IBEX_DEV_EDNO,
27
IBEX_DEV_EDN1,
28
IBEX_DEV_ALERT_HANDLER,
29
- IBEX_DEV_NMI_GEN,
30
+ IBEX_DEV_SRAM_CTRL,
31
IBEX_DEV_OTBN,
32
- IBEX_DEV_PERI,
33
+ IBEX_DEV_IBEX_CFG,
34
};
35
36
enum {
37
@@ -XXX,XX +XXX,XX @@ enum {
38
IBEX_UART0_RX_BREAK_ERR_IRQ = 6,
39
IBEX_UART0_RX_TIMEOUT_IRQ = 7,
40
IBEX_UART0_RX_PARITY_ERR_IRQ = 8,
41
- IBEX_TIMER_TIMEREXPIRED0_0 = 127,
42
- IBEX_SPI_HOST0_ERR_IRQ = 134,
43
- IBEX_SPI_HOST0_SPI_EVENT_IRQ = 135,
44
- IBEX_SPI_HOST1_ERR_IRQ = 136,
45
- IBEX_SPI_HOST1_SPI_EVENT_IRQ = 137,
46
+ IBEX_TIMER_TIMEREXPIRED0_0 = 124,
47
+ IBEX_SPI_HOST0_ERR_IRQ = 131,
48
+ IBEX_SPI_HOST0_SPI_EVENT_IRQ = 132,
49
+ IBEX_SPI_HOST1_ERR_IRQ = 133,
50
+ IBEX_SPI_HOST1_SPI_EVENT_IRQ = 134,
51
};
52
53
#endif
54
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/riscv/opentitan.c
57
+++ b/hw/riscv/opentitan.c
58
@@ -XXX,XX +XXX,XX @@
59
/*
60
* This version of the OpenTitan machine currently supports
61
* OpenTitan RTL version:
62
- * <lowRISC/opentitan@d072ac505f82152678d6e04be95c72b728a347b8>
63
+ * <lowRISC/opentitan@565e4af39760a123c59a184aa2f5812a961fde47>
64
*
65
* MMIO mapping as per (specified commit):
66
* lowRISC/opentitan: hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
67
*/
68
static const MemMapEntry ibex_memmap[] = {
69
- [IBEX_DEV_ROM] = { 0x00008000, 0x8000 },
70
- [IBEX_DEV_RAM] = { 0x10000000, 0x20000 },
71
- [IBEX_DEV_FLASH] = { 0x20000000, 0x100000 },
72
- [IBEX_DEV_UART] = { 0x40000000, 0x1000 },
73
- [IBEX_DEV_GPIO] = { 0x40040000, 0x1000 },
74
- [IBEX_DEV_SPI_DEVICE] = { 0x40050000, 0x1000 },
75
- [IBEX_DEV_I2C] = { 0x40080000, 0x1000 },
76
- [IBEX_DEV_PATTGEN] = { 0x400e0000, 0x1000 },
77
- [IBEX_DEV_TIMER] = { 0x40100000, 0x1000 },
78
- [IBEX_DEV_OTP_CTRL] = { 0x40130000, 0x4000 },
79
- [IBEX_DEV_LC_CTRL] = { 0x40140000, 0x1000 },
80
- [IBEX_DEV_ALERT_HANDLER] = { 0x40150000, 0x1000 },
81
- [IBEX_DEV_SPI_HOST0] = { 0x40300000, 0x1000 },
82
- [IBEX_DEV_SPI_HOST1] = { 0x40310000, 0x1000 },
83
- [IBEX_DEV_USBDEV] = { 0x40320000, 0x1000 },
84
- [IBEX_DEV_PWRMGR] = { 0x40400000, 0x1000 },
85
- [IBEX_DEV_RSTMGR] = { 0x40410000, 0x1000 },
86
- [IBEX_DEV_CLKMGR] = { 0x40420000, 0x1000 },
87
- [IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
88
- [IBEX_DEV_AON_TIMER] = { 0x40470000, 0x1000 },
89
- [IBEX_DEV_SENSOR_CTRL] = { 0x40490000, 0x1000 },
90
- [IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x1000 },
91
- [IBEX_DEV_AES] = { 0x41100000, 0x1000 },
92
- [IBEX_DEV_HMAC] = { 0x41110000, 0x1000 },
93
- [IBEX_DEV_KMAC] = { 0x41120000, 0x1000 },
94
- [IBEX_DEV_OTBN] = { 0x41130000, 0x10000 },
95
- [IBEX_DEV_KEYMGR] = { 0x41140000, 0x1000 },
96
- [IBEX_DEV_CSRNG] = { 0x41150000, 0x1000 },
97
- [IBEX_DEV_ENTROPY] = { 0x41160000, 0x1000 },
98
- [IBEX_DEV_EDNO] = { 0x41170000, 0x1000 },
99
- [IBEX_DEV_EDN1] = { 0x41180000, 0x1000 },
100
- [IBEX_DEV_NMI_GEN] = { 0x411c0000, 0x1000 },
101
- [IBEX_DEV_PERI] = { 0x411f0000, 0x10000 },
102
- [IBEX_DEV_PLIC] = { 0x48000000, 0x4005000 },
103
- [IBEX_DEV_FLASH_VIRTUAL] = { 0x80000000, 0x80000 },
104
+ [IBEX_DEV_ROM] = { 0x00008000, 0x8000 },
105
+ [IBEX_DEV_RAM] = { 0x10000000, 0x20000 },
106
+ [IBEX_DEV_FLASH] = { 0x20000000, 0x100000 },
107
+ [IBEX_DEV_UART] = { 0x40000000, 0x40 },
108
+ [IBEX_DEV_GPIO] = { 0x40040000, 0x40 },
109
+ [IBEX_DEV_SPI_DEVICE] = { 0x40050000, 0x2000 },
110
+ [IBEX_DEV_I2C] = { 0x40080000, 0x80 },
111
+ [IBEX_DEV_PATTGEN] = { 0x400e0000, 0x40 },
112
+ [IBEX_DEV_TIMER] = { 0x40100000, 0x200 },
113
+ [IBEX_DEV_OTP_CTRL] = { 0x40130000, 0x2000 },
114
+ [IBEX_DEV_LC_CTRL] = { 0x40140000, 0x100 },
115
+ [IBEX_DEV_ALERT_HANDLER] = { 0x40150000, 0x800 },
116
+ [IBEX_DEV_SPI_HOST0] = { 0x40300000, 0x40 },
117
+ [IBEX_DEV_SPI_HOST1] = { 0x40310000, 0x40 },
118
+ [IBEX_DEV_USBDEV] = { 0x40320000, 0x1000 },
119
+ [IBEX_DEV_PWRMGR] = { 0x40400000, 0x80 },
120
+ [IBEX_DEV_RSTMGR] = { 0x40410000, 0x80 },
121
+ [IBEX_DEV_CLKMGR] = { 0x40420000, 0x80 },
122
+ [IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
123
+ [IBEX_DEV_AON_TIMER] = { 0x40470000, 0x40 },
124
+ [IBEX_DEV_SENSOR_CTRL] = { 0x40490000, 0x40 },
125
+ [IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x200 },
126
+ [IBEX_DEV_AES] = { 0x41100000, 0x100 },
127
+ [IBEX_DEV_HMAC] = { 0x41110000, 0x1000 },
128
+ [IBEX_DEV_KMAC] = { 0x41120000, 0x1000 },
129
+ [IBEX_DEV_OTBN] = { 0x41130000, 0x10000 },
130
+ [IBEX_DEV_KEYMGR] = { 0x41140000, 0x100 },
131
+ [IBEX_DEV_CSRNG] = { 0x41150000, 0x80 },
132
+ [IBEX_DEV_ENTROPY] = { 0x41160000, 0x100 },
133
+ [IBEX_DEV_EDNO] = { 0x41170000, 0x80 },
134
+ [IBEX_DEV_EDN1] = { 0x41180000, 0x80 },
135
+ [IBEX_DEV_SRAM_CTRL] = { 0x411c0000, 0x20 },
136
+ [IBEX_DEV_IBEX_CFG] = { 0x411f0000, 0x100 },
137
+ [IBEX_DEV_PLIC] = { 0x48000000, 0x8000000 },
138
+ [IBEX_DEV_FLASH_VIRTUAL] = { 0x80000000, 0x80000 },
139
};
140
141
static void opentitan_board_init(MachineState *machine)
142
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
143
memmap[IBEX_DEV_EDN1].base, memmap[IBEX_DEV_EDN1].size);
144
create_unimplemented_device("riscv.lowrisc.ibex.alert_handler",
145
memmap[IBEX_DEV_ALERT_HANDLER].base, memmap[IBEX_DEV_ALERT_HANDLER].size);
146
- create_unimplemented_device("riscv.lowrisc.ibex.nmi_gen",
147
- memmap[IBEX_DEV_NMI_GEN].base, memmap[IBEX_DEV_NMI_GEN].size);
148
+ create_unimplemented_device("riscv.lowrisc.ibex.sram_ctrl",
149
+ memmap[IBEX_DEV_SRAM_CTRL].base, memmap[IBEX_DEV_SRAM_CTRL].size);
150
create_unimplemented_device("riscv.lowrisc.ibex.otbn",
151
memmap[IBEX_DEV_OTBN].base, memmap[IBEX_DEV_OTBN].size);
152
- create_unimplemented_device("riscv.lowrisc.ibex.peri",
153
- memmap[IBEX_DEV_PERI].base, memmap[IBEX_DEV_PERI].size);
154
+ create_unimplemented_device("riscv.lowrisc.ibex.ibex_cfg",
155
+ memmap[IBEX_DEV_IBEX_CFG].base, memmap[IBEX_DEV_IBEX_CFG].size);
156
}
157
158
static Property lowrisc_ibex_soc_props[] = {
159
--
160
2.39.1
diff view generated by jsdifflib
Deleted patch
1
From: Alistair Francis <alistair.francis@wdc.com>
2
1
3
If the CSRs and CSR instructions are disabled because the Zicsr
4
extension isn't enabled then we want to make sure we don't run any CSR
5
instructions in the boot ROM.
6
7
This patches removes the CSR instructions from the reset-vec if the
8
extension isn't enabled. We replace the instruction with a NOP instead.
9
10
Note that we don't do this for the SiFive U machine, as we are modelling
11
the hardware in that case.
12
13
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1447
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
16
Message-Id: <20230123035754.75553-1-alistair.francis@opensource.wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
19
hw/riscv/boot.c | 9 +++++++++
20
1 file changed, 9 insertions(+)
21
22
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/riscv/boot.c
25
+++ b/hw/riscv/boot.c
26
@@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts
27
reset_vec[4] = 0x0182b283; /* ld t0, 24(t0) */
28
}
29
30
+ if (!harts->harts[0].cfg.ext_icsr) {
31
+ /*
32
+ * The Zicsr extension has been disabled, so let's ensure we don't
33
+ * run the CSR instruction. Let's fill the address with a non
34
+ * compressed nop.
35
+ */
36
+ reset_vec[2] = 0x00000013; /* addi x0, x0, 0 */
37
+ }
38
+
39
/* copy in the reset vector in little_endian byte order */
40
for (i = 0; i < ARRAY_SIZE(reset_vec); i++) {
41
reset_vec[i] = cpu_to_le32(reset_vec[i]);
42
--
43
2.39.1
diff view generated by jsdifflib
Deleted patch
1
From: Anup Patel <apatel@ventanamicro.com>
2
1
3
We should call decode_save_opc() for all relevant instructions which
4
can potentially generate a virtual instruction fault or a guest page
5
fault because generating transformed instruction upon guest page fault
6
expects opcode to be available. Without this, hypervisor will see
7
transformed instruction as zero in htinst CSR for guest MMIO emulation
8
which makes MMIO emulation in hypervisor slow and also breaks nested
9
virtualization.
10
11
Fixes: a9814e3e08d2 ("target/riscv: Minimize the calls to decode_save_opc")
12
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-Id: <20230120125950.2246378-5-apatel@ventanamicro.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
target/riscv/insn_trans/trans_rva.c.inc | 10 +++++++---
18
target/riscv/insn_trans/trans_rvd.c.inc | 2 ++
19
target/riscv/insn_trans/trans_rvf.c.inc | 2 ++
20
target/riscv/insn_trans/trans_rvh.c.inc | 3 +++
21
target/riscv/insn_trans/trans_rvi.c.inc | 2 ++
22
target/riscv/insn_trans/trans_rvzfh.c.inc | 2 ++
23
target/riscv/insn_trans/trans_svinval.c.inc | 3 +++
24
7 files changed, 21 insertions(+), 3 deletions(-)
25
26
diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/insn_trans/trans_rva.c.inc
29
+++ b/target/riscv/insn_trans/trans_rva.c.inc
30
@@ -XXX,XX +XXX,XX @@
31
32
static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
33
{
34
- TCGv src1 = get_address(ctx, a->rs1, 0);
35
+ TCGv src1;
36
37
+ decode_save_opc(ctx);
38
+ src1 = get_address(ctx, a->rs1, 0);
39
if (a->rl) {
40
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
41
}
42
@@ -XXX,XX +XXX,XX @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
43
TCGLabel *l1 = gen_new_label();
44
TCGLabel *l2 = gen_new_label();
45
46
+ decode_save_opc(ctx);
47
src1 = get_address(ctx, a->rs1, 0);
48
tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
49
50
@@ -XXX,XX +XXX,XX @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
51
MemOp mop)
52
{
53
TCGv dest = dest_gpr(ctx, a->rd);
54
- TCGv src1 = get_address(ctx, a->rs1, 0);
55
- TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
56
+ TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE);
57
58
+ decode_save_opc(ctx);
59
+ src1 = get_address(ctx, a->rs1, 0);
60
func(dest, src1, src2, ctx->mem_idx, mop);
61
62
gen_set_gpr(ctx, a->rd, dest);
63
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/riscv/insn_trans/trans_rvd.c.inc
66
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
67
@@ -XXX,XX +XXX,XX @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
68
REQUIRE_FPU;
69
REQUIRE_EXT(ctx, RVD);
70
71
+ decode_save_opc(ctx);
72
addr = get_address(ctx, a->rs1, a->imm);
73
tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEUQ);
74
75
@@ -XXX,XX +XXX,XX @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
76
REQUIRE_FPU;
77
REQUIRE_EXT(ctx, RVD);
78
79
+ decode_save_opc(ctx);
80
addr = get_address(ctx, a->rs1, a->imm);
81
tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUQ);
82
return true;
83
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
84
index XXXXXXX..XXXXXXX 100644
85
--- a/target/riscv/insn_trans/trans_rvf.c.inc
86
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
87
@@ -XXX,XX +XXX,XX @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
88
REQUIRE_FPU;
89
REQUIRE_EXT(ctx, RVF);
90
91
+ decode_save_opc(ctx);
92
addr = get_address(ctx, a->rs1, a->imm);
93
dest = cpu_fpr[a->rd];
94
tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
95
@@ -XXX,XX +XXX,XX @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
96
REQUIRE_FPU;
97
REQUIRE_EXT(ctx, RVF);
98
99
+ decode_save_opc(ctx);
100
addr = get_address(ctx, a->rs1, a->imm);
101
tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
102
return true;
103
diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/riscv/insn_trans/trans_rvh.c.inc
106
+++ b/target/riscv/insn_trans/trans_rvh.c.inc
107
@@ -XXX,XX +XXX,XX @@ static bool do_hlv(DisasContext *ctx, arg_r2 *a, MemOp mop)
108
#ifdef CONFIG_USER_ONLY
109
return false;
110
#else
111
+ decode_save_opc(ctx);
112
if (check_access(ctx)) {
113
TCGv dest = dest_gpr(ctx, a->rd);
114
TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
115
@@ -XXX,XX +XXX,XX @@ static bool do_hsv(DisasContext *ctx, arg_r2_s *a, MemOp mop)
116
#ifdef CONFIG_USER_ONLY
117
return false;
118
#else
119
+ decode_save_opc(ctx);
120
if (check_access(ctx)) {
121
TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
122
TCGv data = get_gpr(ctx, a->rs2, EXT_NONE);
123
@@ -XXX,XX +XXX,XX @@ static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a)
124
static bool do_hlvx(DisasContext *ctx, arg_r2 *a,
125
void (*func)(TCGv, TCGv_env, TCGv))
126
{
127
+ decode_save_opc(ctx);
128
if (check_access(ctx)) {
129
TCGv dest = dest_gpr(ctx, a->rd);
130
TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
131
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/riscv/insn_trans/trans_rvi.c.inc
134
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
135
@@ -XXX,XX +XXX,XX @@ static bool gen_load_i128(DisasContext *ctx, arg_lb *a, MemOp memop)
136
137
static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
138
{
139
+ decode_save_opc(ctx);
140
if (get_xl(ctx) == MXL_RV128) {
141
return gen_load_i128(ctx, a, memop);
142
} else {
143
@@ -XXX,XX +XXX,XX @@ static bool gen_store_i128(DisasContext *ctx, arg_sb *a, MemOp memop)
144
145
static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
146
{
147
+ decode_save_opc(ctx);
148
if (get_xl(ctx) == MXL_RV128) {
149
return gen_store_i128(ctx, a, memop);
150
} else {
151
diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc
152
index XXXXXXX..XXXXXXX 100644
153
--- a/target/riscv/insn_trans/trans_rvzfh.c.inc
154
+++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
155
@@ -XXX,XX +XXX,XX @@ static bool trans_flh(DisasContext *ctx, arg_flh *a)
156
REQUIRE_FPU;
157
REQUIRE_ZFH_OR_ZFHMIN(ctx);
158
159
+ decode_save_opc(ctx);
160
t0 = get_gpr(ctx, a->rs1, EXT_NONE);
161
if (a->imm) {
162
TCGv temp = temp_new(ctx);
163
@@ -XXX,XX +XXX,XX @@ static bool trans_fsh(DisasContext *ctx, arg_fsh *a)
164
REQUIRE_FPU;
165
REQUIRE_ZFH_OR_ZFHMIN(ctx);
166
167
+ decode_save_opc(ctx);
168
t0 = get_gpr(ctx, a->rs1, EXT_NONE);
169
if (a->imm) {
170
TCGv temp = tcg_temp_new();
171
diff --git a/target/riscv/insn_trans/trans_svinval.c.inc b/target/riscv/insn_trans/trans_svinval.c.inc
172
index XXXXXXX..XXXXXXX 100644
173
--- a/target/riscv/insn_trans/trans_svinval.c.inc
174
+++ b/target/riscv/insn_trans/trans_svinval.c.inc
175
@@ -XXX,XX +XXX,XX @@ static bool trans_sinval_vma(DisasContext *ctx, arg_sinval_vma *a)
176
/* Do the same as sfence.vma currently */
177
REQUIRE_EXT(ctx, RVS);
178
#ifndef CONFIG_USER_ONLY
179
+ decode_save_opc(ctx);
180
gen_helper_tlb_flush(cpu_env);
181
return true;
182
#endif
183
@@ -XXX,XX +XXX,XX @@ static bool trans_hinval_vvma(DisasContext *ctx, arg_hinval_vvma *a)
184
/* Do the same as hfence.vvma currently */
185
REQUIRE_EXT(ctx, RVH);
186
#ifndef CONFIG_USER_ONLY
187
+ decode_save_opc(ctx);
188
gen_helper_hyp_tlb_flush(cpu_env);
189
return true;
190
#endif
191
@@ -XXX,XX +XXX,XX @@ static bool trans_hinval_gvma(DisasContext *ctx, arg_hinval_gvma *a)
192
/* Do the same as hfence.gvma currently */
193
REQUIRE_EXT(ctx, RVH);
194
#ifndef CONFIG_USER_ONLY
195
+ decode_save_opc(ctx);
196
gen_helper_hyp_gvma_tlb_flush(cpu_env);
197
return true;
198
#endif
199
--
200
2.39.1
diff view generated by jsdifflib
Deleted patch
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
2
1
3
This patch adds support for the XTheadBa ISA extension.
4
The patch uses the T-Head specific decoder and translation.
5
6
Co-developed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
7
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
10
Message-Id: <20230131202013.2541053-4-christoph.muellner@vrull.eu>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/cpu.h | 1 +
14
target/riscv/xthead.decode | 22 ++++++++++++
15
target/riscv/cpu.c | 2 ++
16
target/riscv/translate.c | 3 +-
17
target/riscv/insn_trans/trans_xthead.c.inc | 39 ++++++++++++++++++++++
18
5 files changed, 66 insertions(+), 1 deletion(-)
19
20
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/cpu.h
23
+++ b/target/riscv/cpu.h
24
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
25
uint64_t mimpid;
26
27
/* Vendor-specific custom extensions */
28
+ bool ext_xtheadba;
29
bool ext_xtheadcmo;
30
bool ext_xtheadsync;
31
bool ext_XVentanaCondOps;
32
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/xthead.decode
35
+++ b/target/riscv/xthead.decode
36
@@ -XXX,XX +XXX,XX @@
37
# Translation routines for the instructions of the XThead* ISA extensions
38
#
39
# Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.eu
40
+# Dr. Philipp Tomsich, philipp.tomsich@vrull.eu
41
#
42
# SPDX-License-Identifier: LGPL-2.1-or-later
43
#
44
@@ -XXX,XX +XXX,XX @@
45
# https://github.com/T-head-Semi/thead-extension-spec/releases/latest
46
47
# Fields:
48
+%rd 7:5
49
%rs1 15:5
50
%rs2 20:5
51
52
+# Argument sets
53
+&r rd rs1 rs2 !extern
54
+
55
# Formats
56
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
57
@rs2_s ....... ..... ..... ... ..... ....... %rs2 %rs1
58
+@r ....... ..... ..... ... ..... ....... &r %rs2 %rs1 %rd
59
+
60
+# XTheadBa
61
+# Instead of defining a new encoding, we simply use the decoder to
62
+# extract the imm[0:1] field and dispatch to separate translation
63
+# functions (mirroring the `sh[123]add` instructions from Zba and
64
+# the regular RVI `add` instruction.
65
+#
66
+# The only difference between sh[123]add and addsl is that the shift
67
+# is applied to rs1 (for addsl) instead of rs2 (for sh[123]add).
68
+#
69
+# Note that shift-by-0 is a valid operation according to the manual.
70
+# This will be equivalent to a regular add.
71
+add 0000000 ..... ..... 001 ..... 0001011 @r
72
+th_addsl1 0000001 ..... ..... 001 ..... 0001011 @r
73
+th_addsl2 0000010 ..... ..... 001 ..... 0001011 @r
74
+th_addsl3 0000011 ..... ..... 001 ..... 0001011 @r
75
76
# XTheadCmo
77
th_dcache_call 0000000 00001 00000 000 00000 0001011
78
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/riscv/cpu.c
81
+++ b/target/riscv/cpu.c
82
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
83
ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
84
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
85
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
86
+ ISA_EXT_DATA_ENTRY(xtheadba, true, PRIV_VERSION_1_11_0, ext_xtheadba),
87
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
88
ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
89
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
90
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
91
DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false),
92
93
/* Vendor-specific custom extensions */
94
+ DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
95
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
96
DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
97
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
98
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/riscv/translate.c
101
+++ b/target/riscv/translate.c
102
@@ -XXX,XX +XXX,XX @@ static bool always_true_p(DisasContext *ctx __attribute__((__unused__)))
103
104
static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
105
{
106
- return ctx->cfg_ptr->ext_xtheadcmo || ctx->cfg_ptr->ext_xtheadsync;
107
+ return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadcmo ||
108
+ ctx->cfg_ptr->ext_xtheadsync;
109
}
110
111
#define MATERIALISE_EXT_PREDICATE(ext) \
112
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/riscv/insn_trans/trans_xthead.c.inc
115
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
116
@@ -XXX,XX +XXX,XX @@
117
* this program. If not, see <http://www.gnu.org/licenses/>.
118
*/
119
120
+#define REQUIRE_XTHEADBA(ctx) do { \
121
+ if (!ctx->cfg_ptr->ext_xtheadba) { \
122
+ return false; \
123
+ } \
124
+} while (0)
125
+
126
#define REQUIRE_XTHEADCMO(ctx) do { \
127
if (!ctx->cfg_ptr->ext_xtheadcmo) { \
128
return false; \
129
@@ -XXX,XX +XXX,XX @@
130
} \
131
} while (0)
132
133
+/* XTheadBa */
134
+
135
+/*
136
+ * th.addsl is similar to sh[123]add (from Zba), but not an
137
+ * alternative encoding: while sh[123] applies the shift to rs1,
138
+ * th.addsl shifts rs2.
139
+ */
140
+
141
+#define GEN_TH_ADDSL(SHAMT) \
142
+static void gen_th_addsl##SHAMT(TCGv ret, TCGv arg1, TCGv arg2) \
143
+{ \
144
+ TCGv t = tcg_temp_new(); \
145
+ tcg_gen_shli_tl(t, arg2, SHAMT); \
146
+ tcg_gen_add_tl(ret, t, arg1); \
147
+ tcg_temp_free(t); \
148
+}
149
+
150
+GEN_TH_ADDSL(1)
151
+GEN_TH_ADDSL(2)
152
+GEN_TH_ADDSL(3)
153
+
154
+#define GEN_TRANS_TH_ADDSL(SHAMT) \
155
+static bool trans_th_addsl##SHAMT(DisasContext *ctx, \
156
+ arg_th_addsl##SHAMT * a) \
157
+{ \
158
+ REQUIRE_XTHEADBA(ctx); \
159
+ return gen_arith(ctx, a, EXT_NONE, gen_th_addsl##SHAMT, NULL); \
160
+}
161
+
162
+GEN_TRANS_TH_ADDSL(1)
163
+GEN_TRANS_TH_ADDSL(2)
164
+GEN_TRANS_TH_ADDSL(3)
165
+
166
/* XTheadCmo */
167
168
static inline int priv_level(DisasContext *ctx)
169
--
170
2.39.1
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Yu-Ming Chang <yumin686@andestech.com>
2
2
3
This patch adds support for the T-Head MAC instructions.
3
Both CSRRS and CSRRC always read the addressed CSR and cause any read side
4
The patch uses the T-Head specific decoder and translation.
4
effects regardless of rs1 and rd fields. Note that if rs1 specifies a register
5
holding a zero value other than x0, the instruction will still attempt to write
6
the unmodified value back to the CSR and will cause any attendant side effects.
5
7
6
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
So if CSRRS or CSRRC tries to write a read-only CSR with rs1 which specifies
9
a register holding a zero value, an illegal instruction exception should be
10
raised.
11
12
Signed-off-by: Yu-Ming Chang <yumin686@andestech.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
14
Message-ID: <20240403070823.80897-1-yumin686@andestech.com>
9
Message-Id: <20230131202013.2541053-8-christoph.muellner@vrull.eu>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
16
---
12
target/riscv/cpu.h | 1 +
17
target/riscv/cpu.h | 4 ++++
13
target/riscv/xthead.decode | 8 +++
18
target/riscv/csr.c | 51 ++++++++++++++++++++++++++++++++++++----
14
target/riscv/cpu.c | 2 +
19
target/riscv/op_helper.c | 6 ++---
15
target/riscv/translate.c | 3 +-
20
3 files changed, 53 insertions(+), 8 deletions(-)
16
target/riscv/insn_trans/trans_xthead.c.inc | 83 ++++++++++++++++++++++
17
5 files changed, 96 insertions(+), 1 deletion(-)
18
21
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
22
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
20
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.h
24
--- a/target/riscv/cpu.h
22
+++ b/target/riscv/cpu.h
25
+++ b/target/riscv/cpu.h
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
26
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
24
bool ext_xtheadbs;
27
void riscv_cpu_update_mask(CPURISCVState *env);
25
bool ext_xtheadcmo;
28
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
26
bool ext_xtheadcondmov;
29
27
+ bool ext_xtheadmac;
30
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
28
bool ext_xtheadsync;
31
+ target_ulong *ret_value);
29
bool ext_XVentanaCondOps;
32
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
30
33
target_ulong *ret_value,
31
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
34
target_ulong new_value, target_ulong write_mask);
35
@@ -XXX,XX +XXX,XX @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
36
target_ulong new_value,
37
target_ulong write_mask);
38
39
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
40
+ Int128 *ret_value);
41
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
42
Int128 *ret_value,
43
Int128 new_value, Int128 write_mask);
44
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
32
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/xthead.decode
46
--- a/target/riscv/csr.c
34
+++ b/target/riscv/xthead.decode
47
+++ b/target/riscv/csr.c
35
@@ -XXX,XX +XXX,XX @@ th_l2cache_iall 0000000 10110 00000 000 00000 0001011
48
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
36
th_mveqz 0100000 ..... ..... 001 ..... 0001011 @r
49
37
th_mvnez 0100001 ..... ..... 001 ..... 0001011 @r
50
static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
38
51
int csrno,
39
+# XTheadMac
52
- bool write_mask)
40
+th_mula 00100 00 ..... ..... 001 ..... 0001011 @r
53
+ bool write)
41
+th_mulah 00101 00 ..... ..... 001 ..... 0001011 @r
42
+th_mulaw 00100 10 ..... ..... 001 ..... 0001011 @r
43
+th_muls 00100 01 ..... ..... 001 ..... 0001011 @r
44
+th_mulsh 00101 01 ..... ..... 001 ..... 0001011 @r
45
+th_mulsw 00100 11 ..... ..... 001 ..... 0001011 @r
46
+
47
# XTheadSync
48
th_sfence_vmas 0000010 ..... ..... 000 00000 0001011 @rs2_s
49
th_sync 0000000 11000 00000 000 00000 0001011
50
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/riscv/cpu.c
53
+++ b/target/riscv/cpu.c
54
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
55
ISA_EXT_DATA_ENTRY(xtheadbs, true, PRIV_VERSION_1_11_0, ext_xtheadbs),
56
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
57
ISA_EXT_DATA_ENTRY(xtheadcondmov, true, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
58
+ ISA_EXT_DATA_ENTRY(xtheadmac, true, PRIV_VERSION_1_11_0, ext_xtheadmac),
59
ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
60
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
61
};
62
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
63
DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
64
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
65
DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
66
+ DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false),
67
DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
68
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
69
70
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/riscv/translate.c
73
+++ b/target/riscv/translate.c
74
@@ -XXX,XX +XXX,XX @@ static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
75
{
54
{
76
return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
55
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
77
ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
56
bool read_only = get_field(csrno, 0xC00) == 3;
78
- ctx->cfg_ptr->ext_xtheadcondmov || ctx->cfg_ptr->ext_xtheadsync;
57
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
79
+ ctx->cfg_ptr->ext_xtheadcondmov || ctx->cfg_ptr->ext_xtheadmac ||
58
}
80
+ ctx->cfg_ptr->ext_xtheadsync;
59
60
/* read / write check */
61
- if (write_mask && read_only) {
62
+ if (write && read_only) {
63
return RISCV_EXCP_ILLEGAL_INST;
64
}
65
66
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
67
return RISCV_EXCP_NONE;
81
}
68
}
82
69
83
#define MATERIALISE_EXT_PREDICATE(ext) \
70
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
84
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
71
+ target_ulong *ret_value)
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/riscv/insn_trans/trans_xthead.c.inc
87
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
88
@@ -XXX,XX +XXX,XX @@
89
} \
90
} while (0)
91
92
+#define REQUIRE_XTHEADMAC(ctx) do { \
93
+ if (!ctx->cfg_ptr->ext_xtheadmac) { \
94
+ return false; \
95
+ } \
96
+} while (0)
97
+
98
#define REQUIRE_XTHEADSYNC(ctx) do { \
99
if (!ctx->cfg_ptr->ext_xtheadsync) { \
100
return false; \
101
@@ -XXX,XX +XXX,XX @@ static bool trans_th_mvnez(DisasContext *ctx, arg_th_mveqz *a)
102
return gen_th_condmove(ctx, a, TCG_COND_NE);
103
}
104
105
+/* XTheadMac */
106
+
107
+static bool gen_th_mac(DisasContext *ctx, arg_r *a,
108
+ void (*accumulate_func)(TCGv, TCGv, TCGv),
109
+ void (*extend_operand_func)(TCGv, TCGv))
110
+{
72
+{
111
+ TCGv dest = dest_gpr(ctx, a->rd);
73
+ RISCVException ret = riscv_csrrw_check(env, csrno, false);
112
+ TCGv src0 = get_gpr(ctx, a->rd, EXT_NONE);
74
+ if (ret != RISCV_EXCP_NONE) {
113
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
75
+ return ret;
114
+ TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
115
+ TCGv tmp = tcg_temp_new();
116
+
117
+ if (extend_operand_func) {
118
+ TCGv tmp2 = tcg_temp_new();
119
+ extend_operand_func(tmp, src1);
120
+ extend_operand_func(tmp2, src2);
121
+ tcg_gen_mul_tl(tmp, tmp, tmp2);
122
+ tcg_temp_free(tmp2);
123
+ } else {
124
+ tcg_gen_mul_tl(tmp, src1, src2);
125
+ }
76
+ }
126
+
77
+
127
+ accumulate_func(dest, src0, tmp);
78
+ return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
128
+ gen_set_gpr(ctx, a->rd, dest);
129
+ tcg_temp_free(tmp);
130
+
131
+ return true;
132
+}
79
+}
133
+
80
+
134
+/* th.mula: "rd = rd + rs1 * rs2" */
81
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
135
+static bool trans_th_mula(DisasContext *ctx, arg_th_mula *a)
82
target_ulong *ret_value,
83
target_ulong new_value, target_ulong write_mask)
84
{
85
- RISCVException ret = riscv_csrrw_check(env, csrno, write_mask);
86
+ RISCVException ret = riscv_csrrw_check(env, csrno, true);
87
if (ret != RISCV_EXCP_NONE) {
88
return ret;
89
}
90
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
91
return RISCV_EXCP_NONE;
92
}
93
94
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
95
+ Int128 *ret_value)
136
+{
96
+{
137
+ REQUIRE_XTHEADMAC(ctx);
97
+ RISCVException ret;
138
+ return gen_th_mac(ctx, a, tcg_gen_add_tl, NULL);
98
+
99
+ ret = riscv_csrrw_check(env, csrno, false);
100
+ if (ret != RISCV_EXCP_NONE) {
101
+ return ret;
102
+ }
103
+
104
+ if (csr_ops[csrno].read128) {
105
+ return riscv_csrrw_do128(env, csrno, ret_value,
106
+ int128_zero(), int128_zero());
107
+ }
108
+
109
+ /*
110
+ * Fall back to 64-bit version for now, if the 128-bit alternative isn't
111
+ * at all defined.
112
+ * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
113
+ * significant), for those, this fallback is correctly handling the
114
+ * accesses
115
+ */
116
+ target_ulong old_value;
117
+ ret = riscv_csrrw_do64(env, csrno, &old_value,
118
+ (target_ulong)0,
119
+ (target_ulong)0);
120
+ if (ret == RISCV_EXCP_NONE && ret_value) {
121
+ *ret_value = int128_make64(old_value);
122
+ }
123
+ return ret;
139
+}
124
+}
140
+
125
+
141
+/* th.mulah: "rd = sext.w(rd + sext.w(rs1[15:0]) * sext.w(rs2[15:0]))" */
126
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
142
+static bool trans_th_mulah(DisasContext *ctx, arg_th_mulah *a)
127
Int128 *ret_value,
143
+{
128
Int128 new_value, Int128 write_mask)
144
+ REQUIRE_XTHEADMAC(ctx);
129
{
145
+ ctx->ol = MXL_RV32;
130
RISCVException ret;
146
+ return gen_th_mac(ctx, a, tcg_gen_add_tl, tcg_gen_ext16s_tl);
131
147
+}
132
- ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask));
148
+
133
+ ret = riscv_csrrw_check(env, csrno, true);
149
+/* th.mulaw: "rd = sext.w(rd + rs1 * rs2)" */
134
if (ret != RISCV_EXCP_NONE) {
150
+static bool trans_th_mulaw(DisasContext *ctx, arg_th_mulaw *a)
135
return ret;
151
+{
136
}
152
+ REQUIRE_XTHEADMAC(ctx);
137
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
153
+ REQUIRE_64BIT(ctx);
138
index XXXXXXX..XXXXXXX 100644
154
+ ctx->ol = MXL_RV32;
139
--- a/target/riscv/op_helper.c
155
+ return gen_th_mac(ctx, a, tcg_gen_add_tl, NULL);
140
+++ b/target/riscv/op_helper.c
156
+}
141
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
157
+
142
}
158
+/* th.muls: "rd = rd - rs1 * rs2" */
143
159
+static bool trans_th_muls(DisasContext *ctx, arg_th_muls *a)
144
target_ulong val = 0;
160
+{
145
- RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
161
+ REQUIRE_XTHEADMAC(ctx);
146
+ RISCVException ret = riscv_csrr(env, csr, &val);
162
+ return gen_th_mac(ctx, a, tcg_gen_sub_tl, NULL);
147
163
+}
148
if (ret != RISCV_EXCP_NONE) {
164
+
149
riscv_raise_exception(env, ret, GETPC());
165
+/* th.mulsh: "rd = sext.w(rd - sext.w(rs1[15:0]) * sext.w(rs2[15:0]))" */
150
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
166
+static bool trans_th_mulsh(DisasContext *ctx, arg_th_mulsh *a)
151
target_ulong helper_csrr_i128(CPURISCVState *env, int csr)
167
+{
152
{
168
+ REQUIRE_XTHEADMAC(ctx);
153
Int128 rv = int128_zero();
169
+ ctx->ol = MXL_RV32;
154
- RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
170
+ return gen_th_mac(ctx, a, tcg_gen_sub_tl, tcg_gen_ext16s_tl);
155
- int128_zero(),
171
+}
156
- int128_zero());
172
+
157
+ RISCVException ret = riscv_csrr_i128(env, csr, &rv);
173
+/* th.mulsw: "rd = sext.w(rd - rs1 * rs2)" */
158
174
+static bool trans_th_mulsw(DisasContext *ctx, arg_th_mulsw *a)
159
if (ret != RISCV_EXCP_NONE) {
175
+{
160
riscv_raise_exception(env, ret, GETPC());
176
+ REQUIRE_XTHEADMAC(ctx);
177
+ REQUIRE_64BIT(ctx);
178
+ ctx->ol = MXL_RV32;
179
+ return gen_th_mac(ctx, a, tcg_gen_sub_tl, NULL);
180
+}
181
+
182
/* XTheadSync */
183
184
static bool trans_th_sfence_vmas(DisasContext *ctx, arg_th_sfence_vmas *a)
185
--
161
--
186
2.39.1
162
2.45.1
diff view generated by jsdifflib