1
The following changes since commit 7774e403f2ac58b3e87bfe8d2f77676501ba893e:
1
The following changes since commit ad10b4badc1dd5b28305f9b9f1168cf0aa3ae946:
2
2
3
Merge remote-tracking branch 'remotes/kraxel/tags/fixes-20200825-pull-request' into staging (2020-08-25 10:54:51 +0100)
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
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20200825
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240528
8
8
9
for you to fetch changes up to e39a8320b088dd5efc9ebaafe387e52b3d962665:
9
for you to fetch changes up to 1806da76cb81088ea026ca3441551782b850e393:
10
10
11
target/riscv: Support the Virtual Instruction fault (2020-08-25 09:11:36 -0700)
11
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR (2024-05-28 12:20:27 +1000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
This pull request first adds support for multi-socket NUMA RISC-V
14
RISC-V PR for 9.1
15
machines. The Spike and Virt machines both support NUMA sockets.
16
15
17
This PR also updates the current experimental Hypervisor support to the
16
* APLICs add child earlier than realize
18
v0.6.1 spec.
17
* Fix exposure of Zkr
18
* Raise exceptions on wrs.nto
19
* Implement SBI debug console (DBCN) calls for KVM
20
* Support 64-bit addresses for initrd
21
* Change RISCV_EXCP_SEMIHOST exception number to 63
22
* Tolerate KVM disable ext errors
23
* Set tval in breakpoints
24
* Add support for Zve32x extension
25
* Add support for Zve64x extension
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
19
43
20
----------------------------------------------------------------
44
----------------------------------------------------------------
21
Alistair Francis (13):
45
Alexei Filippov (1):
22
target/riscv: Allow setting a two-stage lookup in the virt status
46
target/riscv: do not set mtval2 for non guest-page faults
23
target/riscv: Allow generating hlv/hlvx/hsv instructions
24
target/riscv: Do two-stage lookups on hlv/hlvx/hsv instructions
25
target/riscv: Don't allow guest to write to htinst
26
target/riscv: Convert MSTATUS MTL to GVA
27
target/riscv: Fix the interrupt cause code
28
target/riscv: Update the Hypervisor trap return/entry
29
target/riscv: Update the CSRs to the v0.6 Hyp extension
30
target/riscv: Only support a single VSXL length
31
target/riscv: Only support little endian guests
32
target/riscv: Support the v0.6 Hypervisor extension CRSs
33
target/riscv: Return the exception from invalid CSR accesses
34
target/riscv: Support the Virtual Instruction fault
35
47
36
Anup Patel (5):
48
Alistair Francis (2):
37
hw/riscv: Allow creating multiple instances of CLINT
49
target/riscv: rvzicbo: Fixup CBO extension register calculation
38
hw/riscv: Allow creating multiple instances of PLIC
50
disas/riscv: Decode all of the pmpcfg and pmpaddr CSRs
39
hw/riscv: Add helpers for RISC-V multi-socket NUMA machines
40
hw/riscv: spike: Allow creating multiple NUMA sockets
41
hw/riscv: virt: Allow creating multiple NUMA sockets
42
51
43
include/hw/riscv/numa.h | 113 +++++++
52
Andrew Jones (2):
44
include/hw/riscv/sifive_clint.h | 7 +-
53
target/riscv/kvm: Fix exposure of Zkr
45
include/hw/riscv/sifive_plic.h | 12 +-
54
target/riscv: Raise exceptions on wrs.nto
46
include/hw/riscv/spike.h | 11 +-
47
include/hw/riscv/virt.h | 9 +-
48
target/riscv/cpu.h | 2 +
49
target/riscv/cpu_bits.h | 25 +-
50
target/riscv/helper.h | 4 +
51
target/riscv/insn32-64.decode | 5 +
52
target/riscv/insn32.decode | 11 +
53
hw/riscv/numa.c | 242 +++++++++++++++
54
hw/riscv/sifive_clint.c | 20 +-
55
hw/riscv/sifive_e.c | 4 +-
56
hw/riscv/sifive_plic.c | 24 +-
57
hw/riscv/sifive_u.c | 4 +-
58
hw/riscv/spike.c | 232 +++++++++-----
59
hw/riscv/virt.c | 526 ++++++++++++++++++--------------
60
target/riscv/cpu_helper.c | 123 ++++----
61
target/riscv/csr.c | 171 +++++++++--
62
target/riscv/op_helper.c | 176 ++++++++++-
63
target/riscv/translate.c | 10 -
64
hw/riscv/meson.build | 1 +
65
target/riscv/insn_trans/trans_rvh.c.inc | 342 ++++++++++++++++++++-
66
23 files changed, 1630 insertions(+), 444 deletions(-)
67
create mode 100644 include/hw/riscv/numa.h
68
create mode 100644 hw/riscv/numa.c
69
55
56
Cheng Yang (1):
57
hw/riscv/boot.c: Support 64-bit address for initrd
58
59
Christoph Müllner (1):
60
riscv: thead: Add th.sxstatus CSR emulation
61
62
Clément Léger (1):
63
target/riscv: change RISCV_EXCP_SEMIHOST exception number to 63
64
65
Daniel Henrique Barboza (6):
66
target/riscv/kvm: implement SBI debug console (DBCN) calls
67
target/riscv/kvm: tolerate KVM disable ext errors
68
target/riscv/debug: set tval=pc in breakpoint exceptions
69
trans_privileged.c.inc: set (m|s)tval on ebreak breakpoint
70
target/riscv: prioritize pmp errors in raise_mmu_exception()
71
riscv, gdbstub.c: fix reg_width in ricsv_gen_dynamic_vector_feature()
72
73
Huang Tao (2):
74
target/riscv: Fix the element agnostic function problem
75
target/riscv: Implement dynamic establishment of custom decoder
76
77
Jason Chien (3):
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
81
82
Max Chou (4):
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
87
88
Rob Bradford (1):
89
target/riscv: Remove experimental prefix from "B" extension
90
91
Yangyu Chen (1):
92
target/riscv/cpu.c: fix Zvkb extension config
93
94
Yong-Xuan Wang (1):
95
target/riscv/kvm.c: Fix the hart bit setting of AIA
96
97
Yu-Ming Chang (1):
98
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR
99
100
yang.zhang (1):
101
hw/intc/riscv_aplic: APLICs should add child earlier than realize
102
103
MAINTAINERS | 1 +
104
target/riscv/cpu.h | 11 ++
105
target/riscv/cpu_bits.h | 2 +-
106
target/riscv/cpu_cfg.h | 2 +
107
target/riscv/helper.h | 1 +
108
target/riscv/sbi_ecall_interface.h | 17 +++
109
target/riscv/tcg/tcg-cpu.h | 15 +++
110
disas/riscv.c | 65 +++++++++-
111
hw/intc/riscv_aplic.c | 8 +-
112
hw/riscv/boot.c | 4 +-
113
target/riscv/cpu.c | 10 +-
114
target/riscv/cpu_helper.c | 37 +++---
115
target/riscv/csr.c | 71 +++++++++--
116
target/riscv/debug.c | 3 +
117
target/riscv/gdbstub.c | 8 +-
118
target/riscv/kvm/kvm-cpu.c | 157 ++++++++++++++++++++++++-
119
target/riscv/op_helper.c | 17 ++-
120
target/riscv/tcg/tcg-cpu.c | 50 +++++---
121
target/riscv/th_csr.c | 79 +++++++++++++
122
target/riscv/translate.c | 31 +++--
123
target/riscv/vector_internals.c | 22 ++++
124
target/riscv/insn_trans/trans_privileged.c.inc | 2 +
125
target/riscv/insn_trans/trans_rvv.c.inc | 46 +++++---
126
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 +++--
127
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++-
128
target/riscv/meson.build | 1 +
129
26 files changed, 596 insertions(+), 109 deletions(-)
130
create mode 100644 target/riscv/th_csr.c
131
diff view generated by jsdifflib
New patch
1
From: "yang.zhang" <yang.zhang@hexintek.com>
1
2
3
Since only root APLICs can have hw IRQ lines, aplic->parent should
4
be initialized first.
5
6
Fixes: e8f79343cf ("hw/intc: Add RISC-V AIA APLIC device emulation")
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Signed-off-by: yang.zhang <yang.zhang@hexintek.com>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
10
Message-ID: <20240409014445.278-1-gaoshanliukou@163.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
hw/intc/riscv_aplic.c | 8 ++++----
14
1 file changed, 4 insertions(+), 4 deletions(-)
15
16
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/riscv_aplic.c
19
+++ b/hw/intc/riscv_aplic.c
20
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
21
qdev_prop_set_bit(dev, "msimode", msimode);
22
qdev_prop_set_bit(dev, "mmode", mmode);
23
24
+ if (parent) {
25
+ riscv_aplic_add_child(parent, dev);
26
+ }
27
+
28
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
29
30
if (!is_kvm_aia(msimode)) {
31
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
32
}
33
34
- if (parent) {
35
- riscv_aplic_add_child(parent, dev);
36
- }
37
-
38
if (!msimode) {
39
for (i = 0; i < num_harts; i++) {
40
CPUState *cpu = cpu_by_arch_id(hartid_base + i);
41
--
42
2.45.1
diff view generated by jsdifflib
1
From: Andrew Jones <ajones@ventanamicro.com>
2
3
The Zkr extension may only be exposed to KVM guests if the VMM
4
implements the SEED CSR. Use the same implementation as TCG.
5
6
Without this patch, running with a KVM which does not forward the
7
SEED CSR access to QEMU will result in an ILL exception being
8
injected into the guest (this results in Linux guests crashing on
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>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Message-id: ca5359fec6b2aff851eef3b3bc4b53cb5d4ad194.1597259519.git.alistair.francis@wdc.com
3
Message-Id: <ca5359fec6b2aff851eef3b3bc4b53cb5d4ad194.1597259519.git.alistair.francis@wdc.com>
4
---
18
---
5
target/riscv/csr.c | 1 -
19
target/riscv/cpu.h | 3 +++
6
1 file changed, 1 deletion(-)
20
target/riscv/csr.c | 18 ++++++++++++++----
21
target/riscv/kvm/kvm-cpu.c | 25 +++++++++++++++++++++++++
22
3 files changed, 42 insertions(+), 4 deletions(-)
7
23
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 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
29
30
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
31
32
+target_ulong riscv_new_csr_seed(target_ulong new_value,
33
+ target_ulong write_mask);
34
+
35
uint8_t satp_mode_max_from_map(uint32_t map);
36
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
37
8
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
38
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
9
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
10
--- a/target/riscv/csr.c
40
--- a/target/riscv/csr.c
11
+++ b/target/riscv/csr.c
41
+++ b/target/riscv/csr.c
12
@@ -XXX,XX +XXX,XX @@ static int read_htinst(CPURISCVState *env, int csrno, target_ulong *val)
42
@@ -XXX,XX +XXX,XX @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
13
43
#endif
14
static int write_htinst(CPURISCVState *env, int csrno, target_ulong val)
44
45
/* Crypto Extension */
46
-static RISCVException rmw_seed(CPURISCVState *env, int csrno,
47
- target_ulong *ret_value,
48
- target_ulong new_value,
49
- target_ulong write_mask)
50
+target_ulong riscv_new_csr_seed(target_ulong new_value,
51
+ target_ulong write_mask)
15
{
52
{
16
- env->htinst = val;
53
uint16_t random_v;
17
return 0;
54
Error *random_e = NULL;
55
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
56
rval = random_v | SEED_OPST_ES16;
57
}
58
59
+ return rval;
60
+}
61
+
62
+static RISCVException rmw_seed(CPURISCVState *env, int csrno,
63
+ target_ulong *ret_value,
64
+ target_ulong new_value,
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
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/riscv/kvm/kvm-cpu.c
77
+++ b/target/riscv/kvm/kvm-cpu.c
78
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
79
return ret;
18
}
80
}
19
81
82
+static int kvm_riscv_handle_csr(CPUState *cs, struct kvm_run *run)
83
+{
84
+ target_ulong csr_num = run->riscv_csr.csr_num;
85
+ target_ulong new_value = run->riscv_csr.new_value;
86
+ target_ulong write_mask = run->riscv_csr.write_mask;
87
+ int ret = 0;
88
+
89
+ switch (csr_num) {
90
+ case CSR_SEED:
91
+ run->riscv_csr.ret_value = riscv_new_csr_seed(new_value, write_mask);
92
+ break;
93
+ default:
94
+ qemu_log_mask(LOG_UNIMP,
95
+ "%s: un-handled CSR EXIT for CSR %lx\n",
96
+ __func__, csr_num);
97
+ ret = -1;
98
+ break;
99
+ }
100
+
101
+ return ret;
102
+}
103
+
104
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
105
{
106
int ret = 0;
107
@@ -XXX,XX +XXX,XX @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
108
case KVM_EXIT_RISCV_SBI:
109
ret = kvm_riscv_handle_sbi(cs, run);
110
break;
111
+ case KVM_EXIT_RISCV_CSR:
112
+ ret = kvm_riscv_handle_csr(cs, run);
113
+ break;
114
default:
115
qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
116
__func__, run->exit_reason);
20
--
117
--
21
2.28.0
118
2.45.1
22
23
diff view generated by jsdifflib
1
From: Andrew Jones <ajones@ventanamicro.com>
2
3
Implementing wrs.nto to always just return is consistent with the
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.
13
14
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
15
Reviewed-by: Christoph Müllner <christoph.muellner@vrull.eu>
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-ID: <20240424142808.62936-2-ajones@ventanamicro.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Message-id: 477c864312280ea55a98dc84cb01d826751b6c14.1597259519.git.alistair.francis@wdc.com
3
Message-Id: <477c864312280ea55a98dc84cb01d826751b6c14.1597259519.git.alistair.francis@wdc.com>
4
---
20
---
5
target/riscv/cpu_bits.h | 1 +
21
target/riscv/helper.h | 1 +
6
target/riscv/helper.h | 3 +
22
target/riscv/op_helper.c | 11 ++++++++
7
target/riscv/insn32-64.decode | 5 +
23
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 ++++++++++++++-------
8
target/riscv/insn32.decode | 11 +
24
3 files changed, 32 insertions(+), 9 deletions(-)
9
target/riscv/op_helper.c | 114 ++++++++
10
target/riscv/insn_trans/trans_rvh.c.inc | 340 ++++++++++++++++++++++++
11
6 files changed, 474 insertions(+)
12
25
13
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/cpu_bits.h
16
+++ b/target/riscv/cpu_bits.h
17
@@ -XXX,XX +XXX,XX @@
18
#define HSTATUS_SP2V 0x00000200
19
#define HSTATUS_VTVM 0x00100000
20
#define HSTATUS_VTSR 0x00400000
21
+#define HSTATUS_HU 0x00000200
22
23
#define HSTATUS32_WPRI 0xFF8FF87E
24
#define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL
25
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
26
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
27
--- a/target/riscv/helper.h
28
--- a/target/riscv/helper.h
28
+++ b/target/riscv/helper.h
29
+++ b/target/riscv/helper.h
29
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(tlb_flush, void, env)
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
30
/* Hypervisor functions */
31
DEF_HELPER_1(sret, tl, env)
31
#ifndef CONFIG_USER_ONLY
32
DEF_HELPER_1(mret, tl, env)
32
DEF_HELPER_1(hyp_tlb_flush, void, env)
33
DEF_HELPER_1(wfi, void, env)
33
+DEF_HELPER_4(hyp_load, tl, env, tl, tl, tl)
34
+DEF_HELPER_1(wrs_nto, void, env)
34
+DEF_HELPER_5(hyp_store, void, env, tl, tl, tl, tl)
35
DEF_HELPER_1(tlb_flush, void, env)
35
+DEF_HELPER_4(hyp_x_load, tl, env, tl, tl, tl)
36
DEF_HELPER_1(tlb_flush_all, void, env)
36
#endif
37
/* Native Debug */
37
38
/* Vector functions */
39
diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/insn32-64.decode
42
+++ b/target/riscv/insn32-64.decode
43
@@ -XXX,XX +XXX,XX @@ fmv_x_d 1110001 00000 ..... 000 ..... 1010011 @r2
44
fcvt_d_l 1101001 00010 ..... ... ..... 1010011 @r2_rm
45
fcvt_d_lu 1101001 00011 ..... ... ..... 1010011 @r2_rm
46
fmv_d_x 1111001 00000 ..... 000 ..... 1010011 @r2
47
+
48
+# *** RV32H Base Instruction Set ***
49
+hlv_wu 0110100 00001 ..... 100 ..... 1110011 @r2
50
+hlv_d 0110110 00000 ..... 100 ..... 1110011 @r2
51
+hsv_d 0110111 ..... ..... 100 00000 1110011 @r2_s
52
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/riscv/insn32.decode
55
+++ b/target/riscv/insn32.decode
56
@@ -XXX,XX +XXX,XX @@
57
@r_vm_0 ...... . ..... ..... ... ..... ....... &rmrr vm=0 %rs2 %rs1 %rd
58
@r_wdvm ..... wd:1 vm:1 ..... ..... ... ..... ....... &rwdvm %rs2 %rs1 %rd
59
@r2_zimm . zimm:11 ..... ... ..... ....... %rs1 %rd
60
+@r2_s ....... ..... ..... ... ..... ....... %rs2 %rs1
61
62
@hfence_gvma ....... ..... ..... ... ..... ....... %rs2 %rs1
63
@hfence_vvma ....... ..... ..... ... ..... ....... %rs2 %rs1
64
@@ -XXX,XX +XXX,XX @@ fcvt_d_w 1101001 00000 ..... ... ..... 1010011 @r2_rm
65
fcvt_d_wu 1101001 00001 ..... ... ..... 1010011 @r2_rm
66
67
# *** RV32H Base Instruction Set ***
68
+hlv_b 0110000 00000 ..... 100 ..... 1110011 @r2
69
+hlv_bu 0110000 00001 ..... 100 ..... 1110011 @r2
70
+hlv_h 0110010 00000 ..... 100 ..... 1110011 @r2
71
+hlv_hu 0110010 00001 ..... 100 ..... 1110011 @r2
72
+hlvx_hu 0110010 00011 ..... 100 ..... 1110011 @r2
73
+hlv_w 0110100 00000 ..... 100 ..... 1110011 @r2
74
+hlvx_wu 0110100 00011 ..... 100 ..... 1110011 @r2
75
+hsv_b 0110001 ..... ..... 100 00000 1110011 @r2_s
76
+hsv_h 0110011 ..... ..... 100 00000 1110011 @r2_s
77
+hsv_w 0110101 ..... ..... 100 00000 1110011 @r2_s
78
hfence_gvma 0110001 ..... ..... 000 00000 1110011 @hfence_gvma
79
hfence_vvma 0010001 ..... ..... 000 00000 1110011 @hfence_vvma
80
81
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
82
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
83
--- a/target/riscv/op_helper.c
40
--- a/target/riscv/op_helper.c
84
+++ b/target/riscv/op_helper.c
41
+++ b/target/riscv/op_helper.c
85
@@ -XXX,XX +XXX,XX @@ void helper_hyp_tlb_flush(CPURISCVState *env)
42
@@ -XXX,XX +XXX,XX @@ void helper_wfi(CPURISCVState *env)
86
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
43
}
87
}
44
}
88
45
89
+target_ulong helper_hyp_load(CPURISCVState *env, target_ulong address,
46
+void helper_wrs_nto(CPURISCVState *env)
90
+ target_ulong attrs, target_ulong memop)
91
+{
47
+{
92
+ if (env->priv == PRV_M ||
48
+ if (env->virt_enabled && (env->priv == PRV_S || env->priv == PRV_U) &&
93
+ (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
49
+ get_field(env->hstatus, HSTATUS_VTW) &&
94
+ (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
50
+ !get_field(env->mstatus, MSTATUS_TW)) {
95
+ get_field(env->hstatus, HSTATUS_HU))) {
51
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
96
+ target_ulong pte;
52
+ } else if (env->priv != PRV_M && get_field(env->mstatus, MSTATUS_TW)) {
97
+
53
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
98
+ riscv_cpu_set_two_stage_lookup(env, true);
99
+
100
+ switch (memop) {
101
+ case MO_SB:
102
+ pte = cpu_ldsb_data_ra(env, address, GETPC());
103
+ break;
104
+ case MO_UB:
105
+ pte = cpu_ldub_data_ra(env, address, GETPC());
106
+ break;
107
+ case MO_TESW:
108
+ pte = cpu_ldsw_data_ra(env, address, GETPC());
109
+ break;
110
+ case MO_TEUW:
111
+ pte = cpu_lduw_data_ra(env, address, GETPC());
112
+ break;
113
+ case MO_TESL:
114
+ pte = cpu_ldl_data_ra(env, address, GETPC());
115
+ break;
116
+ case MO_TEUL:
117
+ pte = cpu_ldl_data_ra(env, address, GETPC());
118
+ break;
119
+ case MO_TEQ:
120
+ pte = cpu_ldq_data_ra(env, address, GETPC());
121
+ break;
122
+ default:
123
+ g_assert_not_reached();
124
+ }
125
+
126
+ riscv_cpu_set_two_stage_lookup(env, false);
127
+
128
+ return pte;
129
+ }
54
+ }
130
+
131
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
132
+ return 0;
133
+}
55
+}
134
+
56
+
135
+void helper_hyp_store(CPURISCVState *env, target_ulong address,
57
void helper_tlb_flush(CPURISCVState *env)
136
+ target_ulong val, target_ulong attrs, target_ulong memop)
58
{
137
+{
59
CPUState *cs = env_cpu(env);
138
+ if (env->priv == PRV_M ||
60
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc
139
+ (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
140
+ (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
141
+ get_field(env->hstatus, HSTATUS_HU))) {
142
+ riscv_cpu_set_two_stage_lookup(env, true);
143
+
144
+ switch (memop) {
145
+ case MO_SB:
146
+ case MO_UB:
147
+ cpu_stb_data_ra(env, address, val, GETPC());
148
+ break;
149
+ case MO_TESW:
150
+ case MO_TEUW:
151
+ cpu_stw_data_ra(env, address, val, GETPC());
152
+ break;
153
+ case MO_TESL:
154
+ case MO_TEUL:
155
+ cpu_stl_data_ra(env, address, val, GETPC());
156
+ break;
157
+ case MO_TEQ:
158
+ cpu_stq_data_ra(env, address, val, GETPC());
159
+ break;
160
+ default:
161
+ g_assert_not_reached();
162
+ }
163
+
164
+ riscv_cpu_set_two_stage_lookup(env, false);
165
+
166
+ return;
167
+ }
168
+
169
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
170
+}
171
+
172
+target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
173
+ target_ulong attrs, target_ulong memop)
174
+{
175
+ if (env->priv == PRV_M ||
176
+ (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
177
+ (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
178
+ get_field(env->hstatus, HSTATUS_HU))) {
179
+ target_ulong pte;
180
+
181
+ riscv_cpu_set_two_stage_lookup(env, true);
182
+
183
+ switch (memop) {
184
+ case MO_TEUL:
185
+ pte = cpu_ldub_data_ra(env, address, GETPC());
186
+ break;
187
+ case MO_TEUW:
188
+ pte = cpu_lduw_data_ra(env, address, GETPC());
189
+ break;
190
+ default:
191
+ g_assert_not_reached();
192
+ }
193
+
194
+ riscv_cpu_set_two_stage_lookup(env, false);
195
+
196
+ return pte;
197
+ }
198
+
199
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
200
+ return 0;
201
+}
202
+
203
#endif /* !CONFIG_USER_ONLY */
204
diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
205
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
206
--- a/target/riscv/insn_trans/trans_rvh.c.inc
62
--- a/target/riscv/insn_trans/trans_rvzawrs.c.inc
207
+++ b/target/riscv/insn_trans/trans_rvh.c.inc
63
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
208
@@ -XXX,XX +XXX,XX @@
64
@@ -XXX,XX +XXX,XX @@
209
* this program. If not, see <http://www.gnu.org/licenses/>.
65
* this program. If not, see <http://www.gnu.org/licenses/>.
210
*/
66
*/
211
67
212
+static bool trans_hlv_b(DisasContext *ctx, arg_hlv_b *a)
68
-static bool trans_wrs(DisasContext *ctx)
69
+static bool trans_wrs_sto(DisasContext *ctx, arg_wrs_sto *a)
70
{
71
if (!ctx->cfg_ptr->ext_zawrs) {
72
return false;
73
@@ -XXX,XX +XXX,XX @@ static bool trans_wrs(DisasContext *ctx)
74
return true;
75
}
76
77
-#define GEN_TRANS_WRS(insn) \
78
-static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn *a) \
79
-{ \
80
- (void)a; \
81
- return trans_wrs(ctx); \
82
-}
83
+static bool trans_wrs_nto(DisasContext *ctx, arg_wrs_nto *a)
213
+{
84
+{
214
+ REQUIRE_EXT(ctx, RVH);
85
+ if (!ctx->cfg_ptr->ext_zawrs) {
86
+ return false;
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
+ */
215
+#ifndef CONFIG_USER_ONLY
98
+#ifndef CONFIG_USER_ONLY
216
+ TCGv t0 = tcg_temp_new();
99
+ gen_helper_wrs_nto(tcg_env);
217
+ TCGv t1 = tcg_temp_new();
218
+ TCGv mem_idx = tcg_temp_new();
219
+ TCGv memop = tcg_temp_new();
220
+
221
+ gen_get_gpr(t0, a->rs1);
222
+ tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
223
+ tcg_gen_movi_tl(memop, MO_SB);
224
+
225
+ gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop);
226
+ gen_set_gpr(a->rd, t1);
227
+
228
+ tcg_temp_free(t0);
229
+ tcg_temp_free(t1);
230
+ tcg_temp_free(mem_idx);
231
+ tcg_temp_free(memop);
232
+ return true;
233
+#else
234
+ return false;
235
+#endif
236
+}
237
+
238
+static bool trans_hlv_h(DisasContext *ctx, arg_hlv_h *a)
239
+{
240
+ REQUIRE_EXT(ctx, RVH);
241
+#ifndef CONFIG_USER_ONLY
242
+ TCGv t0 = tcg_temp_new();
243
+ TCGv t1 = tcg_temp_new();
244
+ TCGv mem_idx = tcg_temp_new();
245
+ TCGv memop = tcg_temp_new();
246
+
247
+ gen_get_gpr(t0, a->rs1);
248
+ tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
249
+ tcg_gen_movi_tl(memop, MO_TESW);
250
+
251
+ gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop);
252
+ gen_set_gpr(a->rd, t1);
253
+
254
+ tcg_temp_free(t0);
255
+ tcg_temp_free(t1);
256
+ tcg_temp_free(mem_idx);
257
+ tcg_temp_free(memop);
258
+ return true;
259
+#else
260
+ return false;
261
+#endif
262
+}
263
+
264
+static bool trans_hlv_w(DisasContext *ctx, arg_hlv_w *a)
265
+{
266
+ REQUIRE_EXT(ctx, RVH);
267
+#ifndef CONFIG_USER_ONLY
268
+ TCGv t0 = tcg_temp_new();
269
+ TCGv t1 = tcg_temp_new();
270
+ TCGv mem_idx = tcg_temp_new();
271
+ TCGv memop = tcg_temp_new();
272
+
273
+ gen_get_gpr(t0, a->rs1);
274
+ tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
275
+ tcg_gen_movi_tl(memop, MO_TESL);
276
+
277
+ gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop);
278
+ gen_set_gpr(a->rd, t1);
279
+
280
+ tcg_temp_free(t0);
281
+ tcg_temp_free(t1);
282
+ tcg_temp_free(mem_idx);
283
+ tcg_temp_free(memop);
284
+ return true;
285
+#else
286
+ return false;
287
+#endif
288
+}
289
+
290
+static bool trans_hlv_bu(DisasContext *ctx, arg_hlv_bu *a)
291
+{
292
+ REQUIRE_EXT(ctx, RVH);
293
+#ifndef CONFIG_USER_ONLY
294
+ TCGv t0 = tcg_temp_new();
295
+ TCGv t1 = tcg_temp_new();
296
+ TCGv mem_idx = tcg_temp_new();
297
+ TCGv memop = tcg_temp_new();
298
+
299
+ gen_get_gpr(t0, a->rs1);
300
+ tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
301
+ tcg_gen_movi_tl(memop, MO_UB);
302
+
303
+ gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop);
304
+ gen_set_gpr(a->rd, t1);
305
+
306
+ tcg_temp_free(t0);
307
+ tcg_temp_free(t1);
308
+ tcg_temp_free(mem_idx);
309
+ tcg_temp_free(memop);
310
+ return true;
311
+#else
312
+ return false;
313
+#endif
314
+}
315
+
316
+static bool trans_hlv_hu(DisasContext *ctx, arg_hlv_hu *a)
317
+{
318
+ REQUIRE_EXT(ctx, RVH);
319
+#ifndef CONFIG_USER_ONLY
320
+ TCGv t0 = tcg_temp_new();
321
+ TCGv t1 = tcg_temp_new();
322
+ TCGv mem_idx = tcg_temp_new();
323
+ TCGv memop = tcg_temp_new();
324
+
325
+ gen_get_gpr(t0, a->rs1);
326
+ tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
327
+ tcg_gen_movi_tl(memop, MO_TEUW);
328
+
329
+ gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop);
330
+ gen_set_gpr(a->rd, t1);
331
+
332
+ tcg_temp_free(t0);
333
+ tcg_temp_free(t1);
334
+ tcg_temp_free(mem_idx);
335
+ tcg_temp_free(memop);
336
+ return true;
337
+#else
338
+ return false;
339
+#endif
340
+}
341
+
342
+static bool trans_hsv_b(DisasContext *ctx, arg_hsv_b *a)
343
+{
344
+ REQUIRE_EXT(ctx, RVH);
345
+#ifndef CONFIG_USER_ONLY
346
+ TCGv t0 = tcg_temp_new();
347
+ TCGv dat = tcg_temp_new();
348
+ TCGv mem_idx = tcg_temp_new();
349
+ TCGv memop = tcg_temp_new();
350
+
351
+ gen_get_gpr(t0, a->rs1);
352
+ gen_get_gpr(dat, a->rs2);
353
+ tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
354
+ tcg_gen_movi_tl(memop, MO_SB);
355
+
356
+ gen_helper_hyp_store(cpu_env, t0, dat, mem_idx, memop);
357
+
358
+ tcg_temp_free(t0);
359
+ tcg_temp_free(dat);
360
+ tcg_temp_free(mem_idx);
361
+ tcg_temp_free(memop);
362
+ return true;
363
+#else
364
+ return false;
365
+#endif
366
+}
367
+
368
+static bool trans_hsv_h(DisasContext *ctx, arg_hsv_h *a)
369
+{
370
+ REQUIRE_EXT(ctx, RVH);
371
+#ifndef CONFIG_USER_ONLY
372
+ TCGv t0 = tcg_temp_new();
373
+ TCGv dat = tcg_temp_new();
374
+ TCGv mem_idx = tcg_temp_new();
375
+ TCGv memop = tcg_temp_new();
376
+
377
+ gen_get_gpr(t0, a->rs1);
378
+ gen_get_gpr(dat, a->rs2);
379
+ tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
380
+ tcg_gen_movi_tl(memop, MO_TESW);
381
+
382
+ gen_helper_hyp_store(cpu_env, t0, dat, mem_idx, memop);
383
+
384
+ tcg_temp_free(t0);
385
+ tcg_temp_free(dat);
386
+ tcg_temp_free(mem_idx);
387
+ tcg_temp_free(memop);
388
+ return true;
389
+#else
390
+ return false;
391
+#endif
392
+}
393
+
394
+static bool trans_hsv_w(DisasContext *ctx, arg_hsv_w *a)
395
+{
396
+ REQUIRE_EXT(ctx, RVH);
397
+#ifndef CONFIG_USER_ONLY
398
+ TCGv t0 = tcg_temp_new();
399
+ TCGv dat = tcg_temp_new();
400
+ TCGv mem_idx = tcg_temp_new();
401
+ TCGv memop = tcg_temp_new();
402
+
403
+ gen_get_gpr(t0, a->rs1);
404
+ gen_get_gpr(dat, a->rs2);
405
+ tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
406
+ tcg_gen_movi_tl(memop, MO_TESL);
407
+
408
+ gen_helper_hyp_store(cpu_env, t0, dat, mem_idx, memop);
409
+
410
+ tcg_temp_free(t0);
411
+ tcg_temp_free(dat);
412
+ tcg_temp_free(mem_idx);
413
+ tcg_temp_free(memop);
414
+ return true;
415
+#else
416
+ return false;
417
+#endif
418
+}
419
+
420
+#ifdef TARGET_RISCV64
421
+static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a)
422
+{
423
+ REQUIRE_EXT(ctx, RVH);
424
+#ifndef CONFIG_USER_ONLY
425
+ TCGv t0 = tcg_temp_new();
426
+ TCGv t1 = tcg_temp_new();
427
+ TCGv mem_idx = tcg_temp_new();
428
+ TCGv memop = tcg_temp_new();
429
+
430
+ gen_get_gpr(t0, a->rs1);
431
+ tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
432
+ tcg_gen_movi_tl(memop, MO_TEUL);
433
+
434
+ gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop);
435
+ gen_set_gpr(a->rd, t1);
436
+
437
+ tcg_temp_free(t0);
438
+ tcg_temp_free(t1);
439
+ tcg_temp_free(mem_idx);
440
+ tcg_temp_free(memop);
441
+ return true;
442
+#else
443
+ return false;
444
+#endif
445
+}
446
+
447
+static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a)
448
+{
449
+ REQUIRE_EXT(ctx, RVH);
450
+#ifndef CONFIG_USER_ONLY
451
+ TCGv t0 = tcg_temp_new();
452
+ TCGv t1 = tcg_temp_new();
453
+ TCGv mem_idx = tcg_temp_new();
454
+ TCGv memop = tcg_temp_new();
455
+
456
+ gen_get_gpr(t0, a->rs1);
457
+ tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
458
+ tcg_gen_movi_tl(memop, MO_TEQ);
459
+
460
+ gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop);
461
+ gen_set_gpr(a->rd, t1);
462
+
463
+ tcg_temp_free(t0);
464
+ tcg_temp_free(t1);
465
+ tcg_temp_free(mem_idx);
466
+ tcg_temp_free(memop);
467
+ return true;
468
+#else
469
+ return false;
470
+#endif
471
+}
472
+
473
+static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a)
474
+{
475
+ REQUIRE_EXT(ctx, RVH);
476
+#ifndef CONFIG_USER_ONLY
477
+ TCGv t0 = tcg_temp_new();
478
+ TCGv dat = tcg_temp_new();
479
+ TCGv mem_idx = tcg_temp_new();
480
+ TCGv memop = tcg_temp_new();
481
+
482
+ gen_get_gpr(t0, a->rs1);
483
+ gen_get_gpr(dat, a->rs2);
484
+ tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
485
+ tcg_gen_movi_tl(memop, MO_TEQ);
486
+
487
+ gen_helper_hyp_store(cpu_env, t0, dat, mem_idx, memop);
488
+
489
+ tcg_temp_free(t0);
490
+ tcg_temp_free(dat);
491
+ tcg_temp_free(mem_idx);
492
+ tcg_temp_free(memop);
493
+ return true;
494
+#else
495
+ return false;
496
+#endif
497
+}
498
+#endif
100
+#endif
499
+
101
+
500
+static bool trans_hlvx_hu(DisasContext *ctx, arg_hlvx_hu *a)
102
+ /* We only get here when helper_wrs_nto() doesn't raise an exception. */
501
+{
103
+ return trans_wrs_sto(ctx, NULL);
502
+ REQUIRE_EXT(ctx, RVH);
503
+#ifndef CONFIG_USER_ONLY
504
+ TCGv t0 = tcg_temp_new();
505
+ TCGv t1 = tcg_temp_new();
506
+ TCGv mem_idx = tcg_temp_new();
507
+ TCGv memop = tcg_temp_new();
508
+
509
+ gen_get_gpr(t0, a->rs1);
510
+ tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
511
+ tcg_gen_movi_tl(memop, MO_TEUW);
512
+
513
+ gen_helper_hyp_x_load(t1, cpu_env, t0, mem_idx, memop);
514
+ gen_set_gpr(a->rd, t1);
515
+
516
+ tcg_temp_free(t0);
517
+ tcg_temp_free(t1);
518
+ tcg_temp_free(mem_idx);
519
+ tcg_temp_free(memop);
520
+ return true;
521
+#else
522
+ return false;
523
+#endif
524
+}
104
+}
525
+
526
+static bool trans_hlvx_wu(DisasContext *ctx, arg_hlvx_wu *a)
527
+{
528
+ REQUIRE_EXT(ctx, RVH);
529
+#ifndef CONFIG_USER_ONLY
530
+ TCGv t0 = tcg_temp_new();
531
+ TCGv t1 = tcg_temp_new();
532
+ TCGv mem_idx = tcg_temp_new();
533
+ TCGv memop = tcg_temp_new();
534
+
535
+ gen_get_gpr(t0, a->rs1);
536
+ tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
537
+ tcg_gen_movi_tl(memop, MO_TEUL);
538
+
539
+ gen_helper_hyp_x_load(t1, cpu_env, t0, mem_idx, memop);
540
+ gen_set_gpr(a->rd, t1);
541
+
542
+ tcg_temp_free(t0);
543
+ tcg_temp_free(t1);
544
+ tcg_temp_free(mem_idx);
545
+ tcg_temp_free(memop);
546
+ return true;
547
+#else
548
+ return false;
549
+#endif
550
+}
551
+
552
static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
553
{
554
REQUIRE_EXT(ctx, RVH);
555
--
105
--
556
2.28.0
106
2.45.1
557
107
558
108
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
3
SBI defines a Debug Console extension "DBCN" that will, in time, replace
4
the legacy console putchar and getchar SBI extensions.
5
6
The appeal of the DBCN extension is that it allows multiple bytes to be
7
read/written in the SBI console in a single SBI call.
8
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>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Message-id: 644b6c114b1a81adbee0ab8c9c66a8672059ec96.1597259519.git.alistair.francis@wdc.com
3
Message-Id: <644b6c114b1a81adbee0ab8c9c66a8672059ec96.1597259519.git.alistair.francis@wdc.com>
4
---
30
---
5
target/riscv/cpu_bits.h | 3 +++
31
target/riscv/sbi_ecall_interface.h | 17 +++++
6
target/riscv/csr.c | 40 ++++++++++++++++++++++++++++++++++++++++
32
target/riscv/kvm/kvm-cpu.c | 111 +++++++++++++++++++++++++++++
7
2 files changed, 43 insertions(+)
33
2 files changed, 128 insertions(+)
8
34
9
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
35
diff --git a/target/riscv/sbi_ecall_interface.h b/target/riscv/sbi_ecall_interface.h
10
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
11
--- a/target/riscv/cpu_bits.h
37
--- a/target/riscv/sbi_ecall_interface.h
12
+++ b/target/riscv/cpu_bits.h
38
+++ b/target/riscv/sbi_ecall_interface.h
13
@@ -XXX,XX +XXX,XX @@
39
@@ -XXX,XX +XXX,XX @@
14
#define CSR_HIDELEG 0x603
40
15
#define CSR_HIE 0x604
41
/* clang-format off */
16
#define CSR_HCOUNTEREN 0x606
42
17
+#define CSR_HGEIE 0x607
43
+#define SBI_SUCCESS 0
18
#define CSR_HTVAL 0x643
44
+#define SBI_ERR_FAILED -1
19
+#define CSR_HVIP 0x645
45
+#define SBI_ERR_NOT_SUPPORTED -2
20
#define CSR_HIP 0x644
46
+#define SBI_ERR_INVALID_PARAM -3
21
#define CSR_HTINST 0x64A
47
+#define SBI_ERR_DENIED -4
22
+#define CSR_HGEIP 0xE12
48
+#define SBI_ERR_INVALID_ADDRESS -5
23
#define CSR_HGATP 0x680
49
+#define SBI_ERR_ALREADY_AVAILABLE -6
24
#define CSR_HTIMEDELTA 0x605
50
+#define SBI_ERR_ALREADY_STARTED -7
25
#define CSR_HTIMEDELTAH 0x615
51
+#define SBI_ERR_ALREADY_STOPPED -8
26
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
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
27
index XXXXXXX..XXXXXXX 100644
78
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/csr.c
79
--- a/target/riscv/kvm/kvm-cpu.c
29
+++ b/target/riscv/csr.c
80
+++ b/target/riscv/kvm/kvm-cpu.c
30
@@ -XXX,XX +XXX,XX @@ static int write_hideleg(CPURISCVState *env, int csrno, target_ulong val)
81
@@ -XXX,XX +XXX,XX @@ static KVMCPUConfig kvm_v_vlenb = {
82
KVM_REG_RISCV_VECTOR_CSR_REG(vlenb)
83
};
84
85
+static KVMCPUConfig kvm_sbi_dbcn = {
86
+ .name = "sbi_dbcn",
87
+ .kvm_reg_id = KVM_REG_RISCV | KVM_REG_SIZE_U64 |
88
+ KVM_REG_RISCV_SBI_EXT | KVM_RISCV_SBI_EXT_DBCN
89
+};
90
+
91
static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
92
{
93
CPURISCVState *env = &cpu->env;
94
@@ -XXX,XX +XXX,XX @@ static int uint64_cmp(const void *a, const void *b)
31
return 0;
95
return 0;
32
}
96
}
33
97
34
+static int rmw_hvip(CPURISCVState *env, int csrno, target_ulong *ret_value,
98
+static void kvm_riscv_check_sbi_dbcn_support(RISCVCPU *cpu,
35
+ target_ulong new_value, target_ulong write_mask)
99
+ KVMScratchCPU *kvmcpu,
100
+ struct kvm_reg_list *reglist)
36
+{
101
+{
37
+ int ret = rmw_mip(env, 0, ret_value, new_value,
102
+ struct kvm_reg_list *reg_search;
38
+ write_mask & hip_writable_mask);
103
+
39
+
104
+ reg_search = bsearch(&kvm_sbi_dbcn.kvm_reg_id, reglist->reg, reglist->n,
40
+ *ret_value &= hip_writable_mask;
105
+ sizeof(uint64_t), uint64_cmp);
41
+
106
+
42
+ return ret;
107
+ if (reg_search) {
108
+ kvm_sbi_dbcn.supported = true;
109
+ }
43
+}
110
+}
44
+
111
+
45
static int rmw_hip(CPURISCVState *env, int csrno, target_ulong *ret_value,
112
static void kvm_riscv_read_vlenb(RISCVCPU *cpu, KVMScratchCPU *kvmcpu,
46
target_ulong new_value, target_ulong write_mask)
113
struct kvm_reg_list *reglist)
47
{
114
{
48
int ret = rmw_mip(env, 0, ret_value, new_value,
115
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
49
write_mask & hip_writable_mask);
116
if (riscv_has_ext(&cpu->env, RVV)) {
50
117
kvm_riscv_read_vlenb(cpu, kvmcpu, reglist);
51
+ *ret_value &= hip_writable_mask;
118
}
52
+
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)
53
return ret;
125
return ret;
54
}
126
}
55
127
56
@@ -XXX,XX +XXX,XX @@ static int write_hcounteren(CPURISCVState *env, int csrno, target_ulong val)
128
+static int kvm_vcpu_enable_sbi_dbcn(RISCVCPU *cpu, CPUState *cs)
57
return 0;
58
}
59
60
+static int read_hgeie(CPURISCVState *env, int csrno, target_ulong *val)
61
+{
129
+{
62
+ qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN.");
130
+ target_ulong reg = 1;
63
+ return 0;
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);
64
+}
137
+}
65
+
138
+
66
+static int write_hgeie(CPURISCVState *env, int csrno, target_ulong val)
139
int kvm_arch_init_vcpu(CPUState *cs)
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)
67
+{
156
+{
68
+ qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN.");
157
+ g_autofree uint8_t *buf = NULL;
69
+ return 0;
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
+ }
70
+}
226
+}
71
+
227
+
72
static int read_htval(CPURISCVState *env, int csrno, target_ulong *val)
228
static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
73
{
229
{
74
*val = env->htval;
230
int ret = 0;
75
@@ -XXX,XX +XXX,XX @@ static int write_htinst(CPURISCVState *env, int csrno, target_ulong val)
231
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
76
return 0;
232
}
77
}
233
ret = 0;
78
234
break;
79
+static int read_hgeip(CPURISCVState *env, int csrno, target_ulong *val)
235
+ case SBI_EXT_DBCN:
80
+{
236
+ kvm_riscv_handle_sbi_dbcn(cs, run);
81
+ qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN.");
237
+ break;
82
+ return 0;
238
default:
83
+}
239
qemu_log_mask(LOG_UNIMP,
84
+
240
"%s: un-handled SBI EXIT, specific reasons is %lu\n",
85
+static int write_hgeip(CPURISCVState *env, int csrno, target_ulong val)
86
+{
87
+ qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN.");
88
+ return 0;
89
+}
90
+
91
static int read_hgatp(CPURISCVState *env, int csrno, target_ulong *val)
92
{
93
*val = env->hgatp;
94
@@ -XXX,XX +XXX,XX @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
95
[CSR_HSTATUS] = { hmode, read_hstatus, write_hstatus },
96
[CSR_HEDELEG] = { hmode, read_hedeleg, write_hedeleg },
97
[CSR_HIDELEG] = { hmode, read_hideleg, write_hideleg },
98
+ [CSR_HVIP] = { hmode, NULL, NULL, rmw_hvip },
99
[CSR_HIP] = { hmode, NULL, NULL, rmw_hip },
100
[CSR_HIE] = { hmode, read_hie, write_hie },
101
[CSR_HCOUNTEREN] = { hmode, read_hcounteren, write_hcounteren },
102
+ [CSR_HGEIE] = { hmode, read_hgeie, write_hgeie },
103
[CSR_HTVAL] = { hmode, read_htval, write_htval },
104
[CSR_HTINST] = { hmode, read_htinst, write_htinst },
105
+ [CSR_HGEIP] = { hmode, read_hgeip, write_hgeip },
106
[CSR_HGATP] = { hmode, read_hgatp, write_hgatp },
107
[CSR_HTIMEDELTA] = { hmode, read_htimedelta, write_htimedelta },
108
#if defined(TARGET_RISCV32)
109
--
241
--
110
2.28.0
242
2.45.1
111
112
diff view generated by jsdifflib
New patch
1
From: Cheng Yang <yangcheng.work@foxmail.com>
1
2
3
Use qemu_fdt_setprop_u64() instead of qemu_fdt_setprop_cell()
4
to set the address of initrd in FDT to support 64-bit address.
5
6
Signed-off-by: Cheng Yang <yangcheng.work@foxmail.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-ID: <tencent_A4482251DD0890F312758FA6B33F60815609@qq.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
hw/riscv/boot.c | 4 ++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
13
14
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/boot.c
17
+++ b/hw/riscv/boot.c
18
@@ -XXX,XX +XXX,XX @@ static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
19
/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
20
if (fdt) {
21
end = start + size;
22
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
23
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
24
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-start", start);
25
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-end", end);
26
}
27
}
28
29
--
30
2.45.1
diff view generated by jsdifflib
1
From: Clément Léger <cleger@rivosinc.com>
2
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.
9
10
Signed-off-by: Clément Léger <cleger@rivosinc.com>
11
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <20240422135840.1959967-1-cleger@rivosinc.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Message-id: 4f227b30cb1816795296c0994f1123fab143666a.1597259519.git.alistair.francis@wdc.com
3
Message-Id: <4f227b30cb1816795296c0994f1123fab143666a.1597259519.git.alistair.francis@wdc.com>
4
---
15
---
5
target/riscv/cpu_bits.h | 14 ++++++++------
16
target/riscv/cpu_bits.h | 2 +-
6
1 file changed, 8 insertions(+), 6 deletions(-)
17
1 file changed, 1 insertion(+), 1 deletion(-)
7
18
8
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
19
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
9
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
10
--- a/target/riscv/cpu_bits.h
21
--- a/target/riscv/cpu_bits.h
11
+++ b/target/riscv/cpu_bits.h
22
+++ b/target/riscv/cpu_bits.h
12
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
13
#endif
24
RISCV_EXCP_INST_PAGE_FAULT = 0xc, /* since: priv-1.10.0 */
14
25
RISCV_EXCP_LOAD_PAGE_FAULT = 0xd, /* since: priv-1.10.0 */
15
/* hstatus CSR bits */
26
RISCV_EXCP_STORE_PAGE_FAULT = 0xf, /* since: priv-1.10.0 */
16
-#define HSTATUS_SPRV 0x00000001
27
- RISCV_EXCP_SEMIHOST = 0x10,
17
+#define HSTATUS_VSBE 0x00000020
28
RISCV_EXCP_INST_GUEST_PAGE_FAULT = 0x14,
18
+#define HSTATUS_GVA 0x00000040
29
RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT = 0x15,
19
#define HSTATUS_SPV 0x00000080
30
RISCV_EXCP_VIRT_INSTRUCTION_FAULT = 0x16,
20
-#define HSTATUS_SP2P 0x00000100
31
RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT = 0x17,
21
-#define HSTATUS_SP2V 0x00000200
32
+ RISCV_EXCP_SEMIHOST = 0x3f,
22
+#define HSTATUS_SPVP 0x00000100
33
} RISCVException;
23
+#define HSTATUS_HU 0x00000200
34
24
+#define HSTATUS_VGEIN 0x0003F000
35
#define RISCV_EXCP_INT_FLAG 0x80000000
25
#define HSTATUS_VTVM 0x00100000
26
#define HSTATUS_VTSR 0x00400000
27
-#define HSTATUS_HU 0x00000200
28
-#define HSTATUS_GVA 0x00000040
29
-#define HSTATUS_SPVP 0x00000100
30
+#if defined(TARGET_RISCV64)
31
+#define HSTATUS_VSXL 0x300000000
32
+#endif
33
34
#define HSTATUS32_WPRI 0xFF8FF87E
35
#define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL
36
--
36
--
37
2.28.0
37
2.45.1
38
38
39
39
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
Running a KVM guest using a 6.9-rc3 kernel, in a 6.8 host that has zkr
4
enabled, will fail with a kernel oops SIGILL right at the start. The
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.
8
9
In hindsight this is too strict. If we keep proceeding, despite not
10
disabling the extension in the KVM vcpu, we'll not add the extension in
11
the riscv,isa. The guest kernel will be unaware of the extension, i.e.
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.
14
15
Change our current logic to not error out if we fail to disable an
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.
21
22
The case we're handling happens with an EINVAL error code. If we fail to
23
disable the extension in KVM for any other reason, error out.
24
25
We'll also keep erroring out when we fail to enable an extension in KVM,
26
since adding the extension in riscv,isa at this point will cause a guest
27
malfunction because the extension isn't enabled in the vcpu.
28
29
Suggested-by: Andrew Jones <ajones@ventanamicro.com>
30
Signed-off-by: Daniel Henrique Barboza <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>
34
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
---
36
target/riscv/kvm/kvm-cpu.c | 12 ++++++++----
37
1 file changed, 8 insertions(+), 4 deletions(-)
38
39
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/kvm/kvm-cpu.c
42
+++ b/target/riscv/kvm/kvm-cpu.c
43
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
44
reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
45
ret = kvm_set_one_reg(cs, id, &reg);
46
if (ret != 0) {
47
- error_report("Unable to %s extension %s in KVM, error %d",
48
- reg ? "enable" : "disable",
49
- multi_ext_cfg->name, ret);
50
- exit(EXIT_FAILURE);
51
+ if (!reg && ret == -EINVAL) {
52
+ warn_report("KVM cannot disable extension %s",
53
+ multi_ext_cfg->name);
54
+ } else {
55
+ error_report("Unable to enable extension %s in KVM, error %d",
56
+ multi_ext_cfg->name, ret);
57
+ exit(EXIT_FAILURE);
58
+ }
59
}
60
}
61
}
62
--
63
2.45.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
3
We're not setting (s/m)tval when triggering breakpoints of type 2
4
(mcontrol) and 6 (mcontrol6). According to the debug spec section
5
5.7.12, "Match Control Type 6":
6
7
"The Privileged Spec says that breakpoint exceptions that occur on
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>
26
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
27
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
28
Message-ID: <20240416230437.1869024-2-dbarboza@ventanamicro.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Message-id: 85b7fdba8abd87adb83275cdc3043ce35a1ed5c3.1597259519.git.alistair.francis@wdc.com
3
Message-Id: <85b7fdba8abd87adb83275cdc3043ce35a1ed5c3.1597259519.git.alistair.francis@wdc.com>
4
---
30
---
5
target/riscv/cpu_helper.c | 5 +++--
31
target/riscv/cpu_helper.c | 1 +
6
1 file changed, 3 insertions(+), 2 deletions(-)
32
target/riscv/debug.c | 3 +++
33
2 files changed, 4 insertions(+)
7
34
8
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
9
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
10
--- a/target/riscv/cpu_helper.c
37
--- a/target/riscv/cpu_helper.c
11
+++ b/target/riscv/cpu_helper.c
38
+++ b/target/riscv/cpu_helper.c
12
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
13
40
tval = env->bins;
14
if (riscv_cpu_virt_enabled(env) && ((hdeleg >> cause) & 1) &&
41
break;
15
!force_hs_execp) {
42
case RISCV_EXCP_BREAKPOINT:
16
+ /* Trap to VS mode */
43
+ tval = env->badaddr;
17
/*
44
if (cs->watchpoint_hit) {
18
* See if we need to adjust cause. Yes if its VS mode interrupt
45
tval = cs->watchpoint_hit->hitaddr;
19
* no if hypervisor has delegated one of hs mode's interrupt
46
cs->watchpoint_hit = NULL;
20
*/
47
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
21
if (cause == IRQ_VS_TIMER || cause == IRQ_VS_SOFT ||
48
index XXXXXXX..XXXXXXX 100644
22
- cause == IRQ_VS_EXT)
49
--- a/target/riscv/debug.c
23
+ cause == IRQ_VS_EXT) {
50
+++ b/target/riscv/debug.c
24
cause = cause - 1;
51
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
25
- /* Trap to VS mode */
52
if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
26
+ }
53
/* check U/S/M bit against current privilege level */
27
env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 0);
54
if ((ctrl >> 3) & BIT(env->priv)) {
28
} else if (riscv_cpu_virt_enabled(env)) {
55
+ env->badaddr = pc;
29
/* Trap into HS mode, from virt */
56
return true;
57
}
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
}
30
--
73
--
31
2.28.0
74
2.45.1
32
33
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
Privileged spec section 4.1.9 mentions:
4
5
"When a trap is taken into S-mode, stval is written with
6
exception-specific information to assist software in handling the trap.
7
(...)
8
9
If stval is written with a nonzero value when a breakpoint,
10
address-misaligned, access-fault, or page-fault exception occurs on an
11
instruction fetch, load, or store, then stval will contain the faulting
12
virtual address."
13
14
A similar text is found for mtval in section 3.1.16.
15
16
Setting mtval/stval in this scenario is optional, but some softwares read
17
these regs when handling ebreaks.
18
19
Write 'badaddr' in all ebreak breakpoints to write the appropriate
20
'tval' during riscv_do_cpu_interrrupt().
21
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.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>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
29
target/riscv/insn_trans/trans_privileged.c.inc | 2 ++
30
1 file changed, 2 insertions(+)
31
32
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/insn_trans/trans_privileged.c.inc
35
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
36
@@ -XXX,XX +XXX,XX @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
37
if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) {
38
generate_exception(ctx, RISCV_EXCP_SEMIHOST);
39
} else {
40
+ tcg_gen_st_tl(tcg_constant_tl(ebreak_addr), tcg_env,
41
+ offsetof(CPURISCVState, badaddr));
42
generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
43
}
44
return true;
45
--
46
2.45.1
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
2
3
Add support for Zve32x extension and replace some checks for Zve32f with
4
Zve32x, since Zve32f depends on Zve32x.
5
6
Signed-off-by: Jason Chien <jason.chien@sifive.com>
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
Reviewed-by: Max Chou <max.chou@sifive.com>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Message-ID: <20240328022343.6871-2-jason.chien@sifive.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Message-id: 9308432988946de550a68524ed76e4b8683f10e2.1597259519.git.alistair.francis@wdc.com
3
Message-Id: <9308432988946de550a68524ed76e4b8683f10e2.1597259519.git.alistair.francis@wdc.com>
4
---
12
---
5
target/riscv/cpu_bits.h | 5 +++--
13
target/riscv/cpu_cfg.h | 1 +
6
target/riscv/cpu_helper.c | 24 ++++++++++++++++++++----
14
target/riscv/cpu.c | 2 ++
7
target/riscv/csr.c | 6 +++---
15
target/riscv/cpu_helper.c | 2 +-
8
3 files changed, 26 insertions(+), 9 deletions(-)
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(-)
9
20
10
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
21
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
11
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
12
--- a/target/riscv/cpu_bits.h
23
--- a/target/riscv/cpu_cfg.h
13
+++ b/target/riscv/cpu_bits.h
24
+++ b/target/riscv/cpu_cfg.h
14
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
15
#define MSTATUS_TW 0x20000000 /* since: priv-1.10 */
26
bool ext_zhinx;
16
#define MSTATUS_TSR 0x40000000 /* since: priv-1.10 */
27
bool ext_zhinxmin;
17
#if defined(TARGET_RISCV64)
28
bool ext_zve32f;
18
-#define MSTATUS_MTL 0x4000000000ULL
29
+ bool ext_zve32x;
19
+#define MSTATUS_GVA 0x4000000000ULL
30
bool ext_zve64f;
20
#define MSTATUS_MPV 0x8000000000ULL
31
bool ext_zve64d;
21
#elif defined(TARGET_RISCV32)
32
bool ext_zvbb;
22
-#define MSTATUS_MTL 0x00000040
33
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
23
+#define MSTATUS_GVA 0x00000040
34
index XXXXXXX..XXXXXXX 100644
24
#define MSTATUS_MPV 0x00000080
35
--- a/target/riscv/cpu.c
25
#endif
36
+++ b/target/riscv/cpu.c
26
37
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
27
@@ -XXX,XX +XXX,XX @@
38
ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
28
#define HSTATUS_VTVM 0x00100000
39
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
29
#define HSTATUS_VTSR 0x00400000
40
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
30
#define HSTATUS_HU 0x00000200
41
+ ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
31
+#define HSTATUS_GVA 0x00000040
42
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
32
43
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
33
#define HSTATUS32_WPRI 0xFF8FF87E
44
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
34
#define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL
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),
35
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
53
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
36
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/cpu_helper.c
55
--- a/target/riscv/cpu_helper.c
38
+++ b/target/riscv/cpu_helper.c
56
+++ b/target/riscv/cpu_helper.c
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
57
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
40
if (riscv_has_ext(env, RVH)) {
58
*pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
41
target_ulong hdeleg = async ? env->hideleg : env->hedeleg;
59
*cs_base = 0;
42
60
43
+ if ((riscv_cpu_virt_enabled(env) ||
61
- if (cpu->cfg.ext_zve32f) {
44
+ riscv_cpu_two_stage_lookup(env)) && tval) {
62
+ if (cpu->cfg.ext_zve32x) {
45
+ /*
63
/*
46
+ * If we are writing a guest virtual address to stval, set
64
* If env->vl equals to VLMAX, we can use generic vector operation
47
+ * this to 1. If we are trapping to VS we will set this to 0
65
* expanders (GVEC) to accerlate the vector operations.
48
+ * later.
49
+ */
50
+ env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 1);
51
+ } else {
52
+ /* For other HS-mode traps, we set this to 0. */
53
+ env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 0);
54
+ }
55
+
56
if (riscv_cpu_virt_enabled(env) && ((hdeleg >> cause) & 1) &&
57
!force_hs_execp) {
58
/*
59
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
60
cause == IRQ_VS_EXT)
61
cause = cause - 1;
62
/* Trap to VS mode */
63
+ env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 0);
64
} else if (riscv_cpu_virt_enabled(env)) {
65
/* Trap into HS mode, from virt */
66
riscv_cpu_swap_hypervisor_regs(env);
67
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
68
#ifdef TARGET_RISCV32
69
env->mstatush = set_field(env->mstatush, MSTATUS_MPV,
70
riscv_cpu_virt_enabled(env));
71
- env->mstatush = set_field(env->mstatush, MSTATUS_MTL,
72
- riscv_cpu_force_hs_excep_enabled(env));
73
+ if (riscv_cpu_virt_enabled(env) && tval) {
74
+ env->mstatush = set_field(env->mstatush, MSTATUS_GVA, 1);
75
+ }
76
#else
77
env->mstatus = set_field(env->mstatus, MSTATUS_MPV,
78
riscv_cpu_virt_enabled(env));
79
- env->mstatus = set_field(env->mstatus, MSTATUS_MTL,
80
- riscv_cpu_force_hs_excep_enabled(env));
81
+ if (riscv_cpu_virt_enabled(env) && tval) {
82
+ env->mstatus = set_field(env->mstatus, MSTATUS_GVA, 1);
83
+ }
84
#endif
85
86
mtval2 = env->guest_phys_fault_addr;
87
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
88
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
89
--- a/target/riscv/csr.c
68
--- a/target/riscv/csr.c
90
+++ b/target/riscv/csr.c
69
+++ b/target/riscv/csr.c
91
@@ -XXX,XX +XXX,XX @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
70
@@ -XXX,XX +XXX,XX @@ static RISCVException fs(CPURISCVState *env, int csrno)
92
MSTATUS_TW;
71
93
#if defined(TARGET_RISCV64)
72
static RISCVException vs(CPURISCVState *env, int csrno)
94
/*
73
{
95
- * RV32: MPV and MTL are not in mstatus. The current plan is to
74
- if (riscv_cpu_cfg(env)->ext_zve32f) {
96
+ * RV32: MPV and GVA are not in mstatus. The current plan is to
75
+ if (riscv_cpu_cfg(env)->ext_zve32x) {
97
* add them to mstatush. For now, we just don't support it.
76
#if !defined(CONFIG_USER_ONLY)
98
*/
77
if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
99
- mask |= MSTATUS_MTL | MSTATUS_MPV;
78
return RISCV_EXCP_ILLEGAL_INST;
100
+ mask |= MSTATUS_MPV | MSTATUS_GVA;
79
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
101
#endif
80
index XXXXXXX..XXXXXXX 100644
102
81
--- a/target/riscv/tcg/tcg-cpu.c
103
mstatus = (mstatus & ~mask) | (val & mask);
82
+++ b/target/riscv/tcg/tcg-cpu.c
104
@@ -XXX,XX +XXX,XX @@ static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val)
83
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
105
tlb_flush(env_cpu(env));
84
return;
106
}
85
}
107
86
108
- val &= MSTATUS_MPV | MSTATUS_MTL;
87
- if (cpu->cfg.ext_zve32f && !riscv_has_ext(env, RVF)) {
109
+ val &= MSTATUS_MPV | MSTATUS_GVA;
88
- error_setg(errp, "Zve32f/Zve64f extensions require F extension");
110
89
- return;
111
env->mstatush = val;
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);
97
}
98
99
if (cpu->cfg.ext_zvfh) {
100
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
101
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zvbc), true);
102
}
103
104
- /*
105
- * In principle Zve*x would also suffice here, were they supported
106
- * in qemu
107
- */
108
if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkg ||
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)
120
{
121
TCGv s1, dst;
122
123
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
124
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
125
return false;
126
}
127
128
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
129
{
130
TCGv dst;
131
132
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
133
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
134
return false;
135
}
112
136
113
--
137
--
114
2.28.0
138
2.45.1
115
116
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
2
3
Add support for Zve64x extension. Enabling Zve64f enables Zve64x and
4
enabling Zve64x enables Zve32x according to their dependency.
5
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2107
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
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>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Message-id: 4c744dce9b0b057cbb5cc0f4d4ac75cda682a8af.1597259519.git.alistair.francis@wdc.com
3
Message-Id: <4c744dce9b0b057cbb5cc0f4d4ac75cda682a8af.1597259519.git.alistair.francis@wdc.com>
4
---
13
---
5
target/riscv/cpu_bits.h | 6 +++
14
target/riscv/cpu_cfg.h | 1 +
6
target/riscv/helper.h | 1 +
15
target/riscv/cpu.c | 2 ++
7
target/riscv/csr.c | 64 ++++++++++++++++++++++++-
16
target/riscv/tcg/tcg-cpu.c | 17 +++++++++++------
8
target/riscv/op_helper.c | 42 ++++++++++++++--
17
3 files changed, 14 insertions(+), 6 deletions(-)
9
target/riscv/insn_trans/trans_rvh.c.inc | 2 +-
10
5 files changed, 109 insertions(+), 6 deletions(-)
11
18
12
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
19
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
13
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
14
--- a/target/riscv/cpu_bits.h
21
--- a/target/riscv/cpu_cfg.h
15
+++ b/target/riscv/cpu_bits.h
22
+++ b/target/riscv/cpu_cfg.h
16
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
17
#define HSTATUS_WPRI HSTATUS64_WPRI
24
bool ext_zve32x;
18
#endif
25
bool ext_zve64f;
19
26
bool ext_zve64d;
20
+#define HCOUNTEREN_CY (1 << 0)
27
+ bool ext_zve64x;
21
+#define HCOUNTEREN_TM (1 << 1)
28
bool ext_zvbb;
22
+#define HCOUNTEREN_IR (1 << 2)
29
bool ext_zvbc;
23
+#define HCOUNTEREN_HPM3 (1 << 3)
30
bool ext_zvkb;
24
+
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
25
/* Privilege modes */
26
#define PRV_U 0
27
#define PRV_S 1
28
@@ -XXX,XX +XXX,XX @@
29
#define RISCV_EXCP_STORE_PAGE_FAULT 0xf /* since: priv-1.10.0 */
30
#define RISCV_EXCP_INST_GUEST_PAGE_FAULT 0x14
31
#define RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT 0x15
32
+#define RISCV_EXCP_VIRT_INSTRUCTION_FAULT 0x16
33
#define RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT 0x17
34
35
#define RISCV_EXCP_INT_FLAG 0x80000000
36
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
37
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/helper.h
33
--- a/target/riscv/cpu.c
39
+++ b/target/riscv/helper.h
34
+++ b/target/riscv/cpu.c
40
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(tlb_flush, void, env)
35
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
41
/* Hypervisor functions */
36
ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
42
#ifndef CONFIG_USER_ONLY
37
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
43
DEF_HELPER_1(hyp_tlb_flush, void, env)
38
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
44
+DEF_HELPER_1(hyp_gvma_tlb_flush, void, env)
39
+ ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x),
45
DEF_HELPER_4(hyp_load, tl, env, tl, tl, tl)
40
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
46
DEF_HELPER_5(hyp_store, void, env, tl, tl, tl, tl)
41
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
47
DEF_HELPER_4(hyp_x_load, tl, env, tl, tl, tl)
42
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
48
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
43
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
44
MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
45
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
46
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
47
+ MULTI_EXT_CFG_BOOL("zve64x", ext_zve64x, false),
48
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
49
MULTI_EXT_CFG_BOOL("zvfbfwma", ext_zvfbfwma, false),
50
MULTI_EXT_CFG_BOOL("zvfh", ext_zvfh, false),
51
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
49
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/csr.c
53
--- a/target/riscv/tcg/tcg-cpu.c
51
+++ b/target/riscv/csr.c
54
+++ b/target/riscv/tcg/tcg-cpu.c
52
@@ -XXX,XX +XXX,XX @@ static int ctr(CPURISCVState *env, int csrno)
55
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
53
/* The Counters extensions is not enabled */
56
54
return -RISCV_EXCP_ILLEGAL_INST;
57
/* The Zve64d extension depends on the Zve64f extension */
58
if (cpu->cfg.ext_zve64d) {
59
+ if (!riscv_has_ext(env, RVD)) {
60
+ error_setg(errp, "Zve64d/V extensions require D extension");
61
+ return;
62
+ }
63
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64f), true);
55
}
64
}
56
+
65
57
+ if (riscv_cpu_virt_enabled(env)) {
66
- /* The Zve64f extension depends on the Zve32f extension */
58
+ switch (csrno) {
67
+ /* The Zve64f extension depends on the Zve64x and Zve32f extensions */
59
+ case CSR_CYCLE:
68
if (cpu->cfg.ext_zve64f) {
60
+ if (!get_field(env->hcounteren, HCOUNTEREN_CY) &&
69
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64x), true);
61
+ get_field(env->mcounteren, HCOUNTEREN_CY)) {
70
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32f), true);
62
+ return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
63
+ }
64
+ break;
65
+ case CSR_TIME:
66
+ if (!get_field(env->hcounteren, HCOUNTEREN_TM) &&
67
+ get_field(env->mcounteren, HCOUNTEREN_TM)) {
68
+ return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
69
+ }
70
+ break;
71
+ case CSR_INSTRET:
72
+ if (!get_field(env->hcounteren, HCOUNTEREN_IR) &&
73
+ get_field(env->mcounteren, HCOUNTEREN_IR)) {
74
+ return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
75
+ }
76
+ break;
77
+ case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
78
+ if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3)) &&
79
+ get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3))) {
80
+ return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
81
+ }
82
+ break;
83
+#if defined(TARGET_RISCV32)
84
+ case CSR_CYCLEH:
85
+ if (!get_field(env->hcounteren, HCOUNTEREN_CY) &&
86
+ get_field(env->mcounteren, HCOUNTEREN_CY)) {
87
+ return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
88
+ }
89
+ break;
90
+ case CSR_TIMEH:
91
+ if (!get_field(env->hcounteren, HCOUNTEREN_TM) &&
92
+ get_field(env->mcounteren, HCOUNTEREN_TM)) {
93
+ return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
94
+ }
95
+ break;
96
+ case CSR_INSTRETH:
97
+ if (!get_field(env->hcounteren, HCOUNTEREN_IR) &&
98
+ get_field(env->mcounteren, HCOUNTEREN_IR)) {
99
+ return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
100
+ }
101
+ break;
102
+ case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
103
+ if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
104
+ get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) {
105
+ return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
106
+ }
107
+ break;
108
+#endif
109
+ }
110
+ }
111
#endif
112
return 0;
113
}
114
@@ -XXX,XX +XXX,XX @@ static int hmode(CPURISCVState *env, int csrno)
115
if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
116
env->priv == PRV_M) {
117
return 0;
118
+ } else {
119
+ return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
120
}
121
}
71
}
122
72
123
@@ -XXX,XX +XXX,XX @@ static const target_ulong delegable_excps =
73
- if (cpu->cfg.ext_zve64d && !riscv_has_ext(env, RVD)) {
124
(1ULL << (RISCV_EXCP_STORE_PAGE_FAULT)) |
74
- error_setg(errp, "Zve64d/V extensions require D extension");
125
(1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) |
75
- return;
126
(1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) |
76
+ /* The Zve64x extension depends on the Zve32x extension */
127
+ (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) |
77
+ if (cpu->cfg.ext_zve64x) {
128
(1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT));
78
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
129
static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
130
SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
131
@@ -XXX,XX +XXX,XX @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
132
}
79
}
133
80
134
/* check predicate */
81
/* The Zve32f extension depends on the Zve32x extension */
135
- if (!csr_ops[csrno].predicate || csr_ops[csrno].predicate(env, csrno) < 0) {
82
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
136
+ if (!csr_ops[csrno].predicate) {
137
return -RISCV_EXCP_ILLEGAL_INST;
138
}
139
+ ret = csr_ops[csrno].predicate(env, csrno);
140
+ if (ret < 0) {
141
+ return ret;
142
+ }
143
144
/* execute combined read/write operation if it exists */
145
if (csr_ops[csrno].op) {
146
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/target/riscv/op_helper.c
149
+++ b/target/riscv/op_helper.c
150
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
151
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
152
}
153
154
+ if (riscv_has_ext(env, RVH) && riscv_cpu_virt_enabled(env) &&
155
+ get_field(env->hstatus, HSTATUS_VTSR)) {
156
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
157
+ }
158
+
159
mstatus = env->mstatus;
160
161
if (riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
162
@@ -XXX,XX +XXX,XX @@ void helper_wfi(CPURISCVState *env)
163
if ((env->priv == PRV_S &&
164
get_field(env->mstatus, MSTATUS_TW)) ||
165
riscv_cpu_virt_enabled(env)) {
166
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
167
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
168
} else {
169
cs->halted = 1;
170
cs->exception_index = EXCP_HLT;
171
@@ -XXX,XX +XXX,XX @@ void helper_tlb_flush(CPURISCVState *env)
172
(env->priv == PRV_S &&
173
get_field(env->mstatus, MSTATUS_TVM))) {
174
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
175
+ } else if (riscv_has_ext(env, RVH) && riscv_cpu_virt_enabled(env) &&
176
+ get_field(env->hstatus, HSTATUS_VTVM)) {
177
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
178
} else {
179
tlb_flush(cs);
180
}
181
@@ -XXX,XX +XXX,XX @@ void helper_hyp_tlb_flush(CPURISCVState *env)
182
{
183
CPUState *cs = env_cpu(env);
184
185
+ if (env->priv == PRV_S && riscv_cpu_virt_enabled(env)) {
186
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
187
+ }
188
+
189
if (env->priv == PRV_M ||
190
(env->priv == PRV_S && !riscv_cpu_virt_enabled(env))) {
191
tlb_flush(cs);
192
@@ -XXX,XX +XXX,XX @@ void helper_hyp_tlb_flush(CPURISCVState *env)
193
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
194
}
195
196
+void helper_hyp_gvma_tlb_flush(CPURISCVState *env)
197
+{
198
+ if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env) &&
199
+ get_field(env->mstatus, MSTATUS_TVM)) {
200
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
201
+ }
202
+
203
+ helper_hyp_tlb_flush(env);
204
+}
205
+
206
target_ulong helper_hyp_load(CPURISCVState *env, target_ulong address,
207
target_ulong attrs, target_ulong memop)
208
{
209
@@ -XXX,XX +XXX,XX @@ target_ulong helper_hyp_load(CPURISCVState *env, target_ulong address,
210
return pte;
211
}
212
213
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
214
+ if (riscv_cpu_virt_enabled(env)) {
215
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
216
+ } else {
217
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
218
+ }
219
return 0;
220
}
221
222
@@ -XXX,XX +XXX,XX @@ void helper_hyp_store(CPURISCVState *env, target_ulong address,
223
return;
83
return;
224
}
84
}
225
85
226
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
86
- if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
227
+ if (riscv_cpu_virt_enabled(env)) {
87
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64x) {
228
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
88
error_setg(
229
+ } else {
89
errp,
230
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
90
- "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
231
+ }
91
+ "Zvbc and Zvknhb extensions require V or Zve64x extensions");
232
}
92
return;
233
234
target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
235
@@ -XXX,XX +XXX,XX @@ target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
236
return pte;
237
}
93
}
238
94
239
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
240
+ if (riscv_cpu_virt_enabled(env)) {
241
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
242
+ } else {
243
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
244
+ }
245
return 0;
246
}
247
248
diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
249
index XXXXXXX..XXXXXXX 100644
250
--- a/target/riscv/insn_trans/trans_rvh.c.inc
251
+++ b/target/riscv/insn_trans/trans_rvh.c.inc
252
@@ -XXX,XX +XXX,XX @@ static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
253
{
254
REQUIRE_EXT(ctx, RVH);
255
#ifndef CONFIG_USER_ONLY
256
- gen_helper_hyp_tlb_flush(cpu_env);
257
+ gen_helper_hyp_gvma_tlb_flush(cpu_env);
258
return true;
259
#endif
260
return false;
261
--
95
--
262
2.28.0
96
2.45.1
263
264
diff view generated by jsdifflib
New patch
1
From: Jason Chien <jason.chien@sifive.com>
1
2
3
In current implementation, the gdbstub allows reading vector registers
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.
7
8
Signed-off-by: Jason Chien <jason.chien@sifive.com>
9
Reviewed-by: Frank Chang <frank.chang@sifive.com>
10
Reviewed-by: Max Chou <max.chou@sifive.com>
11
Message-ID: <20240328022343.6871-4-jason.chien@sifive.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/gdbstub.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
16
17
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/gdbstub.c
20
+++ b/target/riscv/gdbstub.c
21
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
22
gdb_find_static_feature("riscv-32bit-fpu.xml"),
23
0);
24
}
25
- if (env->misa_ext & RVV) {
26
+ if (cpu->cfg.ext_zve32x) {
27
gdb_register_coprocessor(cs, riscv_gdb_get_vector,
28
riscv_gdb_set_vector,
29
ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs),
30
--
31
2.45.1
diff view generated by jsdifflib
New patch
1
From: Huang Tao <eric.huang@linux.alibaba.com>
1
2
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.
6
7
However, this function can't deal the big endian situation. This patch fixes
8
the problem by adding handling of such case.
9
10
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
11
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
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>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
target/riscv/vector_internals.c | 22 ++++++++++++++++++++++
18
1 file changed, 22 insertions(+)
19
20
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/vector_internals.c
23
+++ b/target/riscv/vector_internals.c
24
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
25
if (tot - cnt == 0) {
26
return ;
27
}
28
+
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);
51
}
52
53
--
54
2.45.1
diff view generated by jsdifflib
1
From: Anup Patel <anup.patel@wdc.com>
1
From: Yangyu Chen <cyy@cyyself.name>
2
2
3
We extend PLIC emulation to allow multiple instances of PLIC in
3
This code has a typo that writes zvkb to zvkg, causing users can't
4
a QEMU RISC-V machine. To achieve this, we remove first HART id
4
enable zvkb through the config. This patch gets this fixed.
5
zero assumption from PLIC emulation.
6
5
7
Signed-off-by: Anup Patel <anup.patel@wdc.com>
6
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
8
Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
7
Fixes: ea61ef7097d0 ("target/riscv: Move vector crypto extensions to riscv_cpu_extensions")
8
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20200616032229.766089-3-anup.patel@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>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
15
---
13
include/hw/riscv/sifive_plic.h | 12 +++++++-----
16
target/riscv/cpu.c | 2 +-
14
hw/riscv/sifive_e.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
15
hw/riscv/sifive_plic.c | 24 +++++++++++++-----------
16
hw/riscv/sifive_u.c | 2 +-
17
hw/riscv/virt.c | 2 +-
18
5 files changed, 23 insertions(+), 19 deletions(-)
19
18
20
diff --git a/include/hw/riscv/sifive_plic.h b/include/hw/riscv/sifive_plic.h
19
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
21
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/riscv/sifive_plic.h
21
--- a/target/riscv/cpu.c
23
+++ b/include/hw/riscv/sifive_plic.h
22
+++ b/target/riscv/cpu.c
24
@@ -XXX,XX +XXX,XX @@ typedef struct SiFivePLICState {
23
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
25
/*< public >*/
24
/* Vector cryptography extensions */
26
MemoryRegion mmio;
25
MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false),
27
uint32_t num_addrs;
26
MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false),
28
+ uint32_t num_harts;
27
- MULTI_EXT_CFG_BOOL("zvkb", ext_zvkg, false),
29
uint32_t bitfield_words;
28
+ MULTI_EXT_CFG_BOOL("zvkb", ext_zvkb, false),
30
PLICAddr *addr_config;
29
MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false),
31
uint32_t *source_priority;
30
MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false),
32
@@ -XXX,XX +XXX,XX @@ typedef struct SiFivePLICState {
31
MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false),
33
34
/* config */
35
char *hart_config;
36
+ uint32_t hartid_base;
37
uint32_t num_sources;
38
uint32_t num_priorities;
39
uint32_t priority_base;
40
@@ -XXX,XX +XXX,XX @@ typedef struct SiFivePLICState {
41
} SiFivePLICState;
42
43
DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
44
- uint32_t num_sources, uint32_t num_priorities,
45
- uint32_t priority_base, uint32_t pending_base,
46
- uint32_t enable_base, uint32_t enable_stride,
47
- uint32_t context_base, uint32_t context_stride,
48
- uint32_t aperture_size);
49
+ uint32_t hartid_base, uint32_t num_sources,
50
+ uint32_t num_priorities, uint32_t priority_base,
51
+ uint32_t pending_base, uint32_t enable_base,
52
+ uint32_t enable_stride, uint32_t context_base,
53
+ uint32_t context_stride, uint32_t aperture_size);
54
55
#endif
56
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/riscv/sifive_e.c
59
+++ b/hw/riscv/sifive_e.c
60
@@ -XXX,XX +XXX,XX @@ static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
61
62
/* MMIO */
63
s->plic = sifive_plic_create(memmap[SIFIVE_E_PLIC].base,
64
- (char *)SIFIVE_E_PLIC_HART_CONFIG,
65
+ (char *)SIFIVE_E_PLIC_HART_CONFIG, 0,
66
SIFIVE_E_PLIC_NUM_SOURCES,
67
SIFIVE_E_PLIC_NUM_PRIORITIES,
68
SIFIVE_E_PLIC_PRIORITY_BASE,
69
diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/riscv/sifive_plic.c
72
+++ b/hw/riscv/sifive_plic.c
73
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps sifive_plic_ops = {
74
75
static Property sifive_plic_properties[] = {
76
DEFINE_PROP_STRING("hart-config", SiFivePLICState, hart_config),
77
+ DEFINE_PROP_UINT32("hartid-base", SiFivePLICState, hartid_base, 0),
78
DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 0),
79
DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
80
DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
81
@@ -XXX,XX +XXX,XX @@ static void parse_hart_config(SiFivePLICState *plic)
82
}
83
hartid++;
84
85
- /* store hart/mode combinations */
86
plic->num_addrs = addrid;
87
+ plic->num_harts = hartid;
88
+
89
+ /* store hart/mode combinations */
90
plic->addr_config = g_new(PLICAddr, plic->num_addrs);
91
- addrid = 0, hartid = 0;
92
+ addrid = 0, hartid = plic->hartid_base;
93
p = plic->hart_config;
94
while ((c = *p++)) {
95
if (c == ',') {
96
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_irq_request(void *opaque, int irq, int level)
97
98
static void sifive_plic_realize(DeviceState *dev, Error **errp)
99
{
100
- MachineState *ms = MACHINE(qdev_get_machine());
101
- unsigned int smp_cpus = ms->smp.cpus;
102
SiFivePLICState *plic = SIFIVE_PLIC(dev);
103
int i;
104
105
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
106
* lost a interrupt in the case a PLIC is attached. The SEIP bit must be
107
* hardware controlled when a PLIC is attached.
108
*/
109
- for (i = 0; i < smp_cpus; i++) {
110
- RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(i));
111
+ for (i = 0; i < plic->num_harts; i++) {
112
+ RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(plic->hartid_base + i));
113
if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
114
error_report("SEIP already claimed");
115
exit(1);
116
@@ -XXX,XX +XXX,XX @@ type_init(sifive_plic_register_types)
117
* Create PLIC device.
118
*/
119
DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
120
- uint32_t num_sources, uint32_t num_priorities,
121
- uint32_t priority_base, uint32_t pending_base,
122
- uint32_t enable_base, uint32_t enable_stride,
123
- uint32_t context_base, uint32_t context_stride,
124
- uint32_t aperture_size)
125
+ uint32_t hartid_base, uint32_t num_sources,
126
+ uint32_t num_priorities, uint32_t priority_base,
127
+ uint32_t pending_base, uint32_t enable_base,
128
+ uint32_t enable_stride, uint32_t context_base,
129
+ uint32_t context_stride, uint32_t aperture_size)
130
{
131
DeviceState *dev = qdev_new(TYPE_SIFIVE_PLIC);
132
assert(enable_stride == (enable_stride & -enable_stride));
133
assert(context_stride == (context_stride & -context_stride));
134
qdev_prop_set_string(dev, "hart-config", hart_config);
135
+ qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
136
qdev_prop_set_uint32(dev, "num-sources", num_sources);
137
qdev_prop_set_uint32(dev, "num-priorities", num_priorities);
138
qdev_prop_set_uint32(dev, "priority-base", priority_base);
139
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/hw/riscv/sifive_u.c
142
+++ b/hw/riscv/sifive_u.c
143
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
144
145
/* MMIO */
146
s->plic = sifive_plic_create(memmap[SIFIVE_U_PLIC].base,
147
- plic_hart_config,
148
+ plic_hart_config, 0,
149
SIFIVE_U_PLIC_NUM_SOURCES,
150
SIFIVE_U_PLIC_NUM_PRIORITIES,
151
SIFIVE_U_PLIC_PRIORITY_BASE,
152
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/hw/riscv/virt.c
155
+++ b/hw/riscv/virt.c
156
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
157
158
/* MMIO */
159
s->plic = sifive_plic_create(memmap[VIRT_PLIC].base,
160
- plic_hart_config,
161
+ plic_hart_config, 0,
162
VIRT_PLIC_NUM_SOURCES,
163
VIRT_PLIC_NUM_PRIORITIES,
164
VIRT_PLIC_PRIORITY_BASE,
165
--
32
--
166
2.28.0
33
2.45.1
167
34
168
35
diff view generated by jsdifflib
1
From: Anup Patel <anup.patel@wdc.com>
1
From: Huang Tao <eric.huang@linux.alibaba.com>
2
2
3
We extend RISC-V spike machine to allow creating a multi-socket
3
In this patch, we modify the decoder to be a freely composable data
4
machine. Each RISC-V spike machine socket is a NUMA node having
4
structure instead of a hardcoded one. It can be dynamically builded up
5
a set of HARTs, a memory instance, and a CLINT instance. Other
5
according to the extensions.
6
devices are shared between all sockets. We also update the
6
This approach has several benefits:
7
generated device tree accordingly.
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.
8
20
9
By default, NUMA multi-socket support is disabled for RISC-V spike
21
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
10
machine. To enable it, users can use "-numa" command-line options
22
Suggested-by: Christoph Muellner <christoph.muellner@vrull.eu>
11
of QEMU.
23
Co-authored-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
12
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Example1: For two NUMA nodes with 2 CPUs each, append following
25
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
to command-line options: "-smp 4 -numa node -numa node"
26
Message-ID: <20240506023607.29544-1-eric.huang@linux.alibaba.com>
15
16
Example2: For two NUMA nodes with 1 and 3 CPUs, append following
17
to command-line options:
18
"-smp 4 -numa node -numa node -numa cpu,node-id=0,core-id=0 \
19
-numa cpu,node-id=1,core-id=1 -numa cpu,node-id=1,core-id=2 \
20
-numa cpu,node-id=1,core-id=3"
21
22
The maximum number of sockets in a RISC-V spike machine is 8
23
but this limit can be changed in future.
24
25
Signed-off-by: Anup Patel <anup.patel@wdc.com>
26
Reviewed-by: Atish Patra <atish.patra@wdc.com>
27
Message-Id: <20200616032229.766089-5-anup.patel@wdc.com>
28
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
29
---
28
---
30
include/hw/riscv/spike.h | 11 +-
29
target/riscv/cpu.h | 1 +
31
hw/riscv/spike.c | 232 ++++++++++++++++++++++++++-------------
30
target/riscv/tcg/tcg-cpu.h | 15 +++++++++++++++
32
2 files changed, 167 insertions(+), 76 deletions(-)
31
target/riscv/cpu.c | 1 +
32
target/riscv/tcg/tcg-cpu.c | 15 +++++++++++++++
33
target/riscv/translate.c | 31 +++++++++++++++----------------
34
5 files changed, 47 insertions(+), 16 deletions(-)
33
35
34
diff --git a/include/hw/riscv/spike.h b/include/hw/riscv/spike.h
36
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
35
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/riscv/spike.h
38
--- a/target/riscv/cpu.h
37
+++ b/include/hw/riscv/spike.h
39
+++ b/target/riscv/cpu.h
38
@@ -XXX,XX +XXX,XX @@
40
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
39
#include "hw/riscv/riscv_hart.h"
41
uint32_t pmu_avail_ctrs;
40
#include "hw/sysbus.h"
42
/* Mapping of events to counters */
41
43
GHashTable *pmu_event_ctr_map;
42
+#define SPIKE_CPUS_MAX 8
44
+ const GPtrArray *decoders;
43
+#define SPIKE_SOCKETS_MAX 8
45
};
46
47
/**
48
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/tcg/tcg-cpu.h
51
+++ b/target/riscv/tcg/tcg-cpu.h
52
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
53
void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
54
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
55
56
+struct DisasContext;
57
+struct RISCVCPUConfig;
58
+typedef struct RISCVDecoder {
59
+ bool (*guard_func)(const struct RISCVCPUConfig *);
60
+ bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
61
+} RISCVDecoder;
44
+
62
+
45
+#define TYPE_SPIKE_MACHINE MACHINE_TYPE_NAME("spike")
63
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
46
+#define SPIKE_MACHINE(obj) \
47
+ OBJECT_CHECK(SpikeState, (obj), TYPE_SPIKE_MACHINE)
48
+
64
+
49
typedef struct {
65
+extern const size_t decoder_table_size;
50
/*< private >*/
66
+
51
- SysBusDevice parent_obj;
67
+extern const RISCVDecoder decoder_table[];
52
+ MachineState parent;
68
+
53
69
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
54
/*< public >*/
70
+
55
- RISCVHartArrayState soc;
71
#endif
56
+ RISCVHartArrayState soc[SPIKE_SOCKETS_MAX];
72
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
57
void *fdt;
58
int fdt_size;
59
} SpikeState;
60
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
61
index XXXXXXX..XXXXXXX 100644
73
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/riscv/spike.c
74
--- a/target/riscv/cpu.c
63
+++ b/hw/riscv/spike.c
75
+++ b/target/riscv/cpu.c
64
@@ -XXX,XX +XXX,XX @@
76
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
65
#include "hw/riscv/sifive_clint.h"
77
error_propagate(errp, local_err);
66
#include "hw/riscv/spike.h"
78
return;
67
#include "hw/riscv/boot.h"
79
}
68
+#include "hw/riscv/numa.h"
80
+ riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
69
#include "chardev/char.h"
81
} else if (kvm_enabled()) {
70
#include "sysemu/arch_init.h"
82
riscv_kvm_cpu_finalize_features(cpu, &local_err);
71
#include "sysemu/device_tree.h"
83
if (local_err != NULL) {
72
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap,
84
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
73
uint64_t mem_size, const char *cmdline)
85
index XXXXXXX..XXXXXXX 100644
74
{
86
--- a/target/riscv/tcg/tcg-cpu.c
75
void *fdt;
87
+++ b/target/riscv/tcg/tcg-cpu.c
76
- int cpu;
88
@@ -XXX,XX +XXX,XX @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
77
- uint32_t *cells;
89
}
78
- char *nodename;
90
}
79
+ uint64_t addr, size;
91
80
+ unsigned long clint_addr;
92
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
81
+ int cpu, socket;
93
+{
82
+ MachineState *mc = MACHINE(s);
94
+ GPtrArray *dynamic_decoders;
83
+ uint32_t *clint_cells;
95
+ dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
84
+ uint32_t cpu_phandle, intc_phandle, phandle = 1;
96
+ for (size_t i = 0; i < decoder_table_size; ++i) {
85
+ char *name, *mem_name, *clint_name, *clust_name;
97
+ if (decoder_table[i].guard_func &&
86
+ char *core_name, *cpu_name, *intc_name;
98
+ decoder_table[i].guard_func(&cpu->cfg)) {
87
99
+ g_ptr_array_add(dynamic_decoders,
88
fdt = s->fdt = create_device_tree(&s->fdt_size);
100
+ (gpointer)decoder_table[i].riscv_cpu_decode_fn);
89
if (!fdt) {
90
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap,
91
qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2);
92
qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2);
93
94
- nodename = g_strdup_printf("/memory@%lx",
95
- (long)memmap[SPIKE_DRAM].base);
96
- qemu_fdt_add_subnode(fdt, nodename);
97
- qemu_fdt_setprop_cells(fdt, nodename, "reg",
98
- memmap[SPIKE_DRAM].base >> 32, memmap[SPIKE_DRAM].base,
99
- mem_size >> 32, mem_size);
100
- qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
101
- g_free(nodename);
102
-
103
qemu_fdt_add_subnode(fdt, "/cpus");
104
qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency",
105
SIFIVE_CLINT_TIMEBASE_FREQ);
106
qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
107
qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
108
+ qemu_fdt_add_subnode(fdt, "/cpus/cpu-map");
109
+
110
+ for (socket = (riscv_socket_count(mc) - 1); socket >= 0; socket--) {
111
+ clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket);
112
+ qemu_fdt_add_subnode(fdt, clust_name);
113
+
114
+ clint_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4);
115
116
- for (cpu = s->soc.num_harts - 1; cpu >= 0; cpu--) {
117
- nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
118
- char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
119
- char *isa = riscv_isa_string(&s->soc.harts[cpu]);
120
- qemu_fdt_add_subnode(fdt, nodename);
121
+ for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) {
122
+ cpu_phandle = phandle++;
123
+
124
+ cpu_name = g_strdup_printf("/cpus/cpu@%d",
125
+ s->soc[socket].hartid_base + cpu);
126
+ qemu_fdt_add_subnode(fdt, cpu_name);
127
#if defined(TARGET_RISCV32)
128
- qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv32");
129
+ qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv32");
130
#else
131
- qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
132
+ qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv48");
133
#endif
134
- qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa);
135
- qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv");
136
- qemu_fdt_setprop_string(fdt, nodename, "status", "okay");
137
- qemu_fdt_setprop_cell(fdt, nodename, "reg", cpu);
138
- qemu_fdt_setprop_string(fdt, nodename, "device_type", "cpu");
139
- qemu_fdt_add_subnode(fdt, intc);
140
- qemu_fdt_setprop_cell(fdt, intc, "phandle", 1);
141
- qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
142
- qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
143
- qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
144
- g_free(isa);
145
- g_free(intc);
146
- g_free(nodename);
147
- }
148
+ name = riscv_isa_string(&s->soc[socket].harts[cpu]);
149
+ qemu_fdt_setprop_string(fdt, cpu_name, "riscv,isa", name);
150
+ g_free(name);
151
+ qemu_fdt_setprop_string(fdt, cpu_name, "compatible", "riscv");
152
+ qemu_fdt_setprop_string(fdt, cpu_name, "status", "okay");
153
+ qemu_fdt_setprop_cell(fdt, cpu_name, "reg",
154
+ s->soc[socket].hartid_base + cpu);
155
+ qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu");
156
+ riscv_socket_fdt_write_id(mc, fdt, cpu_name, socket);
157
+ qemu_fdt_setprop_cell(fdt, cpu_name, "phandle", cpu_phandle);
158
159
- cells = g_new0(uint32_t, s->soc.num_harts * 4);
160
- for (cpu = 0; cpu < s->soc.num_harts; cpu++) {
161
- nodename =
162
- g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
163
- uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
164
- cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle);
165
- cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
166
- cells[cpu * 4 + 2] = cpu_to_be32(intc_phandle);
167
- cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
168
- g_free(nodename);
169
+ intc_name = g_strdup_printf("%s/interrupt-controller", cpu_name);
170
+ qemu_fdt_add_subnode(fdt, intc_name);
171
+ intc_phandle = phandle++;
172
+ qemu_fdt_setprop_cell(fdt, intc_name, "phandle", intc_phandle);
173
+ qemu_fdt_setprop_string(fdt, intc_name, "compatible",
174
+ "riscv,cpu-intc");
175
+ qemu_fdt_setprop(fdt, intc_name, "interrupt-controller", NULL, 0);
176
+ qemu_fdt_setprop_cell(fdt, intc_name, "#interrupt-cells", 1);
177
+
178
+ clint_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle);
179
+ clint_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
180
+ clint_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandle);
181
+ clint_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
182
+
183
+ core_name = g_strdup_printf("%s/core%d", clust_name, cpu);
184
+ qemu_fdt_add_subnode(fdt, core_name);
185
+ qemu_fdt_setprop_cell(fdt, core_name, "cpu", cpu_phandle);
186
+
187
+ g_free(core_name);
188
+ g_free(intc_name);
189
+ g_free(cpu_name);
190
+ }
101
+ }
191
+
192
+ addr = memmap[SPIKE_DRAM].base + riscv_socket_mem_offset(mc, socket);
193
+ size = riscv_socket_mem_size(mc, socket);
194
+ mem_name = g_strdup_printf("/memory@%lx", (long)addr);
195
+ qemu_fdt_add_subnode(fdt, mem_name);
196
+ qemu_fdt_setprop_cells(fdt, mem_name, "reg",
197
+ addr >> 32, addr, size >> 32, size);
198
+ qemu_fdt_setprop_string(fdt, mem_name, "device_type", "memory");
199
+ riscv_socket_fdt_write_id(mc, fdt, mem_name, socket);
200
+ g_free(mem_name);
201
+
202
+ clint_addr = memmap[SPIKE_CLINT].base +
203
+ (memmap[SPIKE_CLINT].size * socket);
204
+ clint_name = g_strdup_printf("/soc/clint@%lx", clint_addr);
205
+ qemu_fdt_add_subnode(fdt, clint_name);
206
+ qemu_fdt_setprop_string(fdt, clint_name, "compatible", "riscv,clint0");
207
+ qemu_fdt_setprop_cells(fdt, clint_name, "reg",
208
+ 0x0, clint_addr, 0x0, memmap[SPIKE_CLINT].size);
209
+ qemu_fdt_setprop(fdt, clint_name, "interrupts-extended",
210
+ clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
211
+ riscv_socket_fdt_write_id(mc, fdt, clint_name, socket);
212
+
213
+ g_free(clint_name);
214
+ g_free(clint_cells);
215
+ g_free(clust_name);
216
}
217
- nodename = g_strdup_printf("/soc/clint@%lx",
218
- (long)memmap[SPIKE_CLINT].base);
219
- qemu_fdt_add_subnode(fdt, nodename);
220
- qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv,clint0");
221
- qemu_fdt_setprop_cells(fdt, nodename, "reg",
222
- 0x0, memmap[SPIKE_CLINT].base,
223
- 0x0, memmap[SPIKE_CLINT].size);
224
- qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
225
- cells, s->soc.num_harts * sizeof(uint32_t) * 4);
226
- g_free(cells);
227
- g_free(nodename);
228
+
229
+ riscv_socket_fdt_write_distance_matrix(mc, fdt);
230
231
if (cmdline) {
232
qemu_fdt_add_subnode(fdt, "/chosen");
233
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap,
234
static void spike_board_init(MachineState *machine)
235
{
236
const struct MemmapEntry *memmap = spike_memmap;
237
-
238
- SpikeState *s = g_new0(SpikeState, 1);
239
+ SpikeState *s = SPIKE_MACHINE(machine);
240
MemoryRegion *system_memory = get_system_memory();
241
MemoryRegion *main_mem = g_new(MemoryRegion, 1);
242
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
243
- unsigned int smp_cpus = machine->smp.cpus;
244
uint32_t fdt_load_addr;
245
uint64_t kernel_entry;
246
+ char *soc_name;
247
+ int i, base_hartid, hart_count;
248
249
- /* Initialize SOC */
250
- object_initialize_child(OBJECT(machine), "soc", &s->soc,
251
- TYPE_RISCV_HART_ARRAY);
252
- object_property_set_str(OBJECT(&s->soc), "cpu-type", machine->cpu_type,
253
- &error_abort);
254
- object_property_set_int(OBJECT(&s->soc), "num-harts", smp_cpus,
255
- &error_abort);
256
- sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_abort);
257
+ /* Check socket count limit */
258
+ if (SPIKE_SOCKETS_MAX < riscv_socket_count(machine)) {
259
+ error_report("number of sockets/nodes should be less than %d",
260
+ SPIKE_SOCKETS_MAX);
261
+ exit(1);
262
+ }
102
+ }
263
+
103
+
264
+ /* Initialize sockets */
104
+ cpu->decoders = dynamic_decoders;
265
+ for (i = 0; i < riscv_socket_count(machine); i++) {
266
+ if (!riscv_socket_check_hartids(machine, i)) {
267
+ error_report("discontinuous hartids in socket%d", i);
268
+ exit(1);
269
+ }
270
+
271
+ base_hartid = riscv_socket_first_hartid(machine, i);
272
+ if (base_hartid < 0) {
273
+ error_report("can't find hartid base for socket%d", i);
274
+ exit(1);
275
+ }
276
+
277
+ hart_count = riscv_socket_hart_count(machine, i);
278
+ if (hart_count < 0) {
279
+ error_report("can't find hart count for socket%d", i);
280
+ exit(1);
281
+ }
282
+
283
+ soc_name = g_strdup_printf("soc%d", i);
284
+ object_initialize_child(OBJECT(machine), soc_name, &s->soc[i],
285
+ TYPE_RISCV_HART_ARRAY);
286
+ g_free(soc_name);
287
+ object_property_set_str(OBJECT(&s->soc[i]), "cpu-type",
288
+ machine->cpu_type, &error_abort);
289
+ object_property_set_int(OBJECT(&s->soc[i]), "hartid-base",
290
+ base_hartid, &error_abort);
291
+ object_property_set_int(OBJECT(&s->soc[i]), "num-harts",
292
+ hart_count, &error_abort);
293
+ sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_abort);
294
+
295
+ /* Core Local Interruptor (timer and IPI) for each socket */
296
+ sifive_clint_create(
297
+ memmap[SPIKE_CLINT].base + i * memmap[SPIKE_CLINT].size,
298
+ memmap[SPIKE_CLINT].size, base_hartid, hart_count,
299
+ SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, false);
300
+ }
301
302
/* register system main memory (actual RAM) */
303
memory_region_init_ram(main_mem, NULL, "riscv.spike.ram",
304
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
305
fdt_load_addr, s->fdt);
306
307
/* initialize HTIF using symbols found in load_kernel */
308
- htif_mm_init(system_memory, mask_rom, &s->soc.harts[0].env, serial_hd(0));
309
+ htif_mm_init(system_memory, mask_rom,
310
+ &s->soc[0].harts[0].env, serial_hd(0));
311
+}
312
313
- /* Core Local Interruptor (timer and IPI) */
314
- sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size,
315
- 0, smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
316
- false);
317
+static void spike_machine_instance_init(Object *obj)
318
+{
319
}
320
321
-static void spike_machine_init(MachineClass *mc)
322
+static void spike_machine_class_init(ObjectClass *oc, void *data)
323
{
324
- mc->desc = "RISC-V Spike Board";
325
+ MachineClass *mc = MACHINE_CLASS(oc);
326
+
327
+ mc->desc = "RISC-V Spike board";
328
mc->init = spike_board_init;
329
- mc->max_cpus = 8;
330
+ mc->max_cpus = SPIKE_CPUS_MAX;
331
mc->is_default = true;
332
mc->default_cpu_type = SPIKE_V1_10_0_CPU;
333
+ mc->possible_cpu_arch_ids = riscv_numa_possible_cpu_arch_ids;
334
+ mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
335
+ mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
336
+ mc->numa_mem_supported = true;
337
+}
105
+}
338
+
106
+
339
+static const TypeInfo spike_machine_typeinfo = {
107
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
340
+ .name = MACHINE_TYPE_NAME("spike"),
108
{
341
+ .parent = TYPE_MACHINE,
109
return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
342
+ .class_init = spike_machine_class_init,
110
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
343
+ .instance_init = spike_machine_instance_init,
111
index XXXXXXX..XXXXXXX 100644
344
+ .instance_size = sizeof(SpikeState),
112
--- a/target/riscv/translate.c
113
+++ b/target/riscv/translate.c
114
@@ -XXX,XX +XXX,XX @@
115
#include "exec/helper-info.c.inc"
116
#undef HELPER_H
117
118
+#include "tcg/tcg-cpu.h"
119
+
120
/* global register indices */
121
static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
122
static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
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;
133
}
134
135
+const RISCVDecoder decoder_table[] = {
136
+ { always_true_p, decode_insn32 },
137
+ { has_xthead_p, decode_xthead},
138
+ { has_XVentanaCondOps_p, decode_XVentanaCodeOps},
345
+};
139
+};
346
+
140
+
347
+static void spike_machine_init_register_types(void)
141
+const size_t decoder_table_size = ARRAY_SIZE(decoder_table);
348
+{
142
+
349
+ type_register_static(&spike_machine_typeinfo);
143
static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
144
{
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;
350
}
179
}
351
180
352
-DEFINE_MACHINE("spike", spike_machine_init)
181
static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
353
+type_init(spike_machine_init_register_types)
354
--
182
--
355
2.28.0
183
2.45.1
356
357
diff view generated by jsdifflib
1
From: Anup Patel <anup.patel@wdc.com>
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
2
2
3
We add common helper routines which can be shared by RISC-V
3
The th.sxstatus CSR can be used to identify available custom extension
4
multi-socket NUMA machines.
4
on T-Head CPUs. The CSR is documented here:
5
https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadsxstatus.adoc
5
6
6
We have two types of helpers:
7
An important property of this patch is, that the th.sxstatus MAEE field
7
1. riscv_socket_xyz() - These helper assist managing multiple
8
is not set (indicating that XTheadMae is not available).
8
sockets irrespective whether QEMU NUMA is enabled/disabled
9
XTheadMae is a memory attribute extension (similar to Svpbmt) which is
9
2. riscv_numa_xyz() - These helpers assist in providing
10
implemented in many T-Head CPUs (C906, C910, etc.) and utilizes bits
10
necessary QEMU machine callbacks for QEMU NUMA emulation
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).
11
16
12
Signed-off-by: Anup Patel <anup.patel@wdc.com>
17
Further context can be found on the list:
13
Reviewed-by: Atish Patra <atish.patra@wdc.com>
18
https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg00775.html
14
Message-Id: <20200616032229.766089-4-anup.patel@wdc.com>
19
20
Reviewed-by: LIU Zhiwei <zhiwe_liu@linux.alibaba.com>
21
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
23
Message-ID: <20240429073656.2486732-1-christoph.muellner@vrull.eu>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
25
---
17
include/hw/riscv/numa.h | 113 +++++++++++++++++++
26
MAINTAINERS | 1 +
18
hw/riscv/numa.c | 242 ++++++++++++++++++++++++++++++++++++++++
27
target/riscv/cpu.h | 3 ++
19
hw/riscv/meson.build | 1 +
28
target/riscv/cpu.c | 1 +
20
3 files changed, 356 insertions(+)
29
target/riscv/th_csr.c | 79 ++++++++++++++++++++++++++++++++++++++++
21
create mode 100644 include/hw/riscv/numa.h
30
target/riscv/meson.build | 1 +
22
create mode 100644 hw/riscv/numa.c
31
5 files changed, 85 insertions(+)
32
create mode 100644 target/riscv/th_csr.c
23
33
24
diff --git a/include/hw/riscv/numa.h b/include/hw/riscv/numa.h
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
46
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/cpu.h
49
+++ b/target/riscv/cpu.h
50
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_new_csr_seed(target_ulong new_value,
51
uint8_t satp_mode_max_from_map(uint32_t map);
52
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
53
54
+/* Implemented in th_csr.c */
55
+void th_register_custom_csrs(RISCVCPU *cpu);
56
+
57
#endif /* RISCV_CPU_H */
58
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/riscv/cpu.c
61
+++ b/target/riscv/cpu.c
62
@@ -XXX,XX +XXX,XX @@ static void rv64_thead_c906_cpu_init(Object *obj)
63
cpu->cfg.mvendorid = THEAD_VENDOR_ID;
64
#ifndef CONFIG_USER_ONLY
65
set_satp_mode_max_supported(cpu, VM_1_10_SV39);
66
+ th_register_custom_csrs(cpu);
67
#endif
68
69
/* inherited from parent obj via riscv_cpu_init() */
70
diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
25
new file mode 100644
71
new file mode 100644
26
index XXXXXXX..XXXXXXX
72
index XXXXXXX..XXXXXXX
27
--- /dev/null
73
--- /dev/null
28
+++ b/include/hw/riscv/numa.h
74
+++ b/target/riscv/th_csr.c
29
@@ -XXX,XX +XXX,XX @@
75
@@ -XXX,XX +XXX,XX @@
30
+/*
76
+/*
31
+ * QEMU RISC-V NUMA Helper
77
+ * T-Head-specific CSRs.
32
+ *
78
+ *
33
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
79
+ * Copyright (c) 2024 VRULL GmbH
34
+ *
35
+ * This program is free software; you can redistribute it and/or modify it
36
+ * under the terms and conditions of the GNU General Public License,
37
+ * version 2 or later, as published by the Free Software Foundation.
38
+ *
39
+ * This program is distributed in the hope it will be useful, but WITHOUT
40
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
41
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
42
+ * more details.
43
+ *
44
+ * You should have received a copy of the GNU General Public License along with
45
+ * this program. If not, see <http://www.gnu.org/licenses/>.
46
+ */
47
+
48
+#ifndef RISCV_NUMA_H
49
+#define RISCV_NUMA_H
50
+
51
+#include "hw/sysbus.h"
52
+#include "sysemu/numa.h"
53
+
54
+/**
55
+ * riscv_socket_count:
56
+ * @ms: pointer to machine state
57
+ *
58
+ * Returns: number of sockets for a numa system and 1 for a non-numa system
59
+ */
60
+int riscv_socket_count(const MachineState *ms);
61
+
62
+/**
63
+ * riscv_socket_first_hartid:
64
+ * @ms: pointer to machine state
65
+ * @socket_id: socket index
66
+ *
67
+ * Returns: first hartid for a valid socket and -1 for an invalid socket
68
+ */
69
+int riscv_socket_first_hartid(const MachineState *ms, int socket_id);
70
+
71
+/**
72
+ * riscv_socket_last_hartid:
73
+ * @ms: pointer to machine state
74
+ * @socket_id: socket index
75
+ *
76
+ * Returns: last hartid for a valid socket and -1 for an invalid socket
77
+ */
78
+int riscv_socket_last_hartid(const MachineState *ms, int socket_id);
79
+
80
+/**
81
+ * riscv_socket_hart_count:
82
+ * @ms: pointer to machine state
83
+ * @socket_id: socket index
84
+ *
85
+ * Returns: number of harts for a valid socket and -1 for an invalid socket
86
+ */
87
+int riscv_socket_hart_count(const MachineState *ms, int socket_id);
88
+
89
+/**
90
+ * riscv_socket_mem_offset:
91
+ * @ms: pointer to machine state
92
+ * @socket_id: socket index
93
+ *
94
+ * Returns: offset of ram belonging to given socket
95
+ */
96
+uint64_t riscv_socket_mem_offset(const MachineState *ms, int socket_id);
97
+
98
+/**
99
+ * riscv_socket_mem_size:
100
+ * @ms: pointer to machine state
101
+ * @socket_id: socket index
102
+ *
103
+ * Returns: size of ram belonging to given socket
104
+ */
105
+uint64_t riscv_socket_mem_size(const MachineState *ms, int socket_id);
106
+
107
+/**
108
+ * riscv_socket_check_hartids:
109
+ * @ms: pointer to machine state
110
+ * @socket_id: socket index
111
+ *
112
+ * Returns: true if hardids belonging to given socket are contiguous else false
113
+ */
114
+bool riscv_socket_check_hartids(const MachineState *ms, int socket_id);
115
+
116
+/**
117
+ * riscv_socket_fdt_write_id:
118
+ * @ms: pointer to machine state
119
+ * @socket_id: socket index
120
+ *
121
+ * Write NUMA node-id FDT property for given FDT node
122
+ */
123
+void riscv_socket_fdt_write_id(const MachineState *ms, void *fdt,
124
+ const char *node_name, int socket_id);
125
+
126
+/**
127
+ * riscv_socket_fdt_write_distance_matrix:
128
+ * @ms: pointer to machine state
129
+ * @socket_id: socket index
130
+ *
131
+ * Write NUMA distance matrix in FDT for given machine
132
+ */
133
+void riscv_socket_fdt_write_distance_matrix(const MachineState *ms, void *fdt);
134
+
135
+CpuInstanceProperties
136
+riscv_numa_cpu_index_to_props(MachineState *ms, unsigned cpu_index);
137
+
138
+int64_t riscv_numa_get_default_cpu_node_id(const MachineState *ms, int idx);
139
+
140
+const CPUArchIdList *riscv_numa_possible_cpu_arch_ids(MachineState *ms);
141
+
142
+#endif /* RISCV_NUMA_H */
143
diff --git a/hw/riscv/numa.c b/hw/riscv/numa.c
144
new file mode 100644
145
index XXXXXXX..XXXXXXX
146
--- /dev/null
147
+++ b/hw/riscv/numa.c
148
@@ -XXX,XX +XXX,XX @@
149
+/*
150
+ * QEMU RISC-V NUMA Helper
151
+ *
152
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
153
+ *
80
+ *
154
+ * 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
155
+ * under the terms and conditions of the GNU General Public License,
82
+ * under the terms and conditions of the GNU General Public License,
156
+ * version 2 or later, as published by the Free Software Foundation.
83
+ * version 2 or later, as published by the Free Software Foundation.
157
+ *
84
+ *
...
...
163
+ * 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
164
+ * this program. If not, see <http://www.gnu.org/licenses/>.
91
+ * this program. If not, see <http://www.gnu.org/licenses/>.
165
+ */
92
+ */
166
+
93
+
167
+#include "qemu/osdep.h"
94
+#include "qemu/osdep.h"
168
+#include "qemu/units.h"
95
+#include "cpu.h"
169
+#include "qemu/log.h"
96
+#include "cpu_vendorid.h"
170
+#include "qemu/error-report.h"
171
+#include "qapi/error.h"
172
+#include "hw/boards.h"
173
+#include "hw/qdev-properties.h"
174
+#include "hw/riscv/numa.h"
175
+#include "sysemu/device_tree.h"
176
+
97
+
177
+static bool numa_enabled(const MachineState *ms)
98
+#define CSR_TH_SXSTATUS 0x5c0
99
+
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)
178
+{
112
+{
179
+ return (ms->numa_state && ms->numa_state->num_nodes) ? true : false;
113
+ if (riscv_has_ext(env, RVS)) {
114
+ return RISCV_EXCP_NONE;
115
+ }
116
+
117
+ return RISCV_EXCP_ILLEGAL_INST;
180
+}
118
+}
181
+
119
+
182
+int riscv_socket_count(const MachineState *ms)
120
+static int test_thead_mvendorid(RISCVCPU *cpu)
183
+{
121
+{
184
+ return (numa_enabled(ms)) ? ms->numa_state->num_nodes : 1;
122
+ if (cpu->cfg.mvendorid != THEAD_VENDOR_ID) {
185
+}
186
+
187
+int riscv_socket_first_hartid(const MachineState *ms, int socket_id)
188
+{
189
+ int i, first_hartid = ms->smp.cpus;
190
+
191
+ if (!numa_enabled(ms)) {
192
+ return (!socket_id) ? 0 : -1;
193
+ }
194
+
195
+ for (i = 0; i < ms->smp.cpus; i++) {
196
+ if (ms->possible_cpus->cpus[i].props.node_id != socket_id) {
197
+ continue;
198
+ }
199
+ if (i < first_hartid) {
200
+ first_hartid = i;
201
+ }
202
+ }
203
+
204
+ return (first_hartid < ms->smp.cpus) ? first_hartid : -1;
205
+}
206
+
207
+int riscv_socket_last_hartid(const MachineState *ms, int socket_id)
208
+{
209
+ int i, last_hartid = -1;
210
+
211
+ if (!numa_enabled(ms)) {
212
+ return (!socket_id) ? ms->smp.cpus - 1 : -1;
213
+ }
214
+
215
+ for (i = 0; i < ms->smp.cpus; i++) {
216
+ if (ms->possible_cpus->cpus[i].props.node_id != socket_id) {
217
+ continue;
218
+ }
219
+ if (i > last_hartid) {
220
+ last_hartid = i;
221
+ }
222
+ }
223
+
224
+ return (last_hartid < ms->smp.cpus) ? last_hartid : -1;
225
+}
226
+
227
+int riscv_socket_hart_count(const MachineState *ms, int socket_id)
228
+{
229
+ int first_hartid, last_hartid;
230
+
231
+ if (!numa_enabled(ms)) {
232
+ return (!socket_id) ? ms->smp.cpus : -1;
233
+ }
234
+
235
+ first_hartid = riscv_socket_first_hartid(ms, socket_id);
236
+ if (first_hartid < 0) {
237
+ return -1;
123
+ return -1;
238
+ }
124
+ }
239
+
125
+
240
+ last_hartid = riscv_socket_last_hartid(ms, socket_id);
126
+ return 0;
241
+ if (last_hartid < 0) {
242
+ return -1;
243
+ }
244
+
245
+ if (first_hartid > last_hartid) {
246
+ return -1;
247
+ }
248
+
249
+ return last_hartid - first_hartid + 1;
250
+}
127
+}
251
+
128
+
252
+bool riscv_socket_check_hartids(const MachineState *ms, int socket_id)
129
+static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
130
+ target_ulong *val)
253
+{
131
+{
254
+ int i, first_hartid, last_hartid;
132
+ /* We don't set MAEE here, because QEMU does not implement MAEE. */
133
+ *val = TH_SXSTATUS_UCME | TH_SXSTATUS_THEADISAEE;
134
+ return RISCV_EXCP_NONE;
135
+}
255
+
136
+
256
+ if (!numa_enabled(ms)) {
137
+static riscv_csr th_csr_list[] = {
257
+ return (!socket_id) ? true : false;
138
+ {
139
+ .csrno = CSR_TH_SXSTATUS,
140
+ .insertion_test = test_thead_mvendorid,
141
+ .csr_ops = { "th.sxstatus", smode, read_th_sxstatus }
258
+ }
142
+ }
143
+};
259
+
144
+
260
+ first_hartid = riscv_socket_first_hartid(ms, socket_id);
145
+void th_register_custom_csrs(RISCVCPU *cpu)
261
+ if (first_hartid < 0) {
146
+{
262
+ return false;
147
+ for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
263
+ }
148
+ int csrno = th_csr_list[i].csrno;
264
+
149
+ riscv_csr_operations *csr_ops = &th_csr_list[i].csr_ops;
265
+ last_hartid = riscv_socket_last_hartid(ms, socket_id);
150
+ if (!th_csr_list[i].insertion_test(cpu)) {
266
+ if (last_hartid < 0) {
151
+ riscv_set_csr_ops(csrno, csr_ops);
267
+ return false;
268
+ }
269
+
270
+ for (i = first_hartid; i <= last_hartid; i++) {
271
+ if (ms->possible_cpus->cpus[i].props.node_id != socket_id) {
272
+ return false;
273
+ }
152
+ }
274
+ }
153
+ }
275
+
276
+ return true;
277
+}
154
+}
278
+
155
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
279
+uint64_t riscv_socket_mem_offset(const MachineState *ms, int socket_id)
280
+{
281
+ int i;
282
+ uint64_t mem_offset = 0;
283
+
284
+ if (!numa_enabled(ms)) {
285
+ return 0;
286
+ }
287
+
288
+ for (i = 0; i < ms->numa_state->num_nodes; i++) {
289
+ if (i == socket_id) {
290
+ break;
291
+ }
292
+ mem_offset += ms->numa_state->nodes[i].node_mem;
293
+ }
294
+
295
+ return (i == socket_id) ? mem_offset : 0;
296
+}
297
+
298
+uint64_t riscv_socket_mem_size(const MachineState *ms, int socket_id)
299
+{
300
+ if (!numa_enabled(ms)) {
301
+ return (!socket_id) ? ms->ram_size : 0;
302
+ }
303
+
304
+ return (socket_id < ms->numa_state->num_nodes) ?
305
+ ms->numa_state->nodes[socket_id].node_mem : 0;
306
+}
307
+
308
+void riscv_socket_fdt_write_id(const MachineState *ms, void *fdt,
309
+ const char *node_name, int socket_id)
310
+{
311
+ if (numa_enabled(ms)) {
312
+ qemu_fdt_setprop_cell(fdt, node_name, "numa-node-id", socket_id);
313
+ }
314
+}
315
+
316
+void riscv_socket_fdt_write_distance_matrix(const MachineState *ms, void *fdt)
317
+{
318
+ int i, j, idx;
319
+ uint32_t *dist_matrix, dist_matrix_size;
320
+
321
+ if (numa_enabled(ms) && ms->numa_state->have_numa_distance) {
322
+ dist_matrix_size = riscv_socket_count(ms) * riscv_socket_count(ms);
323
+ dist_matrix_size *= (3 * sizeof(uint32_t));
324
+ dist_matrix = g_malloc0(dist_matrix_size);
325
+
326
+ for (i = 0; i < riscv_socket_count(ms); i++) {
327
+ for (j = 0; j < riscv_socket_count(ms); j++) {
328
+ idx = (i * riscv_socket_count(ms) + j) * 3;
329
+ dist_matrix[idx + 0] = cpu_to_be32(i);
330
+ dist_matrix[idx + 1] = cpu_to_be32(j);
331
+ dist_matrix[idx + 2] =
332
+ cpu_to_be32(ms->numa_state->nodes[i].distance[j]);
333
+ }
334
+ }
335
+
336
+ qemu_fdt_add_subnode(fdt, "/distance-map");
337
+ qemu_fdt_setprop_string(fdt, "/distance-map", "compatible",
338
+ "numa-distance-map-v1");
339
+ qemu_fdt_setprop(fdt, "/distance-map", "distance-matrix",
340
+ dist_matrix, dist_matrix_size);
341
+ g_free(dist_matrix);
342
+ }
343
+}
344
+
345
+CpuInstanceProperties
346
+riscv_numa_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
347
+{
348
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
349
+ const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
350
+
351
+ assert(cpu_index < possible_cpus->len);
352
+ return possible_cpus->cpus[cpu_index].props;
353
+}
354
+
355
+int64_t riscv_numa_get_default_cpu_node_id(const MachineState *ms, int idx)
356
+{
357
+ int64_t nidx = 0;
358
+
359
+ if (ms->numa_state->num_nodes) {
360
+ nidx = idx / (ms->smp.cpus / ms->numa_state->num_nodes);
361
+ if (ms->numa_state->num_nodes <= nidx) {
362
+ nidx = ms->numa_state->num_nodes - 1;
363
+ }
364
+ }
365
+
366
+ return nidx;
367
+}
368
+
369
+const CPUArchIdList *riscv_numa_possible_cpu_arch_ids(MachineState *ms)
370
+{
371
+ int n;
372
+ unsigned int max_cpus = ms->smp.max_cpus;
373
+
374
+ if (ms->possible_cpus) {
375
+ assert(ms->possible_cpus->len == max_cpus);
376
+ return ms->possible_cpus;
377
+ }
378
+
379
+ ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
380
+ sizeof(CPUArchId) * max_cpus);
381
+ ms->possible_cpus->len = max_cpus;
382
+ for (n = 0; n < ms->possible_cpus->len; n++) {
383
+ ms->possible_cpus->cpus[n].type = ms->cpu_type;
384
+ ms->possible_cpus->cpus[n].arch_id = n;
385
+ ms->possible_cpus->cpus[n].props.has_core_id = true;
386
+ ms->possible_cpus->cpus[n].props.core_id = n;
387
+ }
388
+
389
+ return ms->possible_cpus;
390
+}
391
diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
392
index XXXXXXX..XXXXXXX 100644
156
index XXXXXXX..XXXXXXX 100644
393
--- a/hw/riscv/meson.build
157
--- a/target/riscv/meson.build
394
+++ b/hw/riscv/meson.build
158
+++ b/target/riscv/meson.build
395
@@ -XXX,XX +XXX,XX @@
159
@@ -XXX,XX +XXX,XX @@ riscv_system_ss.add(files(
396
riscv_ss = ss.source_set()
160
'monitor.c',
397
riscv_ss.add(files('boot.c'))
161
'machine.c',
398
+riscv_ss.add(files('numa.c'))
162
'pmu.c',
399
riscv_ss.add(when: 'CONFIG_HART', if_true: files('riscv_hart.c'))
163
+ 'th_csr.c',
400
riscv_ss.add(when: 'CONFIG_OPENTITAN', if_true: files('opentitan.c'))
164
'time_helper.c',
401
riscv_ss.add(when: 'CONFIG_RISCV_VIRT', if_true: files('virt.c'))
165
'riscv-qmp-cmds.c',
166
))
402
--
167
--
403
2.28.0
168
2.45.1
404
169
405
170
diff view generated by jsdifflib
1
From: Anup Patel <anup.patel@wdc.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
We extend RISC-V virt machine to allow creating a multi-socket
3
According v spec 18.4, only the vfwcvt.f.f.v and vfncvt.f.f.w
4
machine. Each RISC-V virt machine socket is a NUMA node having
4
instructions will be affected by Zvfhmin extension.
5
a set of HARTs, a memory instance, a CLINT instance, and a PLIC
5
And the vfwcvt.f.f.v and vfncvt.f.f.w instructions only support the
6
instance. Other devices are shared between all sockets. We also
6
conversions of
7
update the generated device tree accordingly.
8
7
9
By default, NUMA multi-socket support is disabled for RISC-V virt
8
* From 1*SEW(16/32) to 2*SEW(32/64)
10
machine. To enable it, users can use "-numa" command-line options
9
* From 2*SEW(32/64) to 1*SEW(16/32)
11
of QEMU.
12
10
13
Example1: For two NUMA nodes with 2 CPUs each, append following
11
Signed-off-by: Max Chou <max.chou@sifive.com>
14
to command-line options: "-smp 4 -numa node -numa node"
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
13
Cc: qemu-stable <qemu-stable@nongnu.org>
16
Example2: For two NUMA nodes with 1 and 3 CPUs, append following
14
Message-ID: <20240322092600.1198921-2-max.chou@sifive.com>
17
to command-line options:
18
"-smp 4 -numa node -numa node -numa cpu,node-id=0,core-id=0 \
19
-numa cpu,node-id=1,core-id=1 -numa cpu,node-id=1,core-id=2 \
20
-numa cpu,node-id=1,core-id=3"
21
22
The maximum number of sockets in a RISC-V virt machine is 8
23
but this limit can be changed in future.
24
25
Signed-off-by: Anup Patel <anup.patel@wdc.com>
26
Reviewed-by: Atish Patra <atish.patra@wdc.com>
27
Message-Id: <20200616032229.766089-6-anup.patel@wdc.com>
28
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
29
---
16
---
30
include/hw/riscv/virt.h | 9 +-
17
target/riscv/insn_trans/trans_rvv.c.inc | 20 ++++++++++++++++++--
31
hw/riscv/virt.c | 526 +++++++++++++++++++++++-----------------
18
1 file changed, 18 insertions(+), 2 deletions(-)
32
2 files changed, 306 insertions(+), 229 deletions(-)
33
19
34
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
35
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/riscv/virt.h
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
37
+++ b/include/hw/riscv/virt.h
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
38
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ static bool require_rvf(DisasContext *s)
39
#include "hw/sysbus.h"
40
#include "hw/block/flash.h"
41
42
+#define VIRT_CPUS_MAX 8
43
+#define VIRT_SOCKETS_MAX 8
44
+
45
#define TYPE_RISCV_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
46
#define RISCV_VIRT_MACHINE(obj) \
47
OBJECT_CHECK(RISCVVirtState, (obj), TYPE_RISCV_VIRT_MACHINE)
48
@@ -XXX,XX +XXX,XX @@ typedef struct {
49
MachineState parent;
50
51
/*< public >*/
52
- RISCVHartArrayState soc;
53
- DeviceState *plic;
54
+ RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
55
+ DeviceState *plic[VIRT_SOCKETS_MAX];
56
PFlashCFI01 *flash[2];
57
58
void *fdt;
59
@@ -XXX,XX +XXX,XX @@ enum {
60
#define VIRT_PLIC_ENABLE_STRIDE 0x80
61
#define VIRT_PLIC_CONTEXT_BASE 0x200000
62
#define VIRT_PLIC_CONTEXT_STRIDE 0x1000
63
+#define VIRT_PLIC_SIZE(__num_context) \
64
+ (VIRT_PLIC_CONTEXT_BASE + (__num_context) * VIRT_PLIC_CONTEXT_STRIDE)
65
66
#define FDT_PCI_ADDR_CELLS 3
67
#define FDT_PCI_INT_CELLS 1
68
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/riscv/virt.c
71
+++ b/hw/riscv/virt.c
72
@@ -XXX,XX +XXX,XX @@
73
#include "hw/riscv/sifive_test.h"
74
#include "hw/riscv/virt.h"
75
#include "hw/riscv/boot.h"
76
+#include "hw/riscv/numa.h"
77
#include "chardev/char.h"
78
#include "sysemu/arch_init.h"
79
#include "sysemu/device_tree.h"
80
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
81
[VIRT_RTC] = { 0x101000, 0x1000 },
82
[VIRT_CLINT] = { 0x2000000, 0x10000 },
83
[VIRT_PCIE_PIO] = { 0x3000000, 0x10000 },
84
- [VIRT_PLIC] = { 0xc000000, 0x4000000 },
85
+ [VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) },
86
[VIRT_UART0] = { 0x10000000, 0x100 },
87
[VIRT_VIRTIO] = { 0x10001000, 0x1000 },
88
[VIRT_FLASH] = { 0x20000000, 0x4000000 },
89
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
90
uint64_t mem_size, const char *cmdline)
91
{
92
void *fdt;
93
- int cpu, i;
94
- uint32_t *cells;
95
- char *nodename;
96
- uint32_t plic_phandle, test_phandle, phandle = 1;
97
+ int i, cpu, socket;
98
+ MachineState *mc = MACHINE(s);
99
+ uint64_t addr, size;
100
+ uint32_t *clint_cells, *plic_cells;
101
+ unsigned long clint_addr, plic_addr;
102
+ uint32_t plic_phandle[MAX_NODES];
103
+ uint32_t cpu_phandle, intc_phandle, test_phandle;
104
+ uint32_t phandle = 1, plic_mmio_phandle = 1;
105
+ uint32_t plic_pcie_phandle = 1, plic_virtio_phandle = 1;
106
+ char *mem_name, *cpu_name, *core_name, *intc_name;
107
+ char *name, *clint_name, *plic_name, *clust_name;
108
hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2;
109
hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
110
111
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
112
qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2);
113
qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2);
114
115
- nodename = g_strdup_printf("/memory@%lx",
116
- (long)memmap[VIRT_DRAM].base);
117
- qemu_fdt_add_subnode(fdt, nodename);
118
- qemu_fdt_setprop_cells(fdt, nodename, "reg",
119
- memmap[VIRT_DRAM].base >> 32, memmap[VIRT_DRAM].base,
120
- mem_size >> 32, mem_size);
121
- qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
122
- g_free(nodename);
123
-
124
qemu_fdt_add_subnode(fdt, "/cpus");
125
qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency",
126
SIFIVE_CLINT_TIMEBASE_FREQ);
127
qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
128
qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
129
+ qemu_fdt_add_subnode(fdt, "/cpus/cpu-map");
130
+
131
+ for (socket = (riscv_socket_count(mc) - 1); socket >= 0; socket--) {
132
+ clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket);
133
+ qemu_fdt_add_subnode(fdt, clust_name);
134
+
135
+ plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4);
136
+ clint_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4);
137
+
138
+ for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) {
139
+ cpu_phandle = phandle++;
140
141
- for (cpu = s->soc.num_harts - 1; cpu >= 0; cpu--) {
142
- int cpu_phandle = phandle++;
143
- int intc_phandle;
144
- nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
145
- char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
146
- char *isa = riscv_isa_string(&s->soc.harts[cpu]);
147
- qemu_fdt_add_subnode(fdt, nodename);
148
+ cpu_name = g_strdup_printf("/cpus/cpu@%d",
149
+ s->soc[socket].hartid_base + cpu);
150
+ qemu_fdt_add_subnode(fdt, cpu_name);
151
#if defined(TARGET_RISCV32)
152
- qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv32");
153
+ qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv32");
154
#else
155
- qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
156
+ qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv48");
157
#endif
158
- qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa);
159
- qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv");
160
- qemu_fdt_setprop_string(fdt, nodename, "status", "okay");
161
- qemu_fdt_setprop_cell(fdt, nodename, "reg", cpu);
162
- qemu_fdt_setprop_string(fdt, nodename, "device_type", "cpu");
163
- qemu_fdt_setprop_cell(fdt, nodename, "phandle", cpu_phandle);
164
- intc_phandle = phandle++;
165
- qemu_fdt_add_subnode(fdt, intc);
166
- qemu_fdt_setprop_cell(fdt, intc, "phandle", intc_phandle);
167
- qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
168
- qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
169
- qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
170
- g_free(isa);
171
- g_free(intc);
172
- g_free(nodename);
173
- }
174
+ name = riscv_isa_string(&s->soc[socket].harts[cpu]);
175
+ qemu_fdt_setprop_string(fdt, cpu_name, "riscv,isa", name);
176
+ g_free(name);
177
+ qemu_fdt_setprop_string(fdt, cpu_name, "compatible", "riscv");
178
+ qemu_fdt_setprop_string(fdt, cpu_name, "status", "okay");
179
+ qemu_fdt_setprop_cell(fdt, cpu_name, "reg",
180
+ s->soc[socket].hartid_base + cpu);
181
+ qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu");
182
+ riscv_socket_fdt_write_id(mc, fdt, cpu_name, socket);
183
+ qemu_fdt_setprop_cell(fdt, cpu_name, "phandle", cpu_phandle);
184
+
185
+ intc_name = g_strdup_printf("%s/interrupt-controller", cpu_name);
186
+ qemu_fdt_add_subnode(fdt, intc_name);
187
+ intc_phandle = phandle++;
188
+ qemu_fdt_setprop_cell(fdt, intc_name, "phandle", intc_phandle);
189
+ qemu_fdt_setprop_string(fdt, intc_name, "compatible",
190
+ "riscv,cpu-intc");
191
+ qemu_fdt_setprop(fdt, intc_name, "interrupt-controller", NULL, 0);
192
+ qemu_fdt_setprop_cell(fdt, intc_name, "#interrupt-cells", 1);
193
+
194
+ clint_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle);
195
+ clint_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
196
+ clint_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandle);
197
+ clint_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
198
+
199
+ plic_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle);
200
+ plic_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_EXT);
201
+ plic_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandle);
202
+ plic_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_S_EXT);
203
+
204
+ core_name = g_strdup_printf("%s/core%d", clust_name, cpu);
205
+ qemu_fdt_add_subnode(fdt, core_name);
206
+ qemu_fdt_setprop_cell(fdt, core_name, "cpu", cpu_phandle);
207
+
208
+ g_free(core_name);
209
+ g_free(intc_name);
210
+ g_free(cpu_name);
211
+ }
212
213
- /* Add cpu-topology node */
214
- qemu_fdt_add_subnode(fdt, "/cpus/cpu-map");
215
- qemu_fdt_add_subnode(fdt, "/cpus/cpu-map/cluster0");
216
- for (cpu = s->soc.num_harts - 1; cpu >= 0; cpu--) {
217
- char *core_nodename = g_strdup_printf("/cpus/cpu-map/cluster0/core%d",
218
- cpu);
219
- char *cpu_nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
220
- uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, cpu_nodename);
221
- qemu_fdt_add_subnode(fdt, core_nodename);
222
- qemu_fdt_setprop_cell(fdt, core_nodename, "cpu", intc_phandle);
223
- g_free(core_nodename);
224
- g_free(cpu_nodename);
225
+ addr = memmap[VIRT_DRAM].base + riscv_socket_mem_offset(mc, socket);
226
+ size = riscv_socket_mem_size(mc, socket);
227
+ mem_name = g_strdup_printf("/memory@%lx", (long)addr);
228
+ qemu_fdt_add_subnode(fdt, mem_name);
229
+ qemu_fdt_setprop_cells(fdt, mem_name, "reg",
230
+ addr >> 32, addr, size >> 32, size);
231
+ qemu_fdt_setprop_string(fdt, mem_name, "device_type", "memory");
232
+ riscv_socket_fdt_write_id(mc, fdt, mem_name, socket);
233
+ g_free(mem_name);
234
+
235
+ clint_addr = memmap[VIRT_CLINT].base +
236
+ (memmap[VIRT_CLINT].size * socket);
237
+ clint_name = g_strdup_printf("/soc/clint@%lx", clint_addr);
238
+ qemu_fdt_add_subnode(fdt, clint_name);
239
+ qemu_fdt_setprop_string(fdt, clint_name, "compatible", "riscv,clint0");
240
+ qemu_fdt_setprop_cells(fdt, clint_name, "reg",
241
+ 0x0, clint_addr, 0x0, memmap[VIRT_CLINT].size);
242
+ qemu_fdt_setprop(fdt, clint_name, "interrupts-extended",
243
+ clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
244
+ riscv_socket_fdt_write_id(mc, fdt, clint_name, socket);
245
+ g_free(clint_name);
246
+
247
+ plic_phandle[socket] = phandle++;
248
+ plic_addr = memmap[VIRT_PLIC].base + (memmap[VIRT_PLIC].size * socket);
249
+ plic_name = g_strdup_printf("/soc/plic@%lx", plic_addr);
250
+ qemu_fdt_add_subnode(fdt, plic_name);
251
+ qemu_fdt_setprop_cell(fdt, plic_name,
252
+ "#address-cells", FDT_PLIC_ADDR_CELLS);
253
+ qemu_fdt_setprop_cell(fdt, plic_name,
254
+ "#interrupt-cells", FDT_PLIC_INT_CELLS);
255
+ qemu_fdt_setprop_string(fdt, plic_name, "compatible", "riscv,plic0");
256
+ qemu_fdt_setprop(fdt, plic_name, "interrupt-controller", NULL, 0);
257
+ qemu_fdt_setprop(fdt, plic_name, "interrupts-extended",
258
+ plic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
259
+ qemu_fdt_setprop_cells(fdt, plic_name, "reg",
260
+ 0x0, plic_addr, 0x0, memmap[VIRT_PLIC].size);
261
+ qemu_fdt_setprop_cell(fdt, plic_name, "riscv,ndev", VIRTIO_NDEV);
262
+ riscv_socket_fdt_write_id(mc, fdt, plic_name, socket);
263
+ qemu_fdt_setprop_cell(fdt, plic_name, "phandle", plic_phandle[socket]);
264
+ g_free(plic_name);
265
+
266
+ g_free(clint_cells);
267
+ g_free(plic_cells);
268
+ g_free(clust_name);
269
}
25
}
270
271
- cells = g_new0(uint32_t, s->soc.num_harts * 4);
272
- for (cpu = 0; cpu < s->soc.num_harts; cpu++) {
273
- nodename =
274
- g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
275
- uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
276
- cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle);
277
- cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
278
- cells[cpu * 4 + 2] = cpu_to_be32(intc_phandle);
279
- cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
280
- g_free(nodename);
281
- }
282
- nodename = g_strdup_printf("/soc/clint@%lx",
283
- (long)memmap[VIRT_CLINT].base);
284
- qemu_fdt_add_subnode(fdt, nodename);
285
- qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv,clint0");
286
- qemu_fdt_setprop_cells(fdt, nodename, "reg",
287
- 0x0, memmap[VIRT_CLINT].base,
288
- 0x0, memmap[VIRT_CLINT].size);
289
- qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
290
- cells, s->soc.num_harts * sizeof(uint32_t) * 4);
291
- g_free(cells);
292
- g_free(nodename);
293
-
294
- plic_phandle = phandle++;
295
- cells = g_new0(uint32_t, s->soc.num_harts * 4);
296
- for (cpu = 0; cpu < s->soc.num_harts; cpu++) {
297
- nodename =
298
- g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
299
- uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
300
- cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle);
301
- cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_EXT);
302
- cells[cpu * 4 + 2] = cpu_to_be32(intc_phandle);
303
- cells[cpu * 4 + 3] = cpu_to_be32(IRQ_S_EXT);
304
- g_free(nodename);
305
+ for (socket = 0; socket < riscv_socket_count(mc); socket++) {
306
+ if (socket == 0) {
307
+ plic_mmio_phandle = plic_phandle[socket];
308
+ plic_virtio_phandle = plic_phandle[socket];
309
+ plic_pcie_phandle = plic_phandle[socket];
310
+ }
311
+ if (socket == 1) {
312
+ plic_virtio_phandle = plic_phandle[socket];
313
+ plic_pcie_phandle = plic_phandle[socket];
314
+ }
315
+ if (socket == 2) {
316
+ plic_pcie_phandle = plic_phandle[socket];
317
+ }
318
}
319
- nodename = g_strdup_printf("/soc/interrupt-controller@%lx",
320
- (long)memmap[VIRT_PLIC].base);
321
- qemu_fdt_add_subnode(fdt, nodename);
322
- qemu_fdt_setprop_cell(fdt, nodename, "#address-cells",
323
- FDT_PLIC_ADDR_CELLS);
324
- qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells",
325
- FDT_PLIC_INT_CELLS);
326
- qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv,plic0");
327
- qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
328
- qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
329
- cells, s->soc.num_harts * sizeof(uint32_t) * 4);
330
- qemu_fdt_setprop_cells(fdt, nodename, "reg",
331
- 0x0, memmap[VIRT_PLIC].base,
332
- 0x0, memmap[VIRT_PLIC].size);
333
- qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", VIRTIO_NDEV);
334
- qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
335
- plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
336
- g_free(cells);
337
- g_free(nodename);
338
+
339
+ riscv_socket_fdt_write_distance_matrix(mc, fdt);
340
341
for (i = 0; i < VIRTIO_COUNT; i++) {
342
- nodename = g_strdup_printf("/virtio_mmio@%lx",
343
+ name = g_strdup_printf("/soc/virtio_mmio@%lx",
344
(long)(memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size));
345
- qemu_fdt_add_subnode(fdt, nodename);
346
- qemu_fdt_setprop_string(fdt, nodename, "compatible", "virtio,mmio");
347
- qemu_fdt_setprop_cells(fdt, nodename, "reg",
348
+ qemu_fdt_add_subnode(fdt, name);
349
+ qemu_fdt_setprop_string(fdt, name, "compatible", "virtio,mmio");
350
+ qemu_fdt_setprop_cells(fdt, name, "reg",
351
0x0, memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size,
352
0x0, memmap[VIRT_VIRTIO].size);
353
- qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
354
- qemu_fdt_setprop_cell(fdt, nodename, "interrupts", VIRTIO_IRQ + i);
355
- g_free(nodename);
356
+ qemu_fdt_setprop_cell(fdt, name, "interrupt-parent",
357
+ plic_virtio_phandle);
358
+ qemu_fdt_setprop_cell(fdt, name, "interrupts", VIRTIO_IRQ + i);
359
+ g_free(name);
360
}
361
362
- nodename = g_strdup_printf("/soc/pci@%lx",
363
+ name = g_strdup_printf("/soc/pci@%lx",
364
(long) memmap[VIRT_PCIE_ECAM].base);
365
- qemu_fdt_add_subnode(fdt, nodename);
366
- qemu_fdt_setprop_cell(fdt, nodename, "#address-cells",
367
- FDT_PCI_ADDR_CELLS);
368
- qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells",
369
- FDT_PCI_INT_CELLS);
370
- qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0x2);
371
- qemu_fdt_setprop_string(fdt, nodename, "compatible",
372
- "pci-host-ecam-generic");
373
- qemu_fdt_setprop_string(fdt, nodename, "device_type", "pci");
374
- qemu_fdt_setprop_cell(fdt, nodename, "linux,pci-domain", 0);
375
- qemu_fdt_setprop_cells(fdt, nodename, "bus-range", 0,
376
- memmap[VIRT_PCIE_ECAM].size /
377
- PCIE_MMCFG_SIZE_MIN - 1);
378
- qemu_fdt_setprop(fdt, nodename, "dma-coherent", NULL, 0);
379
- qemu_fdt_setprop_cells(fdt, nodename, "reg", 0, memmap[VIRT_PCIE_ECAM].base,
380
- 0, memmap[VIRT_PCIE_ECAM].size);
381
- qemu_fdt_setprop_sized_cells(fdt, nodename, "ranges",
382
+ qemu_fdt_add_subnode(fdt, name);
383
+ qemu_fdt_setprop_cell(fdt, name, "#address-cells", FDT_PCI_ADDR_CELLS);
384
+ qemu_fdt_setprop_cell(fdt, name, "#interrupt-cells", FDT_PCI_INT_CELLS);
385
+ qemu_fdt_setprop_cell(fdt, name, "#size-cells", 0x2);
386
+ qemu_fdt_setprop_string(fdt, name, "compatible", "pci-host-ecam-generic");
387
+ qemu_fdt_setprop_string(fdt, name, "device_type", "pci");
388
+ qemu_fdt_setprop_cell(fdt, name, "linux,pci-domain", 0);
389
+ qemu_fdt_setprop_cells(fdt, name, "bus-range", 0,
390
+ memmap[VIRT_PCIE_ECAM].size / PCIE_MMCFG_SIZE_MIN - 1);
391
+ qemu_fdt_setprop(fdt, name, "dma-coherent", NULL, 0);
392
+ qemu_fdt_setprop_cells(fdt, name, "reg", 0,
393
+ memmap[VIRT_PCIE_ECAM].base, 0, memmap[VIRT_PCIE_ECAM].size);
394
+ qemu_fdt_setprop_sized_cells(fdt, name, "ranges",
395
1, FDT_PCI_RANGE_IOPORT, 2, 0,
396
2, memmap[VIRT_PCIE_PIO].base, 2, memmap[VIRT_PCIE_PIO].size,
397
1, FDT_PCI_RANGE_MMIO,
398
2, memmap[VIRT_PCIE_MMIO].base,
399
2, memmap[VIRT_PCIE_MMIO].base, 2, memmap[VIRT_PCIE_MMIO].size);
400
- create_pcie_irq_map(fdt, nodename, plic_phandle);
401
- g_free(nodename);
402
+ create_pcie_irq_map(fdt, name, plic_pcie_phandle);
403
+ g_free(name);
404
405
test_phandle = phandle++;
406
- nodename = g_strdup_printf("/test@%lx",
407
+ name = g_strdup_printf("/soc/test@%lx",
408
(long)memmap[VIRT_TEST].base);
409
- qemu_fdt_add_subnode(fdt, nodename);
410
+ qemu_fdt_add_subnode(fdt, name);
411
{
412
const char compat[] = "sifive,test1\0sifive,test0\0syscon";
413
- qemu_fdt_setprop(fdt, nodename, "compatible", compat, sizeof(compat));
414
+ qemu_fdt_setprop(fdt, name, "compatible", compat, sizeof(compat));
415
}
416
- qemu_fdt_setprop_cells(fdt, nodename, "reg",
417
+ qemu_fdt_setprop_cells(fdt, name, "reg",
418
0x0, memmap[VIRT_TEST].base,
419
0x0, memmap[VIRT_TEST].size);
420
- qemu_fdt_setprop_cell(fdt, nodename, "phandle", test_phandle);
421
- test_phandle = qemu_fdt_get_phandle(fdt, nodename);
422
- g_free(nodename);
423
-
424
- nodename = g_strdup_printf("/reboot");
425
- qemu_fdt_add_subnode(fdt, nodename);
426
- qemu_fdt_setprop_string(fdt, nodename, "compatible", "syscon-reboot");
427
- qemu_fdt_setprop_cell(fdt, nodename, "regmap", test_phandle);
428
- qemu_fdt_setprop_cell(fdt, nodename, "offset", 0x0);
429
- qemu_fdt_setprop_cell(fdt, nodename, "value", FINISHER_RESET);
430
- g_free(nodename);
431
-
432
- nodename = g_strdup_printf("/poweroff");
433
- qemu_fdt_add_subnode(fdt, nodename);
434
- qemu_fdt_setprop_string(fdt, nodename, "compatible", "syscon-poweroff");
435
- qemu_fdt_setprop_cell(fdt, nodename, "regmap", test_phandle);
436
- qemu_fdt_setprop_cell(fdt, nodename, "offset", 0x0);
437
- qemu_fdt_setprop_cell(fdt, nodename, "value", FINISHER_PASS);
438
- g_free(nodename);
439
-
440
- nodename = g_strdup_printf("/uart@%lx",
441
- (long)memmap[VIRT_UART0].base);
442
- qemu_fdt_add_subnode(fdt, nodename);
443
- qemu_fdt_setprop_string(fdt, nodename, "compatible", "ns16550a");
444
- qemu_fdt_setprop_cells(fdt, nodename, "reg",
445
+ qemu_fdt_setprop_cell(fdt, name, "phandle", test_phandle);
446
+ test_phandle = qemu_fdt_get_phandle(fdt, name);
447
+ g_free(name);
448
+
449
+ name = g_strdup_printf("/soc/reboot");
450
+ qemu_fdt_add_subnode(fdt, name);
451
+ qemu_fdt_setprop_string(fdt, name, "compatible", "syscon-reboot");
452
+ qemu_fdt_setprop_cell(fdt, name, "regmap", test_phandle);
453
+ qemu_fdt_setprop_cell(fdt, name, "offset", 0x0);
454
+ qemu_fdt_setprop_cell(fdt, name, "value", FINISHER_RESET);
455
+ g_free(name);
456
+
457
+ name = g_strdup_printf("/soc/poweroff");
458
+ qemu_fdt_add_subnode(fdt, name);
459
+ qemu_fdt_setprop_string(fdt, name, "compatible", "syscon-poweroff");
460
+ qemu_fdt_setprop_cell(fdt, name, "regmap", test_phandle);
461
+ qemu_fdt_setprop_cell(fdt, name, "offset", 0x0);
462
+ qemu_fdt_setprop_cell(fdt, name, "value", FINISHER_PASS);
463
+ g_free(name);
464
+
465
+ name = g_strdup_printf("/soc/uart@%lx", (long)memmap[VIRT_UART0].base);
466
+ qemu_fdt_add_subnode(fdt, name);
467
+ qemu_fdt_setprop_string(fdt, name, "compatible", "ns16550a");
468
+ qemu_fdt_setprop_cells(fdt, name, "reg",
469
0x0, memmap[VIRT_UART0].base,
470
0x0, memmap[VIRT_UART0].size);
471
- qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", 3686400);
472
- qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
473
- qemu_fdt_setprop_cell(fdt, nodename, "interrupts", UART0_IRQ);
474
+ qemu_fdt_setprop_cell(fdt, name, "clock-frequency", 3686400);
475
+ qemu_fdt_setprop_cell(fdt, name, "interrupt-parent", plic_mmio_phandle);
476
+ qemu_fdt_setprop_cell(fdt, name, "interrupts", UART0_IRQ);
477
478
qemu_fdt_add_subnode(fdt, "/chosen");
479
- qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
480
+ qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", name);
481
if (cmdline) {
482
qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
483
}
484
- g_free(nodename);
485
-
486
- nodename = g_strdup_printf("/rtc@%lx",
487
- (long)memmap[VIRT_RTC].base);
488
- qemu_fdt_add_subnode(fdt, nodename);
489
- qemu_fdt_setprop_string(fdt, nodename, "compatible",
490
- "google,goldfish-rtc");
491
- qemu_fdt_setprop_cells(fdt, nodename, "reg",
492
+ g_free(name);
493
+
494
+ name = g_strdup_printf("/soc/rtc@%lx", (long)memmap[VIRT_RTC].base);
495
+ qemu_fdt_add_subnode(fdt, name);
496
+ qemu_fdt_setprop_string(fdt, name, "compatible", "google,goldfish-rtc");
497
+ qemu_fdt_setprop_cells(fdt, name, "reg",
498
0x0, memmap[VIRT_RTC].base,
499
0x0, memmap[VIRT_RTC].size);
500
- qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
501
- qemu_fdt_setprop_cell(fdt, nodename, "interrupts", RTC_IRQ);
502
- g_free(nodename);
503
-
504
- nodename = g_strdup_printf("/flash@%" PRIx64, flashbase);
505
- qemu_fdt_add_subnode(s->fdt, nodename);
506
- qemu_fdt_setprop_string(s->fdt, nodename, "compatible", "cfi-flash");
507
- qemu_fdt_setprop_sized_cells(s->fdt, nodename, "reg",
508
+ qemu_fdt_setprop_cell(fdt, name, "interrupt-parent", plic_mmio_phandle);
509
+ qemu_fdt_setprop_cell(fdt, name, "interrupts", RTC_IRQ);
510
+ g_free(name);
511
+
512
+ name = g_strdup_printf("/soc/flash@%" PRIx64, flashbase);
513
+ qemu_fdt_add_subnode(s->fdt, name);
514
+ qemu_fdt_setprop_string(s->fdt, name, "compatible", "cfi-flash");
515
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
516
2, flashbase, 2, flashsize,
517
2, flashbase + flashsize, 2, flashsize);
518
- qemu_fdt_setprop_cell(s->fdt, nodename, "bank-width", 4);
519
- g_free(nodename);
520
+ qemu_fdt_setprop_cell(s->fdt, name, "bank-width", 4);
521
+ g_free(name);
522
}
26
}
523
27
524
-
28
+static bool require_rvfmin(DisasContext *s)
525
static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
29
+{
526
hwaddr ecam_base, hwaddr ecam_size,
30
+ if (s->mstatus_fs == EXT_STATUS_DISABLED) {
527
hwaddr mmio_base, hwaddr mmio_size,
31
+ return false;
528
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
529
MemoryRegion *system_memory = get_system_memory();
530
MemoryRegion *main_mem = g_new(MemoryRegion, 1);
531
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
532
- char *plic_hart_config;
533
+ char *plic_hart_config, *soc_name;
534
size_t plic_hart_config_len;
535
target_ulong start_addr = memmap[VIRT_DRAM].base;
536
uint32_t fdt_load_addr;
537
uint64_t kernel_entry;
538
- int i;
539
- unsigned int smp_cpus = machine->smp.cpus;
540
+ DeviceState *mmio_plic, *virtio_plic, *pcie_plic;
541
+ int i, j, base_hartid, hart_count;
542
543
- /* Initialize SOC */
544
- object_initialize_child(OBJECT(machine), "soc", &s->soc,
545
- TYPE_RISCV_HART_ARRAY);
546
- object_property_set_str(OBJECT(&s->soc), "cpu-type", machine->cpu_type,
547
- &error_abort);
548
- object_property_set_int(OBJECT(&s->soc), "num-harts", smp_cpus,
549
- &error_abort);
550
- sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_abort);
551
+ /* Check socket count limit */
552
+ if (VIRT_SOCKETS_MAX < riscv_socket_count(machine)) {
553
+ error_report("number of sockets/nodes should be less than %d",
554
+ VIRT_SOCKETS_MAX);
555
+ exit(1);
556
+ }
32
+ }
557
+
33
+
558
+ /* Initialize sockets */
34
+ switch (s->sew) {
559
+ mmio_plic = virtio_plic = pcie_plic = NULL;
35
+ case MO_16:
560
+ for (i = 0; i < riscv_socket_count(machine); i++) {
36
+ return s->cfg_ptr->ext_zvfhmin;
561
+ if (!riscv_socket_check_hartids(machine, i)) {
37
+ case MO_32:
562
+ error_report("discontinuous hartids in socket%d", i);
38
+ return s->cfg_ptr->ext_zve32f;
563
+ exit(1);
39
+ default:
564
+ }
40
+ return false;
41
+ }
42
+}
565
+
43
+
566
+ base_hartid = riscv_socket_first_hartid(machine, i);
44
static bool require_scale_rvf(DisasContext *s)
567
+ if (base_hartid < 0) {
45
{
568
+ error_report("can't find hartid base for socket%d", i);
46
if (s->mstatus_fs == EXT_STATUS_DISABLED) {
569
+ exit(1);
47
@@ -XXX,XX +XXX,XX @@ static bool require_scale_rvfmin(DisasContext *s)
570
+ }
571
+
572
+ hart_count = riscv_socket_hart_count(machine, i);
573
+ if (hart_count < 0) {
574
+ error_report("can't find hart count for socket%d", i);
575
+ exit(1);
576
+ }
577
+
578
+ soc_name = g_strdup_printf("soc%d", i);
579
+ object_initialize_child(OBJECT(machine), soc_name, &s->soc[i],
580
+ TYPE_RISCV_HART_ARRAY);
581
+ g_free(soc_name);
582
+ object_property_set_str(OBJECT(&s->soc[i]), "cpu-type",
583
+ machine->cpu_type, &error_abort);
584
+ object_property_set_int(OBJECT(&s->soc[i]), "hartid-base",
585
+ base_hartid, &error_abort);
586
+ object_property_set_int(OBJECT(&s->soc[i]), "num-harts",
587
+ hart_count, &error_abort);
588
+ sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_abort);
589
+
590
+ /* Per-socket CLINT */
591
+ sifive_clint_create(
592
+ memmap[VIRT_CLINT].base + i * memmap[VIRT_CLINT].size,
593
+ memmap[VIRT_CLINT].size, base_hartid, hart_count,
594
+ SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, true);
595
+
596
+ /* Per-socket PLIC hart topology configuration string */
597
+ plic_hart_config_len =
598
+ (strlen(VIRT_PLIC_HART_CONFIG) + 1) * hart_count;
599
+ plic_hart_config = g_malloc0(plic_hart_config_len);
600
+ for (j = 0; j < hart_count; j++) {
601
+ if (j != 0) {
602
+ strncat(plic_hart_config, ",", plic_hart_config_len);
603
+ }
604
+ strncat(plic_hart_config, VIRT_PLIC_HART_CONFIG,
605
+ plic_hart_config_len);
606
+ plic_hart_config_len -= (strlen(VIRT_PLIC_HART_CONFIG) + 1);
607
+ }
608
+
609
+ /* Per-socket PLIC */
610
+ s->plic[i] = sifive_plic_create(
611
+ memmap[VIRT_PLIC].base + i * memmap[VIRT_PLIC].size,
612
+ plic_hart_config, base_hartid,
613
+ VIRT_PLIC_NUM_SOURCES,
614
+ VIRT_PLIC_NUM_PRIORITIES,
615
+ VIRT_PLIC_PRIORITY_BASE,
616
+ VIRT_PLIC_PENDING_BASE,
617
+ VIRT_PLIC_ENABLE_BASE,
618
+ VIRT_PLIC_ENABLE_STRIDE,
619
+ VIRT_PLIC_CONTEXT_BASE,
620
+ VIRT_PLIC_CONTEXT_STRIDE,
621
+ memmap[VIRT_PLIC].size);
622
+ g_free(plic_hart_config);
623
+
624
+ /* Try to use different PLIC instance based device type */
625
+ if (i == 0) {
626
+ mmio_plic = s->plic[i];
627
+ virtio_plic = s->plic[i];
628
+ pcie_plic = s->plic[i];
629
+ }
630
+ if (i == 1) {
631
+ virtio_plic = s->plic[i];
632
+ pcie_plic = s->plic[i];
633
+ }
634
+ if (i == 2) {
635
+ pcie_plic = s->plic[i];
636
+ }
637
+ }
638
639
/* register system main memory (actual RAM) */
640
memory_region_init_ram(main_mem, NULL, "riscv_virt_board.ram",
641
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
642
virt_memmap[VIRT_MROM].size, kernel_entry,
643
fdt_load_addr, s->fdt);
644
645
- /* create PLIC hart topology configuration string */
646
- plic_hart_config_len = (strlen(VIRT_PLIC_HART_CONFIG) + 1) * smp_cpus;
647
- plic_hart_config = g_malloc0(plic_hart_config_len);
648
- for (i = 0; i < smp_cpus; i++) {
649
- if (i != 0) {
650
- strncat(plic_hart_config, ",", plic_hart_config_len);
651
- }
652
- strncat(plic_hart_config, VIRT_PLIC_HART_CONFIG, plic_hart_config_len);
653
- plic_hart_config_len -= (strlen(VIRT_PLIC_HART_CONFIG) + 1);
654
- }
655
-
656
- /* MMIO */
657
- s->plic = sifive_plic_create(memmap[VIRT_PLIC].base,
658
- plic_hart_config, 0,
659
- VIRT_PLIC_NUM_SOURCES,
660
- VIRT_PLIC_NUM_PRIORITIES,
661
- VIRT_PLIC_PRIORITY_BASE,
662
- VIRT_PLIC_PENDING_BASE,
663
- VIRT_PLIC_ENABLE_BASE,
664
- VIRT_PLIC_ENABLE_STRIDE,
665
- VIRT_PLIC_CONTEXT_BASE,
666
- VIRT_PLIC_CONTEXT_STRIDE,
667
- memmap[VIRT_PLIC].size);
668
- sifive_clint_create(memmap[VIRT_CLINT].base,
669
- memmap[VIRT_CLINT].size, 0, smp_cpus,
670
- SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, true);
671
+ /* SiFive Test MMIO device */
672
sifive_test_create(memmap[VIRT_TEST].base);
673
674
+ /* VirtIO MMIO devices */
675
for (i = 0; i < VIRTIO_COUNT; i++) {
676
sysbus_create_simple("virtio-mmio",
677
memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size,
678
- qdev_get_gpio_in(DEVICE(s->plic), VIRTIO_IRQ + i));
679
+ qdev_get_gpio_in(DEVICE(virtio_plic), VIRTIO_IRQ + i));
680
}
48
}
681
49
682
gpex_pcie_init(system_memory,
50
switch (s->sew) {
683
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
51
- case MO_8:
684
memmap[VIRT_PCIE_MMIO].base,
52
- return s->cfg_ptr->ext_zvfhmin;
685
memmap[VIRT_PCIE_MMIO].size,
53
case MO_16:
686
memmap[VIRT_PCIE_PIO].base,
54
return s->cfg_ptr->ext_zve32f;
687
- DEVICE(s->plic), true);
55
case MO_32:
688
+ DEVICE(pcie_plic), true);
56
@@ -XXX,XX +XXX,XX @@ static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
689
57
static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
690
serial_mm_init(system_memory, memmap[VIRT_UART0].base,
58
{
691
- 0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
59
return opfv_widen_check(s, a) &&
692
+ 0, qdev_get_gpio_in(DEVICE(mmio_plic), UART0_IRQ), 399193,
60
+ require_rvfmin(s) &&
693
serial_hd(0), DEVICE_LITTLE_ENDIAN);
61
require_scale_rvfmin(s) &&
694
62
(s->sew != MO_8);
695
sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base,
696
- qdev_get_gpio_in(DEVICE(s->plic), RTC_IRQ));
697
+ qdev_get_gpio_in(DEVICE(mmio_plic), RTC_IRQ));
698
699
virt_flash_create(s);
700
701
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
702
drive_get(IF_PFLASH, 0, i));
703
}
704
virt_flash_map(s, system_memory);
705
-
706
- g_free(plic_hart_config);
707
}
63
}
708
64
@@ -XXX,XX +XXX,XX @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
709
static void virt_machine_instance_init(Object *obj)
65
static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
710
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
66
{
711
67
return opfv_narrow_check(s, a) &&
712
mc->desc = "RISC-V VirtIO board";
68
+ require_rvfmin(s) &&
713
mc->init = virt_machine_init;
69
require_scale_rvfmin(s) &&
714
- mc->max_cpus = 8;
70
(s->sew != MO_8);
715
+ mc->max_cpus = VIRT_CPUS_MAX;
716
mc->default_cpu_type = VIRT_CPU;
717
mc->pci_allow_0_address = true;
718
+ mc->possible_cpu_arch_ids = riscv_numa_possible_cpu_arch_ids;
719
+ mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
720
+ mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
721
+ mc->numa_mem_supported = true;
722
}
71
}
723
724
static const TypeInfo virt_machine_typeinfo = {
725
--
72
--
726
2.28.0
73
2.45.1
727
728
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
2
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.
6
7
The vfwcvt.f.x.v and vfwcvt.f.xu.v instructions convert single width
8
integer to double width float, so the opfxv_widen_check function doesn’t
9
need require_rvf for the single width operator(integer).
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>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Message-id: 93e5d4f13eca0d2a588e407187f33c6437aeaaf9.1597259519.git.alistair.francis@wdc.com
3
Message-Id: <93e5d4f13eca0d2a588e407187f33c6437aeaaf9.1597259519.git.alistair.francis@wdc.com>
4
---
16
---
5
target/riscv/csr.c | 5 +++++
17
target/riscv/insn_trans/trans_rvv.c.inc | 5 +++++
6
1 file changed, 5 insertions(+)
18
1 file changed, 5 insertions(+)
7
19
8
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
9
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
10
--- a/target/riscv/csr.c
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
11
+++ b/target/riscv/csr.c
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
12
@@ -XXX,XX +XXX,XX @@ static int read_hstatus(CPURISCVState *env, int csrno, target_ulong *val)
24
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check)
13
/* We only support 64-bit VSXL */
25
static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
14
*val = set_field(*val, HSTATUS_VSXL, 2);
26
{
15
#endif
27
return require_rvv(s) &&
16
+ /* We only support little endian */
28
+ require_rvf(s) &&
17
+ *val = set_field(*val, HSTATUS_VSBE, 0);
29
require_scale_rvf(s) &&
18
return 0;
30
(s->sew != MO_8) &&
31
vext_check_isa_ill(s) &&
32
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check)
33
static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
34
{
35
return require_rvv(s) &&
36
+ require_rvf(s) &&
37
require_scale_rvf(s) &&
38
(s->sew != MO_8) &&
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);
19
}
63
}
20
21
@@ -XXX,XX +XXX,XX @@ static int write_hstatus(CPURISCVState *env, int csrno, target_ulong val)
22
qemu_log_mask(LOG_UNIMP, "QEMU does not support mixed HSXLEN options.");
23
}
24
#endif
25
+ if (get_field(val, HSTATUS_VSBE) != 0) {
26
+ qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests.");
27
+ }
28
return 0;
29
}
30
31
--
64
--
32
2.28.0
65
2.45.1
33
66
34
67
diff view generated by jsdifflib
New patch
1
From: Max Chou <max.chou@sifive.com>
1
2
3
The opfv_narrow_check needs to check the single width float operator by
4
require_rvf.
5
6
Signed-off-by: Max Chou <max.chou@sifive.com>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Cc: qemu-stable <qemu-stable@nongnu.org>
9
Message-ID: <20240322092600.1198921-4-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
13
1 file changed, 1 insertion(+)
14
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
20
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
21
{
22
return opfv_narrow_check(s, a) &&
23
+ require_rvf(s) &&
24
require_scale_rvf(s) &&
25
(s->sew != MO_8);
26
}
27
--
28
2.45.1
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
2
3
If the checking functions check both the single and double width
4
operators at the same time, then the single width operator checking
5
functions (require_rvf[min]) will check whether the SEW is 8.
6
7
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
10
Message-ID: <20240322092600.1198921-5-max.chou@sifive.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Message-id: f3f4fd2ec22a07cc1d750e96895d6813f131de4d.1597259519.git.alistair.francis@wdc.com
3
Message-Id: <f3f4fd2ec22a07cc1d750e96895d6813f131de4d.1597259519.git.alistair.francis@wdc.com>
4
---
12
---
5
target/riscv/csr.c | 9 +++++++++
13
target/riscv/insn_trans/trans_rvv.c.inc | 16 ++++------------
6
1 file changed, 9 insertions(+)
14
1 file changed, 4 insertions(+), 12 deletions(-)
7
15
8
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
16
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
9
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
10
--- a/target/riscv/csr.c
18
--- a/target/riscv/insn_trans/trans_rvv.c.inc
11
+++ b/target/riscv/csr.c
19
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
12
@@ -XXX,XX +XXX,XX @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val)
20
@@ -XXX,XX +XXX,XX @@ static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
13
static int read_hstatus(CPURISCVState *env, int csrno, target_ulong *val)
21
return require_rvv(s) &&
22
require_rvf(s) &&
23
require_scale_rvf(s) &&
24
- (s->sew != MO_8) &&
25
vext_check_isa_ill(s) &&
26
vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
27
}
28
@@ -XXX,XX +XXX,XX @@ static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
29
return require_rvv(s) &&
30
require_rvf(s) &&
31
require_scale_rvf(s) &&
32
- (s->sew != MO_8) &&
33
vext_check_isa_ill(s) &&
34
vext_check_ds(s, a->rd, a->rs2, a->vm);
35
}
36
@@ -XXX,XX +XXX,XX @@ static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
37
return require_rvv(s) &&
38
require_rvf(s) &&
39
require_scale_rvf(s) &&
40
- (s->sew != MO_8) &&
41
vext_check_isa_ill(s) &&
42
vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
43
}
44
@@ -XXX,XX +XXX,XX @@ static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
45
return require_rvv(s) &&
46
require_rvf(s) &&
47
require_scale_rvf(s) &&
48
- (s->sew != MO_8) &&
49
vext_check_isa_ill(s) &&
50
vext_check_dd(s, a->rd, a->rs2, a->vm);
51
}
52
@@ -XXX,XX +XXX,XX @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
14
{
53
{
15
*val = env->hstatus;
54
return opfv_widen_check(s, a) &&
16
+#ifdef TARGET_RISCV64
55
require_rvfmin(s) &&
17
+ /* We only support 64-bit VSXL */
56
- require_scale_rvfmin(s) &&
18
+ *val = set_field(*val, HSTATUS_VSXL, 2);
57
- (s->sew != MO_8);
19
+#endif
58
+ require_scale_rvfmin(s);
20
return 0;
21
}
59
}
22
60
23
static int write_hstatus(CPURISCVState *env, int csrno, target_ulong val)
61
#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
62
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
24
{
63
{
25
env->hstatus = val;
64
return opfv_narrow_check(s, a) &&
26
+#ifdef TARGET_RISCV64
65
require_rvfmin(s) &&
27
+ if (get_field(val, HSTATUS_VSXL) != 2) {
66
- require_scale_rvfmin(s) &&
28
+ qemu_log_mask(LOG_UNIMP, "QEMU does not support mixed HSXLEN options.");
67
- (s->sew != MO_8);
29
+ }
68
+ require_scale_rvfmin(s);
30
+#endif
31
return 0;
32
}
69
}
33
70
71
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
72
{
73
return opfv_narrow_check(s, a) &&
74
require_rvf(s) &&
75
- require_scale_rvf(s) &&
76
- (s->sew != MO_8);
77
+ require_scale_rvf(s);
78
}
79
80
#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \
81
@@ -XXX,XX +XXX,XX @@ static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
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)
34
--
91
--
35
2.28.0
92
2.45.1
36
37
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
3
raise_mmu_exception(), as is today, is prioritizing guest page faults by
4
checking first if virt_enabled && !first_stage, and then considering the
5
regular inst/load/store faults.
6
7
There's no mention in the spec about guest page fault being a higher
8
priority that PMP faults. In fact, privileged spec section 3.7.1 says:
9
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>
30
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
31
Message-ID: <20240413105929.7030-1-alexei.filippov@syntacore.com>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Message-id: 024ad8a594fb2feaf0950fbfad1508cfa82ce7f0.1597259519.git.alistair.francis@wdc.com
3
Message-Id: <024ad8a594fb2feaf0950fbfad1508cfa82ce7f0.1597259519.git.alistair.francis@wdc.com>
4
---
34
---
5
target/riscv/cpu_helper.c | 60 ++++++++++++++++-----------------------
35
target/riscv/cpu_helper.c | 22 ++++++++++++----------
6
1 file changed, 25 insertions(+), 35 deletions(-)
36
1 file changed, 12 insertions(+), 10 deletions(-)
7
37
8
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
9
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
10
--- a/target/riscv/cpu_helper.c
40
--- a/target/riscv/cpu_helper.c
11
+++ b/target/riscv/cpu_helper.c
41
+++ b/target/riscv/cpu_helper.c
12
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
13
* was called. Background registers will be used if the guest has
14
* forced a two stage translation to be on (in HS or M mode).
15
*/
16
+ if (riscv_cpu_two_stage_lookup(env) && access_type != MMU_INST_FETCH) {
17
+ use_background = true;
18
+ }
19
+
20
if (mode == PRV_M && access_type != MMU_INST_FETCH) {
21
if (get_field(env->mstatus, MSTATUS_MPRV)) {
22
mode = get_field(env->mstatus, MSTATUS_MPP);
23
-
24
- if (riscv_has_ext(env, RVH) &&
25
- MSTATUS_MPV_ISSET(env)) {
26
- use_background = true;
27
- }
28
- }
29
- }
30
-
31
- if (mode == PRV_S && access_type != MMU_INST_FETCH &&
32
- riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
33
- if (get_field(env->hstatus, HSTATUS_SPRV)) {
34
- mode = get_field(env->mstatus, SSTATUS_SPP);
35
- use_background = true;
36
}
37
}
38
39
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
42
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
43
44
switch (access_type) {
45
case MMU_INST_FETCH:
46
- if (env->virt_enabled && !first_stage) {
47
+ if (pmp_violation) {
48
+ cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT;
49
+ } else if (env->virt_enabled && !first_stage) {
50
cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT;
51
} else {
52
- cs->exception_index = pmp_violation ?
53
- RISCV_EXCP_INST_ACCESS_FAULT : RISCV_EXCP_INST_PAGE_FAULT;
54
+ cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT;
40
}
55
}
41
break;
56
break;
42
case MMU_DATA_LOAD:
57
case MMU_DATA_LOAD:
43
- if (riscv_cpu_virt_enabled(env) && !first_stage) {
58
- if (two_stage && !first_stage) {
44
+ if ((riscv_cpu_virt_enabled(env) || riscv_cpu_two_stage_lookup(env)) &&
59
+ if (pmp_violation) {
45
+ !first_stage) {
60
+ cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT;
61
+ } else if (two_stage && !first_stage) {
46
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
62
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
47
} else {
63
} else {
48
cs->exception_index = page_fault_exceptions ?
64
- cs->exception_index = pmp_violation ?
49
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
65
- RISCV_EXCP_LOAD_ACCESS_FAULT : RISCV_EXCP_LOAD_PAGE_FAULT;
66
+ cs->exception_index = RISCV_EXCP_LOAD_PAGE_FAULT;
50
}
67
}
51
break;
68
break;
52
case MMU_DATA_STORE:
69
case MMU_DATA_STORE:
53
- if (riscv_cpu_virt_enabled(env) && !first_stage) {
70
- if (two_stage && !first_stage) {
54
+ if ((riscv_cpu_virt_enabled(env) || riscv_cpu_two_stage_lookup(env)) &&
71
+ if (pmp_violation) {
55
+ !first_stage) {
72
+ cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
73
+ } else if (two_stage && !first_stage) {
56
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
74
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
57
} else {
75
} else {
58
cs->exception_index = page_fault_exceptions ?
76
- cs->exception_index = pmp_violation ?
59
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
77
- RISCV_EXCP_STORE_AMO_ACCESS_FAULT :
60
hwaddr pa = 0;
78
- RISCV_EXCP_STORE_PAGE_FAULT;
61
int prot, prot2;
79
+ cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
62
bool pmp_violation = false;
63
- bool m_mode_two_stage = false;
64
- bool hs_mode_two_stage = false;
65
bool first_stage_error = true;
66
int ret = TRANSLATE_FAIL;
67
int mode = mmu_idx;
68
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
69
qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
70
__func__, address, access_type, mmu_idx);
71
72
- /*
73
- * Determine if we are in M mode and MPRV is set or in HS mode and SPRV is
74
- * set and we want to access a virtulisation address.
75
- */
76
- if (riscv_has_ext(env, RVH)) {
77
- m_mode_two_stage = env->priv == PRV_M &&
78
- access_type != MMU_INST_FETCH &&
79
- get_field(env->mstatus, MSTATUS_MPRV) &&
80
- MSTATUS_MPV_ISSET(env);
81
-
82
- hs_mode_two_stage = env->priv == PRV_S &&
83
- !riscv_cpu_virt_enabled(env) &&
84
- access_type != MMU_INST_FETCH &&
85
- get_field(env->hstatus, HSTATUS_SPRV) &&
86
- get_field(env->hstatus, HSTATUS_SPV);
87
- }
88
-
89
if (mode == PRV_M && access_type != MMU_INST_FETCH) {
90
if (get_field(env->mstatus, MSTATUS_MPRV)) {
91
mode = get_field(env->mstatus, MSTATUS_MPP);
92
}
80
}
93
}
81
break;
94
82
default:
95
- if (riscv_cpu_virt_enabled(env) || m_mode_two_stage || hs_mode_two_stage) {
96
+ if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
97
+ access_type != MMU_INST_FETCH &&
98
+ get_field(env->mstatus, MSTATUS_MPRV) &&
99
+ MSTATUS_MPV_ISSET(env)) {
100
+ riscv_cpu_set_two_stage_lookup(env, true);
101
+ }
102
+
103
+ if (riscv_cpu_virt_enabled(env) ||
104
+ (riscv_cpu_two_stage_lookup(env) && access_type != MMU_INST_FETCH)) {
105
/* Two stage lookup */
106
ret = get_physical_address(env, &pa, &prot, address, access_type,
107
mmu_idx, true, true);
108
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
109
__func__, address, ret, pa, prot);
110
}
111
112
+ /* We did the two stage lookup based on MPRV, unset the lookup */
113
+ if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
114
+ access_type != MMU_INST_FETCH &&
115
+ get_field(env->mstatus, MSTATUS_MPRV) &&
116
+ MSTATUS_MPV_ISSET(env)) {
117
+ riscv_cpu_set_two_stage_lookup(env, false);
118
+ }
119
+
120
if (riscv_feature(env, RISCV_FEATURE_PMP) &&
121
(ret == TRANSLATE_SUCCESS) &&
122
!pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
123
--
83
--
124
2.28.0
84
2.45.1
125
126
diff view generated by jsdifflib
1
From: Alexei Filippov <alexei.filippov@syntacore.com>
2
3
Previous patch fixed the PMP priority in raise_mmu_exception() but we're still
4
setting mtval2 incorrectly. In riscv_cpu_tlb_fill(), after pmp check in 2 stage
5
translation part, mtval2 will be set in case of successes 2 stage translation but
6
failed pmp check.
7
8
In this case we gonna set mtval2 via env->guest_phys_fault_addr in context of
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>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-ID: <20240503103052.6819-1-alexei.filippov@syntacore.com>
19
Cc: qemu-stable <qemu-stable@nongnu.org>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Message-id: e7e4e801234f2934306e734f65860f601a5745bd.1597259519.git.alistair.francis@wdc.com
3
Message-Id: <e7e4e801234f2934306e734f65860f601a5745bd.1597259519.git.alistair.francis@wdc.com>
4
---
21
---
5
target/riscv/cpu_bits.h | 1 +
22
target/riscv/cpu_helper.c | 12 ++++++------
6
target/riscv/cpu_helper.c | 16 ++++++----------
23
1 file changed, 6 insertions(+), 6 deletions(-)
7
target/riscv/op_helper.c | 8 ++------
8
target/riscv/translate.c | 10 ----------
9
4 files changed, 9 insertions(+), 26 deletions(-)
10
24
11
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/riscv/cpu_bits.h
14
+++ b/target/riscv/cpu_bits.h
15
@@ -XXX,XX +XXX,XX @@
16
#define HSTATUS_VTSR 0x00400000
17
#define HSTATUS_HU 0x00000200
18
#define HSTATUS_GVA 0x00000040
19
+#define HSTATUS_SPVP 0x00000100
20
21
#define HSTATUS32_WPRI 0xFF8FF87E
22
#define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL
23
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
24
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/cpu_helper.c
27
--- a/target/riscv/cpu_helper.c
26
+++ b/target/riscv/cpu_helper.c
28
+++ b/target/riscv/cpu_helper.c
27
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
29
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
28
} else if (riscv_cpu_virt_enabled(env)) {
30
__func__, pa, ret, prot_pmp, tlb_size);
29
/* Trap into HS mode, from virt */
31
30
riscv_cpu_swap_hypervisor_regs(env);
32
prot &= prot_pmp;
31
- env->hstatus = set_field(env->hstatus, HSTATUS_SP2V,
33
- }
32
- get_field(env->hstatus, HSTATUS_SPV));
33
- env->hstatus = set_field(env->hstatus, HSTATUS_SP2P,
34
+ env->hstatus = set_field(env->hstatus, HSTATUS_SPVP,
35
get_field(env->mstatus, SSTATUS_SPP));
36
env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
37
riscv_cpu_virt_enabled(env));
38
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
39
riscv_cpu_set_force_hs_excep(env, 0);
40
} else {
41
/* Trap into HS mode */
42
- env->hstatus = set_field(env->hstatus, HSTATUS_SP2V,
43
- get_field(env->hstatus, HSTATUS_SPV));
44
- env->hstatus = set_field(env->hstatus, HSTATUS_SP2P,
45
- get_field(env->mstatus, SSTATUS_SPP));
46
- env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
47
- riscv_cpu_virt_enabled(env));
48
-
34
-
49
+ if (!riscv_cpu_two_stage_lookup(env)) {
35
- if (ret != TRANSLATE_SUCCESS) {
50
+ env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
36
+ } else {
51
+ riscv_cpu_virt_enabled(env));
37
/*
38
* Guest physical address translation failed, this is a HS
39
* level exception
40
*/
41
first_stage_error = false;
42
- env->guest_phys_fault_addr = (im_address |
43
- (address &
44
- (TARGET_PAGE_SIZE - 1))) >> 2;
45
+ if (ret != TRANSLATE_PMP_FAIL) {
46
+ env->guest_phys_fault_addr = (im_address |
47
+ (address &
48
+ (TARGET_PAGE_SIZE - 1))) >> 2;
52
+ }
49
+ }
53
+ riscv_cpu_set_two_stage_lookup(env, false);
54
htval = env->guest_phys_fault_addr;
55
}
50
}
56
}
51
}
57
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/riscv/op_helper.c
60
+++ b/target/riscv/op_helper.c
61
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
62
prev_priv = get_field(mstatus, MSTATUS_SPP);
63
prev_virt = get_field(hstatus, HSTATUS_SPV);
64
65
- hstatus = set_field(hstatus, HSTATUS_SPV,
66
- get_field(hstatus, HSTATUS_SP2V));
67
- mstatus = set_field(mstatus, MSTATUS_SPP,
68
- get_field(hstatus, HSTATUS_SP2P));
69
- hstatus = set_field(hstatus, HSTATUS_SP2V, 0);
70
- hstatus = set_field(hstatus, HSTATUS_SP2P, 0);
71
+ hstatus = set_field(hstatus, HSTATUS_SPV, 0);
72
+ mstatus = set_field(mstatus, MSTATUS_SPP, 0);
73
mstatus = set_field(mstatus, SSTATUS_SIE,
74
get_field(mstatus, SSTATUS_SPIE));
75
mstatus = set_field(mstatus, SSTATUS_SPIE, 1);
76
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/riscv/translate.c
79
+++ b/target/riscv/translate.c
80
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
81
#if !defined(CONFIG_USER_ONLY)
82
if (riscv_has_ext(env, RVH)) {
83
ctx->virt_enabled = riscv_cpu_virt_enabled(env);
84
- if (env->priv_ver == PRV_M &&
85
- get_field(env->mstatus, MSTATUS_MPRV) &&
86
- MSTATUS_MPV_ISSET(env)) {
87
- ctx->virt_enabled = true;
88
- } else if (env->priv == PRV_S &&
89
- !riscv_cpu_virt_enabled(env) &&
90
- get_field(env->hstatus, HSTATUS_SPRV) &&
91
- get_field(env->hstatus, HSTATUS_SPV)) {
92
- ctx->virt_enabled = true;
93
- }
94
} else {
52
} else {
95
ctx->virt_enabled = false;
96
}
97
--
53
--
98
2.28.0
54
2.45.1
99
100
diff view generated by jsdifflib
New patch
1
From: Rob Bradford <rbradford@rivosinc.com>
1
2
3
This extension has now been ratified:
4
https://jira.riscv.org/browse/RVS-2006 so the "x-" prefix can be
5
removed.
6
7
Since this is now a ratified extension add it to the list of extensions
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>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
15
Message-ID: <20240514110217.22516-1-rbradford@rivosinc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
target/riscv/cpu.c | 2 +-
19
target/riscv/tcg/tcg-cpu.c | 2 +-
20
2 files changed, 2 insertions(+), 2 deletions(-)
21
22
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/cpu.c
25
+++ b/target/riscv/cpu.c
26
@@ -XXX,XX +XXX,XX @@ static const MISAExtInfo misa_ext_info_arr[] = {
27
MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
28
MISA_EXT_INFO(RVV, "v", "Vector operations"),
29
MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
30
- MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)")
31
+ MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
32
};
33
34
static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc)
35
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/tcg/tcg-cpu.c
38
+++ b/target/riscv/tcg/tcg-cpu.c
39
@@ -XXX,XX +XXX,XX @@ static void riscv_init_max_cpu_extensions(Object *obj)
40
const RISCVCPUMultiExtConfig *prop;
41
42
/* Enable RVG, RVJ and RVV that are disabled by default */
43
- riscv_cpu_set_misa_ext(env, env->misa_ext | RVG | RVJ | RVV);
44
+ riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVJ | RVV);
45
46
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
47
isa_ext_update_enabled(cpu, prop->offset, true);
48
--
49
2.45.1
diff view generated by jsdifflib
1
When performing a CSR access let's return a negative exception value on
1
From: Alistair Francis <alistair23@gmail.com>
2
an error instead of -1. This will allow us to specify the exception in
2
3
future patches.
3
When running the instruction
4
5
```
6
cbo.flush 0(x0)
7
```
8
9
QEMU would segfault.
10
11
The issue was in cpu_gpr[a->rs1] as QEMU does not have cpu_gpr[0]
12
allocated.
13
14
In order to fix this let's use the existing get_address()
15
helper. This also has the benefit of performing pointer mask
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.
4
26
5
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
6
Message-id: a487dad60c9b8fe7a2b992c5e0dcc2504a9000a7.1597259519.git.alistair.francis@wdc.com
28
Reported-by: Fabian Thomas <fabian.thomas@cispa.de>
7
Message-Id: <a487dad60c9b8fe7a2b992c5e0dcc2504a9000a7.1597259519.git.alistair.francis@wdc.com>
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>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
---
34
---
9
target/riscv/csr.c | 46 ++++++++++++++++++++--------------------
35
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++++++++++++----
10
target/riscv/op_helper.c | 18 ++++++++++------
36
1 file changed, 12 insertions(+), 4 deletions(-)
11
2 files changed, 35 insertions(+), 29 deletions(-)
12
37
13
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
38
diff --git a/target/riscv/insn_trans/trans_rvzicbo.c.inc b/target/riscv/insn_trans/trans_rvzicbo.c.inc
14
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/csr.c
40
--- a/target/riscv/insn_trans/trans_rvzicbo.c.inc
16
+++ b/target/riscv/csr.c
41
+++ b/target/riscv/insn_trans/trans_rvzicbo.c.inc
17
@@ -XXX,XX +XXX,XX @@ static int fs(CPURISCVState *env, int csrno)
42
@@ -XXX,XX +XXX,XX @@
18
return 0;
43
static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a)
19
}
44
{
20
if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
45
REQUIRE_ZICBOM(ctx);
21
- return -1;
46
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
22
+ return -RISCV_EXCP_ILLEGAL_INST;
47
+ TCGv src = get_address(ctx, a->rs1, 0);
23
}
48
+
24
#endif
49
+ gen_helper_cbo_clean_flush(tcg_env, src);
25
return 0;
50
return true;
26
@@ -XXX,XX +XXX,XX @@ static int ctr(CPURISCVState *env, int csrno)
27
28
if (!cpu->cfg.ext_counters) {
29
/* The Counters extensions is not enabled */
30
- return -1;
31
+ return -RISCV_EXCP_ILLEGAL_INST;
32
}
33
#endif
34
return 0;
35
@@ -XXX,XX +XXX,XX @@ static int hmode(CPURISCVState *env, int csrno)
36
}
37
}
38
39
- return -1;
40
+ return -RISCV_EXCP_ILLEGAL_INST;
41
}
51
}
42
52
43
static int pmp(CPURISCVState *env, int csrno)
53
static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a)
44
@@ -XXX,XX +XXX,XX @@ static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val)
45
{
54
{
46
#if !defined(CONFIG_USER_ONLY)
55
REQUIRE_ZICBOM(ctx);
47
if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
56
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
48
- return -1;
57
+ TCGv src = get_address(ctx, a->rs1, 0);
49
+ return -RISCV_EXCP_ILLEGAL_INST;
58
+
50
}
59
+ gen_helper_cbo_clean_flush(tcg_env, src);
51
#endif
60
return true;
52
*val = riscv_cpu_get_fflags(env);
61
}
53
@@ -XXX,XX +XXX,XX @@ static int write_fflags(CPURISCVState *env, int csrno, target_ulong val)
62
63
static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a)
54
{
64
{
55
#if !defined(CONFIG_USER_ONLY)
65
REQUIRE_ZICBOM(ctx);
56
if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
66
- gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]);
57
- return -1;
67
+ TCGv src = get_address(ctx, a->rs1, 0);
58
+ return -RISCV_EXCP_ILLEGAL_INST;
68
+
59
}
69
+ gen_helper_cbo_inval(tcg_env, src);
60
env->mstatus |= MSTATUS_FS;
70
return true;
61
#endif
71
}
62
@@ -XXX,XX +XXX,XX @@ static int read_frm(CPURISCVState *env, int csrno, target_ulong *val)
72
73
static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)
63
{
74
{
64
#if !defined(CONFIG_USER_ONLY)
75
REQUIRE_ZICBOZ(ctx);
65
if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
76
- gen_helper_cbo_zero(tcg_env, cpu_gpr[a->rs1]);
66
- return -1;
77
+ TCGv src = get_address(ctx, a->rs1, 0);
67
+ return -RISCV_EXCP_ILLEGAL_INST;
68
}
69
#endif
70
*val = env->frm;
71
@@ -XXX,XX +XXX,XX @@ static int write_frm(CPURISCVState *env, int csrno, target_ulong val)
72
{
73
#if !defined(CONFIG_USER_ONLY)
74
if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
75
- return -1;
76
+ return -RISCV_EXCP_ILLEGAL_INST;
77
}
78
env->mstatus |= MSTATUS_FS;
79
#endif
80
@@ -XXX,XX +XXX,XX @@ static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val)
81
{
82
#if !defined(CONFIG_USER_ONLY)
83
if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
84
- return -1;
85
+ return -RISCV_EXCP_ILLEGAL_INST;
86
}
87
#endif
88
*val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
89
@@ -XXX,XX +XXX,XX @@ static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val)
90
{
91
#if !defined(CONFIG_USER_ONLY)
92
if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
93
- return -1;
94
+ return -RISCV_EXCP_ILLEGAL_INST;
95
}
96
env->mstatus |= MSTATUS_FS;
97
#endif
98
@@ -XXX,XX +XXX,XX @@ static int read_time(CPURISCVState *env, int csrno, target_ulong *val)
99
uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
100
101
if (!env->rdtime_fn) {
102
- return -1;
103
+ return -RISCV_EXCP_ILLEGAL_INST;
104
}
105
106
*val = env->rdtime_fn() + delta;
107
@@ -XXX,XX +XXX,XX @@ static int read_timeh(CPURISCVState *env, int csrno, target_ulong *val)
108
uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
109
110
if (!env->rdtime_fn) {
111
- return -1;
112
+ return -RISCV_EXCP_ILLEGAL_INST;
113
}
114
115
*val = (env->rdtime_fn() + delta) >> 32;
116
@@ -XXX,XX +XXX,XX @@ static int write_mcounteren(CPURISCVState *env, int csrno, target_ulong val)
117
static int read_mscounteren(CPURISCVState *env, int csrno, target_ulong *val)
118
{
119
if (env->priv_ver < PRIV_VERSION_1_11_0) {
120
- return -1;
121
+ return -RISCV_EXCP_ILLEGAL_INST;
122
}
123
*val = env->mcounteren;
124
return 0;
125
@@ -XXX,XX +XXX,XX @@ static int read_mscounteren(CPURISCVState *env, int csrno, target_ulong *val)
126
static int write_mscounteren(CPURISCVState *env, int csrno, target_ulong val)
127
{
128
if (env->priv_ver < PRIV_VERSION_1_11_0) {
129
- return -1;
130
+ return -RISCV_EXCP_ILLEGAL_INST;
131
}
132
env->mcounteren = val;
133
return 0;
134
@@ -XXX,XX +XXX,XX @@ static int read_satp(CPURISCVState *env, int csrno, target_ulong *val)
135
}
136
137
if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
138
- return -1;
139
+ return -RISCV_EXCP_ILLEGAL_INST;
140
} else {
141
*val = env->satp;
142
}
143
@@ -XXX,XX +XXX,XX @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val)
144
((val ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN)))
145
{
146
if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
147
- return -1;
148
+ return -RISCV_EXCP_ILLEGAL_INST;
149
} else {
150
if((val ^ env->satp) & SATP_ASID) {
151
tlb_flush(env_cpu(env));
152
@@ -XXX,XX +XXX,XX @@ static int write_hgatp(CPURISCVState *env, int csrno, target_ulong val)
153
static int read_htimedelta(CPURISCVState *env, int csrno, target_ulong *val)
154
{
155
if (!env->rdtime_fn) {
156
- return -1;
157
+ return -RISCV_EXCP_ILLEGAL_INST;
158
}
159
160
#if defined(TARGET_RISCV32)
161
@@ -XXX,XX +XXX,XX @@ static int read_htimedelta(CPURISCVState *env, int csrno, target_ulong *val)
162
static int write_htimedelta(CPURISCVState *env, int csrno, target_ulong val)
163
{
164
if (!env->rdtime_fn) {
165
- return -1;
166
+ return -RISCV_EXCP_ILLEGAL_INST;
167
}
168
169
#if defined(TARGET_RISCV32)
170
@@ -XXX,XX +XXX,XX @@ static int write_htimedelta(CPURISCVState *env, int csrno, target_ulong val)
171
static int read_htimedeltah(CPURISCVState *env, int csrno, target_ulong *val)
172
{
173
if (!env->rdtime_fn) {
174
- return -1;
175
+ return -RISCV_EXCP_ILLEGAL_INST;
176
}
177
178
*val = env->htimedelta >> 32;
179
@@ -XXX,XX +XXX,XX @@ static int read_htimedeltah(CPURISCVState *env, int csrno, target_ulong *val)
180
static int write_htimedeltah(CPURISCVState *env, int csrno, target_ulong val)
181
{
182
if (!env->rdtime_fn) {
183
- return -1;
184
+ return -RISCV_EXCP_ILLEGAL_INST;
185
}
186
187
env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
188
@@ -XXX,XX +XXX,XX @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
189
190
if ((write_mask && read_only) ||
191
(!env->debugger && (effective_priv < get_field(csrno, 0x300)))) {
192
- return -1;
193
+ return -RISCV_EXCP_ILLEGAL_INST;
194
}
195
#endif
196
197
/* ensure the CSR extension is enabled. */
198
if (!cpu->cfg.ext_icsr) {
199
- return -1;
200
+ return -RISCV_EXCP_ILLEGAL_INST;
201
}
202
203
/* check predicate */
204
if (!csr_ops[csrno].predicate || csr_ops[csrno].predicate(env, csrno) < 0) {
205
- return -1;
206
+ return -RISCV_EXCP_ILLEGAL_INST;
207
}
208
209
/* execute combined read/write operation if it exists */
210
@@ -XXX,XX +XXX,XX @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
211
212
/* if no accessor exists then return failure */
213
if (!csr_ops[csrno].read) {
214
- return -1;
215
+ return -RISCV_EXCP_ILLEGAL_INST;
216
}
217
218
/* read old value */
219
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
220
index XXXXXXX..XXXXXXX 100644
221
--- a/target/riscv/op_helper.c
222
+++ b/target/riscv/op_helper.c
223
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrw(CPURISCVState *env, target_ulong src,
224
target_ulong csr)
225
{
226
target_ulong val = 0;
227
- if (riscv_csrrw(env, csr, &val, src, -1) < 0) {
228
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
229
+ int ret = riscv_csrrw(env, csr, &val, src, -1);
230
+
78
+
231
+ if (ret < 0) {
79
+ gen_helper_cbo_zero(tcg_env, src);
232
+ riscv_raise_exception(env, -ret, GETPC());
80
return true;
233
}
234
return val;
235
}
236
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrs(CPURISCVState *env, target_ulong src,
237
target_ulong csr, target_ulong rs1_pass)
238
{
239
target_ulong val = 0;
240
- if (riscv_csrrw(env, csr, &val, -1, rs1_pass ? src : 0) < 0) {
241
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
242
+ int ret = riscv_csrrw(env, csr, &val, -1, rs1_pass ? src : 0);
243
+
244
+ if (ret < 0) {
245
+ riscv_raise_exception(env, -ret, GETPC());
246
}
247
return val;
248
}
249
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
250
target_ulong csr, target_ulong rs1_pass)
251
{
252
target_ulong val = 0;
253
- if (riscv_csrrw(env, csr, &val, 0, rs1_pass ? src : 0) < 0) {
254
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
255
+ int ret = riscv_csrrw(env, csr, &val, 0, rs1_pass ? src : 0);
256
+
257
+ if (ret < 0) {
258
+ riscv_raise_exception(env, -ret, GETPC());
259
}
260
return val;
261
}
81
}
262
--
82
--
263
2.28.0
83
2.45.1
264
265
diff view generated by jsdifflib
New patch
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
1
2
3
In AIA spec, each hart (or each hart within a group) has a unique hart
4
number to locate the memory pages of interrupt files in the address
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.
8
9
However, if the largest hart number among groups is a power of 2, QEMU
10
will pass an inaccurate hart-index-bit setting to Linux. For example, when
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>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
26
target/riscv/kvm/kvm-cpu.c | 9 ++++++++-
27
1 file changed, 8 insertions(+), 1 deletion(-)
28
29
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/kvm/kvm-cpu.c
32
+++ b/target/riscv/kvm/kvm-cpu.c
33
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
34
}
35
}
36
37
- hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
38
+
39
+ if (max_hart_per_socket > 1) {
40
+ max_hart_per_socket--;
41
+ hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
42
+ } else {
43
+ hart_bits = 0;
44
+ }
45
+
46
ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
47
KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
48
&hart_bits, true, NULL);
49
--
50
2.45.1
diff view generated by jsdifflib
1
From: Anup Patel <anup.patel@wdc.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
We extend CLINT emulation to allow multiple instances of CLINT in
3
Commit 33a24910ae changed 'reg_width' to use 'vlenb', i.e. vector length
4
a QEMU RISC-V machine. To achieve this, we remove first HART id
4
in bytes, when in this context we want 'reg_width' as the length in
5
zero assumption from CLINT emulation.
5
bits.
6
6
7
Signed-off-by: Anup Patel <anup.patel@wdc.com>
7
Fix 'reg_width' back to the value in bits like 7cb59921c05a
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
Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
25
Cc: qemu-stable <qemu-stable@nongnu.org>
10
Message-Id: <20200616032229.766089-2-anup.patel@wdc.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
include/hw/riscv/sifive_clint.h | 7 ++++---
29
target/riscv/gdbstub.c | 6 +++---
14
hw/riscv/sifive_clint.c | 20 ++++++++++++--------
30
1 file changed, 3 insertions(+), 3 deletions(-)
15
hw/riscv/sifive_e.c | 2 +-
16
hw/riscv/sifive_u.c | 2 +-
17
hw/riscv/spike.c | 2 +-
18
hw/riscv/virt.c | 2 +-
19
6 files changed, 20 insertions(+), 15 deletions(-)
20
31
21
diff --git a/include/hw/riscv/sifive_clint.h b/include/hw/riscv/sifive_clint.h
32
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
22
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/riscv/sifive_clint.h
34
--- a/target/riscv/gdbstub.c
24
+++ b/include/hw/riscv/sifive_clint.h
35
+++ b/target/riscv/gdbstub.c
25
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveCLINTState {
36
@@ -XXX,XX +XXX,XX @@ static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg)
26
37
static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
27
/*< public >*/
28
MemoryRegion mmio;
29
+ uint32_t hartid_base;
30
uint32_t num_harts;
31
uint32_t sip_base;
32
uint32_t timecmp_base;
33
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveCLINTState {
34
uint32_t aperture_size;
35
} SiFiveCLINTState;
36
37
-DeviceState *sifive_clint_create(hwaddr addr, hwaddr size, uint32_t num_harts,
38
- uint32_t sip_base, uint32_t timecmp_base, uint32_t time_base,
39
- bool provide_rdtime);
40
+DeviceState *sifive_clint_create(hwaddr addr, hwaddr size,
41
+ uint32_t hartid_base, uint32_t num_harts, uint32_t sip_base,
42
+ uint32_t timecmp_base, uint32_t time_base, bool provide_rdtime);
43
44
enum {
45
SIFIVE_SIP_BASE = 0x0,
46
diff --git a/hw/riscv/sifive_clint.c b/hw/riscv/sifive_clint.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/riscv/sifive_clint.c
49
+++ b/hw/riscv/sifive_clint.c
50
@@ -XXX,XX +XXX,XX @@ static uint64_t sifive_clint_read(void *opaque, hwaddr addr, unsigned size)
51
SiFiveCLINTState *clint = opaque;
52
if (addr >= clint->sip_base &&
53
addr < clint->sip_base + (clint->num_harts << 2)) {
54
- size_t hartid = (addr - clint->sip_base) >> 2;
55
+ size_t hartid = clint->hartid_base + ((addr - clint->sip_base) >> 2);
56
CPUState *cpu = qemu_get_cpu(hartid);
57
CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
58
if (!env) {
59
@@ -XXX,XX +XXX,XX @@ static uint64_t sifive_clint_read(void *opaque, hwaddr addr, unsigned size)
60
}
61
} else if (addr >= clint->timecmp_base &&
62
addr < clint->timecmp_base + (clint->num_harts << 3)) {
63
- size_t hartid = (addr - clint->timecmp_base) >> 3;
64
+ size_t hartid = clint->hartid_base +
65
+ ((addr - clint->timecmp_base) >> 3);
66
CPUState *cpu = qemu_get_cpu(hartid);
67
CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
68
if (!env) {
69
@@ -XXX,XX +XXX,XX @@ static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value,
70
71
if (addr >= clint->sip_base &&
72
addr < clint->sip_base + (clint->num_harts << 2)) {
73
- size_t hartid = (addr - clint->sip_base) >> 2;
74
+ size_t hartid = clint->hartid_base + ((addr - clint->sip_base) >> 2);
75
CPUState *cpu = qemu_get_cpu(hartid);
76
CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
77
if (!env) {
78
@@ -XXX,XX +XXX,XX @@ static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value,
79
return;
80
} else if (addr >= clint->timecmp_base &&
81
addr < clint->timecmp_base + (clint->num_harts << 3)) {
82
- size_t hartid = (addr - clint->timecmp_base) >> 3;
83
+ size_t hartid = clint->hartid_base +
84
+ ((addr - clint->timecmp_base) >> 3);
85
CPUState *cpu = qemu_get_cpu(hartid);
86
CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
87
if (!env) {
88
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps sifive_clint_ops = {
89
};
90
91
static Property sifive_clint_properties[] = {
92
+ DEFINE_PROP_UINT32("hartid-base", SiFiveCLINTState, hartid_base, 0),
93
DEFINE_PROP_UINT32("num-harts", SiFiveCLINTState, num_harts, 0),
94
DEFINE_PROP_UINT32("sip-base", SiFiveCLINTState, sip_base, 0),
95
DEFINE_PROP_UINT32("timecmp-base", SiFiveCLINTState, timecmp_base, 0),
96
@@ -XXX,XX +XXX,XX @@ type_init(sifive_clint_register_types)
97
/*
98
* Create CLINT device.
99
*/
100
-DeviceState *sifive_clint_create(hwaddr addr, hwaddr size, uint32_t num_harts,
101
- uint32_t sip_base, uint32_t timecmp_base, uint32_t time_base,
102
- bool provide_rdtime)
103
+DeviceState *sifive_clint_create(hwaddr addr, hwaddr size,
104
+ uint32_t hartid_base, uint32_t num_harts, uint32_t sip_base,
105
+ uint32_t timecmp_base, uint32_t time_base, bool provide_rdtime)
106
{
38
{
39
RISCVCPU *cpu = RISCV_CPU(cs);
40
- int reg_width = cpu->cfg.vlenb;
41
+ int bitsize = cpu->cfg.vlenb << 3;
42
GDBFeatureBuilder builder;
107
int i;
43
int i;
108
for (i = 0; i < num_harts; i++) {
44
109
- CPUState *cpu = qemu_get_cpu(i);
45
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
110
+ CPUState *cpu = qemu_get_cpu(hartid_base + i);
46
111
CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
47
/* First define types and totals in a whole VL */
112
if (!env) {
48
for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
113
continue;
49
- int count = reg_width / vec_lanes[i].size;
114
@@ -XXX,XX +XXX,XX @@ DeviceState *sifive_clint_create(hwaddr addr, hwaddr size, uint32_t num_harts,
50
+ int count = bitsize / vec_lanes[i].size;
51
gdb_feature_builder_append_tag(
52
&builder, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
53
vec_lanes[i].id, vec_lanes[i].gdb_type, count);
54
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
55
/* Define vector registers */
56
for (i = 0; i < 32; i++) {
57
gdb_feature_builder_append_reg(&builder, g_strdup_printf("v%d", i),
58
- reg_width, i, "riscv_vector", "vector");
59
+ bitsize, i, "riscv_vector", "vector");
115
}
60
}
116
61
117
DeviceState *dev = qdev_new(TYPE_SIFIVE_CLINT);
62
gdb_feature_builder_end(&builder);
118
+ qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
119
qdev_prop_set_uint32(dev, "num-harts", num_harts);
120
qdev_prop_set_uint32(dev, "sip-base", sip_base);
121
qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
122
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/hw/riscv/sifive_e.c
125
+++ b/hw/riscv/sifive_e.c
126
@@ -XXX,XX +XXX,XX @@ static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
127
SIFIVE_E_PLIC_CONTEXT_STRIDE,
128
memmap[SIFIVE_E_PLIC].size);
129
sifive_clint_create(memmap[SIFIVE_E_CLINT].base,
130
- memmap[SIFIVE_E_CLINT].size, ms->smp.cpus,
131
+ memmap[SIFIVE_E_CLINT].size, 0, ms->smp.cpus,
132
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, false);
133
create_unimplemented_device("riscv.sifive.e.aon",
134
memmap[SIFIVE_E_AON].base, memmap[SIFIVE_E_AON].size);
135
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
136
index XXXXXXX..XXXXXXX 100644
137
--- a/hw/riscv/sifive_u.c
138
+++ b/hw/riscv/sifive_u.c
139
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
140
sifive_uart_create(system_memory, memmap[SIFIVE_U_UART1].base,
141
serial_hd(1), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_UART1_IRQ));
142
sifive_clint_create(memmap[SIFIVE_U_CLINT].base,
143
- memmap[SIFIVE_U_CLINT].size, ms->smp.cpus,
144
+ memmap[SIFIVE_U_CLINT].size, 0, ms->smp.cpus,
145
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, false);
146
147
if (!sysbus_realize(SYS_BUS_DEVICE(&s->prci), errp)) {
148
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/hw/riscv/spike.c
151
+++ b/hw/riscv/spike.c
152
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
153
154
/* Core Local Interruptor (timer and IPI) */
155
sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size,
156
- smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
157
+ 0, smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
158
false);
159
}
160
161
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
162
index XXXXXXX..XXXXXXX 100644
163
--- a/hw/riscv/virt.c
164
+++ b/hw/riscv/virt.c
165
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
166
VIRT_PLIC_CONTEXT_STRIDE,
167
memmap[VIRT_PLIC].size);
168
sifive_clint_create(memmap[VIRT_CLINT].base,
169
- memmap[VIRT_CLINT].size, smp_cpus,
170
+ memmap[VIRT_CLINT].size, 0, smp_cpus,
171
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, true);
172
sifive_test_create(memmap[VIRT_TEST].base);
173
174
--
63
--
175
2.28.0
64
2.45.1
176
65
177
66
diff view generated by jsdifflib
New patch
1
From: Alistair Francis <alistair23@gmail.com>
1
2
3
Previously we only listed a single pmpcfg CSR and the first 16 pmpaddr
4
CSRs. This patch fixes this to list all 16 pmpcfg and all 64 pmpaddr
5
CSRs are part of the disassembly.
6
7
Reported-by: Eric DeVolder <eric_devolder@yahoo.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Fixes: ea10325917 ("RISC-V Disassembler")
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Cc: qemu-stable <qemu-stable@nongnu.org>
12
Message-ID: <20240514051615.330979-1-alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
disas/riscv.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-
16
1 file changed, 64 insertions(+), 1 deletion(-)
17
18
diff --git a/disas/riscv.c b/disas/riscv.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/disas/riscv.c
21
+++ b/disas/riscv.c
22
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
23
case 0x0383: return "mibound";
24
case 0x0384: return "mdbase";
25
case 0x0385: return "mdbound";
26
- case 0x03a0: return "pmpcfg3";
27
+ case 0x03a0: return "pmpcfg0";
28
+ case 0x03a1: return "pmpcfg1";
29
+ case 0x03a2: return "pmpcfg2";
30
+ case 0x03a3: return "pmpcfg3";
31
+ case 0x03a4: return "pmpcfg4";
32
+ case 0x03a5: return "pmpcfg5";
33
+ case 0x03a6: return "pmpcfg6";
34
+ case 0x03a7: return "pmpcfg7";
35
+ case 0x03a8: return "pmpcfg8";
36
+ case 0x03a9: return "pmpcfg9";
37
+ case 0x03aa: return "pmpcfg10";
38
+ case 0x03ab: return "pmpcfg11";
39
+ case 0x03ac: return "pmpcfg12";
40
+ case 0x03ad: return "pmpcfg13";
41
+ case 0x03ae: return "pmpcfg14";
42
+ case 0x03af: return "pmpcfg15";
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";
101
--
102
2.45.1
diff view generated by jsdifflib
1
From: Yu-Ming Chang <yumin686@andestech.com>
2
3
Both CSRRS and CSRRC always read the addressed CSR and cause any read side
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.
7
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>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-ID: <20240403070823.80897-1-yumin686@andestech.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Message-id: 08cdefb171b1bdb0c9e3151c509aaadefc3dcd3e.1597259519.git.alistair.francis@wdc.com
3
Message-Id: <08cdefb171b1bdb0c9e3151c509aaadefc3dcd3e.1597259519.git.alistair.francis@wdc.com>
4
---
16
---
5
target/riscv/cpu.h | 2 ++
17
target/riscv/cpu.h | 4 ++++
6
target/riscv/cpu_bits.h | 1 +
18
target/riscv/csr.c | 51 ++++++++++++++++++++++++++++++++++++----
7
target/riscv/cpu_helper.c | 18 ++++++++++++++++++
19
target/riscv/op_helper.c | 6 ++---
8
3 files changed, 21 insertions(+)
20
3 files changed, 53 insertions(+), 8 deletions(-)
9
21
10
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
11
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
12
--- a/target/riscv/cpu.h
24
--- a/target/riscv/cpu.h
13
+++ b/target/riscv/cpu.h
25
+++ b/target/riscv/cpu.h
14
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_virt_enabled(CPURISCVState *env);
26
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
15
void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
27
void riscv_cpu_update_mask(CPURISCVState *env);
16
bool riscv_cpu_force_hs_excep_enabled(CPURISCVState *env);
28
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
17
void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable);
29
18
+bool riscv_cpu_two_stage_lookup(CPURISCVState *env);
30
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
19
+void riscv_cpu_set_two_stage_lookup(CPURISCVState *env, bool enable);
31
+ target_ulong *ret_value);
20
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
32
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
21
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
33
target_ulong *ret_value,
22
void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
34
target_ulong new_value, target_ulong write_mask);
23
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
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
24
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/cpu_bits.h
46
--- a/target/riscv/csr.c
26
+++ b/target/riscv/cpu_bits.h
47
+++ b/target/riscv/csr.c
27
@@ -XXX,XX +XXX,XX @@
48
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
28
* page table fault.
49
29
*/
50
static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
30
#define FORCE_HS_EXCEP 2
51
int csrno,
31
+#define HS_TWO_STAGE 4
52
- bool write_mask)
32
53
+ bool write)
33
/* RV32 satp CSR field masks */
54
{
34
#define SATP32_MODE 0x80000000
55
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
35
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
56
bool read_only = get_field(csrno, 0xC00) == 3;
36
index XXXXXXX..XXXXXXX 100644
57
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
37
--- a/target/riscv/cpu_helper.c
58
}
38
+++ b/target/riscv/cpu_helper.c
59
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable)
60
/* read / write check */
40
env->virt = set_field(env->virt, FORCE_HS_EXCEP, enable);
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;
41
}
68
}
42
69
43
+bool riscv_cpu_two_stage_lookup(CPURISCVState *env)
70
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
71
+ target_ulong *ret_value)
44
+{
72
+{
45
+ if (!riscv_has_ext(env, RVH)) {
73
+ RISCVException ret = riscv_csrrw_check(env, csrno, false);
46
+ return false;
74
+ if (ret != RISCV_EXCP_NONE) {
75
+ return ret;
47
+ }
76
+ }
48
+
77
+
49
+ return get_field(env->virt, HS_TWO_STAGE);
78
+ return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
50
+}
79
+}
51
+
80
+
52
+void riscv_cpu_set_two_stage_lookup(CPURISCVState *env, bool enable)
81
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
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)
53
+{
96
+{
54
+ if (!riscv_has_ext(env, RVH)) {
97
+ RISCVException ret;
55
+ return;
98
+
99
+ ret = riscv_csrrw_check(env, csrno, false);
100
+ if (ret != RISCV_EXCP_NONE) {
101
+ return ret;
56
+ }
102
+ }
57
+
103
+
58
+ env->virt = set_field(env->virt, HS_TWO_STAGE, enable);
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;
59
+}
124
+}
60
+
125
+
61
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts)
126
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
127
Int128 *ret_value,
128
Int128 new_value, Int128 write_mask)
62
{
129
{
63
CPURISCVState *env = &cpu->env;
130
RISCVException ret;
131
132
- ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask));
133
+ ret = riscv_csrrw_check(env, csrno, true);
134
if (ret != RISCV_EXCP_NONE) {
135
return ret;
136
}
137
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
138
index XXXXXXX..XXXXXXX 100644
139
--- a/target/riscv/op_helper.c
140
+++ b/target/riscv/op_helper.c
141
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
142
}
143
144
target_ulong val = 0;
145
- RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
146
+ RISCVException ret = riscv_csrr(env, csr, &val);
147
148
if (ret != RISCV_EXCP_NONE) {
149
riscv_raise_exception(env, ret, GETPC());
150
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
151
target_ulong helper_csrr_i128(CPURISCVState *env, int csr)
152
{
153
Int128 rv = int128_zero();
154
- RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
155
- int128_zero(),
156
- int128_zero());
157
+ RISCVException ret = riscv_csrr_i128(env, csr, &rv);
158
159
if (ret != RISCV_EXCP_NONE) {
160
riscv_raise_exception(env, ret, GETPC());
64
--
161
--
65
2.28.0
162
2.45.1
66
67
diff view generated by jsdifflib