1
The following changes since commit 946e9bccf12f2bcc3ca471b820738fb22d14fc80:
1
The following changes since commit ad10b4badc1dd5b28305f9b9f1168cf0aa3ae946:
2
2
3
Merge tag 'samuel-thibault' of https://people.debian.org/~sthibault/qemu into staging (2022-09-06 08:31:24 -0400)
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-20220907
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240528
8
8
9
for you to fetch changes up to f0551560b5c01b1dcbed1ac46ca0bd1155330f5f:
9
for you to fetch changes up to 1806da76cb81088ea026ca3441551782b850e393:
10
10
11
target/riscv: Update the privilege field for sscofpmf CSRs (2022-09-07 09:19:15 +0200)
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
First RISC-V PR for QEMU 7.2
14
RISC-V PR for 9.1
15
15
16
* Update [m|h]tinst CSR in interrupt handling
16
* APLICs add child earlier than realize
17
* Force disable extensions if priv spec version does not match
17
* Fix exposure of Zkr
18
* fix shifts shamt value for rv128c
18
* Raise exceptions on wrs.nto
19
* move zmmul out of the experimental
19
* Implement SBI debug console (DBCN) calls for KVM
20
* virt: pass random seed to fdt
20
* Support 64-bit addresses for initrd
21
* Add checks for supported extension combinations
21
* Change RISCV_EXCP_SEMIHOST exception number to 63
22
* Upgrade OpenSBI to v1.1
22
* Tolerate KVM disable ext errors
23
* Fix typo and restore Pointer Masking functionality for RISC-V
23
* Set tval in breakpoints
24
* Add mask agnostic behaviour (rvv_ma_all_1s) for vector extension
24
* Add support for Zve32x extension
25
* Add Zihintpause support
25
* Add support for Zve64x extension
26
* opentitan: bump opentitan version
26
* Relax vector register check in RISCV gdbstub
27
* microchip_pfsoc: fix kernel panics due to missing peripherals
27
* Fix the element agnostic Vector function problem
28
* Remove additional priv version check for mcountinhibit
28
* Fix Zvkb extension config
29
* virt machine device tree improvements
29
* Implement dynamic establishment of custom decoder
30
* Add xicondops in ISA entry
30
* Add th.sxstatus CSR emulation
31
* Use official extension names for AIA CSRs
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
32
43
33
----------------------------------------------------------------
44
----------------------------------------------------------------
34
Alexey Baturo (1):
45
Alexei Filippov (1):
35
target/riscv: Fix typo and restore Pointer Masking functionality for RISC-V
46
target/riscv: do not set mtval2 for non guest-page faults
36
47
37
Anup Patel (3):
48
Alistair Francis (2):
38
target/riscv: Update [m|h]tinst CSR in riscv_cpu_do_interrupt()
49
target/riscv: rvzicbo: Fixup CBO extension register calculation
39
target/riscv: Force disable extensions if priv spec version does not match
50
disas/riscv: Decode all of the pmpcfg and pmpaddr CSRs
40
target/riscv: Use official extension names for AIA CSRs
41
51
42
Atish Patra (9):
52
Andrew Jones (2):
43
target/riscv: Remove additional priv version check for mcountinhibit
53
target/riscv/kvm: Fix exposure of Zkr
44
hw/intc: Move mtimer/mtimecmp to aclint
54
target/riscv: Raise exceptions on wrs.nto
45
target/riscv: Add stimecmp support
46
target/riscv: Add vstimecmp support
47
target/riscv: Add sscofpmf extension support
48
target/riscv: Simplify counter predicate function
49
target/riscv: Add few cache related PMU events
50
hw/riscv: virt: Add PMU DT node to the device tree
51
target/riscv: Update the privilege field for sscofpmf CSRs
52
55
53
Bin Meng (2):
56
Cheng Yang (1):
54
roms/opensbi: Upgrade from v1.0 to v1.1
57
hw/riscv/boot.c: Support 64-bit address for initrd
55
docs: List kvm as a supported accelerator on RISC-V
56
58
57
Conor Dooley (5):
59
Christoph Müllner (1):
58
hw/riscv: microchip_pfsoc: fix kernel panics due to missing peripherals
60
riscv: thead: Add th.sxstatus CSR emulation
59
hw/riscv: virt: fix uart node name
60
hw/riscv: virt: fix the plic's address cells
61
hw/riscv: virt: fix syscon subnode paths
62
hw/core: fix platform bus node name
63
61
64
Daniel Henrique Barboza (1):
62
Clément Léger (1):
65
hw/riscv: remove 'fdt' param from riscv_setup_rom_reset_vec()
63
target/riscv: change RISCV_EXCP_SEMIHOST exception number to 63
66
64
67
Dao Lu (1):
65
Daniel Henrique Barboza (6):
68
target/riscv: Add Zihintpause support
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()
69
72
70
Frédéric Pétrot (1):
73
Huang Tao (2):
71
target/riscv: fix shifts shamt value for rv128c
74
target/riscv: Fix the element agnostic function problem
75
target/riscv: Implement dynamic establishment of custom decoder
72
76
73
Jason A. Donenfeld (1):
77
Jason Chien (3):
74
hw/riscv: virt: pass random seed to fdt
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
75
81
76
Rahul Pathak (1):
82
Max Chou (4):
77
target/riscv: Add xicondops in ISA entry
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
78
87
79
Weiwei Li (8):
88
Rob Bradford (1):
80
target/riscv: move zmmul out of the experimental properties
89
target/riscv: Remove experimental prefix from "B" extension
81
target/riscv: Add check for supported privilege mode combinations
82
target/riscv: H extension depends on I extension
83
target/riscv: Fix checkpatch warning may triggered in csr_ops table
84
target/riscv: Add check for csrs existed with U extension
85
target/riscv: Fix checks in hmode/hmode32
86
target/riscv: Simplify the check in hmode to reuse the check in riscv_csrrw_check
87
target/riscv: Fix priority of csr related check in riscv_csrrw_check
88
90
89
Wilfred Mallawa (1):
91
Yangyu Chen (1):
90
hw/riscv: opentitan: bump opentitan version
92
target/riscv/cpu.c: fix Zvkb extension config
91
93
92
Yueh-Ting (eop) Chen (9):
94
Yong-Xuan Wang (1):
93
target/riscv: rvv: Add mask agnostic for vv instructions
95
target/riscv/kvm.c: Fix the hart bit setting of AIA
94
target/riscv: rvv: Add mask agnostic for vector load / store instructions
95
target/riscv: rvv: Add mask agnostic for vx instructions
96
target/riscv: rvv: Add mask agnostic for vector integer shift instructions
97
target/riscv: rvv: Add mask agnostic for vector integer comparison instructions
98
target/riscv: rvv: Add mask agnostic for vector fix-point arithmetic instructions
99
target/riscv: rvv: Add mask agnostic for vector floating-point instructions
100
target/riscv: rvv: Add mask agnostic for vector mask instructions
101
target/riscv: rvv: Add mask agnostic for vector permutation instructions
102
96
103
eopXD (1):
97
Yu-Ming Chang (1):
104
target/riscv: rvv: Add option 'rvv_ma_all_1s' to enable optional mask agnostic behavior
98
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR
105
99
106
docs/about/build-platforms.rst | 2 +-
100
yang.zhang (1):
107
include/hw/intc/riscv_aclint.h | 2 +
101
hw/intc/riscv_aplic: APLICs should add child earlier than realize
108
include/hw/riscv/boot.h | 2 +-
109
include/hw/riscv/microchip_pfsoc.h | 14 +-
110
include/hw/riscv/opentitan.h | 11 +-
111
include/hw/riscv/virt.h | 1 +
112
include/hw/timer/ibex_timer.h | 2 +
113
target/riscv/cpu.h | 48 +-
114
target/riscv/cpu_bits.h | 63 ++
115
target/riscv/instmap.h | 45 +
116
target/riscv/internals.h | 5 +-
117
target/riscv/pmu.h | 8 +
118
target/riscv/time_helper.h | 30 +
119
target/riscv/insn16.decode | 7 +-
120
target/riscv/insn32.decode | 7 +-
121
disas/riscv.c | 27 +-
122
hw/core/sysbus-fdt.c | 2 +-
123
hw/intc/riscv_aclint.c | 48 +-
124
hw/intc/riscv_imsic.c | 4 +-
125
hw/riscv/boot.c | 4 +-
126
hw/riscv/microchip_pfsoc.c | 69 +-
127
hw/riscv/opentitan.c | 12 +-
128
hw/riscv/shakti_c.c | 3 +-
129
hw/riscv/spike.c | 2 +-
130
hw/riscv/virt.c | 45 +-
131
hw/timer/ibex_timer.c | 18 +-
132
target/riscv/cpu.c | 204 +++--
133
target/riscv/cpu_helper.c | 293 ++++++-
134
target/riscv/csr.c | 1038 +++++++++++++++---------
135
target/riscv/machine.c | 8 +-
136
target/riscv/pmu.c | 425 +++++++++-
137
target/riscv/time_helper.c | 114 +++
138
target/riscv/translate.c | 24 +-
139
target/riscv/vector_helper.c | 152 +++-
140
target/riscv/insn_trans/trans_rvi.c.inc | 16 +
141
target/riscv/insn_trans/trans_rvv.c.inc | 28 +
142
pc-bios/opensbi-riscv32-generic-fw_dynamic.bin | Bin 108504 -> 117704 bytes
143
pc-bios/opensbi-riscv64-generic-fw_dynamic.bin | Bin 105296 -> 115344 bytes
144
roms/opensbi | 2 +-
145
target/riscv/meson.build | 3 +-
146
40 files changed, 2229 insertions(+), 559 deletions(-)
147
create mode 100644 target/riscv/time_helper.h
148
create mode 100644 target/riscv/time_helper.c
149
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
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
From: "yang.zhang" <yang.zhang@hexintek.com>
2
2
3
Normally, riscv_csrrw_check is called when executing Zicsr instructions.
3
Since only root APLICs can have hw IRQ lines, aplic->parent should
4
And we can only do access control for existed CSRs. So the priority of
4
be initialized first.
5
CSR related check, from highest to lowest, should be as follows:
6
1) check whether Zicsr is supported: raise RISCV_EXCP_ILLEGAL_INST if not
7
2) check whether csr is existed: raise RISCV_EXCP_ILLEGAL_INST if not
8
3) do access control: raise RISCV_EXCP_ILLEGAL_INST or RISCV_EXCP_VIRT_
9
INSTRUCTION_FAULT if not allowed
10
5
11
The predicates contain parts of function of both 2) and 3), So they need
6
Fixes: e8f79343cf ("hw/intc: Add RISC-V AIA APLIC device emulation")
12
to be placed in the middle of riscv_csrrw_check
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
8
Signed-off-by: yang.zhang <yang.zhang@hexintek.com>
14
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
15
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
10
Message-ID: <20240409014445.278-1-gaoshanliukou@163.com>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-Id: <20220803123652.3700-1-liweiwei@iscas.ac.cn>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
12
---
20
target/riscv/csr.c | 44 +++++++++++++++++++++++++-------------------
13
hw/intc/riscv_aplic.c | 8 ++++----
21
1 file changed, 25 insertions(+), 19 deletions(-)
14
1 file changed, 4 insertions(+), 4 deletions(-)
22
15
23
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
16
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
24
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/csr.c
18
--- a/hw/intc/riscv_aplic.c
26
+++ b/target/riscv/csr.c
19
+++ b/hw/intc/riscv_aplic.c
27
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
20
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
28
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
21
qdev_prop_set_bit(dev, "msimode", msimode);
29
int read_only = get_field(csrno, 0xC00) == 3;
22
qdev_prop_set_bit(dev, "mmode", mmode);
30
int csr_min_priv = csr_ops[csrno].min_priv_ver;
23
31
+
24
+ if (parent) {
32
+ /* ensure the CSR extension is enabled. */
25
+ riscv_aplic_add_child(parent, dev);
33
+ if (!cpu->cfg.ext_icsr) {
34
+ return RISCV_EXCP_ILLEGAL_INST;
35
+ }
26
+ }
36
+
27
+
37
+ if (env->priv_ver < csr_min_priv) {
28
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
38
+ return RISCV_EXCP_ILLEGAL_INST;
29
39
+ }
30
if (!is_kvm_aia(msimode)) {
40
+
31
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
41
+ /* check predicate */
42
+ if (!csr_ops[csrno].predicate) {
43
+ return RISCV_EXCP_ILLEGAL_INST;
44
+ }
45
+
46
+ if (write_mask && read_only) {
47
+ return RISCV_EXCP_ILLEGAL_INST;
48
+ }
49
+
50
+ RISCVException ret = csr_ops[csrno].predicate(env, csrno);
51
+ if (ret != RISCV_EXCP_NONE) {
52
+ return ret;
53
+ }
54
+
55
#if !defined(CONFIG_USER_ONLY)
56
int csr_priv, effective_priv = env->priv;
57
58
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
59
return RISCV_EXCP_ILLEGAL_INST;
60
}
32
}
61
#endif
33
62
- if (write_mask && read_only) {
34
- if (parent) {
63
- return RISCV_EXCP_ILLEGAL_INST;
35
- riscv_aplic_add_child(parent, dev);
64
- }
36
- }
65
-
37
-
66
- /* ensure the CSR extension is enabled. */
38
if (!msimode) {
67
- if (!cpu->cfg.ext_icsr) {
39
for (i = 0; i < num_harts; i++) {
68
- return RISCV_EXCP_ILLEGAL_INST;
40
CPUState *cpu = cpu_by_arch_id(hartid_base + i);
69
- }
70
-
71
- /* check predicate */
72
- if (!csr_ops[csrno].predicate) {
73
- return RISCV_EXCP_ILLEGAL_INST;
74
- }
75
-
76
- if (env->priv_ver < csr_min_priv) {
77
- return RISCV_EXCP_ILLEGAL_INST;
78
- }
79
-
80
- return csr_ops[csrno].predicate(env, csrno);
81
+ return RISCV_EXCP_NONE;
82
}
83
84
static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
85
--
41
--
86
2.37.2
42
2.45.1
diff view generated by jsdifflib
1
From: Atish Patra <atishp@rivosinc.com>
1
From: Andrew Jones <ajones@ventanamicro.com>
2
2
3
The Sscofpmf ('Ss' for Privileged arch and Supervisor-level extensions,
3
The Zkr extension may only be exposed to KVM guests if the VMM
4
and 'cofpmf' for Count OverFlow and Privilege Mode Filtering)
4
implements the SEED CSR. Use the same implementation as TCG.
5
extension allows the perf to handle overflow interrupts and filtering
6
support. This patch provides a framework for programmable
7
counters to leverage the extension. As the extension doesn't have any
8
provision for the overflow bit for fixed counters, the fixed events
9
can also be monitoring using programmable counters. The underlying
10
counters for cycle and instruction counters are always running. Thus,
11
a separate timer device is programmed to handle the overflow.
12
5
13
Tested-by: Heiko Stuebner <heiko@sntech.de>
6
Without this patch, running with a KVM which does not forward the
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
SEED CSR access to QEMU will result in an ILL exception being
15
Signed-off-by: Atish Patra <atish.patra@wdc.com>
8
injected into the guest (this results in Linux guests crashing on
16
Signed-off-by: Atish Patra <atishp@rivosinc.com>
9
boot). And, when running with a KVM which does forward the access,
17
Message-Id: <20220824221701.41932-2-atishp@rivosinc.com>
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>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
18
---
20
target/riscv/cpu.h | 25 +++
19
target/riscv/cpu.h | 3 +++
21
target/riscv/cpu_bits.h | 55 ++++++
20
target/riscv/csr.c | 18 ++++++++++++++----
22
target/riscv/pmu.h | 7 +
21
target/riscv/kvm/kvm-cpu.c | 25 +++++++++++++++++++++++++
23
target/riscv/cpu.c | 12 ++
22
3 files changed, 42 insertions(+), 4 deletions(-)
24
target/riscv/csr.c | 166 +++++++++++++++++-
25
target/riscv/machine.c | 1 +
26
target/riscv/pmu.c | 368 +++++++++++++++++++++++++++++++++++++++-
27
7 files changed, 623 insertions(+), 11 deletions(-)
28
23
29
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
30
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu.h
26
--- a/target/riscv/cpu.h
32
+++ b/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
33
@@ -XXX,XX +XXX,XX @@ typedef struct PMUCTRState {
28
@@ -XXX,XX +XXX,XX @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
34
/* Snapshort value of a counter in RV32 */
29
35
target_ulong mhpmcounterh_prev;
30
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
36
bool started;
31
37
+ /* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt trigger */
32
+target_ulong riscv_new_csr_seed(target_ulong new_value,
38
+ target_ulong irq_overflow_left;
33
+ target_ulong write_mask);
39
} PMUCTRState;
40
41
struct CPUArchState {
42
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
43
/* PMU event selector configured values. First three are unused*/
44
target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
45
46
+ /* PMU event selector configured values for RV32*/
47
+ target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
48
+
34
+
49
target_ulong sscratch;
35
uint8_t satp_mode_max_from_map(uint32_t map);
50
target_ulong mscratch;
36
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
51
37
52
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
53
bool ext_zmmul;
54
bool ext_smaia;
55
bool ext_ssaia;
56
+ bool ext_sscofpmf;
57
bool rvv_ta_all_1s;
58
bool rvv_ma_all_1s;
59
60
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
61
62
/* Configuration Settings */
63
RISCVCPUConfig cfg;
64
+
65
+ QEMUTimer *pmu_timer;
66
+ /* A bitmask of Available programmable counters */
67
+ uint32_t pmu_avail_ctrs;
68
+ /* Mapping of events to counters */
69
+ GHashTable *pmu_event_ctr_map;
70
};
71
72
static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
73
@@ -XXX,XX +XXX,XX @@ enum {
74
CSR_TABLE_SIZE = 0x1000
75
};
76
77
+/**
78
+ * The event id are encoded based on the encoding specified in the
79
+ * SBI specification v0.3
80
+ */
81
+
82
+enum riscv_pmu_event_idx {
83
+ RISCV_PMU_EVENT_HW_CPU_CYCLES = 0x01,
84
+ RISCV_PMU_EVENT_HW_INSTRUCTIONS = 0x02,
85
+ RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS = 0x10019,
86
+ RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS = 0x1001B,
87
+ RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS = 0x10021,
88
+};
89
+
90
/* CSR function table */
91
extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
92
93
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
94
index XXXXXXX..XXXXXXX 100644
95
--- a/target/riscv/cpu_bits.h
96
+++ b/target/riscv/cpu_bits.h
97
@@ -XXX,XX +XXX,XX @@
98
#define CSR_MHPMEVENT29 0x33d
99
#define CSR_MHPMEVENT30 0x33e
100
#define CSR_MHPMEVENT31 0x33f
101
+
102
+#define CSR_MHPMEVENT3H 0x723
103
+#define CSR_MHPMEVENT4H 0x724
104
+#define CSR_MHPMEVENT5H 0x725
105
+#define CSR_MHPMEVENT6H 0x726
106
+#define CSR_MHPMEVENT7H 0x727
107
+#define CSR_MHPMEVENT8H 0x728
108
+#define CSR_MHPMEVENT9H 0x729
109
+#define CSR_MHPMEVENT10H 0x72a
110
+#define CSR_MHPMEVENT11H 0x72b
111
+#define CSR_MHPMEVENT12H 0x72c
112
+#define CSR_MHPMEVENT13H 0x72d
113
+#define CSR_MHPMEVENT14H 0x72e
114
+#define CSR_MHPMEVENT15H 0x72f
115
+#define CSR_MHPMEVENT16H 0x730
116
+#define CSR_MHPMEVENT17H 0x731
117
+#define CSR_MHPMEVENT18H 0x732
118
+#define CSR_MHPMEVENT19H 0x733
119
+#define CSR_MHPMEVENT20H 0x734
120
+#define CSR_MHPMEVENT21H 0x735
121
+#define CSR_MHPMEVENT22H 0x736
122
+#define CSR_MHPMEVENT23H 0x737
123
+#define CSR_MHPMEVENT24H 0x738
124
+#define CSR_MHPMEVENT25H 0x739
125
+#define CSR_MHPMEVENT26H 0x73a
126
+#define CSR_MHPMEVENT27H 0x73b
127
+#define CSR_MHPMEVENT28H 0x73c
128
+#define CSR_MHPMEVENT29H 0x73d
129
+#define CSR_MHPMEVENT30H 0x73e
130
+#define CSR_MHPMEVENT31H 0x73f
131
+
132
#define CSR_MHPMCOUNTER3H 0xb83
133
#define CSR_MHPMCOUNTER4H 0xb84
134
#define CSR_MHPMCOUNTER5H 0xb85
135
@@ -XXX,XX +XXX,XX @@
136
#define CSR_VSMTE 0x2c0
137
#define CSR_VSPMMASK 0x2c1
138
#define CSR_VSPMBASE 0x2c2
139
+#define CSR_SCOUNTOVF 0xda0
140
141
/* Crypto Extension */
142
#define CSR_SEED 0x015
143
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
144
#define IRQ_VS_EXT 10
145
#define IRQ_M_EXT 11
146
#define IRQ_S_GEXT 12
147
+#define IRQ_PMU_OVF 13
148
#define IRQ_LOCAL_MAX 16
149
#define IRQ_LOCAL_GUEST_MAX (TARGET_LONG_BITS - 1)
150
151
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
152
#define MIP_VSEIP (1 << IRQ_VS_EXT)
153
#define MIP_MEIP (1 << IRQ_M_EXT)
154
#define MIP_SGEIP (1 << IRQ_S_GEXT)
155
+#define MIP_LCOFIP (1 << IRQ_PMU_OVF)
156
157
/* sip masks */
158
#define SIP_SSIP MIP_SSIP
159
#define SIP_STIP MIP_STIP
160
#define SIP_SEIP MIP_SEIP
161
+#define SIP_LCOFIP MIP_LCOFIP
162
163
/* MIE masks */
164
#define MIE_SEIE (1 << IRQ_S_EXT)
165
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
166
#define SEED_OPST_WAIT (0b01 << 30)
167
#define SEED_OPST_ES16 (0b10 << 30)
168
#define SEED_OPST_DEAD (0b11 << 30)
169
+/* PMU related bits */
170
+#define MIE_LCOFIE (1 << IRQ_PMU_OVF)
171
+
172
+#define MHPMEVENT_BIT_OF BIT_ULL(63)
173
+#define MHPMEVENTH_BIT_OF BIT(31)
174
+#define MHPMEVENT_BIT_MINH BIT_ULL(62)
175
+#define MHPMEVENTH_BIT_MINH BIT(30)
176
+#define MHPMEVENT_BIT_SINH BIT_ULL(61)
177
+#define MHPMEVENTH_BIT_SINH BIT(29)
178
+#define MHPMEVENT_BIT_UINH BIT_ULL(60)
179
+#define MHPMEVENTH_BIT_UINH BIT(28)
180
+#define MHPMEVENT_BIT_VSINH BIT_ULL(59)
181
+#define MHPMEVENTH_BIT_VSINH BIT(27)
182
+#define MHPMEVENT_BIT_VUINH BIT_ULL(58)
183
+#define MHPMEVENTH_BIT_VUINH BIT(26)
184
+
185
+#define MHPMEVENT_SSCOF_MASK _ULL(0xFFFF000000000000)
186
+#define MHPMEVENT_IDX_MASK 0xFFFFF
187
+#define MHPMEVENT_SSCOF_RESVD 16
188
+
189
#endif
190
diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
191
index XXXXXXX..XXXXXXX 100644
192
--- a/target/riscv/pmu.h
193
+++ b/target/riscv/pmu.h
194
@@ -XXX,XX +XXX,XX @@ bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env,
195
uint32_t target_ctr);
196
bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env,
197
uint32_t target_ctr);
198
+void riscv_pmu_timer_cb(void *priv);
199
+int riscv_pmu_init(RISCVCPU *cpu, int num_counters);
200
+int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
201
+ uint32_t ctr_idx);
202
+int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx);
203
+int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value,
204
+ uint32_t ctr_idx);
205
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
206
index XXXXXXX..XXXXXXX 100644
207
--- a/target/riscv/cpu.c
208
+++ b/target/riscv/cpu.c
209
@@ -XXX,XX +XXX,XX @@
210
#include "qemu/ctype.h"
211
#include "qemu/log.h"
212
#include "cpu.h"
213
+#include "pmu.h"
214
#include "internals.h"
215
#include "time_helper.h"
216
#include "exec/exec-all.h"
217
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
218
ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
219
ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
220
ISA_EXT_DATA_ENTRY(ssaia, true, PRIV_VERSION_1_12_0, ext_ssaia),
221
+ ISA_EXT_DATA_ENTRY(sscofpmf, true, PRIV_VERSION_1_12_0, ext_sscofpmf),
222
ISA_EXT_DATA_ENTRY(sstc, true, PRIV_VERSION_1_12_0, ext_sstc),
223
ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
224
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
225
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
226
set_misa(env, env->misa_mxl, ext);
227
}
228
229
+#ifndef CONFIG_USER_ONLY
230
+ if (cpu->cfg.pmu_num) {
231
+ if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) {
232
+ cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
233
+ riscv_pmu_timer_cb, cpu);
234
+ }
235
+ }
236
+#endif
237
+
238
riscv_cpu_register_gdb_regs_for_features(cs);
239
240
qemu_init_vcpu(cs);
241
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
242
DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
243
DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, true),
244
DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
245
+ DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
246
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
247
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
248
DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
249
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
250
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
251
--- a/target/riscv/csr.c
40
--- a/target/riscv/csr.c
252
+++ b/target/riscv/csr.c
41
+++ b/target/riscv/csr.c
253
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
42
@@ -XXX,XX +XXX,XX @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
254
CPUState *cs = env_cpu(env);
43
#endif
255
RISCVCPU *cpu = RISCV_CPU(cs);
44
256
int ctr_index;
45
/* Crypto Extension */
257
- int base_csrno = CSR_HPMCOUNTER3;
46
-static RISCVException rmw_seed(CPURISCVState *env, int csrno,
258
+ int base_csrno = CSR_CYCLE;
47
- target_ulong *ret_value,
259
bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
48
- target_ulong new_value,
260
49
- target_ulong write_mask)
261
if (rv32 && csrno >= CSR_CYCLEH) {
50
+target_ulong riscv_new_csr_seed(target_ulong new_value,
262
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
51
+ target_ulong write_mask)
52
{
53
uint16_t random_v;
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;
263
}
57
}
264
ctr_index = csrno - base_csrno;
58
265
59
+ return rval;
266
- if (!cpu->cfg.pmu_num || ctr_index >= (cpu->cfg.pmu_num)) {
267
+ if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
268
+ (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
269
+ goto skip_ext_pmu_check;
270
+ }
271
+
272
+ if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & BIT(ctr_index)))) {
273
/* No counter is enabled in PMU or the counter is out of range */
274
return RISCV_EXCP_ILLEGAL_INST;
275
}
276
277
+skip_ext_pmu_check:
278
+
279
if (env->priv == PRV_S) {
280
switch (csrno) {
281
case CSR_CYCLE:
282
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
283
}
284
break;
285
case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
286
- ctr_index = csrno - CSR_CYCLE;
287
if (!get_field(env->mcounteren, 1 << ctr_index)) {
288
return RISCV_EXCP_ILLEGAL_INST;
289
}
290
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
291
}
292
break;
293
case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
294
- ctr_index = csrno - CSR_CYCLEH;
295
if (!get_field(env->mcounteren, 1 << ctr_index)) {
296
return RISCV_EXCP_ILLEGAL_INST;
297
}
298
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
299
}
300
break;
301
case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
302
- ctr_index = csrno - CSR_CYCLE;
303
if (!get_field(env->hcounteren, 1 << ctr_index) &&
304
get_field(env->mcounteren, 1 << ctr_index)) {
305
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
306
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
307
}
308
break;
309
case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
310
- ctr_index = csrno - CSR_CYCLEH;
311
if (!get_field(env->hcounteren, 1 << ctr_index) &&
312
get_field(env->mcounteren, 1 << ctr_index)) {
313
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
314
@@ -XXX,XX +XXX,XX @@ static RISCVException mctr32(CPURISCVState *env, int csrno)
315
return mctr(env, csrno);
316
}
317
318
+static RISCVException sscofpmf(CPURISCVState *env, int csrno)
319
+{
320
+ CPUState *cs = env_cpu(env);
321
+ RISCVCPU *cpu = RISCV_CPU(cs);
322
+
323
+ if (!cpu->cfg.ext_sscofpmf) {
324
+ return RISCV_EXCP_ILLEGAL_INST;
325
+ }
326
+
327
+ return RISCV_EXCP_NONE;
328
+}
60
+}
329
+
61
+
330
static RISCVException any(CPURISCVState *env, int csrno)
62
+static RISCVException rmw_seed(CPURISCVState *env, int csrno,
331
{
63
+ target_ulong *ret_value,
332
return RISCV_EXCP_NONE;
64
+ target_ulong new_value,
333
@@ -XXX,XX +XXX,XX @@ static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
65
+ target_ulong write_mask)
334
static int write_mhpmevent(CPURISCVState *env, int csrno, target_ulong val)
66
+{
335
{
67
+ target_ulong rval;
336
int evt_index = csrno - CSR_MCOUNTINHIBIT;
337
+ uint64_t mhpmevt_val = val;
338
339
env->mhpmevent_val[evt_index] = val;
340
341
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
342
+ mhpmevt_val = mhpmevt_val |
343
+ ((uint64_t)env->mhpmeventh_val[evt_index] << 32);
344
+ }
345
+ riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
346
+
68
+
347
+ return RISCV_EXCP_NONE;
69
+ rval = riscv_new_csr_seed(new_value, write_mask);
348
+}
349
+
70
+
350
+static int read_mhpmeventh(CPURISCVState *env, int csrno, target_ulong *val)
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;
80
}
81
82
+static int kvm_riscv_handle_csr(CPUState *cs, struct kvm_run *run)
351
+{
83
+{
352
+ int evt_index = csrno - CSR_MHPMEVENT3H + 3;
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;
353
+
88
+
354
+ *val = env->mhpmeventh_val[evt_index];
89
+ switch (csr_num) {
355
+
90
+ case CSR_SEED:
356
+ return RISCV_EXCP_NONE;
91
+ run->riscv_csr.ret_value = riscv_new_csr_seed(new_value, write_mask);
357
+}
92
+ break;
358
+
93
+ default:
359
+static int write_mhpmeventh(CPURISCVState *env, int csrno, target_ulong val)
94
+ qemu_log_mask(LOG_UNIMP,
360
+{
95
+ "%s: un-handled CSR EXIT for CSR %lx\n",
361
+ int evt_index = csrno - CSR_MHPMEVENT3H + 3;
96
+ __func__, csr_num);
362
+ uint64_t mhpmevth_val = val;
97
+ ret = -1;
363
+ uint64_t mhpmevt_val = env->mhpmevent_val[evt_index];
98
+ break;
364
+
365
+ mhpmevt_val = mhpmevt_val | (mhpmevth_val << 32);
366
+ env->mhpmeventh_val[evt_index] = val;
367
+
368
+ riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
369
+
370
return RISCV_EXCP_NONE;
371
}
372
373
@@ -XXX,XX +XXX,XX @@ static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val)
374
{
375
int ctr_idx = csrno - CSR_MCYCLE;
376
PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
377
+ uint64_t mhpmctr_val = val;
378
379
counter->mhpmcounter_val = val;
380
if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
381
riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
382
counter->mhpmcounter_prev = get_ticks(false);
383
- } else {
384
+ if (ctr_idx > 2) {
385
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
386
+ mhpmctr_val = mhpmctr_val |
387
+ ((uint64_t)counter->mhpmcounterh_val << 32);
388
+ }
389
+ riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
390
+ }
391
+ } else {
392
/* Other counters can keep incrementing from the given value */
393
counter->mhpmcounter_prev = val;
394
}
395
@@ -XXX,XX +XXX,XX @@ static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val)
396
{
397
int ctr_idx = csrno - CSR_MCYCLEH;
398
PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
399
+ uint64_t mhpmctr_val = counter->mhpmcounter_val;
400
+ uint64_t mhpmctrh_val = val;
401
402
counter->mhpmcounterh_val = val;
403
+ mhpmctr_val = mhpmctr_val | (mhpmctrh_val << 32);
404
if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
405
riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
406
counter->mhpmcounterh_prev = get_ticks(true);
407
+ if (ctr_idx > 2) {
408
+ riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
409
+ }
410
} else {
411
counter->mhpmcounterh_prev = val;
412
}
413
@@ -XXX,XX +XXX,XX @@ static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val)
414
return riscv_pmu_read_ctr(env, val, true, ctr_index);
415
}
416
417
+static int read_scountovf(CPURISCVState *env, int csrno, target_ulong *val)
418
+{
419
+ int mhpmevt_start = CSR_MHPMEVENT3 - CSR_MCOUNTINHIBIT;
420
+ int i;
421
+ *val = 0;
422
+ target_ulong *mhpm_evt_val;
423
+ uint64_t of_bit_mask;
424
+
425
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
426
+ mhpm_evt_val = env->mhpmeventh_val;
427
+ of_bit_mask = MHPMEVENTH_BIT_OF;
428
+ } else {
429
+ mhpm_evt_val = env->mhpmevent_val;
430
+ of_bit_mask = MHPMEVENT_BIT_OF;
431
+ }
432
+
433
+ for (i = mhpmevt_start; i < RV_MAX_MHPMEVENTS; i++) {
434
+ if ((get_field(env->mcounteren, BIT(i))) &&
435
+ (mhpm_evt_val[i] & of_bit_mask)) {
436
+ *val |= BIT(i);
437
+ }
438
+ }
439
+
440
+ return RISCV_EXCP_NONE;
441
+}
442
+
443
static RISCVException read_time(CPURISCVState *env, int csrno,
444
target_ulong *val)
445
{
446
@@ -XXX,XX +XXX,XX @@ static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
447
/* Machine constants */
448
449
#define M_MODE_INTERRUPTS ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP))
450
-#define S_MODE_INTERRUPTS ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP))
451
+#define S_MODE_INTERRUPTS ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP | \
452
+ MIP_LCOFIP))
453
#define VS_MODE_INTERRUPTS ((uint64_t)(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP))
454
#define HS_MODE_INTERRUPTS ((uint64_t)(MIP_SGEIP | VS_MODE_INTERRUPTS))
455
456
@@ -XXX,XX +XXX,XX @@ static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS &
457
static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
458
SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
459
SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
460
-static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
461
+static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP |
462
+ SIP_LCOFIP;
463
static const target_ulong hip_writable_mask = MIP_VSSIP;
464
static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
465
static const target_ulong vsip_writable_mask = MIP_VSSIP;
466
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
467
[CSR_MHPMEVENT31] = { "mhpmevent31", any, read_mhpmevent,
468
write_mhpmevent },
469
470
+ [CSR_MHPMEVENT3H] = { "mhpmevent3h", sscofpmf, read_mhpmeventh,
471
+ write_mhpmeventh },
472
+ [CSR_MHPMEVENT4H] = { "mhpmevent4h", sscofpmf, read_mhpmeventh,
473
+ write_mhpmeventh },
474
+ [CSR_MHPMEVENT5H] = { "mhpmevent5h", sscofpmf, read_mhpmeventh,
475
+ write_mhpmeventh },
476
+ [CSR_MHPMEVENT6H] = { "mhpmevent6h", sscofpmf, read_mhpmeventh,
477
+ write_mhpmeventh },
478
+ [CSR_MHPMEVENT7H] = { "mhpmevent7h", sscofpmf, read_mhpmeventh,
479
+ write_mhpmeventh },
480
+ [CSR_MHPMEVENT8H] = { "mhpmevent8h", sscofpmf, read_mhpmeventh,
481
+ write_mhpmeventh },
482
+ [CSR_MHPMEVENT9H] = { "mhpmevent9h", sscofpmf, read_mhpmeventh,
483
+ write_mhpmeventh },
484
+ [CSR_MHPMEVENT10H] = { "mhpmevent10h", sscofpmf, read_mhpmeventh,
485
+ write_mhpmeventh },
486
+ [CSR_MHPMEVENT11H] = { "mhpmevent11h", sscofpmf, read_mhpmeventh,
487
+ write_mhpmeventh },
488
+ [CSR_MHPMEVENT12H] = { "mhpmevent12h", sscofpmf, read_mhpmeventh,
489
+ write_mhpmeventh },
490
+ [CSR_MHPMEVENT13H] = { "mhpmevent13h", sscofpmf, read_mhpmeventh,
491
+ write_mhpmeventh },
492
+ [CSR_MHPMEVENT14H] = { "mhpmevent14h", sscofpmf, read_mhpmeventh,
493
+ write_mhpmeventh },
494
+ [CSR_MHPMEVENT15H] = { "mhpmevent15h", sscofpmf, read_mhpmeventh,
495
+ write_mhpmeventh },
496
+ [CSR_MHPMEVENT16H] = { "mhpmevent16h", sscofpmf, read_mhpmeventh,
497
+ write_mhpmeventh },
498
+ [CSR_MHPMEVENT17H] = { "mhpmevent17h", sscofpmf, read_mhpmeventh,
499
+ write_mhpmeventh },
500
+ [CSR_MHPMEVENT18H] = { "mhpmevent18h", sscofpmf, read_mhpmeventh,
501
+ write_mhpmeventh },
502
+ [CSR_MHPMEVENT19H] = { "mhpmevent19h", sscofpmf, read_mhpmeventh,
503
+ write_mhpmeventh },
504
+ [CSR_MHPMEVENT20H] = { "mhpmevent20h", sscofpmf, read_mhpmeventh,
505
+ write_mhpmeventh },
506
+ [CSR_MHPMEVENT21H] = { "mhpmevent21h", sscofpmf, read_mhpmeventh,
507
+ write_mhpmeventh },
508
+ [CSR_MHPMEVENT22H] = { "mhpmevent22h", sscofpmf, read_mhpmeventh,
509
+ write_mhpmeventh },
510
+ [CSR_MHPMEVENT23H] = { "mhpmevent23h", sscofpmf, read_mhpmeventh,
511
+ write_mhpmeventh },
512
+ [CSR_MHPMEVENT24H] = { "mhpmevent24h", sscofpmf, read_mhpmeventh,
513
+ write_mhpmeventh },
514
+ [CSR_MHPMEVENT25H] = { "mhpmevent25h", sscofpmf, read_mhpmeventh,
515
+ write_mhpmeventh },
516
+ [CSR_MHPMEVENT26H] = { "mhpmevent26h", sscofpmf, read_mhpmeventh,
517
+ write_mhpmeventh },
518
+ [CSR_MHPMEVENT27H] = { "mhpmevent27h", sscofpmf, read_mhpmeventh,
519
+ write_mhpmeventh },
520
+ [CSR_MHPMEVENT28H] = { "mhpmevent28h", sscofpmf, read_mhpmeventh,
521
+ write_mhpmeventh },
522
+ [CSR_MHPMEVENT29H] = { "mhpmevent29h", sscofpmf, read_mhpmeventh,
523
+ write_mhpmeventh },
524
+ [CSR_MHPMEVENT30H] = { "mhpmevent30h", sscofpmf, read_mhpmeventh,
525
+ write_mhpmeventh },
526
+ [CSR_MHPMEVENT31H] = { "mhpmevent31h", sscofpmf, read_mhpmeventh,
527
+ write_mhpmeventh },
528
+
529
[CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_hpmcounterh },
530
[CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_hpmcounterh },
531
[CSR_HPMCOUNTER5H] = { "hpmcounter5h", ctr32, read_hpmcounterh },
532
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
533
write_mhpmcounterh },
534
[CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32, read_hpmcounterh,
535
write_mhpmcounterh },
536
+ [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf },
537
+
538
#endif /* !CONFIG_USER_ONLY */
539
};
540
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
541
index XXXXXXX..XXXXXXX 100644
542
--- a/target/riscv/machine.c
543
+++ b/target/riscv/machine.c
544
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
545
VMSTATE_STRUCT_ARRAY(env.pmu_ctrs, RISCVCPU, RV_MAX_MHPMCOUNTERS, 0,
546
vmstate_pmu_ctr_state, PMUCTRState),
547
VMSTATE_UINTTL_ARRAY(env.mhpmevent_val, RISCVCPU, RV_MAX_MHPMEVENTS),
548
+ VMSTATE_UINTTL_ARRAY(env.mhpmeventh_val, RISCVCPU, RV_MAX_MHPMEVENTS),
549
VMSTATE_UINTTL(env.sscratch, RISCVCPU),
550
VMSTATE_UINTTL(env.mscratch, RISCVCPU),
551
VMSTATE_UINT64(env.mfromhost, RISCVCPU),
552
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
553
index XXXXXXX..XXXXXXX 100644
554
--- a/target/riscv/pmu.c
555
+++ b/target/riscv/pmu.c
556
@@ -XXX,XX +XXX,XX @@
557
#include "qemu/osdep.h"
558
#include "cpu.h"
559
#include "pmu.h"
560
+#include "sysemu/cpu-timers.h"
561
+
562
+#define RISCV_TIMEBASE_FREQ 1000000000 /* 1Ghz */
563
+#define MAKE_32BIT_MASK(shift, length) \
564
+ (((uint32_t)(~0UL) >> (32 - (length))) << (shift))
565
+
566
+static bool riscv_pmu_counter_valid(RISCVCPU *cpu, uint32_t ctr_idx)
567
+{
568
+ if (ctr_idx < 3 || ctr_idx >= RV_MAX_MHPMCOUNTERS ||
569
+ !(cpu->pmu_avail_ctrs & BIT(ctr_idx))) {
570
+ return false;
571
+ } else {
572
+ return true;
573
+ }
574
+}
575
+
576
+static bool riscv_pmu_counter_enabled(RISCVCPU *cpu, uint32_t ctr_idx)
577
+{
578
+ CPURISCVState *env = &cpu->env;
579
+
580
+ if (riscv_pmu_counter_valid(cpu, ctr_idx) &&
581
+ !get_field(env->mcountinhibit, BIT(ctr_idx))) {
582
+ return true;
583
+ } else {
584
+ return false;
585
+ }
586
+}
587
+
588
+static int riscv_pmu_incr_ctr_rv32(RISCVCPU *cpu, uint32_t ctr_idx)
589
+{
590
+ CPURISCVState *env = &cpu->env;
591
+ target_ulong max_val = UINT32_MAX;
592
+ PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
593
+ bool virt_on = riscv_cpu_virt_enabled(env);
594
+
595
+ /* Privilege mode filtering */
596
+ if ((env->priv == PRV_M &&
597
+ (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_MINH)) ||
598
+ (env->priv == PRV_S && virt_on &&
599
+ (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_VSINH)) ||
600
+ (env->priv == PRV_U && virt_on &&
601
+ (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_VUINH)) ||
602
+ (env->priv == PRV_S && !virt_on &&
603
+ (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_SINH)) ||
604
+ (env->priv == PRV_U && !virt_on &&
605
+ (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_UINH))) {
606
+ return 0;
607
+ }
608
+
609
+ /* Handle the overflow scenario */
610
+ if (counter->mhpmcounter_val == max_val) {
611
+ if (counter->mhpmcounterh_val == max_val) {
612
+ counter->mhpmcounter_val = 0;
613
+ counter->mhpmcounterh_val = 0;
614
+ /* Generate interrupt only if OF bit is clear */
615
+ if (!(env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_OF)) {
616
+ env->mhpmeventh_val[ctr_idx] |= MHPMEVENTH_BIT_OF;
617
+ riscv_cpu_update_mip(cpu, MIP_LCOFIP, BOOL_TO_MASK(1));
618
+ }
619
+ } else {
620
+ counter->mhpmcounterh_val++;
621
+ }
622
+ } else {
623
+ counter->mhpmcounter_val++;
624
+ }
625
+
626
+ return 0;
627
+}
628
+
629
+static int riscv_pmu_incr_ctr_rv64(RISCVCPU *cpu, uint32_t ctr_idx)
630
+{
631
+ CPURISCVState *env = &cpu->env;
632
+ PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
633
+ uint64_t max_val = UINT64_MAX;
634
+ bool virt_on = riscv_cpu_virt_enabled(env);
635
+
636
+ /* Privilege mode filtering */
637
+ if ((env->priv == PRV_M &&
638
+ (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_MINH)) ||
639
+ (env->priv == PRV_S && virt_on &&
640
+ (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_VSINH)) ||
641
+ (env->priv == PRV_U && virt_on &&
642
+ (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_VUINH)) ||
643
+ (env->priv == PRV_S && !virt_on &&
644
+ (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_SINH)) ||
645
+ (env->priv == PRV_U && !virt_on &&
646
+ (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_UINH))) {
647
+ return 0;
648
+ }
649
+
650
+ /* Handle the overflow scenario */
651
+ if (counter->mhpmcounter_val == max_val) {
652
+ counter->mhpmcounter_val = 0;
653
+ /* Generate interrupt only if OF bit is clear */
654
+ if (!(env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_OF)) {
655
+ env->mhpmevent_val[ctr_idx] |= MHPMEVENT_BIT_OF;
656
+ riscv_cpu_update_mip(cpu, MIP_LCOFIP, BOOL_TO_MASK(1));
657
+ }
658
+ } else {
659
+ counter->mhpmcounter_val++;
660
+ }
661
+ return 0;
662
+}
663
+
664
+int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx)
665
+{
666
+ uint32_t ctr_idx;
667
+ int ret;
668
+ CPURISCVState *env = &cpu->env;
669
+ gpointer value;
670
+
671
+ if (!cpu->cfg.pmu_num) {
672
+ return 0;
673
+ }
674
+ value = g_hash_table_lookup(cpu->pmu_event_ctr_map,
675
+ GUINT_TO_POINTER(event_idx));
676
+ if (!value) {
677
+ return -1;
678
+ }
679
+
680
+ ctr_idx = GPOINTER_TO_UINT(value);
681
+ if (!riscv_pmu_counter_enabled(cpu, ctr_idx) ||
682
+ get_field(env->mcountinhibit, BIT(ctr_idx))) {
683
+ return -1;
684
+ }
685
+
686
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
687
+ ret = riscv_pmu_incr_ctr_rv32(cpu, ctr_idx);
688
+ } else {
689
+ ret = riscv_pmu_incr_ctr_rv64(cpu, ctr_idx);
690
+ }
691
+
692
+ return ret;
693
+}
694
695
bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env,
696
uint32_t target_ctr)
697
{
698
- return (target_ctr == 0) ? true : false;
699
+ RISCVCPU *cpu;
700
+ uint32_t event_idx;
701
+ uint32_t ctr_idx;
702
+
703
+ /* Fixed instret counter */
704
+ if (target_ctr == 2) {
705
+ return true;
706
+ }
707
+
708
+ cpu = RISCV_CPU(env_cpu(env));
709
+ if (!cpu->pmu_event_ctr_map) {
710
+ return false;
711
+ }
712
+
713
+ event_idx = RISCV_PMU_EVENT_HW_INSTRUCTIONS;
714
+ ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map,
715
+ GUINT_TO_POINTER(event_idx)));
716
+ if (!ctr_idx) {
717
+ return false;
718
+ }
719
+
720
+ return target_ctr == ctr_idx ? true : false;
721
}
722
723
bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env, uint32_t target_ctr)
724
{
725
- return (target_ctr == 2) ? true : false;
726
+ RISCVCPU *cpu;
727
+ uint32_t event_idx;
728
+ uint32_t ctr_idx;
729
+
730
+ /* Fixed mcycle counter */
731
+ if (target_ctr == 0) {
732
+ return true;
733
+ }
734
+
735
+ cpu = RISCV_CPU(env_cpu(env));
736
+ if (!cpu->pmu_event_ctr_map) {
737
+ return false;
738
+ }
739
+
740
+ event_idx = RISCV_PMU_EVENT_HW_CPU_CYCLES;
741
+ ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map,
742
+ GUINT_TO_POINTER(event_idx)));
743
+
744
+ /* Counter zero is not used for event_ctr_map */
745
+ if (!ctr_idx) {
746
+ return false;
747
+ }
748
+
749
+ return (target_ctr == ctr_idx) ? true : false;
750
+}
751
+
752
+static gboolean pmu_remove_event_map(gpointer key, gpointer value,
753
+ gpointer udata)
754
+{
755
+ return (GPOINTER_TO_UINT(value) == GPOINTER_TO_UINT(udata)) ? true : false;
756
+}
757
+
758
+static int64_t pmu_icount_ticks_to_ns(int64_t value)
759
+{
760
+ int64_t ret = 0;
761
+
762
+ if (icount_enabled()) {
763
+ ret = icount_to_ns(value);
764
+ } else {
765
+ ret = (NANOSECONDS_PER_SECOND / RISCV_TIMEBASE_FREQ) * value;
766
+ }
99
+ }
767
+
100
+
768
+ return ret;
101
+ return ret;
769
+}
102
+}
770
+
103
+
771
+int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
104
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
772
+ uint32_t ctr_idx)
105
{
773
+{
106
int ret = 0;
774
+ uint32_t event_idx;
107
@@ -XXX,XX +XXX,XX @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
775
+ RISCVCPU *cpu = RISCV_CPU(env_cpu(env));
108
case KVM_EXIT_RISCV_SBI:
776
+
109
ret = kvm_riscv_handle_sbi(cs, run);
777
+ if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->pmu_event_ctr_map) {
110
break;
778
+ return -1;
111
+ case KVM_EXIT_RISCV_CSR:
779
+ }
112
+ ret = kvm_riscv_handle_csr(cs, run);
780
+
781
+ /*
782
+ * Expected mhpmevent value is zero for reset case. Remove the current
783
+ * mapping.
784
+ */
785
+ if (!value) {
786
+ g_hash_table_foreach_remove(cpu->pmu_event_ctr_map,
787
+ pmu_remove_event_map,
788
+ GUINT_TO_POINTER(ctr_idx));
789
+ return 0;
790
+ }
791
+
792
+ event_idx = value & MHPMEVENT_IDX_MASK;
793
+ if (g_hash_table_lookup(cpu->pmu_event_ctr_map,
794
+ GUINT_TO_POINTER(event_idx))) {
795
+ return 0;
796
+ }
797
+
798
+ switch (event_idx) {
799
+ case RISCV_PMU_EVENT_HW_CPU_CYCLES:
800
+ case RISCV_PMU_EVENT_HW_INSTRUCTIONS:
801
+ case RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS:
802
+ case RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS:
803
+ case RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS:
804
+ break;
113
+ break;
805
+ default:
114
default:
806
+ /* We don't support any raw events right now */
115
qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
807
+ return -1;
116
__func__, run->exit_reason);
808
+ }
809
+ g_hash_table_insert(cpu->pmu_event_ctr_map, GUINT_TO_POINTER(event_idx),
810
+ GUINT_TO_POINTER(ctr_idx));
811
+
812
+ return 0;
813
+}
814
+
815
+static void pmu_timer_trigger_irq(RISCVCPU *cpu,
816
+ enum riscv_pmu_event_idx evt_idx)
817
+{
818
+ uint32_t ctr_idx;
819
+ CPURISCVState *env = &cpu->env;
820
+ PMUCTRState *counter;
821
+ target_ulong *mhpmevent_val;
822
+ uint64_t of_bit_mask;
823
+ int64_t irq_trigger_at;
824
+
825
+ if (evt_idx != RISCV_PMU_EVENT_HW_CPU_CYCLES &&
826
+ evt_idx != RISCV_PMU_EVENT_HW_INSTRUCTIONS) {
827
+ return;
828
+ }
829
+
830
+ ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map,
831
+ GUINT_TO_POINTER(evt_idx)));
832
+ if (!riscv_pmu_counter_enabled(cpu, ctr_idx)) {
833
+ return;
834
+ }
835
+
836
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
837
+ mhpmevent_val = &env->mhpmeventh_val[ctr_idx];
838
+ of_bit_mask = MHPMEVENTH_BIT_OF;
839
+ } else {
840
+ mhpmevent_val = &env->mhpmevent_val[ctr_idx];
841
+ of_bit_mask = MHPMEVENT_BIT_OF;
842
+ }
843
+
844
+ counter = &env->pmu_ctrs[ctr_idx];
845
+ if (counter->irq_overflow_left > 0) {
846
+ irq_trigger_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
847
+ counter->irq_overflow_left;
848
+ timer_mod_anticipate_ns(cpu->pmu_timer, irq_trigger_at);
849
+ counter->irq_overflow_left = 0;
850
+ return;
851
+ }
852
+
853
+ if (cpu->pmu_avail_ctrs & BIT(ctr_idx)) {
854
+ /* Generate interrupt only if OF bit is clear */
855
+ if (!(*mhpmevent_val & of_bit_mask)) {
856
+ *mhpmevent_val |= of_bit_mask;
857
+ riscv_cpu_update_mip(cpu, MIP_LCOFIP, BOOL_TO_MASK(1));
858
+ }
859
+ }
860
+}
861
+
862
+/* Timer callback for instret and cycle counter overflow */
863
+void riscv_pmu_timer_cb(void *priv)
864
+{
865
+ RISCVCPU *cpu = priv;
866
+
867
+ /* Timer event was triggered only for these events */
868
+ pmu_timer_trigger_irq(cpu, RISCV_PMU_EVENT_HW_CPU_CYCLES);
869
+ pmu_timer_trigger_irq(cpu, RISCV_PMU_EVENT_HW_INSTRUCTIONS);
870
+}
871
+
872
+int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value, uint32_t ctr_idx)
873
+{
874
+ uint64_t overflow_delta, overflow_at;
875
+ int64_t overflow_ns, overflow_left = 0;
876
+ RISCVCPU *cpu = RISCV_CPU(env_cpu(env));
877
+ PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
878
+
879
+ if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->cfg.ext_sscofpmf) {
880
+ return -1;
881
+ }
882
+
883
+ if (value) {
884
+ overflow_delta = UINT64_MAX - value + 1;
885
+ } else {
886
+ overflow_delta = UINT64_MAX;
887
+ }
888
+
889
+ /*
890
+ * QEMU supports only int64_t timers while RISC-V counters are uint64_t.
891
+ * Compute the leftover and save it so that it can be reprogrammed again
892
+ * when timer expires.
893
+ */
894
+ if (overflow_delta > INT64_MAX) {
895
+ overflow_left = overflow_delta - INT64_MAX;
896
+ }
897
+
898
+ if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
899
+ riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
900
+ overflow_ns = pmu_icount_ticks_to_ns((int64_t)overflow_delta);
901
+ overflow_left = pmu_icount_ticks_to_ns(overflow_left) ;
902
+ } else {
903
+ return -1;
904
+ }
905
+ overflow_at = (uint64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + overflow_ns;
906
+
907
+ if (overflow_at > INT64_MAX) {
908
+ overflow_left += overflow_at - INT64_MAX;
909
+ counter->irq_overflow_left = overflow_left;
910
+ overflow_at = INT64_MAX;
911
+ }
912
+ timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
913
+
914
+ return 0;
915
+}
916
+
917
+
918
+int riscv_pmu_init(RISCVCPU *cpu, int num_counters)
919
+{
920
+ if (num_counters > (RV_MAX_MHPMCOUNTERS - 3)) {
921
+ return -1;
922
+ }
923
+
924
+ cpu->pmu_event_ctr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
925
+ if (!cpu->pmu_event_ctr_map) {
926
+ /* PMU support can not be enabled */
927
+ qemu_log_mask(LOG_UNIMP, "PMU events can't be supported\n");
928
+ cpu->cfg.pmu_num = 0;
929
+ return -1;
930
+ }
931
+
932
+ /* Create a bitmask of available programmable counters */
933
+ cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, num_counters);
934
+
935
+ return 0;
936
}
937
--
117
--
938
2.37.2
118
2.45.1
diff view generated by jsdifflib
1
From: Atish Patra <atishp@rivosinc.com>
1
From: Andrew Jones <ajones@ventanamicro.com>
2
2
3
Qemu virt machine can support few cache events and cycle/instret counters.
3
Implementing wrs.nto to always just return is consistent with the
4
It also supports counter overflow for these events.
4
specification, as the instruction is permitted to terminate the
5
stall for any reason, but it's not useful for virtualization, where
6
we'd like the guest to trap to the hypervisor in order to allow
7
scheduling of the lock holding VCPU. Change to always immediately
8
raise exceptions when the appropriate conditions are present,
9
otherwise continue to just return. Note, immediately raising
10
exceptions is also consistent with the specification since the
11
time limit that should expire prior to the exception is
12
implementation-specific.
5
13
6
Add a DT node so that OpenSBI/Linux kernel is aware of the virt machine
14
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
7
capabilities. There are some dummy nodes added for testing as well.
15
Reviewed-by: Christoph Müllner <christoph.muellner@vrull.eu>
8
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Atish Patra <atish.patra@wdc.com>
18
Message-ID: <20240424142808.62936-2-ajones@ventanamicro.com>
11
Signed-off-by: Atish Patra <atishp@rivosinc.com>
12
Message-Id: <20220824221701.41932-5-atishp@rivosinc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
20
---
15
target/riscv/pmu.h | 1 +
21
target/riscv/helper.h | 1 +
16
hw/riscv/virt.c | 16 +++++++++++++
22
target/riscv/op_helper.c | 11 ++++++++
17
target/riscv/pmu.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++
23
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 ++++++++++++++-------
18
3 files changed, 74 insertions(+)
24
3 files changed, 32 insertions(+), 9 deletions(-)
19
25
20
diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
26
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
21
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/pmu.h
28
--- a/target/riscv/helper.h
23
+++ b/target/riscv/pmu.h
29
+++ b/target/riscv/helper.h
24
@@ -XXX,XX +XXX,XX @@ int riscv_pmu_init(RISCVCPU *cpu, int num_counters);
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
25
int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
31
DEF_HELPER_1(sret, tl, env)
26
uint32_t ctr_idx);
32
DEF_HELPER_1(mret, tl, env)
27
int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx);
33
DEF_HELPER_1(wfi, void, env)
28
+void riscv_pmu_generate_fdt_node(void *fdt, int num_counters, char *pmu_name);
34
+DEF_HELPER_1(wrs_nto, void, env)
29
int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value,
35
DEF_HELPER_1(tlb_flush, void, env)
30
uint32_t ctr_idx);
36
DEF_HELPER_1(tlb_flush_all, void, env)
31
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
37
/* Native Debug */
38
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
32
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/riscv/virt.c
40
--- a/target/riscv/op_helper.c
34
+++ b/hw/riscv/virt.c
41
+++ b/target/riscv/op_helper.c
35
@@ -XXX,XX +XXX,XX @@
42
@@ -XXX,XX +XXX,XX @@ void helper_wfi(CPURISCVState *env)
36
#include "hw/char/serial.h"
43
}
37
#include "target/riscv/cpu.h"
38
#include "hw/core/sysbus-fdt.h"
39
+#include "target/riscv/pmu.h"
40
#include "hw/riscv/riscv_hart.h"
41
#include "hw/riscv/virt.h"
42
#include "hw/riscv/boot.h"
43
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
44
aplic_phandles[socket] = aplic_s_phandle;
45
}
44
}
46
45
47
+static void create_fdt_pmu(RISCVVirtState *s)
46
+void helper_wrs_nto(CPURISCVState *env)
48
+{
47
+{
49
+ char *pmu_name;
48
+ if (env->virt_enabled && (env->priv == PRV_S || env->priv == PRV_U) &&
50
+ MachineState *mc = MACHINE(s);
49
+ get_field(env->hstatus, HSTATUS_VTW) &&
51
+ RISCVCPU hart = s->soc[0].harts[0];
50
+ !get_field(env->mstatus, MSTATUS_TW)) {
52
+
51
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
53
+ pmu_name = g_strdup_printf("/soc/pmu");
52
+ } else if (env->priv != PRV_M && get_field(env->mstatus, MSTATUS_TW)) {
54
+ qemu_fdt_add_subnode(mc->fdt, pmu_name);
53
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
55
+ qemu_fdt_setprop_string(mc->fdt, pmu_name, "compatible", "riscv,pmu");
54
+ }
56
+ riscv_pmu_generate_fdt_node(mc->fdt, hart.cfg.pmu_num, pmu_name);
57
+
58
+ g_free(pmu_name);
59
+}
55
+}
60
+
56
+
61
static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
57
void helper_tlb_flush(CPURISCVState *env)
62
bool is_32_bit, uint32_t *phandle,
58
{
63
uint32_t *irq_mmio_phandle,
59
CPUState *cs = env_cpu(env);
64
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
60
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc
65
66
create_fdt_flash(s, memmap);
67
create_fdt_fw_cfg(s, memmap);
68
+ create_fdt_pmu(s);
69
70
update_bootargs:
71
if (cmdline && *cmdline) {
72
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
73
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
74
--- a/target/riscv/pmu.c
62
--- a/target/riscv/insn_trans/trans_rvzawrs.c.inc
75
+++ b/target/riscv/pmu.c
63
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
76
@@ -XXX,XX +XXX,XX @@
64
@@ -XXX,XX +XXX,XX @@
77
#include "cpu.h"
65
* this program. If not, see <http://www.gnu.org/licenses/>.
78
#include "pmu.h"
66
*/
79
#include "sysemu/cpu-timers.h"
67
80
+#include "sysemu/device_tree.h"
68
-static bool trans_wrs(DisasContext *ctx)
81
69
+static bool trans_wrs_sto(DisasContext *ctx, arg_wrs_sto *a)
82
#define RISCV_TIMEBASE_FREQ 1000000000 /* 1Ghz */
70
{
83
#define MAKE_32BIT_MASK(shift, length) \
71
if (!ctx->cfg_ptr->ext_zawrs) {
84
(((uint32_t)(~0UL) >> (32 - (length))) << (shift))
72
return false;
85
73
@@ -XXX,XX +XXX,XX @@ static bool trans_wrs(DisasContext *ctx)
86
+/*
74
return true;
87
+ * To keep it simple, any event can be mapped to any programmable counters in
75
}
88
+ * QEMU. The generic cycle & instruction count events can also be monitored
76
89
+ * using programmable counters. In that case, mcycle & minstret must continue
77
-#define GEN_TRANS_WRS(insn) \
90
+ * to provide the correct value as well. Heterogeneous PMU per hart is not
78
-static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn *a) \
91
+ * supported yet. Thus, number of counters are same across all harts.
79
-{ \
92
+ */
80
- (void)a; \
93
+void riscv_pmu_generate_fdt_node(void *fdt, int num_ctrs, char *pmu_name)
81
- return trans_wrs(ctx); \
82
-}
83
+static bool trans_wrs_nto(DisasContext *ctx, arg_wrs_nto *a)
94
+{
84
+{
95
+ uint32_t fdt_event_ctr_map[20] = {};
85
+ if (!ctx->cfg_ptr->ext_zawrs) {
96
+ uint32_t cmask;
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
+ */
98
+#ifndef CONFIG_USER_ONLY
99
+ gen_helper_wrs_nto(tcg_env);
100
+#endif
97
+
101
+
98
+ /* All the programmable counters can map to any event */
102
+ /* We only get here when helper_wrs_nto() doesn't raise an exception. */
99
+ cmask = MAKE_32BIT_MASK(3, num_ctrs);
103
+ return trans_wrs_sto(ctx, NULL);
100
+
101
+ /*
102
+ * The event encoding is specified in the SBI specification
103
+ * Event idx is a 20bits wide number encoded as follows:
104
+ * event_idx[19:16] = type
105
+ * event_idx[15:0] = code
106
+ * The code field in cache events are encoded as follows:
107
+ * event_idx.code[15:3] = cache_id
108
+ * event_idx.code[2:1] = op_id
109
+ * event_idx.code[0:0] = result_id
110
+ */
111
+
112
+ /* SBI_PMU_HW_CPU_CYCLES: 0x01 : type(0x00) */
113
+ fdt_event_ctr_map[0] = cpu_to_be32(0x00000001);
114
+ fdt_event_ctr_map[1] = cpu_to_be32(0x00000001);
115
+ fdt_event_ctr_map[2] = cpu_to_be32(cmask | 1 << 0);
116
+
117
+ /* SBI_PMU_HW_INSTRUCTIONS: 0x02 : type(0x00) */
118
+ fdt_event_ctr_map[3] = cpu_to_be32(0x00000002);
119
+ fdt_event_ctr_map[4] = cpu_to_be32(0x00000002);
120
+ fdt_event_ctr_map[5] = cpu_to_be32(cmask | 1 << 2);
121
+
122
+ /* SBI_PMU_HW_CACHE_DTLB : 0x03 READ : 0x00 MISS : 0x00 type(0x01) */
123
+ fdt_event_ctr_map[6] = cpu_to_be32(0x00010019);
124
+ fdt_event_ctr_map[7] = cpu_to_be32(0x00010019);
125
+ fdt_event_ctr_map[8] = cpu_to_be32(cmask);
126
+
127
+ /* SBI_PMU_HW_CACHE_DTLB : 0x03 WRITE : 0x01 MISS : 0x00 type(0x01) */
128
+ fdt_event_ctr_map[9] = cpu_to_be32(0x0001001B);
129
+ fdt_event_ctr_map[10] = cpu_to_be32(0x0001001B);
130
+ fdt_event_ctr_map[11] = cpu_to_be32(cmask);
131
+
132
+ /* SBI_PMU_HW_CACHE_ITLB : 0x04 READ : 0x00 MISS : 0x00 type(0x01) */
133
+ fdt_event_ctr_map[12] = cpu_to_be32(0x00010021);
134
+ fdt_event_ctr_map[13] = cpu_to_be32(0x00010021);
135
+ fdt_event_ctr_map[14] = cpu_to_be32(cmask);
136
+
137
+ /* This a OpenSBI specific DT property documented in OpenSBI docs */
138
+ qemu_fdt_setprop(fdt, pmu_name, "riscv,event-to-mhpmcounters",
139
+ fdt_event_ctr_map, sizeof(fdt_event_ctr_map));
140
+}
104
+}
141
+
142
static bool riscv_pmu_counter_valid(RISCVCPU *cpu, uint32_t ctr_idx)
143
{
144
if (ctr_idx < 3 || ctr_idx >= RV_MAX_MHPMCOUNTERS ||
145
--
105
--
146
2.37.2
106
2.45.1
107
108
diff view generated by jsdifflib
1
From: Anup Patel <apatel@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
We should disable extensions in riscv_cpu_realize() if minimum required
3
SBI defines a Debug Console extension "DBCN" that will, in time, replace
4
priv spec version is not satisfied. This also ensures that machines with
4
the legacy console putchar and getchar SBI extensions.
5
priv spec v1.11 (or lower) cannot enable H, V, and various multi-letter
5
6
extensions.
6
The appeal of the DBCN extension is that it allows multiple bytes to be
7
7
read/written in the SBI console in a single SBI call.
8
Fixes: a775398be2e9 ("target/riscv: Add isa extenstion strings to the device tree")
8
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
As far as KVM goes, the DBCN calls are forwarded by an in-kernel KVM
10
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
10
module to userspace. But this will only happens if the KVM module
11
Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
11
actually supports this SBI extension and we activate it.
12
Message-Id: <20220630061150.905174-3-apatel@ventanamicro.com>
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>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
30
---
15
target/riscv/cpu.c | 150 ++++++++++++++++++++++++++++-----------------
31
target/riscv/sbi_ecall_interface.h | 17 +++++
16
1 file changed, 94 insertions(+), 56 deletions(-)
32
target/riscv/kvm/kvm-cpu.c | 111 +++++++++++++++++++++++++++++
17
33
2 files changed, 128 insertions(+)
18
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
34
35
diff --git a/target/riscv/sbi_ecall_interface.h b/target/riscv/sbi_ecall_interface.h
19
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/cpu.c
37
--- a/target/riscv/sbi_ecall_interface.h
21
+++ b/target/riscv/cpu.c
38
+++ b/target/riscv/sbi_ecall_interface.h
22
@@ -XXX,XX +XXX,XX @@ static const char riscv_single_letter_exts[] = "IEMAFDQCPVH";
39
@@ -XXX,XX +XXX,XX @@
23
40
24
struct isa_ext_data {
41
/* clang-format off */
25
const char *name;
42
26
- bool enabled;
43
+#define SBI_SUCCESS 0
27
+ bool multi_letter;
44
+#define SBI_ERR_FAILED -1
28
+ int min_version;
45
+#define SBI_ERR_NOT_SUPPORTED -2
29
+ int ext_enable_offset;
46
+#define SBI_ERR_INVALID_PARAM -3
47
+#define SBI_ERR_DENIED -4
48
+#define SBI_ERR_INVALID_ADDRESS -5
49
+#define SBI_ERR_ALREADY_AVAILABLE -6
50
+#define SBI_ERR_ALREADY_STARTED -7
51
+#define SBI_ERR_ALREADY_STOPPED -8
52
+#define SBI_ERR_NO_SHMEM -9
53
+
54
/* SBI Extension IDs */
55
#define SBI_EXT_0_1_SET_TIMER 0x0
56
#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
57
@@ -XXX,XX +XXX,XX @@
58
#define SBI_EXT_IPI 0x735049
59
#define SBI_EXT_RFENCE 0x52464E43
60
#define SBI_EXT_HSM 0x48534D
61
+#define SBI_EXT_DBCN 0x4442434E
62
63
/* SBI function IDs for BASE extension */
64
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
65
@@ -XXX,XX +XXX,XX @@
66
#define SBI_EXT_HSM_HART_STOP 0x1
67
#define SBI_EXT_HSM_HART_GET_STATUS 0x2
68
69
+/* SBI function IDs for DBCN extension */
70
+#define SBI_EXT_DBCN_CONSOLE_WRITE 0x0
71
+#define SBI_EXT_DBCN_CONSOLE_READ 0x1
72
+#define SBI_EXT_DBCN_CONSOLE_WRITE_BYTE 0x2
73
+
74
#define SBI_HSM_HART_STATUS_STARTED 0x0
75
#define SBI_HSM_HART_STATUS_STOPPED 0x1
76
#define SBI_HSM_HART_STATUS_START_PENDING 0x2
77
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/riscv/kvm/kvm-cpu.c
80
+++ b/target/riscv/kvm/kvm-cpu.c
81
@@ -XXX,XX +XXX,XX @@ static KVMCPUConfig kvm_v_vlenb = {
82
KVM_REG_RISCV_VECTOR_CSR_REG(vlenb)
30
};
83
};
31
84
32
+#define ISA_EXT_DATA_ENTRY(_name, _m_letter, _min_ver, _prop) \
85
+static KVMCPUConfig kvm_sbi_dbcn = {
33
+{#_name, _m_letter, _min_ver, offsetof(struct RISCVCPUConfig, _prop)}
86
+ .name = "sbi_dbcn",
34
+
87
+ .kvm_reg_id = KVM_REG_RISCV | KVM_REG_SIZE_U64 |
35
+/**
88
+ KVM_REG_RISCV_SBI_EXT | KVM_RISCV_SBI_EXT_DBCN
36
+ * Here are the ordering rules of extension naming defined by RISC-V
37
+ * specification :
38
+ * 1. All extensions should be separated from other multi-letter extensions
39
+ * by an underscore.
40
+ * 2. The first letter following the 'Z' conventionally indicates the most
41
+ * closely related alphabetical extension category, IMAFDQLCBKJTPVH.
42
+ * If multiple 'Z' extensions are named, they should be ordered first
43
+ * by category, then alphabetically within a category.
44
+ * 3. Standard supervisor-level extensions (starts with 'S') should be
45
+ * listed after standard unprivileged extensions. If multiple
46
+ * supervisor-level extensions are listed, they should be ordered
47
+ * alphabetically.
48
+ * 4. Non-standard extensions (starts with 'X') must be listed after all
49
+ * standard extensions. They must be separated from other multi-letter
50
+ * extensions by an underscore.
51
+ */
52
+static const struct isa_ext_data isa_edata_arr[] = {
53
+ ISA_EXT_DATA_ENTRY(h, false, PRIV_VERSION_1_12_0, ext_h),
54
+ ISA_EXT_DATA_ENTRY(v, false, PRIV_VERSION_1_12_0, ext_v),
55
+ ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr),
56
+ ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
57
+ ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_12_0, ext_zfh),
58
+ ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
59
+ ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
60
+ ISA_EXT_DATA_ENTRY(zdinx, true, PRIV_VERSION_1_12_0, ext_zdinx),
61
+ ISA_EXT_DATA_ENTRY(zba, true, PRIV_VERSION_1_12_0, ext_zba),
62
+ ISA_EXT_DATA_ENTRY(zbb, true, PRIV_VERSION_1_12_0, ext_zbb),
63
+ ISA_EXT_DATA_ENTRY(zbc, true, PRIV_VERSION_1_12_0, ext_zbc),
64
+ ISA_EXT_DATA_ENTRY(zbkb, true, PRIV_VERSION_1_12_0, ext_zbkb),
65
+ ISA_EXT_DATA_ENTRY(zbkc, true, PRIV_VERSION_1_12_0, ext_zbkc),
66
+ ISA_EXT_DATA_ENTRY(zbkx, true, PRIV_VERSION_1_12_0, ext_zbkx),
67
+ ISA_EXT_DATA_ENTRY(zbs, true, PRIV_VERSION_1_12_0, ext_zbs),
68
+ ISA_EXT_DATA_ENTRY(zk, true, PRIV_VERSION_1_12_0, ext_zk),
69
+ ISA_EXT_DATA_ENTRY(zkn, true, PRIV_VERSION_1_12_0, ext_zkn),
70
+ ISA_EXT_DATA_ENTRY(zknd, true, PRIV_VERSION_1_12_0, ext_zknd),
71
+ ISA_EXT_DATA_ENTRY(zkne, true, PRIV_VERSION_1_12_0, ext_zkne),
72
+ ISA_EXT_DATA_ENTRY(zknh, true, PRIV_VERSION_1_12_0, ext_zknh),
73
+ ISA_EXT_DATA_ENTRY(zkr, true, PRIV_VERSION_1_12_0, ext_zkr),
74
+ ISA_EXT_DATA_ENTRY(zks, true, PRIV_VERSION_1_12_0, ext_zks),
75
+ ISA_EXT_DATA_ENTRY(zksed, true, PRIV_VERSION_1_12_0, ext_zksed),
76
+ ISA_EXT_DATA_ENTRY(zksh, true, PRIV_VERSION_1_12_0, ext_zksh),
77
+ ISA_EXT_DATA_ENTRY(zkt, true, PRIV_VERSION_1_12_0, ext_zkt),
78
+ ISA_EXT_DATA_ENTRY(zve32f, true, PRIV_VERSION_1_12_0, ext_zve32f),
79
+ ISA_EXT_DATA_ENTRY(zve64f, true, PRIV_VERSION_1_12_0, ext_zve64f),
80
+ ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
81
+ ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
82
+ ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
83
+ ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
84
+ ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
85
+};
89
+};
86
+
90
+
87
+static bool isa_ext_is_enabled(RISCVCPU *cpu,
91
static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
88
+ const struct isa_ext_data *edata)
92
{
93
CPURISCVState *env = &cpu->env;
94
@@ -XXX,XX +XXX,XX @@ static int uint64_cmp(const void *a, const void *b)
95
return 0;
96
}
97
98
+static void kvm_riscv_check_sbi_dbcn_support(RISCVCPU *cpu,
99
+ KVMScratchCPU *kvmcpu,
100
+ struct kvm_reg_list *reglist)
89
+{
101
+{
90
+ bool *ext_enabled = (void *)&cpu->cfg + edata->ext_enable_offset;
102
+ struct kvm_reg_list *reg_search;
91
+
103
+
92
+ return *ext_enabled;
104
+ reg_search = bsearch(&kvm_sbi_dbcn.kvm_reg_id, reglist->reg, reglist->n,
105
+ sizeof(uint64_t), uint64_cmp);
106
+
107
+ if (reg_search) {
108
+ kvm_sbi_dbcn.supported = true;
109
+ }
93
+}
110
+}
94
+
111
+
95
+static void isa_ext_update_enabled(RISCVCPU *cpu,
112
static void kvm_riscv_read_vlenb(RISCVCPU *cpu, KVMScratchCPU *kvmcpu,
96
+ const struct isa_ext_data *edata, bool en)
113
struct kvm_reg_list *reglist)
114
{
115
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
116
if (riscv_has_ext(&cpu->env, RVV)) {
117
kvm_riscv_read_vlenb(cpu, kvmcpu, reglist);
118
}
119
+
120
+ kvm_riscv_check_sbi_dbcn_support(cpu, kvmcpu, reglist);
121
}
122
123
static void riscv_init_kvm_registers(Object *cpu_obj)
124
@@ -XXX,XX +XXX,XX @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs)
125
return ret;
126
}
127
128
+static int kvm_vcpu_enable_sbi_dbcn(RISCVCPU *cpu, CPUState *cs)
97
+{
129
+{
98
+ bool *ext_enabled = (void *)&cpu->cfg + edata->ext_enable_offset;
130
+ target_ulong reg = 1;
99
+
131
+
100
+ *ext_enabled = en;
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);
101
+}
137
+}
102
+
138
+
103
const char * const riscv_int_regnames[] = {
139
int kvm_arch_init_vcpu(CPUState *cs)
104
"x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
140
{
105
"x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
141
int ret = 0;
106
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
142
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
107
CPURISCVState *env = &cpu->env;
143
kvm_riscv_update_cpu_misa_ext(cpu, cs);
108
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
144
kvm_riscv_update_cpu_cfg_isa_ext(cpu, cs);
109
CPUClass *cc = CPU_CLASS(mcc);
145
110
- int priv_version = -1;
146
+ ret = kvm_vcpu_enable_sbi_dbcn(cpu, cs);
111
+ int i, priv_version = -1;
147
+
112
Error *local_err = NULL;
148
return ret;
113
149
}
114
cpu_exec_realizefn(cs, &local_err);
150
115
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
151
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
116
set_priv_version(env, priv_version);
152
return true;
117
}
153
}
118
154
119
+ /* Force disable extensions if priv spec version does not match */
155
+static void kvm_riscv_handle_sbi_dbcn(CPUState *cs, struct kvm_run *run)
120
+ for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
156
+{
121
+ if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) &&
157
+ g_autofree uint8_t *buf = NULL;
122
+ (env->priv_ver < isa_edata_arr[i].min_version)) {
158
+ RISCVCPU *cpu = RISCV_CPU(cs);
123
+ isa_ext_update_enabled(cpu, &isa_edata_arr[i], false);
159
+ target_ulong num_bytes;
124
+#ifndef CONFIG_USER_ONLY
160
+ uint64_t addr;
125
+ warn_report("disabling %s extension for hart 0x%lx because "
161
+ unsigned char ch;
126
+ "privilege spec version does not match",
162
+ int ret;
127
+ isa_edata_arr[i].name, (unsigned long)env->mhartid);
163
+
128
+#else
164
+ switch (run->riscv_sbi.function_id) {
129
+ warn_report("disabling %s extension because "
165
+ case SBI_EXT_DBCN_CONSOLE_READ:
130
+ "privilege spec version does not match",
166
+ case SBI_EXT_DBCN_CONSOLE_WRITE:
131
+ isa_edata_arr[i].name);
167
+ num_bytes = run->riscv_sbi.args[0];
132
+#endif
168
+
133
+ }
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;
134
+ }
225
+ }
135
+
226
+}
136
if (cpu->cfg.mmu) {
227
+
137
riscv_set_feature(env, RISCV_FEATURE_MMU);
228
static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
138
}
229
{
139
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
230
int ret = 0;
140
device_class_set_props(dc, riscv_cpu_properties);
231
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
141
}
232
}
142
233
ret = 0;
143
-#define ISA_EDATA_ENTRY(name, prop) {#name, cpu->cfg.prop}
234
break;
144
-
235
+ case SBI_EXT_DBCN:
145
static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int max_str_len)
236
+ kvm_riscv_handle_sbi_dbcn(cs, run);
146
{
237
+ break;
147
char *old = *isa_str;
238
default:
148
char *new = *isa_str;
239
qemu_log_mask(LOG_UNIMP,
149
int i;
240
"%s: un-handled SBI EXIT, specific reasons is %lu\n",
150
151
- /**
152
- * Here are the ordering rules of extension naming defined by RISC-V
153
- * specification :
154
- * 1. All extensions should be separated from other multi-letter extensions
155
- * by an underscore.
156
- * 2. The first letter following the 'Z' conventionally indicates the most
157
- * closely related alphabetical extension category, IMAFDQLCBKJTPVH.
158
- * If multiple 'Z' extensions are named, they should be ordered first
159
- * by category, then alphabetically within a category.
160
- * 3. Standard supervisor-level extensions (starts with 'S') should be
161
- * listed after standard unprivileged extensions. If multiple
162
- * supervisor-level extensions are listed, they should be ordered
163
- * alphabetically.
164
- * 4. Non-standard extensions (starts with 'X') must be listed after all
165
- * standard extensions. They must be separated from other multi-letter
166
- * extensions by an underscore.
167
- */
168
- struct isa_ext_data isa_edata_arr[] = {
169
- ISA_EDATA_ENTRY(zicsr, ext_icsr),
170
- ISA_EDATA_ENTRY(zifencei, ext_ifencei),
171
- ISA_EDATA_ENTRY(zmmul, ext_zmmul),
172
- ISA_EDATA_ENTRY(zfh, ext_zfh),
173
- ISA_EDATA_ENTRY(zfhmin, ext_zfhmin),
174
- ISA_EDATA_ENTRY(zfinx, ext_zfinx),
175
- ISA_EDATA_ENTRY(zdinx, ext_zdinx),
176
- ISA_EDATA_ENTRY(zba, ext_zba),
177
- ISA_EDATA_ENTRY(zbb, ext_zbb),
178
- ISA_EDATA_ENTRY(zbc, ext_zbc),
179
- ISA_EDATA_ENTRY(zbkb, ext_zbkb),
180
- ISA_EDATA_ENTRY(zbkc, ext_zbkc),
181
- ISA_EDATA_ENTRY(zbkx, ext_zbkx),
182
- ISA_EDATA_ENTRY(zbs, ext_zbs),
183
- ISA_EDATA_ENTRY(zk, ext_zk),
184
- ISA_EDATA_ENTRY(zkn, ext_zkn),
185
- ISA_EDATA_ENTRY(zknd, ext_zknd),
186
- ISA_EDATA_ENTRY(zkne, ext_zkne),
187
- ISA_EDATA_ENTRY(zknh, ext_zknh),
188
- ISA_EDATA_ENTRY(zkr, ext_zkr),
189
- ISA_EDATA_ENTRY(zks, ext_zks),
190
- ISA_EDATA_ENTRY(zksed, ext_zksed),
191
- ISA_EDATA_ENTRY(zksh, ext_zksh),
192
- ISA_EDATA_ENTRY(zkt, ext_zkt),
193
- ISA_EDATA_ENTRY(zve32f, ext_zve32f),
194
- ISA_EDATA_ENTRY(zve64f, ext_zve64f),
195
- ISA_EDATA_ENTRY(zhinx, ext_zhinx),
196
- ISA_EDATA_ENTRY(zhinxmin, ext_zhinxmin),
197
- ISA_EDATA_ENTRY(svinval, ext_svinval),
198
- ISA_EDATA_ENTRY(svnapot, ext_svnapot),
199
- ISA_EDATA_ENTRY(svpbmt, ext_svpbmt),
200
- };
201
-
202
for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
203
- if (isa_edata_arr[i].enabled) {
204
+ if (isa_edata_arr[i].multi_letter &&
205
+ isa_ext_is_enabled(cpu, &isa_edata_arr[i])) {
206
new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL);
207
g_free(old);
208
old = new;
209
--
241
--
210
2.37.2
242
2.45.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <danielhb413@gmail.com>
1
From: Cheng Yang <yangcheng.work@foxmail.com>
2
2
3
The 'fdt' param is not being used in riscv_setup_rom_reset_vec().
3
Use qemu_fdt_setprop_u64() instead of qemu_fdt_setprop_cell()
4
Simplify the API by removing it. While we're at it, remove the redundant
4
to set the address of initrd in FDT to support 64-bit address.
5
'return' statement at the end of function.
6
5
7
Cc: Palmer Dabbelt <palmer@dabbelt.com>
6
Signed-off-by: Cheng Yang <yangcheng.work@foxmail.com>
8
Cc: Alistair Francis <alistair.francis@wdc.com>
9
Cc: Bin Meng <bin.meng@windriver.com>
10
Cc: Vijai Kumar K <vijai@behindbytes.com>
11
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
12
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-Id: <20220728181926.2123771-1-danielhb413@gmail.com>
8
Message-ID: <tencent_A4482251DD0890F312758FA6B33F60815609@qq.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
10
---
17
include/hw/riscv/boot.h | 2 +-
11
hw/riscv/boot.c | 4 ++--
18
hw/riscv/boot.c | 4 +---
12
1 file changed, 2 insertions(+), 2 deletions(-)
19
hw/riscv/microchip_pfsoc.c | 2 +-
20
hw/riscv/shakti_c.c | 3 +--
21
hw/riscv/spike.c | 2 +-
22
hw/riscv/virt.c | 2 +-
23
6 files changed, 6 insertions(+), 9 deletions(-)
24
13
25
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/riscv/boot.h
28
+++ b/include/hw/riscv/boot.h
29
@@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts
30
hwaddr saddr,
31
hwaddr rom_base, hwaddr rom_size,
32
uint64_t kernel_entry,
33
- uint64_t fdt_load_addr, void *fdt);
34
+ uint64_t fdt_load_addr);
35
void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base,
36
hwaddr rom_size,
37
uint32_t reset_vec_size,
38
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
14
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
39
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/riscv/boot.c
16
--- a/hw/riscv/boot.c
41
+++ b/hw/riscv/boot.c
17
+++ b/hw/riscv/boot.c
42
@@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts
18
@@ -XXX,XX +XXX,XX @@ static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
43
hwaddr start_addr,
19
/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
44
hwaddr rom_base, hwaddr rom_size,
20
if (fdt) {
45
uint64_t kernel_entry,
21
end = start + size;
46
- uint64_t fdt_load_addr, void *fdt)
22
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
47
+ uint64_t fdt_load_addr)
23
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
48
{
24
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-start", start);
49
int i;
25
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-end", end);
50
uint32_t start_addr_hi32 = 0x00000000;
51
@@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts
52
rom_base, &address_space_memory);
53
riscv_rom_copy_firmware_info(machine, rom_base, rom_size, sizeof(reset_vec),
54
kernel_entry);
55
-
56
- return;
57
}
58
59
void riscv_setup_direct_kernel(hwaddr kernel_addr, hwaddr fdt_addr)
60
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/riscv/microchip_pfsoc.c
63
+++ b/hw/riscv/microchip_pfsoc.c
64
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
65
riscv_setup_rom_reset_vec(machine, &s->soc.u_cpus, firmware_load_addr,
66
memmap[MICROCHIP_PFSOC_ENVM_DATA].base,
67
memmap[MICROCHIP_PFSOC_ENVM_DATA].size,
68
- kernel_entry, fdt_load_addr, machine->fdt);
69
+ kernel_entry, fdt_load_addr);
70
}
26
}
71
}
27
}
72
28
73
diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/riscv/shakti_c.c
76
+++ b/hw/riscv/shakti_c.c
77
@@ -XXX,XX +XXX,XX @@ static void shakti_c_machine_state_init(MachineState *mstate)
78
riscv_setup_rom_reset_vec(mstate, &sms->soc.cpus,
79
shakti_c_memmap[SHAKTI_C_RAM].base,
80
shakti_c_memmap[SHAKTI_C_ROM].base,
81
- shakti_c_memmap[SHAKTI_C_ROM].size, 0, 0,
82
- NULL);
83
+ shakti_c_memmap[SHAKTI_C_ROM].size, 0, 0);
84
if (mstate->firmware) {
85
riscv_load_firmware(mstate->firmware,
86
shakti_c_memmap[SHAKTI_C_RAM].base,
87
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/riscv/spike.c
90
+++ b/hw/riscv/spike.c
91
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
92
riscv_setup_rom_reset_vec(machine, &s->soc[0], memmap[SPIKE_DRAM].base,
93
memmap[SPIKE_MROM].base,
94
memmap[SPIKE_MROM].size, kernel_entry,
95
- fdt_load_addr, s->fdt);
96
+ fdt_load_addr);
97
98
/* initialize HTIF using symbols found in load_kernel */
99
htif_mm_init(system_memory, mask_rom,
100
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/riscv/virt.c
103
+++ b/hw/riscv/virt.c
104
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
105
riscv_setup_rom_reset_vec(machine, &s->soc[0], start_addr,
106
virt_memmap[VIRT_MROM].base,
107
virt_memmap[VIRT_MROM].size, kernel_entry,
108
- fdt_load_addr, machine->fdt);
109
+ fdt_load_addr);
110
111
/*
112
* Only direct boot kernel is currently supported for KVM VM,
113
--
29
--
114
2.37.2
30
2.45.1
diff view generated by jsdifflib
1
From: Alexey Baturo <baturo.alexey@gmail.com>
1
From: Clément Léger <cleger@rivosinc.com>
2
2
3
Fixes: 4302bef9e178 ("target/riscv: Calculate address according to XLEN")
3
The current semihost exception number (16) is a reserved number (range
4
Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com>
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
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Message-Id: <20220717101543.478533-2-space.monkey.delivers@gmail.com>
13
Message-ID: <20240422135840.1959967-1-cleger@rivosinc.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
---
15
---
9
target/riscv/translate.c | 2 +-
16
target/riscv/cpu_bits.h | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
17
1 file changed, 1 insertion(+), 1 deletion(-)
11
18
12
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
19
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
13
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
14
--- a/target/riscv/translate.c
21
--- a/target/riscv/cpu_bits.h
15
+++ b/target/riscv/translate.c
22
+++ b/target/riscv/cpu_bits.h
16
@@ -XXX,XX +XXX,XX @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm)
23
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
17
24
RISCV_EXCP_INST_PAGE_FAULT = 0xc, /* since: priv-1.10.0 */
18
tcg_gen_addi_tl(addr, src1, imm);
25
RISCV_EXCP_LOAD_PAGE_FAULT = 0xd, /* since: priv-1.10.0 */
19
if (ctx->pm_mask_enabled) {
26
RISCV_EXCP_STORE_PAGE_FAULT = 0xf, /* since: priv-1.10.0 */
20
- tcg_gen_and_tl(addr, addr, pm_mask);
27
- RISCV_EXCP_SEMIHOST = 0x10,
21
+ tcg_gen_andc_tl(addr, addr, pm_mask);
28
RISCV_EXCP_INST_GUEST_PAGE_FAULT = 0x14,
22
} else if (get_xl(ctx) == MXL_RV32) {
29
RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT = 0x15,
23
tcg_gen_ext32u_tl(addr, addr);
30
RISCV_EXCP_VIRT_INSTRUCTION_FAULT = 0x16,
24
}
31
RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT = 0x17,
32
+ RISCV_EXCP_SEMIHOST = 0x3f,
33
} RISCVException;
34
35
#define RISCV_EXCP_INT_FLAG 0x80000000
25
--
36
--
26
2.37.2
37
2.45.1
38
39
diff view generated by jsdifflib
1
From: Atish Patra <atishp@rivosinc.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
All the hpmcounters and the fixed counters (CY, IR, TM) can be represented
3
Running a KVM guest using a 6.9-rc3 kernel, in a 6.8 host that has zkr
4
as a unified counter. Thus, the predicate function doesn't need handle each
4
enabled, will fail with a kernel oops SIGILL right at the start. The
5
case separately.
5
reason is that we can't expose zkr without implementing the SEED CSR.
6
Disabling zkr in the guest would be a workaround, but if the KVM doesn't
7
allow it we'll error out and never boot.
6
8
7
Simplify the predicate function so that we just handle things differently
9
In hindsight this is too strict. If we keep proceeding, despite not
8
between RV32/RV64 and S/HS mode.
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.
9
14
10
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
15
Change our current logic to not error out if we fail to disable an
11
Acked-by: Alistair Francis <alistair.francis@wdc.com>
16
extension in kvm_set_one_reg(), but show a warning and keep booting. It
12
Signed-off-by: Atish Patra <atishp@rivosinc.com>
17
is important to throw a warning because we must make the user aware that
13
Message-Id: <20220824221701.41932-3-atishp@rivosinc.com>
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>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
34
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
35
---
16
target/riscv/csr.c | 110 ++++-----------------------------------------
36
target/riscv/kvm/kvm-cpu.c | 12 ++++++++----
17
1 file changed, 9 insertions(+), 101 deletions(-)
37
1 file changed, 8 insertions(+), 4 deletions(-)
18
38
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
39
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
20
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/csr.c
41
--- a/target/riscv/kvm/kvm-cpu.c
22
+++ b/target/riscv/csr.c
42
+++ b/target/riscv/kvm/kvm-cpu.c
23
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
43
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
24
CPUState *cs = env_cpu(env);
44
reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
25
RISCVCPU *cpu = RISCV_CPU(cs);
45
ret = kvm_set_one_reg(cs, id, &reg);
26
int ctr_index;
46
if (ret != 0) {
27
+ target_ulong ctr_mask;
47
- error_report("Unable to %s extension %s in KVM, error %d",
28
int base_csrno = CSR_CYCLE;
48
- reg ? "enable" : "disable",
29
bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
49
- multi_ext_cfg->name, ret);
30
50
- exit(EXIT_FAILURE);
31
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
51
+ if (!reg && ret == -EINVAL) {
32
base_csrno += 0x80;
52
+ warn_report("KVM cannot disable extension %s",
33
}
53
+ multi_ext_cfg->name);
34
ctr_index = csrno - base_csrno;
54
+ } else {
35
+ ctr_mask = BIT(ctr_index);
55
+ error_report("Unable to enable extension %s in KVM, error %d",
36
56
+ multi_ext_cfg->name, ret);
37
if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
57
+ exit(EXIT_FAILURE);
38
(csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
58
+ }
39
goto skip_ext_pmu_check;
40
}
41
42
- if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & BIT(ctr_index)))) {
43
+ if (!(cpu->pmu_avail_ctrs & ctr_mask)) {
44
/* No counter is enabled in PMU or the counter is out of range */
45
return RISCV_EXCP_ILLEGAL_INST;
46
}
47
48
skip_ext_pmu_check:
49
50
- if (env->priv == PRV_S) {
51
- switch (csrno) {
52
- case CSR_CYCLE:
53
- if (!get_field(env->mcounteren, COUNTEREN_CY)) {
54
- return RISCV_EXCP_ILLEGAL_INST;
55
- }
56
- break;
57
- case CSR_TIME:
58
- if (!get_field(env->mcounteren, COUNTEREN_TM)) {
59
- return RISCV_EXCP_ILLEGAL_INST;
60
- }
61
- break;
62
- case CSR_INSTRET:
63
- if (!get_field(env->mcounteren, COUNTEREN_IR)) {
64
- return RISCV_EXCP_ILLEGAL_INST;
65
- }
66
- break;
67
- case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
68
- if (!get_field(env->mcounteren, 1 << ctr_index)) {
69
- return RISCV_EXCP_ILLEGAL_INST;
70
- }
71
- break;
72
- }
73
- if (rv32) {
74
- switch (csrno) {
75
- case CSR_CYCLEH:
76
- if (!get_field(env->mcounteren, COUNTEREN_CY)) {
77
- return RISCV_EXCP_ILLEGAL_INST;
78
- }
79
- break;
80
- case CSR_TIMEH:
81
- if (!get_field(env->mcounteren, COUNTEREN_TM)) {
82
- return RISCV_EXCP_ILLEGAL_INST;
83
- }
84
- break;
85
- case CSR_INSTRETH:
86
- if (!get_field(env->mcounteren, COUNTEREN_IR)) {
87
- return RISCV_EXCP_ILLEGAL_INST;
88
- }
89
- break;
90
- case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
91
- if (!get_field(env->mcounteren, 1 << ctr_index)) {
92
- return RISCV_EXCP_ILLEGAL_INST;
93
- }
94
- break;
95
- }
96
- }
97
+ if (((env->priv == PRV_S) && (!get_field(env->mcounteren, ctr_mask))) ||
98
+ ((env->priv == PRV_U) && (!get_field(env->scounteren, ctr_mask)))) {
99
+ return RISCV_EXCP_ILLEGAL_INST;
100
}
101
102
if (riscv_cpu_virt_enabled(env)) {
103
- switch (csrno) {
104
- case CSR_CYCLE:
105
- if (!get_field(env->hcounteren, COUNTEREN_CY) &&
106
- get_field(env->mcounteren, COUNTEREN_CY)) {
107
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
108
- }
109
- break;
110
- case CSR_TIME:
111
- if (!get_field(env->hcounteren, COUNTEREN_TM) &&
112
- get_field(env->mcounteren, COUNTEREN_TM)) {
113
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
114
- }
115
- break;
116
- case CSR_INSTRET:
117
- if (!get_field(env->hcounteren, COUNTEREN_IR) &&
118
- get_field(env->mcounteren, COUNTEREN_IR)) {
119
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
120
- }
121
- break;
122
- case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
123
- if (!get_field(env->hcounteren, 1 << ctr_index) &&
124
- get_field(env->mcounteren, 1 << ctr_index)) {
125
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
126
- }
127
- break;
128
- }
129
- if (rv32) {
130
- switch (csrno) {
131
- case CSR_CYCLEH:
132
- if (!get_field(env->hcounteren, COUNTEREN_CY) &&
133
- get_field(env->mcounteren, COUNTEREN_CY)) {
134
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
135
- }
136
- break;
137
- case CSR_TIMEH:
138
- if (!get_field(env->hcounteren, COUNTEREN_TM) &&
139
- get_field(env->mcounteren, COUNTEREN_TM)) {
140
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
141
- }
142
- break;
143
- case CSR_INSTRETH:
144
- if (!get_field(env->hcounteren, COUNTEREN_IR) &&
145
- get_field(env->mcounteren, COUNTEREN_IR)) {
146
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
147
- }
148
- break;
149
- case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
150
- if (!get_field(env->hcounteren, 1 << ctr_index) &&
151
- get_field(env->mcounteren, 1 << ctr_index)) {
152
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
153
- }
154
- break;
155
- }
156
+ if (!get_field(env->hcounteren, ctr_mask) &&
157
+ get_field(env->mcounteren, ctr_mask)) {
158
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
159
}
59
}
160
}
60
}
161
#endif
61
}
162
--
62
--
163
2.37.2
63
2.45.1
diff view generated by jsdifflib
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
According to v-spec, mask agnostic behavior can be either kept as
3
We're not setting (s/m)tval when triggering breakpoints of type 2
4
undisturbed or set elements' bits to all 1s. To distinguish the
4
(mcontrol) and 6 (mcontrol6). According to the debug spec section
5
difference of mask policies, QEMU should be able to simulate the mask
5
5.7.12, "Match Control Type 6":
6
agnostic behavior as "set mask elements' bits to all 1s".
7
6
8
There are multiple possibility for agnostic elements according to
7
"The Privileged Spec says that breakpoint exceptions that occur on
9
v-spec. The main intent of this patch-set tries to add option that
8
instruction fetches, loads, or stores update the tval CSR with either
10
can distinguish between mask policies. Setting agnostic elements to
9
zero or the faulting virtual address. The faulting virtual address for
11
all 1s allows QEMU to express this.
10
an mcontrol6 trigger with action = 0 is the address being accessed and
11
which caused that trigger to fire."
12
12
13
This is the first commit regarding the optional mask agnostic
13
A similar text is also found in the Debug spec section 5.7.11 w.r.t.
14
behavior. Follow-up commits will add this optional behavior
14
mcontrol.
15
for all rvv instructions.
16
15
17
Signed-off-by: eop Chen <eop.chen@sifive.com>
16
Note that what we're doing ATM is not violating the spec, but it's
18
Reviewed-by: Frank Chang <frank.chang@sifive.com>
17
simple enough to set mtval/stval and it makes life easier for any
19
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
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>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
26
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-Id: <165570784143.17634.35095816584573691-1@git.sr.ht>
27
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
28
Message-ID: <20240416230437.1869024-2-dbarboza@ventanamicro.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
30
---
24
target/riscv/cpu.h | 2 ++
31
target/riscv/cpu_helper.c | 1 +
25
target/riscv/internals.h | 5 +++--
32
target/riscv/debug.c | 3 +++
26
target/riscv/cpu_helper.c | 2 ++
33
2 files changed, 4 insertions(+)
27
target/riscv/translate.c | 2 ++
28
target/riscv/vector_helper.c | 8 ++++++++
29
target/riscv/insn_trans/trans_rvv.c.inc | 3 +++
30
6 files changed, 20 insertions(+), 2 deletions(-)
31
34
32
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/cpu.h
35
+++ b/target/riscv/cpu.h
36
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
37
bool ext_zve64f;
38
bool ext_zmmul;
39
bool rvv_ta_all_1s;
40
+ bool rvv_ma_all_1s;
41
42
uint32_t mvendorid;
43
uint64_t marchid;
44
@@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, XL, 20, 2)
45
FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
46
FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
47
FIELD(TB_FLAGS, VTA, 24, 1)
48
+FIELD(TB_FLAGS, VMA, 25, 1)
49
50
#ifdef TARGET_RISCV32
51
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
52
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/riscv/internals.h
55
+++ b/target/riscv/internals.h
56
@@ -XXX,XX +XXX,XX @@ FIELD(VDATA, VM, 0, 1)
57
FIELD(VDATA, LMUL, 1, 3)
58
FIELD(VDATA, VTA, 4, 1)
59
FIELD(VDATA, VTA_ALL_1S, 5, 1)
60
-FIELD(VDATA, NF, 6, 4)
61
-FIELD(VDATA, WD, 6, 1)
62
+FIELD(VDATA, VMA, 6, 1)
63
+FIELD(VDATA, NF, 7, 4)
64
+FIELD(VDATA, WD, 7, 1)
65
66
/* float point classify helpers */
67
target_ulong fclass_h(uint64_t frs1);
68
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
69
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/cpu_helper.c
37
--- a/target/riscv/cpu_helper.c
71
+++ b/target/riscv/cpu_helper.c
38
+++ b/target/riscv/cpu_helper.c
72
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
73
flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
40
tval = env->bins;
74
flags = FIELD_DP32(flags, TB_FLAGS, VTA,
41
break;
75
FIELD_EX64(env->vtype, VTYPE, VTA));
42
case RISCV_EXCP_BREAKPOINT:
76
+ flags = FIELD_DP32(flags, TB_FLAGS, VMA,
43
+ tval = env->badaddr;
77
+ FIELD_EX64(env->vtype, VTYPE, VMA));
44
if (cs->watchpoint_hit) {
78
} else {
45
tval = cs->watchpoint_hit->hitaddr;
79
flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
46
cs->watchpoint_hit = NULL;
80
}
47
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
81
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
82
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
83
--- a/target/riscv/translate.c
49
--- a/target/riscv/debug.c
84
+++ b/target/riscv/translate.c
50
+++ b/target/riscv/debug.c
85
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
51
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
86
int8_t lmul;
52
if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
87
uint8_t sew;
53
/* check U/S/M bit against current privilege level */
88
uint8_t vta;
54
if ((ctrl >> 3) & BIT(env->priv)) {
89
+ uint8_t vma;
55
+ env->badaddr = pc;
90
bool cfg_vta_all_1s;
56
return true;
91
target_ulong vstart;
57
}
92
bool vl_eq_vlmax;
58
}
93
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
59
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
94
ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW);
60
if (env->virt_enabled) {
95
ctx->lmul = sextract32(FIELD_EX32(tb_flags, TB_FLAGS, LMUL), 0, 3);
61
/* check VU/VS bit against current privilege level */
96
ctx->vta = FIELD_EX32(tb_flags, TB_FLAGS, VTA) && cpu->cfg.rvv_ta_all_1s;
62
if ((ctrl >> 23) & BIT(env->priv)) {
97
+ ctx->vma = FIELD_EX32(tb_flags, TB_FLAGS, VMA) && cpu->cfg.rvv_ma_all_1s;
63
+ env->badaddr = pc;
98
ctx->cfg_vta_all_1s = cpu->cfg.rvv_ta_all_1s;
64
return true;
99
ctx->vstart = env->vstart;
65
}
100
ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
66
} else {
101
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
67
/* check U/S/M bit against current privilege level */
102
index XXXXXXX..XXXXXXX 100644
68
if ((ctrl >> 3) & BIT(env->priv)) {
103
--- a/target/riscv/vector_helper.c
69
+ env->badaddr = pc;
104
+++ b/target/riscv/vector_helper.c
70
return true;
105
@@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_vta(uint32_t desc)
71
}
106
return FIELD_EX32(simd_data(desc), VDATA, VTA);
72
}
107
}
108
109
+static inline uint32_t vext_vma(uint32_t desc)
110
+{
111
+ return FIELD_EX32(simd_data(desc), VDATA, VMA);
112
+}
113
+
114
static inline uint32_t vext_vta_all_1s(uint32_t desc)
115
{
116
return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S);
117
@@ -XXX,XX +XXX,XX @@ static void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
118
uint32_t vl = env->vl;
119
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
120
uint32_t vta = vext_vta(desc);
121
+ uint32_t vma = vext_vma(desc);
122
uint32_t i;
123
124
for (i = env->vstart; i < vl; i++) {
125
if (!vm && !vext_elem_mask(v0, i)) {
126
+ /* set masked-off elements to 1s */
127
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
128
continue;
129
}
130
fn(vd, vs1, vs2, i);
131
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/riscv/insn_trans/trans_rvv.c.inc
134
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
135
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
136
data = FIELD_DP32(data, VDATA, VM, a->vm);
137
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
138
data = FIELD_DP32(data, VDATA, VTA, s->vta);
139
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
140
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
141
vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2),
142
cpu_env, s->cfg_ptr->vlen / 8,
143
@@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
144
data = FIELD_DP32(data, VDATA, VM, a->vm);
145
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
146
data = FIELD_DP32(data, VDATA, VTA, s->vta);
147
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
148
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
149
vreg_ofs(s, a->rs1),
150
vreg_ofs(s, a->rs2),
151
@@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
152
data = FIELD_DP32(data, VDATA, VM, a->vm);
153
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
154
data = FIELD_DP32(data, VDATA, VTA, s->vta);
155
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
156
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
157
vreg_ofs(s, a->rs1),
158
vreg_ofs(s, a->rs2),
159
--
73
--
160
2.37.2
74
2.45.1
diff view generated by jsdifflib
1
From: Atish Patra <atishp@rivosinc.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
The sscofpmf extension was ratified as a part of priv spec v1.12.
3
Privileged spec section 4.1.9 mentions:
4
Mark the csr_ops accordingly.
5
4
6
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
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>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Atish Patra <atishp@rivosinc.com>
24
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Message-Id: <20220824221701.41932-6-atishp@rivosinc.com>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-ID: <20240416230437.1869024-3-dbarboza@ventanamicro.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
28
---
12
target/riscv/csr.c | 90 ++++++++++++++++++++++++++++++----------------
29
target/riscv/insn_trans/trans_privileged.c.inc | 2 ++
13
1 file changed, 60 insertions(+), 30 deletions(-)
30
1 file changed, 2 insertions(+)
14
31
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
32
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
16
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/csr.c
34
--- a/target/riscv/insn_trans/trans_privileged.c.inc
18
+++ b/target/riscv/csr.c
35
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
19
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
36
@@ -XXX,XX +XXX,XX @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
20
write_mhpmevent },
37
if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) {
21
38
generate_exception(ctx, RISCV_EXCP_SEMIHOST);
22
[CSR_MHPMEVENT3H] = { "mhpmevent3h", sscofpmf, read_mhpmeventh,
39
} else {
23
- write_mhpmeventh },
40
+ tcg_gen_st_tl(tcg_constant_tl(ebreak_addr), tcg_env,
24
+ write_mhpmeventh,
41
+ offsetof(CPURISCVState, badaddr));
25
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
42
generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
26
[CSR_MHPMEVENT4H] = { "mhpmevent4h", sscofpmf, read_mhpmeventh,
43
}
27
- write_mhpmeventh },
44
return true;
28
+ write_mhpmeventh,
29
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
30
[CSR_MHPMEVENT5H] = { "mhpmevent5h", sscofpmf, read_mhpmeventh,
31
- write_mhpmeventh },
32
+ write_mhpmeventh,
33
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
34
[CSR_MHPMEVENT6H] = { "mhpmevent6h", sscofpmf, read_mhpmeventh,
35
- write_mhpmeventh },
36
+ write_mhpmeventh,
37
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
38
[CSR_MHPMEVENT7H] = { "mhpmevent7h", sscofpmf, read_mhpmeventh,
39
- write_mhpmeventh },
40
+ write_mhpmeventh,
41
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
42
[CSR_MHPMEVENT8H] = { "mhpmevent8h", sscofpmf, read_mhpmeventh,
43
- write_mhpmeventh },
44
+ write_mhpmeventh,
45
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
46
[CSR_MHPMEVENT9H] = { "mhpmevent9h", sscofpmf, read_mhpmeventh,
47
- write_mhpmeventh },
48
+ write_mhpmeventh,
49
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
50
[CSR_MHPMEVENT10H] = { "mhpmevent10h", sscofpmf, read_mhpmeventh,
51
- write_mhpmeventh },
52
+ write_mhpmeventh,
53
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
54
[CSR_MHPMEVENT11H] = { "mhpmevent11h", sscofpmf, read_mhpmeventh,
55
- write_mhpmeventh },
56
+ write_mhpmeventh,
57
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
58
[CSR_MHPMEVENT12H] = { "mhpmevent12h", sscofpmf, read_mhpmeventh,
59
- write_mhpmeventh },
60
+ write_mhpmeventh,
61
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
62
[CSR_MHPMEVENT13H] = { "mhpmevent13h", sscofpmf, read_mhpmeventh,
63
- write_mhpmeventh },
64
+ write_mhpmeventh,
65
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
66
[CSR_MHPMEVENT14H] = { "mhpmevent14h", sscofpmf, read_mhpmeventh,
67
- write_mhpmeventh },
68
+ write_mhpmeventh,
69
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
70
[CSR_MHPMEVENT15H] = { "mhpmevent15h", sscofpmf, read_mhpmeventh,
71
- write_mhpmeventh },
72
+ write_mhpmeventh,
73
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
74
[CSR_MHPMEVENT16H] = { "mhpmevent16h", sscofpmf, read_mhpmeventh,
75
- write_mhpmeventh },
76
+ write_mhpmeventh,
77
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
78
[CSR_MHPMEVENT17H] = { "mhpmevent17h", sscofpmf, read_mhpmeventh,
79
- write_mhpmeventh },
80
+ write_mhpmeventh,
81
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
82
[CSR_MHPMEVENT18H] = { "mhpmevent18h", sscofpmf, read_mhpmeventh,
83
- write_mhpmeventh },
84
+ write_mhpmeventh,
85
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
86
[CSR_MHPMEVENT19H] = { "mhpmevent19h", sscofpmf, read_mhpmeventh,
87
- write_mhpmeventh },
88
+ write_mhpmeventh,
89
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
90
[CSR_MHPMEVENT20H] = { "mhpmevent20h", sscofpmf, read_mhpmeventh,
91
- write_mhpmeventh },
92
+ write_mhpmeventh,
93
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
94
[CSR_MHPMEVENT21H] = { "mhpmevent21h", sscofpmf, read_mhpmeventh,
95
- write_mhpmeventh },
96
+ write_mhpmeventh,
97
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
98
[CSR_MHPMEVENT22H] = { "mhpmevent22h", sscofpmf, read_mhpmeventh,
99
- write_mhpmeventh },
100
+ write_mhpmeventh,
101
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
102
[CSR_MHPMEVENT23H] = { "mhpmevent23h", sscofpmf, read_mhpmeventh,
103
- write_mhpmeventh },
104
+ write_mhpmeventh,
105
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
106
[CSR_MHPMEVENT24H] = { "mhpmevent24h", sscofpmf, read_mhpmeventh,
107
- write_mhpmeventh },
108
+ write_mhpmeventh,
109
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
110
[CSR_MHPMEVENT25H] = { "mhpmevent25h", sscofpmf, read_mhpmeventh,
111
- write_mhpmeventh },
112
+ write_mhpmeventh,
113
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
114
[CSR_MHPMEVENT26H] = { "mhpmevent26h", sscofpmf, read_mhpmeventh,
115
- write_mhpmeventh },
116
+ write_mhpmeventh,
117
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
118
[CSR_MHPMEVENT27H] = { "mhpmevent27h", sscofpmf, read_mhpmeventh,
119
- write_mhpmeventh },
120
+ write_mhpmeventh,
121
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
122
[CSR_MHPMEVENT28H] = { "mhpmevent28h", sscofpmf, read_mhpmeventh,
123
- write_mhpmeventh },
124
+ write_mhpmeventh,
125
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
126
[CSR_MHPMEVENT29H] = { "mhpmevent29h", sscofpmf, read_mhpmeventh,
127
- write_mhpmeventh },
128
+ write_mhpmeventh,
129
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
130
[CSR_MHPMEVENT30H] = { "mhpmevent30h", sscofpmf, read_mhpmeventh,
131
- write_mhpmeventh },
132
+ write_mhpmeventh,
133
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
134
[CSR_MHPMEVENT31H] = { "mhpmevent31h", sscofpmf, read_mhpmeventh,
135
- write_mhpmeventh },
136
+ write_mhpmeventh,
137
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
138
139
[CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_hpmcounterh },
140
[CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_hpmcounterh },
141
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
142
write_mhpmcounterh },
143
[CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32, read_hpmcounterh,
144
write_mhpmcounterh },
145
- [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf },
146
+ [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf,
147
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
148
149
#endif /* !CONFIG_USER_ONLY */
150
};
151
--
45
--
152
2.37.2
46
2.45.1
diff view generated by jsdifflib
1
From: Anup Patel <apatel@ventanamicro.com>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
The arch review of AIA spec is completed and we now have official
3
Add support for Zve32x extension and replace some checks for Zve32f with
4
extension names for AIA: Smaia (M-mode AIA CSRs) and Ssaia (S-mode
4
Zve32x, since Zve32f depends on Zve32x.
5
AIA CSRs).
6
5
7
Refer, section 1.6 of the latest AIA v0.3.1 stable specification at
6
Signed-off-by: Jason Chien <jason.chien@sifive.com>
8
https://github.com/riscv/riscv-aia/releases/download/0.3.1-draft.32/riscv-interrupts-032.pdf)
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
9
8
Reviewed-by: Max Chou <max.chou@sifive.com>
10
Based on above, we update QEMU RISC-V to:
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
1) Have separate config options for Smaia and Ssaia extensions
10
Message-ID: <20240328022343.6871-2-jason.chien@sifive.com>
12
which replace RISCV_FEATURE_AIA in CPU features
13
2) Not generate AIA INTC compatible string in virt machine
14
15
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
16
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-id: 20220820042958.377018-1-apatel@ventanamicro.com
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
12
---
21
target/riscv/cpu.h | 4 ++--
13
target/riscv/cpu_cfg.h | 1 +
22
hw/intc/riscv_imsic.c | 4 +++-
14
target/riscv/cpu.c | 2 ++
23
hw/riscv/virt.c | 13 ++-----------
15
target/riscv/cpu_helper.c | 2 +-
24
target/riscv/cpu.c | 9 ++++-----
16
target/riscv/csr.c | 2 +-
25
target/riscv/cpu_helper.c | 3 ++-
17
target/riscv/tcg/tcg-cpu.c | 16 ++++++++--------
26
target/riscv/csr.c | 24 ++++++++++++++++++------
18
target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
27
6 files changed, 31 insertions(+), 26 deletions(-)
19
6 files changed, 15 insertions(+), 12 deletions(-)
28
20
29
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
21
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
30
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu.h
23
--- a/target/riscv/cpu_cfg.h
32
+++ b/target/riscv/cpu.h
24
+++ b/target/riscv/cpu_cfg.h
33
@@ -XXX,XX +XXX,XX @@ enum {
34
RISCV_FEATURE_PMP,
35
RISCV_FEATURE_EPMP,
36
RISCV_FEATURE_MISA,
37
- RISCV_FEATURE_AIA,
38
RISCV_FEATURE_DEBUG
39
};
40
41
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
25
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
26
bool ext_zhinx;
27
bool ext_zhinxmin;
42
bool ext_zve32f;
28
bool ext_zve32f;
29
+ bool ext_zve32x;
43
bool ext_zve64f;
30
bool ext_zve64f;
44
bool ext_zmmul;
31
bool ext_zve64d;
45
+ bool ext_smaia;
32
bool ext_zvbb;
46
+ bool ext_ssaia;
47
bool rvv_ta_all_1s;
48
bool rvv_ma_all_1s;
49
50
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
51
bool mmu;
52
bool pmp;
53
bool epmp;
54
- bool aia;
55
bool debug;
56
uint64_t resetvec;
57
58
diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/hw/intc/riscv_imsic.c
61
+++ b/hw/intc/riscv_imsic.c
62
@@ -XXX,XX +XXX,XX @@ static void riscv_imsic_realize(DeviceState *dev, Error **errp)
63
64
/* Force select AIA feature and setup CSR read-modify-write callback */
65
if (env) {
66
- riscv_set_feature(env, RISCV_FEATURE_AIA);
67
if (!imsic->mmode) {
68
+ rcpu->cfg.ext_ssaia = true;
69
riscv_cpu_set_geilen(env, imsic->num_pages - 1);
70
+ } else {
71
+ rcpu->cfg.ext_smaia = true;
72
}
73
riscv_cpu_set_aia_ireg_rmw_fn(env, (imsic->mmode) ? PRV_M : PRV_S,
74
riscv_imsic_rmw, imsic);
75
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/riscv/virt.c
78
+++ b/hw/riscv/virt.c
79
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
80
qemu_fdt_add_subnode(mc->fdt, intc_name);
81
qemu_fdt_setprop_cell(mc->fdt, intc_name, "phandle",
82
intc_phandles[cpu]);
83
- if (riscv_feature(&s->soc[socket].harts[cpu].env,
84
- RISCV_FEATURE_AIA)) {
85
- static const char * const compat[2] = {
86
- "riscv,cpu-intc-aia", "riscv,cpu-intc"
87
- };
88
- qemu_fdt_setprop_string_array(mc->fdt, intc_name, "compatible",
89
- (char **)&compat, ARRAY_SIZE(compat));
90
- } else {
91
- qemu_fdt_setprop_string(mc->fdt, intc_name, "compatible",
92
- "riscv,cpu-intc");
93
- }
94
+ qemu_fdt_setprop_string(mc->fdt, intc_name, "compatible",
95
+ "riscv,cpu-intc");
96
qemu_fdt_setprop(mc->fdt, intc_name, "interrupt-controller", NULL, 0);
97
qemu_fdt_setprop_cell(mc->fdt, intc_name, "#interrupt-cells", 1);
98
99
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
33
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
100
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
101
--- a/target/riscv/cpu.c
35
--- a/target/riscv/cpu.c
102
+++ b/target/riscv/cpu.c
36
+++ b/target/riscv/cpu.c
103
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
37
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
104
ISA_EXT_DATA_ENTRY(zve64f, true, PRIV_VERSION_1_12_0, ext_zve64f),
38
ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
105
ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
39
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
106
ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
40
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
107
+ ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
41
+ ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
108
+ ISA_EXT_DATA_ENTRY(ssaia, true, PRIV_VERSION_1_12_0, ext_ssaia),
42
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
109
ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
43
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
110
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
44
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
111
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
45
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
112
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
46
MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false),
113
}
47
MULTI_EXT_CFG_BOOL("zfhmin", ext_zfhmin, false),
114
}
48
MULTI_EXT_CFG_BOOL("zve32f", ext_zve32f, false),
115
49
+ MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
116
- if (cpu->cfg.aia) {
50
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
117
- riscv_set_feature(env, RISCV_FEATURE_AIA);
51
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
118
- }
52
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
119
-
120
if (cpu->cfg.debug) {
121
riscv_set_feature(env, RISCV_FEATURE_DEBUG);
122
}
123
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
124
DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
125
/* ePMP 0.9.3 */
126
DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
127
- DEFINE_PROP_BOOL("x-aia", RISCVCPU, cfg.aia, false),
128
+ DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false),
129
+ DEFINE_PROP_BOOL("x-ssaia", RISCVCPU, cfg.ext_ssaia, false),
130
131
DEFINE_PROP_END_OF_LIST(),
132
};
133
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
134
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
135
--- a/target/riscv/cpu_helper.c
55
--- a/target/riscv/cpu_helper.c
136
+++ b/target/riscv/cpu_helper.c
56
+++ b/target/riscv/cpu_helper.c
137
@@ -XXX,XX +XXX,XX @@ static int riscv_cpu_pending_to_irq(CPURISCVState *env,
57
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
138
int extirq, unsigned int extirq_def_prio,
58
*pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
139
uint64_t pending, uint8_t *iprio)
59
*cs_base = 0;
140
{
60
141
+ RISCVCPU *cpu = env_archcpu(env);
61
- if (cpu->cfg.ext_zve32f) {
142
int irq, best_irq = RISCV_EXCP_NONE;
62
+ if (cpu->cfg.ext_zve32x) {
143
unsigned int prio, best_prio = UINT_MAX;
63
/*
144
64
* If env->vl equals to VLMAX, we can use generic vector operation
145
@@ -XXX,XX +XXX,XX @@ static int riscv_cpu_pending_to_irq(CPURISCVState *env,
65
* expanders (GVEC) to accerlate the vector operations.
146
}
147
148
irq = ctz64(pending);
149
- if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
150
+ if (!((extirq == IRQ_M_EXT) ? cpu->cfg.ext_smaia : cpu->cfg.ext_ssaia)) {
151
return irq;
152
}
153
154
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
155
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
156
--- a/target/riscv/csr.c
68
--- a/target/riscv/csr.c
157
+++ b/target/riscv/csr.c
69
+++ b/target/riscv/csr.c
158
@@ -XXX,XX +XXX,XX @@ static RISCVException any32(CPURISCVState *env, int csrno)
70
@@ -XXX,XX +XXX,XX @@ static RISCVException fs(CPURISCVState *env, int csrno)
159
71
160
static int aia_any(CPURISCVState *env, int csrno)
72
static RISCVException vs(CPURISCVState *env, int csrno)
161
{
73
{
162
- if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
74
- if (riscv_cpu_cfg(env)->ext_zve32f) {
163
+ RISCVCPU *cpu = env_archcpu(env);
75
+ if (riscv_cpu_cfg(env)->ext_zve32x) {
164
+
76
#if !defined(CONFIG_USER_ONLY)
165
+ if (!cpu->cfg.ext_smaia) {
77
if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
166
return RISCV_EXCP_ILLEGAL_INST;
78
return RISCV_EXCP_ILLEGAL_INST;
79
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/riscv/tcg/tcg-cpu.c
82
+++ b/target/riscv/tcg/tcg-cpu.c
83
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
84
return;
167
}
85
}
168
86
169
@@ -XXX,XX +XXX,XX @@ static int aia_any(CPURISCVState *env, int csrno)
87
- if (cpu->cfg.ext_zve32f && !riscv_has_ext(env, RVF)) {
170
88
- error_setg(errp, "Zve32f/Zve64f extensions require F extension");
171
static int aia_any32(CPURISCVState *env, int csrno)
89
- return;
90
+ /* The Zve32f extension depends on the Zve32x extension */
91
+ if (cpu->cfg.ext_zve32f) {
92
+ if (!riscv_has_ext(env, RVF)) {
93
+ error_setg(errp, "Zve32f/Zve64f extensions require F extension");
94
+ return;
95
+ }
96
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
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)
172
{
120
{
173
- if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
121
TCGv s1, dst;
174
+ RISCVCPU *cpu = env_archcpu(env);
122
175
+
123
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
176
+ if (!cpu->cfg.ext_smaia) {
124
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
177
return RISCV_EXCP_ILLEGAL_INST;
125
return false;
178
}
126
}
179
127
180
@@ -XXX,XX +XXX,XX @@ static int smode32(CPURISCVState *env, int csrno)
128
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
181
182
static int aia_smode(CPURISCVState *env, int csrno)
183
{
129
{
184
- if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
130
TCGv dst;
185
+ RISCVCPU *cpu = env_archcpu(env);
131
186
+
132
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
187
+ if (!cpu->cfg.ext_ssaia) {
133
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
188
return RISCV_EXCP_ILLEGAL_INST;
134
return false;
189
}
135
}
190
136
191
@@ -XXX,XX +XXX,XX @@ static int aia_smode(CPURISCVState *env, int csrno)
192
193
static int aia_smode32(CPURISCVState *env, int csrno)
194
{
195
- if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
196
+ RISCVCPU *cpu = env_archcpu(env);
197
+
198
+ if (!cpu->cfg.ext_ssaia) {
199
return RISCV_EXCP_ILLEGAL_INST;
200
}
201
202
@@ -XXX,XX +XXX,XX @@ static RISCVException pointer_masking(CPURISCVState *env, int csrno)
203
204
static int aia_hmode(CPURISCVState *env, int csrno)
205
{
206
- if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
207
+ RISCVCPU *cpu = env_archcpu(env);
208
+
209
+ if (!cpu->cfg.ext_ssaia) {
210
return RISCV_EXCP_ILLEGAL_INST;
211
}
212
213
@@ -XXX,XX +XXX,XX @@ static int aia_hmode(CPURISCVState *env, int csrno)
214
215
static int aia_hmode32(CPURISCVState *env, int csrno)
216
{
217
- if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
218
+ RISCVCPU *cpu = env_archcpu(env);
219
+
220
+ if (!cpu->cfg.ext_ssaia) {
221
return RISCV_EXCP_ILLEGAL_INST;
222
}
223
224
--
137
--
225
2.37.2
138
2.45.1
diff view generated by jsdifflib
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
Add check for the implicit dependence between H and S
3
Add support for Zve64x extension. Enabling Zve64f enables Zve64x and
4
enabling Zve64x enables Zve32x according to their dependency.
4
5
5
Csrs only existed in RV32 will not trigger virtual instruction fault
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2107
6
when not in RV32 based on section 8.6.1 of riscv-privileged spec
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
7
(draft-20220717)
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
9
Reviewed-by: Max Chou <max.chou@sifive.com>
9
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
11
Message-ID: <20240328022343.6871-3-jason.chien@sifive.com>
11
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-Id: <20220718130955.11899-6-liweiwei@iscas.ac.cn>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
13
---
16
target/riscv/cpu.c | 5 +++++
14
target/riscv/cpu_cfg.h | 1 +
17
target/riscv/csr.c | 9 ++-------
15
target/riscv/cpu.c | 2 ++
18
2 files changed, 7 insertions(+), 7 deletions(-)
16
target/riscv/tcg/tcg-cpu.c | 17 +++++++++++------
17
3 files changed, 14 insertions(+), 6 deletions(-)
19
18
19
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu_cfg.h
22
+++ b/target/riscv/cpu_cfg.h
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
24
bool ext_zve32x;
25
bool ext_zve64f;
26
bool ext_zve64d;
27
+ bool ext_zve64x;
28
bool ext_zvbb;
29
bool ext_zvbc;
30
bool ext_zvkb;
20
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
21
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/cpu.c
33
--- a/target/riscv/cpu.c
23
+++ b/target/riscv/cpu.c
34
+++ b/target/riscv/cpu.c
24
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
35
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
25
return;
36
ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
26
}
37
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
27
38
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
28
+ if (cpu->cfg.ext_h && !cpu->cfg.ext_s) {
39
+ ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x),
29
+ error_setg(errp, "H extension implicitly requires S-mode");
40
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
41
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
42
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
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
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/tcg/tcg-cpu.c
54
+++ b/target/riscv/tcg/tcg-cpu.c
55
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
56
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");
30
+ return;
61
+ return;
31
+ }
62
+ }
32
+
63
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64f), true);
33
if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) {
34
error_setg(errp, "F extension requires Zicsr");
35
return;
36
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/csr.c
39
+++ b/target/riscv/csr.c
40
@@ -XXX,XX +XXX,XX @@ static int aia_smode32(CPURISCVState *env, int csrno)
41
42
static RISCVException hmode(CPURISCVState *env, int csrno)
43
{
44
- if (riscv_has_ext(env, RVS) &&
45
- riscv_has_ext(env, RVH)) {
46
+ if (riscv_has_ext(env, RVH)) {
47
/* Hypervisor extension is supported */
48
if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
49
env->priv == PRV_M) {
50
@@ -XXX,XX +XXX,XX @@ static RISCVException hmode(CPURISCVState *env, int csrno)
51
static RISCVException hmode32(CPURISCVState *env, int csrno)
52
{
53
if (riscv_cpu_mxl(env) != MXL_RV32) {
54
- if (!riscv_cpu_virt_enabled(env)) {
55
- return RISCV_EXCP_ILLEGAL_INST;
56
- } else {
57
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
58
- }
59
+ return RISCV_EXCP_ILLEGAL_INST;
60
}
64
}
61
65
62
return hmode(env, csrno);
66
- /* The Zve64f extension depends on the Zve32f extension */
67
+ /* The Zve64f extension depends on the Zve64x and Zve32f extensions */
68
if (cpu->cfg.ext_zve64f) {
69
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64x), true);
70
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32f), true);
71
}
72
73
- if (cpu->cfg.ext_zve64d && !riscv_has_ext(env, RVD)) {
74
- error_setg(errp, "Zve64d/V extensions require D extension");
75
- return;
76
+ /* The Zve64x extension depends on the Zve32x extension */
77
+ if (cpu->cfg.ext_zve64x) {
78
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
79
}
80
81
/* The Zve32f extension depends on the Zve32x extension */
82
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
83
return;
84
}
85
86
- if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
87
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64x) {
88
error_setg(
89
errp,
90
- "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
91
+ "Zvbc and Zvknhb extensions require V or Zve64x extensions");
92
return;
93
}
94
63
--
95
--
64
2.37.2
96
2.45.1
diff view generated by jsdifflib
1
From: Conor Dooley <conor.dooley@microchip.com>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
"platform" is not a valid name for a bus node in dt-schema, so warnings
3
In current implementation, the gdbstub allows reading vector registers
4
can be see in dt-validate on a dump of the riscv virt dtb:
4
only if V extension is supported. However, all vector extensions and
5
vector crypto extensions have the vector registers and they all depend
6
on Zve32x. The gdbstub should check for Zve32x instead.
5
7
6
/stuff/qemu/qemu.dtb: platform@4000000: $nodename:0: 'platform@4000000' does not match '^([a-z][a-z0-9\\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$'
8
Signed-off-by: Jason Chien <jason.chien@sifive.com>
7
From schema: /home/conor/.local/lib/python3.9/site-packages/dtschema/schemas/simple-bus.yaml
9
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
"platform-bus" is a valid name, so use that instead.
10
Reviewed-by: Max Chou <max.chou@sifive.com>
9
11
Message-ID: <20240328022343.6871-4-jason.chien@sifive.com>
10
CC: Rob Herring <robh@kernel.org>
11
Fixes: 11d306b9df ("hw/arm/sysbus-fdt: helpers for platform bus nodes addition")
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
14
Message-id: 20220810184612.157317-5-mail@conchuod.ie
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
13
---
17
hw/core/sysbus-fdt.c | 2 +-
14
target/riscv/gdbstub.c | 2 +-
18
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 1 insertion(+), 1 deletion(-)
19
16
20
diff --git a/hw/core/sysbus-fdt.c b/hw/core/sysbus-fdt.c
17
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/core/sysbus-fdt.c
19
--- a/target/riscv/gdbstub.c
23
+++ b/hw/core/sysbus-fdt.c
20
+++ b/target/riscv/gdbstub.c
24
@@ -XXX,XX +XXX,XX @@ void platform_bus_add_all_fdt_nodes(void *fdt, const char *intc, hwaddr addr,
21
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
25
22
gdb_find_static_feature("riscv-32bit-fpu.xml"),
26
assert(fdt);
23
0);
27
24
}
28
- node = g_strdup_printf("/platform@%"PRIx64, addr);
25
- if (env->misa_ext & RVV) {
29
+ node = g_strdup_printf("/platform-bus@%"PRIx64, addr);
26
+ if (cpu->cfg.ext_zve32x) {
30
27
gdb_register_coprocessor(cs, riscv_gdb_get_vector,
31
/* Create a /platform node that we can put all devices into */
28
riscv_gdb_set_vector,
32
qemu_fdt_add_subnode(fdt, node);
29
ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs),
33
--
30
--
34
2.37.2
31
2.45.1
diff view generated by jsdifflib
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
1
From: Huang Tao <eric.huang@linux.alibaba.com>
2
2
3
If the FDT contains /chosen/rng-seed, then the Linux RNG will use it to
3
In RVV and vcrypto instructions, the masked and tail elements are set to 1s
4
initialize early. Set this using the usual guest random number
4
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
5
generation function. This is confirmed to successfully initialize the
5
agnostic policy.
6
RNG on Linux 5.19-rc2.
7
6
8
Cc: Alistair Francis <alistair.francis@wdc.com>
7
However, this function can't deal the big endian situation. This patch fixes
9
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
8
the problem by adding handling of such case.
10
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
9
11
Message-Id: <20220613115810.178210-1-Jason@zx2c4.com>
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>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
16
---
14
hw/riscv/virt.c | 6 ++++++
17
target/riscv/vector_internals.c | 22 ++++++++++++++++++++++
15
1 file changed, 6 insertions(+)
18
1 file changed, 22 insertions(+)
16
19
17
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
20
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/riscv/virt.c
22
--- a/target/riscv/vector_internals.c
20
+++ b/hw/riscv/virt.c
23
+++ b/target/riscv/vector_internals.c
21
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
22
#include "qemu/osdep.h"
25
if (tot - cnt == 0) {
23
#include "qemu/units.h"
26
return ;
24
#include "qemu/error-report.h"
25
+#include "qemu/guest-random.h"
26
#include "qapi/error.h"
27
#include "hw/boards.h"
28
#include "hw/loader.h"
29
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
30
MachineState *mc = MACHINE(s);
31
uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1;
32
uint32_t irq_pcie_phandle = 1, irq_virtio_phandle = 1;
33
+ uint8_t rng_seed[32];
34
35
if (mc->dtb) {
36
mc->fdt = load_device_tree(mc->dtb, &s->fdt_size);
37
@@ -XXX,XX +XXX,XX @@ update_bootargs:
38
if (cmdline && *cmdline) {
39
qemu_fdt_setprop_string(mc->fdt, "/chosen", "bootargs", cmdline);
40
}
27
}
41
+
28
+
42
+ /* Pass seed to RNG */
29
+ if (HOST_BIG_ENDIAN) {
43
+ qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
30
+ /*
44
+ qemu_fdt_setprop(mc->fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed));
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);
45
}
51
}
46
52
47
static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
48
--
53
--
49
2.37.2
54
2.45.1
diff view generated by jsdifflib
1
From: Rahul Pathak <rpathak@ventanamicro.com>
1
From: Yangyu Chen <cyy@cyyself.name>
2
2
3
XVentanaCondOps is Ventana custom extension. Add
3
This code has a typo that writes zvkb to zvkg, causing users can't
4
its extension entry in the ISA Ext array
4
enable zvkb through the config. This patch gets this fixed.
5
5
6
Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
6
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
7
Fixes: ea61ef7097d0 ("target/riscv: Move vector crypto extensions to riscv_cpu_extensions")
8
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20220816045408.1231135-1-rpathak@ventanamicro.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>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
15
---
11
target/riscv/cpu.c | 1 +
16
target/riscv/cpu.c | 2 +-
12
1 file changed, 1 insertion(+)
17
1 file changed, 1 insertion(+), 1 deletion(-)
13
18
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
19
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu.c
21
--- a/target/riscv/cpu.c
17
+++ b/target/riscv/cpu.c
22
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
23
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
19
ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
24
/* Vector cryptography extensions */
20
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
25
MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false),
21
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
26
MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false),
22
+ ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
27
- MULTI_EXT_CFG_BOOL("zvkb", ext_zvkg, false),
23
};
28
+ MULTI_EXT_CFG_BOOL("zvkb", ext_zvkb, false),
24
29
MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false),
25
static bool isa_ext_is_enabled(RISCVCPU *cpu,
30
MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false),
31
MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false),
26
--
32
--
27
2.37.2
33
2.45.1
34
35
diff view generated by jsdifflib
1
From: Dao Lu <daolu@rivosinc.com>
1
From: Huang Tao <eric.huang@linux.alibaba.com>
2
2
3
Added support for RISC-V PAUSE instruction from Zihintpause extension,
3
In this patch, we modify the decoder to be a freely composable data
4
enabled by default.
4
structure instead of a hardcoded one. It can be dynamically builded up
5
according to the extensions.
6
This approach has several benefits:
7
1. Provides support for heterogeneous cpu architectures. As we add decoder in
8
RISCVCPU, each cpu can have their own decoder, and the decoders can be
9
different due to cpu's features.
10
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
11
can be added to the dynamic_decoder when building up the decoder. Therefore,
12
there is no need to run the guard_func when decoding each instruction. It can
13
improve the decoding efficiency
14
3. For vendor or dynamic cpus, it allows them to customize their own decoder
15
functions to improve decoding efficiency, especially when vendor-defined
16
instruction sets increase. Because of dynamic building up, it can skip the other
17
decoder guard functions when decoding.
18
4. Pre patch for allowing adding a vendor decoder before decode_insn32() with minimal
19
overhead for users that don't need this particular vendor decoder.
5
20
6
Tested-by: Heiko Stuebner <heiko@sntech.de>
21
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
22
Suggested-by: Christoph Muellner <christoph.muellner@vrull.eu>
23
Co-authored-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
25
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Dao Lu <daolu@rivosinc.com>
26
Message-ID: <20240506023607.29544-1-eric.huang@linux.alibaba.com>
9
Message-Id: <20220725034728.2620750-2-daolu@rivosinc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
28
---
12
target/riscv/cpu.h | 1 +
29
target/riscv/cpu.h | 1 +
13
target/riscv/insn32.decode | 7 ++++++-
30
target/riscv/tcg/tcg-cpu.h | 15 +++++++++++++++
14
target/riscv/cpu.c | 2 ++
31
target/riscv/cpu.c | 1 +
15
target/riscv/insn_trans/trans_rvi.c.inc | 16 ++++++++++++++++
32
target/riscv/tcg/tcg-cpu.c | 15 +++++++++++++++
16
4 files changed, 25 insertions(+), 1 deletion(-)
33
target/riscv/translate.c | 31 +++++++++++++++----------------
34
5 files changed, 47 insertions(+), 16 deletions(-)
17
35
18
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
36
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
19
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/cpu.h
38
--- a/target/riscv/cpu.h
21
+++ b/target/riscv/cpu.h
39
+++ b/target/riscv/cpu.h
22
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
40
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
23
bool ext_zkt;
41
uint32_t pmu_avail_ctrs;
24
bool ext_ifencei;
42
/* Mapping of events to counters */
25
bool ext_icsr;
43
GHashTable *pmu_event_ctr_map;
26
+ bool ext_zihintpause;
44
+ const GPtrArray *decoders;
27
bool ext_svinval;
45
};
28
bool ext_svnapot;
46
29
bool ext_svpbmt;
47
/**
30
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
48
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
31
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
32
--- a/target/riscv/insn32.decode
50
--- a/target/riscv/tcg/tcg-cpu.h
33
+++ b/target/riscv/insn32.decode
51
+++ b/target/riscv/tcg/tcg-cpu.h
34
@@ -XXX,XX +XXX,XX @@ srl 0000000 ..... ..... 101 ..... 0110011 @r
52
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
35
sra 0100000 ..... ..... 101 ..... 0110011 @r
53
void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
36
or 0000000 ..... ..... 110 ..... 0110011 @r
54
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
37
and 0000000 ..... ..... 111 ..... 0110011 @r
55
38
-fence ---- pred:4 succ:4 ----- 000 ----- 0001111
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;
39
+
62
+
40
+{
63
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
41
+ pause 0000 0001 0000 00000 000 00000 0001111
42
+ fence ---- pred:4 succ:4 ----- 000 ----- 0001111
43
+}
44
+
64
+
45
fence_i ---- ---- ---- ----- 001 ----- 0001111
65
+extern const size_t decoder_table_size;
46
csrrw ............ ..... 001 ..... 1110011 @csr
66
+
47
csrrs ............ ..... 010 ..... 1110011 @csr
67
+extern const RISCVDecoder decoder_table[];
68
+
69
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
70
+
71
#endif
48
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
72
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
49
index XXXXXXX..XXXXXXX 100644
73
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/cpu.c
74
--- a/target/riscv/cpu.c
51
+++ b/target/riscv/cpu.c
75
+++ b/target/riscv/cpu.c
52
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
76
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
53
ISA_EXT_DATA_ENTRY(v, false, PRIV_VERSION_1_12_0, ext_v),
77
error_propagate(errp, local_err);
54
ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr),
78
return;
55
ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
79
}
56
+ ISA_EXT_DATA_ENTRY(zihintpause, true, PRIV_VERSION_1_10_0, ext_zihintpause),
80
+ riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
57
ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_12_0, ext_zfh),
81
} else if (kvm_enabled()) {
58
ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
82
riscv_kvm_cpu_finalize_features(cpu, &local_err);
59
ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
83
if (local_err != NULL) {
60
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
84
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
61
DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
62
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
63
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
64
+ DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
65
DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
66
DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
67
DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false),
68
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
69
index XXXXXXX..XXXXXXX 100644
85
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/insn_trans/trans_rvi.c.inc
86
--- a/target/riscv/tcg/tcg-cpu.c
71
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
87
+++ b/target/riscv/tcg/tcg-cpu.c
72
@@ -XXX,XX +XXX,XX @@ static bool trans_srad(DisasContext *ctx, arg_srad *a)
88
@@ -XXX,XX +XXX,XX @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
73
return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl, NULL);
89
}
74
}
90
}
75
91
76
+static bool trans_pause(DisasContext *ctx, arg_pause *a)
92
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
77
+{
93
+{
78
+ if (!ctx->cfg_ptr->ext_zihintpause) {
94
+ GPtrArray *dynamic_decoders;
79
+ return false;
95
+ dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
96
+ for (size_t i = 0; i < decoder_table_size; ++i) {
97
+ if (decoder_table[i].guard_func &&
98
+ decoder_table[i].guard_func(&cpu->cfg)) {
99
+ g_ptr_array_add(dynamic_decoders,
100
+ (gpointer)decoder_table[i].riscv_cpu_decode_fn);
101
+ }
80
+ }
102
+ }
81
+
103
+
82
+ /*
104
+ cpu->decoders = dynamic_decoders;
83
+ * PAUSE is a no-op in QEMU,
105
+}
84
+ * end the TB and return to main loop
85
+ */
86
+ gen_set_pc_imm(ctx, ctx->pc_succ_insn);
87
+ tcg_gen_exit_tb(NULL, 0);
88
+ ctx->base.is_jmp = DISAS_NORETURN;
89
+
106
+
90
+ return true;
107
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
91
+}
92
93
static bool trans_fence(DisasContext *ctx, arg_fence *a)
94
{
108
{
109
return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
110
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
111
index XXXXXXX..XXXXXXX 100644
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},
139
+};
140
+
141
+const size_t decoder_table_size = ARRAY_SIZE(decoder_table);
142
+
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;
179
}
180
181
static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
95
--
182
--
96
2.37.2
183
2.45.1
diff view generated by jsdifflib
1
From: Atish Patra <atishp@rivosinc.com>
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
2
2
3
stimecmp allows the supervisor mode to update stimecmp CSR directly
3
The th.sxstatus CSR can be used to identify available custom extension
4
to program the next timer interrupt. This CSR is part of the Sstc
4
on T-Head CPUs. The CSR is documented here:
5
extension which was ratified recently.
5
https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadsxstatus.adoc
6
6
7
An important property of this patch is, that the th.sxstatus MAEE field
8
is not set (indicating that XTheadMae is not available).
9
XTheadMae is a memory attribute extension (similar to Svpbmt) which is
10
implemented in many T-Head CPUs (C906, C910, etc.) and utilizes bits
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).
16
17
Further context can be found on the list:
18
https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg00775.html
19
20
Reviewed-by: LIU Zhiwei <zhiwe_liu@linux.alibaba.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Atish Patra <atishp@rivosinc.com>
22
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
9
Message-Id: <20220824221357.41070-3-atishp@rivosinc.com>
23
Message-ID: <20240429073656.2486732-1-christoph.muellner@vrull.eu>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
25
---
12
target/riscv/cpu.h | 5 ++
26
MAINTAINERS | 1 +
13
target/riscv/cpu_bits.h | 4 ++
27
target/riscv/cpu.h | 3 ++
14
target/riscv/time_helper.h | 30 ++++++++++++
28
target/riscv/cpu.c | 1 +
15
target/riscv/cpu.c | 9 ++++
29
target/riscv/th_csr.c | 79 ++++++++++++++++++++++++++++++++++++++++
16
target/riscv/csr.c | 86 +++++++++++++++++++++++++++++++++
30
target/riscv/meson.build | 1 +
17
target/riscv/machine.c | 1 +
31
5 files changed, 85 insertions(+)
18
target/riscv/time_helper.c | 98 ++++++++++++++++++++++++++++++++++++++
32
create mode 100644 target/riscv/th_csr.c
19
target/riscv/meson.build | 3 +-
20
8 files changed, 235 insertions(+), 1 deletion(-)
21
create mode 100644 target/riscv/time_helper.h
22
create mode 100644 target/riscv/time_helper.c
23
33
34
diff --git a/MAINTAINERS b/MAINTAINERS
35
index XXXXXXX..XXXXXXX 100644
36
--- a/MAINTAINERS
37
+++ b/MAINTAINERS
38
@@ -XXX,XX +XXX,XX @@ L: qemu-riscv@nongnu.org
39
S: Supported
40
F: target/riscv/insn_trans/trans_xthead.c.inc
41
F: target/riscv/xthead*.decode
42
+F: target/riscv/th_*
43
F: disas/riscv-xthead*
44
45
RISC-V XVentanaCondOps extension
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
46
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
48
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
49
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
50
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_new_csr_seed(target_ulong new_value,
29
uint64_t mfromhost;
51
uint8_t satp_mode_max_from_map(uint32_t map);
30
uint64_t mtohost;
52
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
31
53
32
+ /* Sstc CSRs */
54
+/* Implemented in th_csr.c */
33
+ uint64_t stimecmp;
55
+void th_register_custom_csrs(RISCVCPU *cpu);
34
+
56
+
35
/* physical memory protection */
57
#endif /* RISCV_CPU_H */
36
pmp_table_t pmp_state;
37
target_ulong mseccfg;
38
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
39
float_status fp_status;
40
41
/* Fields from here on are preserved across CPU reset. */
42
+ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
43
44
hwaddr kernel_addr;
45
hwaddr fdt_addr;
46
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
47
bool ext_ifencei;
48
bool ext_icsr;
49
bool ext_zihintpause;
50
+ bool ext_sstc;
51
bool ext_svinval;
52
bool ext_svnapot;
53
bool ext_svpbmt;
54
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/riscv/cpu_bits.h
57
+++ b/target/riscv/cpu_bits.h
58
@@ -XXX,XX +XXX,XX @@
59
#define CSR_STVAL 0x143
60
#define CSR_SIP 0x144
61
62
+/* Sstc supervisor CSRs */
63
+#define CSR_STIMECMP 0x14D
64
+#define CSR_STIMECMPH 0x15D
65
+
66
/* Supervisor Protection and Translation */
67
#define CSR_SPTBR 0x180
68
#define CSR_SATP 0x180
69
diff --git a/target/riscv/time_helper.h b/target/riscv/time_helper.h
70
new file mode 100644
71
index XXXXXXX..XXXXXXX
72
--- /dev/null
73
+++ b/target/riscv/time_helper.h
74
@@ -XXX,XX +XXX,XX @@
75
+/*
76
+ * RISC-V timer header file.
77
+ *
78
+ * Copyright (c) 2022 Rivos Inc.
79
+ *
80
+ * This program is free software; you can redistribute it and/or modify it
81
+ * under the terms and conditions of the GNU General Public License,
82
+ * version 2 or later, as published by the Free Software Foundation.
83
+ *
84
+ * This program is distributed in the hope it will be useful, but WITHOUT
85
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
86
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
87
+ * more details.
88
+ *
89
+ * You should have received a copy of the GNU General Public License along with
90
+ * this program. If not, see <http://www.gnu.org/licenses/>.
91
+ */
92
+
93
+#ifndef RISCV_TIME_HELPER_H
94
+#define RISCV_TIME_HELPER_H
95
+
96
+#include "cpu.h"
97
+#include "qemu/timer.h"
98
+
99
+void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer,
100
+ uint64_t timecmp, uint64_t delta,
101
+ uint32_t timer_irq);
102
+void riscv_timer_init(RISCVCPU *cpu);
103
+
104
+#endif
105
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
58
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
106
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
107
--- a/target/riscv/cpu.c
60
--- a/target/riscv/cpu.c
108
+++ b/target/riscv/cpu.c
61
+++ b/target/riscv/cpu.c
109
@@ -XXX,XX +XXX,XX @@
62
@@ -XXX,XX +XXX,XX @@ static void rv64_thead_c906_cpu_init(Object *obj)
110
#include "qemu/log.h"
63
cpu->cfg.mvendorid = THEAD_VENDOR_ID;
111
#include "cpu.h"
64
#ifndef CONFIG_USER_ONLY
112
#include "internals.h"
65
set_satp_mode_max_supported(cpu, VM_1_10_SV39);
113
+#include "time_helper.h"
66
+ th_register_custom_csrs(cpu);
114
#include "exec/exec-all.h"
67
#endif
115
#include "qapi/error.h"
68
116
#include "qemu/error-report.h"
69
/* inherited from parent obj via riscv_cpu_init() */
117
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
70
diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
118
ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
119
ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
120
ISA_EXT_DATA_ENTRY(ssaia, true, PRIV_VERSION_1_12_0, ext_ssaia),
121
+ ISA_EXT_DATA_ENTRY(sstc, true, PRIV_VERSION_1_12_0, ext_sstc),
122
ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
123
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
124
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
125
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
126
127
set_resetvec(env, cpu->cfg.resetvec);
128
129
+#ifndef CONFIG_USER_ONLY
130
+ if (cpu->cfg.ext_sstc) {
131
+ riscv_timer_init(cpu);
132
+ }
133
+#endif /* CONFIG_USER_ONLY */
134
+
135
/* Validate that MISA_MXL is set properly. */
136
switch (env->misa_mxl_max) {
137
#ifdef TARGET_RISCV64
138
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
139
DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
140
DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
141
DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
142
+ DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true),
143
144
DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
145
DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
146
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/target/riscv/csr.c
149
+++ b/target/riscv/csr.c
150
@@ -XXX,XX +XXX,XX @@
151
#include "qemu/timer.h"
152
#include "cpu.h"
153
#include "pmu.h"
154
+#include "time_helper.h"
155
#include "qemu/main-loop.h"
156
#include "exec/exec-all.h"
157
#include "sysemu/cpu-timers.h"
158
@@ -XXX,XX +XXX,XX @@ static RISCVException read_timeh(CPURISCVState *env, int csrno,
159
return RISCV_EXCP_NONE;
160
}
161
162
+static RISCVException sstc(CPURISCVState *env, int csrno)
163
+{
164
+ CPUState *cs = env_cpu(env);
165
+ RISCVCPU *cpu = RISCV_CPU(cs);
166
+
167
+ if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
168
+ return RISCV_EXCP_ILLEGAL_INST;
169
+ }
170
+
171
+ if (env->priv == PRV_M) {
172
+ return RISCV_EXCP_NONE;
173
+ }
174
+
175
+ /*
176
+ * No need of separate function for rv32 as menvcfg stores both menvcfg
177
+ * menvcfgh for RV32.
178
+ */
179
+ if (!(get_field(env->mcounteren, COUNTEREN_TM) &&
180
+ get_field(env->menvcfg, MENVCFG_STCE))) {
181
+ return RISCV_EXCP_ILLEGAL_INST;
182
+ }
183
+
184
+ return smode(env, csrno);
185
+}
186
+
187
+static RISCVException sstc_32(CPURISCVState *env, int csrno)
188
+{
189
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
190
+ return RISCV_EXCP_ILLEGAL_INST;
191
+ }
192
+
193
+ return sstc(env, csrno);
194
+}
195
+
196
+static RISCVException read_stimecmp(CPURISCVState *env, int csrno,
197
+ target_ulong *val)
198
+{
199
+ *val = env->stimecmp;
200
+ return RISCV_EXCP_NONE;
201
+}
202
+
203
+static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
204
+ target_ulong *val)
205
+{
206
+ *val = env->stimecmp >> 32;
207
+ return RISCV_EXCP_NONE;
208
+}
209
+
210
+static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
211
+ target_ulong val)
212
+{
213
+ RISCVCPU *cpu = env_archcpu(env);
214
+
215
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
216
+ env->stimecmp = deposit64(env->stimecmp, 0, 32, (uint64_t)val);
217
+ } else {
218
+ env->stimecmp = val;
219
+ }
220
+
221
+ riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP);
222
+
223
+ return RISCV_EXCP_NONE;
224
+}
225
+
226
+static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
227
+ target_ulong val)
228
+{
229
+ RISCVCPU *cpu = env_archcpu(env);
230
+
231
+ env->stimecmp = deposit64(env->stimecmp, 32, 32, (uint64_t)val);
232
+ riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP);
233
+
234
+ return RISCV_EXCP_NONE;
235
+}
236
+
237
/* Machine constants */
238
239
#define M_MODE_INTERRUPTS ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP))
240
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
241
new_val |= env->external_seip * MIP_SEIP;
242
}
243
244
+ if (cpu->cfg.ext_sstc && (env->priv == PRV_M) &&
245
+ get_field(env->menvcfg, MENVCFG_STCE)) {
246
+ /* sstc extension forbids STIP & VSTIP to be writeable in mip */
247
+ mask = mask & ~(MIP_STIP | MIP_VSTIP);
248
+ }
249
+
250
if (mask) {
251
old_mip = riscv_cpu_update_mip(cpu, mask, (new_val & mask));
252
} else {
253
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
254
[CSR_SCAUSE] = { "scause", smode, read_scause, write_scause },
255
[CSR_STVAL] = { "stval", smode, read_stval, write_stval },
256
[CSR_SIP] = { "sip", smode, NULL, NULL, rmw_sip },
257
+ [CSR_STIMECMP] = { "stimecmp", sstc, read_stimecmp, write_stimecmp,
258
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
259
+ [CSR_STIMECMPH] = { "stimecmph", sstc_32, read_stimecmph, write_stimecmph,
260
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
261
262
/* Supervisor Protection and Translation */
263
[CSR_SATP] = { "satp", smode, read_satp, write_satp },
264
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
265
index XXXXXXX..XXXXXXX 100644
266
--- a/target/riscv/machine.c
267
+++ b/target/riscv/machine.c
268
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
269
VMSTATE_UINTTL(env.mscratch, RISCVCPU),
270
VMSTATE_UINT64(env.mfromhost, RISCVCPU),
271
VMSTATE_UINT64(env.mtohost, RISCVCPU),
272
+ VMSTATE_UINT64(env.stimecmp, RISCVCPU),
273
274
VMSTATE_END_OF_LIST()
275
},
276
diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
277
new file mode 100644
71
new file mode 100644
278
index XXXXXXX..XXXXXXX
72
index XXXXXXX..XXXXXXX
279
--- /dev/null
73
--- /dev/null
280
+++ b/target/riscv/time_helper.c
74
+++ b/target/riscv/th_csr.c
281
@@ -XXX,XX +XXX,XX @@
75
@@ -XXX,XX +XXX,XX @@
282
+/*
76
+/*
283
+ * RISC-V timer helper implementation.
77
+ * T-Head-specific CSRs.
284
+ *
78
+ *
285
+ * Copyright (c) 2022 Rivos Inc.
79
+ * Copyright (c) 2024 VRULL GmbH
286
+ *
80
+ *
287
+ * 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
288
+ * under the terms and conditions of the GNU General Public License,
82
+ * under the terms and conditions of the GNU General Public License,
289
+ * version 2 or later, as published by the Free Software Foundation.
83
+ * version 2 or later, as published by the Free Software Foundation.
290
+ *
84
+ *
...
...
296
+ * 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
297
+ * this program. If not, see <http://www.gnu.org/licenses/>.
91
+ * this program. If not, see <http://www.gnu.org/licenses/>.
298
+ */
92
+ */
299
+
93
+
300
+#include "qemu/osdep.h"
94
+#include "qemu/osdep.h"
301
+#include "qemu/log.h"
95
+#include "cpu.h"
302
+#include "cpu_bits.h"
96
+#include "cpu_vendorid.h"
303
+#include "time_helper.h"
304
+#include "hw/intc/riscv_aclint.h"
305
+
97
+
306
+static void riscv_stimer_cb(void *opaque)
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)
307
+{
112
+{
308
+ RISCVCPU *cpu = opaque;
113
+ if (riscv_has_ext(env, RVS)) {
309
+ riscv_cpu_update_mip(cpu, MIP_STIP, BOOL_TO_MASK(1));
114
+ return RISCV_EXCP_NONE;
115
+ }
116
+
117
+ return RISCV_EXCP_ILLEGAL_INST;
310
+}
118
+}
311
+
119
+
312
+/*
120
+static int test_thead_mvendorid(RISCVCPU *cpu)
313
+ * Called when timecmp is written to update the QEMU timer or immediately
314
+ * trigger timer interrupt if mtimecmp <= current timer value.
315
+ */
316
+void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer,
317
+ uint64_t timecmp, uint64_t delta,
318
+ uint32_t timer_irq)
319
+{
121
+{
320
+ uint64_t diff, ns_diff, next;
122
+ if (cpu->cfg.mvendorid != THEAD_VENDOR_ID) {
321
+ CPURISCVState *env = &cpu->env;
123
+ return -1;
322
+ RISCVAclintMTimerState *mtimer = env->rdtime_fn_arg;
323
+ uint32_t timebase_freq = mtimer->timebase_freq;
324
+ uint64_t rtc_r = env->rdtime_fn(env->rdtime_fn_arg) + delta;
325
+
326
+ if (timecmp <= rtc_r) {
327
+ /*
328
+ * If we're setting an stimecmp value in the "past",
329
+ * immediately raise the timer interrupt
330
+ */
331
+ riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(1));
332
+ return;
333
+ }
124
+ }
334
+
125
+
335
+ /* Clear the [V]STIP bit in mip */
126
+ return 0;
336
+ riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
337
+
338
+ /* otherwise, set up the future timer interrupt */
339
+ diff = timecmp - rtc_r;
340
+ /* back to ns (note args switched in muldiv64) */
341
+ ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
342
+
343
+ /*
344
+ * check if ns_diff overflowed and check if the addition would potentially
345
+ * overflow
346
+ */
347
+ if ((NANOSECONDS_PER_SECOND > timebase_freq && ns_diff < diff) ||
348
+ ns_diff > INT64_MAX) {
349
+ next = INT64_MAX;
350
+ } else {
351
+ /*
352
+ * as it is very unlikely qemu_clock_get_ns will return a value
353
+ * greater than INT64_MAX, no additional check is needed for an
354
+ * unsigned integer overflow.
355
+ */
356
+ next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns_diff;
357
+ /*
358
+ * if ns_diff is INT64_MAX next may still be outside the range
359
+ * of a signed integer.
360
+ */
361
+ next = MIN(next, INT64_MAX);
362
+ }
363
+
364
+ timer_mod(timer, next);
365
+}
127
+}
366
+
128
+
367
+void riscv_timer_init(RISCVCPU *cpu)
129
+static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
130
+ target_ulong *val)
368
+{
131
+{
369
+ CPURISCVState *env;
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
+}
370
+
136
+
371
+ if (!cpu) {
137
+static riscv_csr th_csr_list[] = {
372
+ return;
138
+ {
139
+ .csrno = CSR_TH_SXSTATUS,
140
+ .insertion_test = test_thead_mvendorid,
141
+ .csr_ops = { "th.sxstatus", smode, read_th_sxstatus }
373
+ }
142
+ }
143
+};
374
+
144
+
375
+ env = &cpu->env;
145
+void th_register_custom_csrs(RISCVCPU *cpu)
376
+ env->stimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_stimer_cb, cpu);
146
+{
377
+ env->stimecmp = 0;
147
+ for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
378
+
148
+ int csrno = th_csr_list[i].csrno;
149
+ riscv_csr_operations *csr_ops = &th_csr_list[i].csr_ops;
150
+ if (!th_csr_list[i].insertion_test(cpu)) {
151
+ riscv_set_csr_ops(csrno, csr_ops);
152
+ }
153
+ }
379
+}
154
+}
380
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
155
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
381
index XXXXXXX..XXXXXXX 100644
156
index XXXXXXX..XXXXXXX 100644
382
--- a/target/riscv/meson.build
157
--- a/target/riscv/meson.build
383
+++ b/target/riscv/meson.build
158
+++ b/target/riscv/meson.build
384
@@ -XXX,XX +XXX,XX @@ riscv_softmmu_ss.add(files(
159
@@ -XXX,XX +XXX,XX @@ riscv_system_ss.add(files(
385
'debug.c',
386
'monitor.c',
160
'monitor.c',
387
'machine.c',
161
'machine.c',
388
- 'pmu.c'
162
'pmu.c',
389
+ 'pmu.c',
163
+ 'th_csr.c',
390
+ 'time_helper.c'
164
'time_helper.c',
165
'riscv-qmp-cmds.c',
391
))
166
))
392
393
target_arch += {'riscv': riscv_ss}
394
--
167
--
395
2.37.2
168
2.45.1
169
170
diff view generated by jsdifflib
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
3
According v spec 18.4, only the vfwcvt.f.f.v and vfncvt.f.f.w
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
4
instructions will be affected by Zvfhmin extension.
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
5
And the vfwcvt.f.f.v and vfncvt.f.f.w instructions only support the
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
6
conversions of
7
Message-Id: <165570784143.17634.35095816584573691-2@git.sr.ht>
7
8
* From 1*SEW(16/32) to 2*SEW(32/64)
9
* From 2*SEW(32/64) to 1*SEW(16/32)
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-2-max.chou@sifive.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
16
---
10
target/riscv/vector_helper.c | 35 +++++++++++++++++--------
17
target/riscv/insn_trans/trans_rvv.c.inc | 20 ++++++++++++++++++--
11
target/riscv/insn_trans/trans_rvv.c.inc | 5 ++++
18
1 file changed, 18 insertions(+), 2 deletions(-)
12
2 files changed, 29 insertions(+), 11 deletions(-)
13
19
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
19
uint32_t esz = 1 << log2_esz;
20
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
21
uint32_t vta = vext_vta(desc);
22
+ uint32_t vma = vext_vma(desc);
23
24
for (i = env->vstart; i < env->vl; i++, env->vstart++) {
25
- if (!vm && !vext_elem_mask(v0, i)) {
26
- continue;
27
- }
28
-
29
k = 0;
30
while (k < nf) {
31
+ if (!vm && !vext_elem_mask(v0, i)) {
32
+ /* set masked-off elements to 1s */
33
+ vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz,
34
+ (i + k * max_elems + 1) * esz);
35
+ k++;
36
+ continue;
37
+ }
38
target_ulong addr = base + stride * i + (k << log2_esz);
39
ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
40
k++;
41
@@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
42
uint32_t esz = 1 << log2_esz;
43
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
44
uint32_t vta = vext_vta(desc);
45
+ uint32_t vma = vext_vma(desc);
46
47
/* load bytes from guest memory */
48
for (i = env->vstart; i < env->vl; i++, env->vstart++) {
49
- if (!vm && !vext_elem_mask(v0, i)) {
50
- continue;
51
- }
52
-
53
k = 0;
54
while (k < nf) {
55
+ if (!vm && !vext_elem_mask(v0, i)) {
56
+ /* set masked-off elements to 1s */
57
+ vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz,
58
+ (i + k * max_elems + 1) * esz);
59
+ k++;
60
+ continue;
61
+ }
62
abi_ptr addr = get_index_addr(base, i, vs2) + (k << log2_esz);
63
ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
64
k++;
65
@@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base,
66
uint32_t esz = 1 << log2_esz;
67
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
68
uint32_t vta = vext_vta(desc);
69
+ uint32_t vma = vext_vma(desc);
70
target_ulong addr, offset, remain;
71
72
/* probe every access*/
73
@@ -XXX,XX +XXX,XX @@ ProbeSuccess:
74
}
75
for (i = env->vstart; i < env->vl; i++) {
76
k = 0;
77
- if (!vm && !vext_elem_mask(v0, i)) {
78
- continue;
79
- }
80
while (k < nf) {
81
+ if (!vm && !vext_elem_mask(v0, i)) {
82
+ /* set masked-off elements to 1s */
83
+ vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz,
84
+ (i + k * max_elems + 1) * esz);
85
+ k++;
86
+ continue;
87
+ }
88
target_ulong addr = base + ((i * nf + k) << log2_esz);
89
ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
90
k++;
91
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
92
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
93
--- a/target/riscv/insn_trans/trans_rvv.c.inc
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
94
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
95
@@ -XXX,XX +XXX,XX @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew)
24
@@ -XXX,XX +XXX,XX @@ static bool require_rvf(DisasContext *s)
96
data = FIELD_DP32(data, VDATA, LMUL, emul);
25
}
97
data = FIELD_DP32(data, VDATA, NF, a->nf);
98
data = FIELD_DP32(data, VDATA, VTA, s->vta);
99
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
100
return ldst_us_trans(a->rd, a->rs1, data, fn, s, false);
101
}
26
}
102
27
103
@@ -XXX,XX +XXX,XX @@ static bool ld_us_mask_op(DisasContext *s, arg_vlm_v *a, uint8_t eew)
28
+static bool require_rvfmin(DisasContext *s)
104
data = FIELD_DP32(data, VDATA, NF, 1);
29
+{
105
/* Mask destination register are always tail-agnostic */
30
+ if (s->mstatus_fs == EXT_STATUS_DISABLED) {
106
data = FIELD_DP32(data, VDATA, VTA, s->cfg_vta_all_1s);
31
+ return false;
107
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
32
+ }
108
return ldst_us_trans(a->rd, a->rs1, data, fn, s, false);
33
+
34
+ switch (s->sew) {
35
+ case MO_16:
36
+ return s->cfg_ptr->ext_zvfhmin;
37
+ case MO_32:
38
+ return s->cfg_ptr->ext_zve32f;
39
+ default:
40
+ return false;
41
+ }
42
+}
43
+
44
static bool require_scale_rvf(DisasContext *s)
45
{
46
if (s->mstatus_fs == EXT_STATUS_DISABLED) {
47
@@ -XXX,XX +XXX,XX @@ static bool require_scale_rvfmin(DisasContext *s)
48
}
49
50
switch (s->sew) {
51
- case MO_8:
52
- return s->cfg_ptr->ext_zvfhmin;
53
case MO_16:
54
return s->cfg_ptr->ext_zve32f;
55
case MO_32:
56
@@ -XXX,XX +XXX,XX @@ static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
57
static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
58
{
59
return opfv_widen_check(s, a) &&
60
+ require_rvfmin(s) &&
61
require_scale_rvfmin(s) &&
62
(s->sew != MO_8);
109
}
63
}
110
64
@@ -XXX,XX +XXX,XX @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
111
@@ -XXX,XX +XXX,XX @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t eew)
65
static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
112
data = FIELD_DP32(data, VDATA, LMUL, emul);
66
{
113
data = FIELD_DP32(data, VDATA, NF, a->nf);
67
return opfv_narrow_check(s, a) &&
114
data = FIELD_DP32(data, VDATA, VTA, s->vta);
68
+ require_rvfmin(s) &&
115
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
69
require_scale_rvfmin(s) &&
116
return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
70
(s->sew != MO_8);
117
}
71
}
118
119
@@ -XXX,XX +XXX,XX @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t eew)
120
data = FIELD_DP32(data, VDATA, LMUL, emul);
121
data = FIELD_DP32(data, VDATA, NF, a->nf);
122
data = FIELD_DP32(data, VDATA, VTA, s->vta);
123
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
124
return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
125
}
126
127
@@ -XXX,XX +XXX,XX @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew)
128
data = FIELD_DP32(data, VDATA, LMUL, emul);
129
data = FIELD_DP32(data, VDATA, NF, a->nf);
130
data = FIELD_DP32(data, VDATA, VTA, s->vta);
131
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
132
return ldff_trans(a->rd, a->rs1, data, fn, s);
133
}
134
135
--
72
--
136
2.37.2
73
2.45.1
diff view generated by jsdifflib
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
3
The require_scale_rvf function only checks the double width operator for
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
4
the vector floating point widen instructions, so most of the widen
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
5
checking functions need to add require_rvf for single width operator.
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
6
7
Message-Id: <165570784143.17634.35095816584573691-9@git.sr.ht>
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>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
16
---
10
target/riscv/vector_helper.c | 26 +++++++++++++++++++++++--
17
target/riscv/insn_trans/trans_rvv.c.inc | 5 +++++
11
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
18
1 file changed, 5 insertions(+)
12
2 files changed, 25 insertions(+), 2 deletions(-)
13
19
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
19
uint32_t esz = sizeof(ETYPE); \
20
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
21
uint32_t vta = vext_vta(desc); \
22
+ uint32_t vma = vext_vma(desc); \
23
target_ulong offset = s1, i_min, i; \
24
\
25
i_min = MAX(env->vstart, offset); \
26
for (i = i_min; i < vl; i++) { \
27
if (!vm && !vext_elem_mask(v0, i)) { \
28
+ /* set masked-off elements to 1s */ \
29
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
30
continue; \
31
} \
32
*((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - offset)); \
33
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
34
uint32_t esz = sizeof(ETYPE); \
35
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
36
uint32_t vta = vext_vta(desc); \
37
+ uint32_t vma = vext_vma(desc); \
38
target_ulong i_max, i; \
39
\
40
i_max = MAX(MIN(s1 < vlmax ? vlmax - s1 : 0, vl), env->vstart); \
41
for (i = env->vstart; i < i_max; ++i) { \
42
- if (vm || vext_elem_mask(v0, i)) { \
43
- *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + s1)); \
44
+ if (!vm && !vext_elem_mask(v0, i)) { \
45
+ /* set masked-off elements to 1s */ \
46
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
47
+ continue; \
48
} \
49
+ *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + s1)); \
50
} \
51
\
52
for (i = i_max; i < vl; ++i) { \
53
@@ -XXX,XX +XXX,XX @@ static void vslide1up_##BITWIDTH(void *vd, void *v0, target_ulong s1, \
54
uint32_t esz = sizeof(ETYPE); \
55
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
56
uint32_t vta = vext_vta(desc); \
57
+ uint32_t vma = vext_vma(desc); \
58
uint32_t i; \
59
\
60
for (i = env->vstart; i < vl; i++) { \
61
if (!vm && !vext_elem_mask(v0, i)) { \
62
+ /* set masked-off elements to 1s */ \
63
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
64
continue; \
65
} \
66
if (i == 0) { \
67
@@ -XXX,XX +XXX,XX @@ static void vslide1down_##BITWIDTH(void *vd, void *v0, target_ulong s1, \
68
uint32_t esz = sizeof(ETYPE); \
69
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
70
uint32_t vta = vext_vta(desc); \
71
+ uint32_t vma = vext_vma(desc); \
72
uint32_t i; \
73
\
74
for (i = env->vstart; i < vl; i++) { \
75
if (!vm && !vext_elem_mask(v0, i)) { \
76
+ /* set masked-off elements to 1s */ \
77
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
78
continue; \
79
} \
80
if (i == vl - 1) { \
81
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
82
uint32_t esz = sizeof(TS2); \
83
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
84
uint32_t vta = vext_vta(desc); \
85
+ uint32_t vma = vext_vma(desc); \
86
uint64_t index; \
87
uint32_t i; \
88
\
89
for (i = env->vstart; i < vl; i++) { \
90
if (!vm && !vext_elem_mask(v0, i)) { \
91
+ /* set masked-off elements to 1s */ \
92
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
93
continue; \
94
} \
95
index = *((TS1 *)vs1 + HS1(i)); \
96
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
97
uint32_t esz = sizeof(ETYPE); \
98
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
99
uint32_t vta = vext_vta(desc); \
100
+ uint32_t vma = vext_vma(desc); \
101
uint64_t index = s1; \
102
uint32_t i; \
103
\
104
for (i = env->vstart; i < vl; i++) { \
105
if (!vm && !vext_elem_mask(v0, i)) { \
106
+ /* set masked-off elements to 1s */ \
107
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
108
continue; \
109
} \
110
if (index >= vlmax) { \
111
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \
112
uint32_t esz = sizeof(ETYPE); \
113
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
114
uint32_t vta = vext_vta(desc); \
115
+ uint32_t vma = vext_vma(desc); \
116
uint32_t i; \
117
\
118
for (i = env->vstart; i < vl; i++) { \
119
if (!vm && !vext_elem_mask(v0, i)) { \
120
+ /* set masked-off elements to 1s */ \
121
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
122
continue; \
123
} \
124
*((ETYPE *)vd + HD(i)) = *((DTYPE *)vs2 + HS1(i)); \
125
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
126
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
127
--- a/target/riscv/insn_trans/trans_rvv.c.inc
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
128
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
129
@@ -XXX,XX +XXX,XX @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
24
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check)
130
data = FIELD_DP32(data, VDATA, VM, a->vm);
25
static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
131
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
26
{
132
data = FIELD_DP32(data, VDATA, VTA, s->vta);
27
return require_rvv(s) &&
133
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
28
+ require_rvf(s) &&
134
29
require_scale_rvf(s) &&
135
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
30
(s->sew != MO_8) &&
136
vreg_ofs(s, a->rs2), cpu_env,
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);
63
}
137
--
64
--
138
2.37.2
65
2.45.1
66
67
diff view generated by jsdifflib
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
3
The opfv_narrow_check needs to check the single width float operator by
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
4
require_rvf.
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
5
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
6
Signed-off-by: Max Chou <max.chou@sifive.com>
7
Message-Id: <165570784143.17634.35095816584573691-8@git.sr.ht>
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>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
11
---
10
target/riscv/vector_helper.c | 11 +++++++++++
12
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
11
target/riscv/insn_trans/trans_rvv.c.inc | 3 +++
13
1 file changed, 1 insertion(+)
12
2 files changed, 14 insertions(+)
13
14
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ static void vmsetm(void *vd, void *v0, void *vs2, CPURISCVState *env,
19
uint32_t vl = env->vl;
20
uint32_t total_elems = env_archcpu(env)->cfg.vlen;
21
uint32_t vta_all_1s = vext_vta_all_1s(desc);
22
+ uint32_t vma = vext_vma(desc);
23
int i;
24
bool first_mask_bit = false;
25
26
for (i = env->vstart; i < vl; i++) {
27
if (!vm && !vext_elem_mask(v0, i)) {
28
+ /* set masked-off elements to 1s */
29
+ if (vma) {
30
+ vext_set_elem_mask(vd, i, 1);
31
+ }
32
continue;
33
}
34
/* write a zero to all following active elements */
35
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, CPURISCVState *env, \
36
uint32_t esz = sizeof(ETYPE); \
37
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
38
uint32_t vta = vext_vta(desc); \
39
+ uint32_t vma = vext_vma(desc); \
40
uint32_t sum = 0; \
41
int i; \
42
\
43
for (i = env->vstart; i < vl; i++) { \
44
if (!vm && !vext_elem_mask(v0, i)) { \
45
+ /* set masked-off elements to 1s */ \
46
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
47
continue; \
48
} \
49
*((ETYPE *)vd + H(i)) = sum; \
50
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, CPURISCVState *env, uint32_t desc) \
51
uint32_t esz = sizeof(ETYPE); \
52
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
53
uint32_t vta = vext_vta(desc); \
54
+ uint32_t vma = vext_vma(desc); \
55
int i; \
56
\
57
for (i = env->vstart; i < vl; i++) { \
58
if (!vm && !vext_elem_mask(v0, i)) { \
59
+ /* set masked-off elements to 1s */ \
60
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
61
continue; \
62
} \
63
*((ETYPE *)vd + H(i)) = i; \
64
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
65
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
66
--- a/target/riscv/insn_trans/trans_rvv.c.inc
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
67
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
68
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
19
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
69
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
20
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
70
data = \
21
{
71
FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
22
return opfv_narrow_check(s, a) &&
72
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
23
+ require_rvf(s) &&
73
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), \
24
require_scale_rvf(s) &&
74
vreg_ofs(s, 0), vreg_ofs(s, a->rs2), \
25
(s->sew != MO_8);
75
cpu_env, s->cfg_ptr->vlen / 8, \
26
}
76
@@ -XXX,XX +XXX,XX @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
77
data = FIELD_DP32(data, VDATA, VM, a->vm);
78
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
79
data = FIELD_DP32(data, VDATA, VTA, s->vta);
80
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
81
static gen_helper_gvec_3_ptr * const fns[4] = {
82
gen_helper_viota_m_b, gen_helper_viota_m_h,
83
gen_helper_viota_m_w, gen_helper_viota_m_d,
84
@@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
85
data = FIELD_DP32(data, VDATA, VM, a->vm);
86
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
87
data = FIELD_DP32(data, VDATA, VTA, s->vta);
88
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
89
static gen_helper_gvec_2_ptr * const fns[4] = {
90
gen_helper_vid_v_b, gen_helper_vid_v_h,
91
gen_helper_vid_v_w, gen_helper_vid_v_d,
92
--
27
--
93
2.37.2
28
2.45.1
diff view generated by jsdifflib
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
3
If the checking functions check both the single and double width
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
4
operators at the same time, then the single width operator checking
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
5
functions (require_rvf[min]) will check whether the SEW is 8.
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
6
7
Message-Id: <165570784143.17634.35095816584573691-7@git.sr.ht>
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>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
12
---
10
target/riscv/vector_helper.c | 26 +++++++++++++++++++++++++
13
target/riscv/insn_trans/trans_rvv.c.inc | 16 ++++------------
11
target/riscv/insn_trans/trans_rvv.c.inc | 12 ++++++++++++
14
1 file changed, 4 insertions(+), 12 deletions(-)
12
2 files changed, 38 insertions(+)
13
15
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \
19
uint32_t total_elems = \
20
vext_get_total_elems(env, desc, ESZ); \
21
uint32_t vta = vext_vta(desc); \
22
+ uint32_t vma = vext_vma(desc); \
23
uint32_t i; \
24
\
25
for (i = env->vstart; i < vl; i++) { \
26
if (!vm && !vext_elem_mask(v0, i)) { \
27
+ /* set masked-off elements to 1s */ \
28
+ vext_set_elems_1s(vd, vma, i * ESZ, \
29
+ (i + 1) * ESZ); \
30
continue; \
31
} \
32
do_##NAME(vd, vs1, vs2, i, env); \
33
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, \
34
uint32_t total_elems = \
35
vext_get_total_elems(env, desc, ESZ); \
36
uint32_t vta = vext_vta(desc); \
37
+ uint32_t vma = vext_vma(desc); \
38
uint32_t i; \
39
\
40
for (i = env->vstart; i < vl; i++) { \
41
if (!vm && !vext_elem_mask(v0, i)) { \
42
+ /* set masked-off elements to 1s */ \
43
+ vext_set_elems_1s(vd, vma, i * ESZ, \
44
+ (i + 1) * ESZ); \
45
continue; \
46
} \
47
do_##NAME(vd, s1, vs2, i, env); \
48
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \
49
uint32_t total_elems = \
50
vext_get_total_elems(env, desc, ESZ); \
51
uint32_t vta = vext_vta(desc); \
52
+ uint32_t vma = vext_vma(desc); \
53
uint32_t i; \
54
\
55
if (vl == 0) { \
56
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \
57
} \
58
for (i = env->vstart; i < vl; i++) { \
59
if (!vm && !vext_elem_mask(v0, i)) { \
60
+ /* set masked-off elements to 1s */ \
61
+ vext_set_elems_1s(vd, vma, i * ESZ, \
62
+ (i + 1) * ESZ); \
63
continue; \
64
} \
65
do_##NAME(vd, vs2, i, env); \
66
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
67
uint32_t vl = env->vl; \
68
uint32_t total_elems = env_archcpu(env)->cfg.vlen; \
69
uint32_t vta_all_1s = vext_vta_all_1s(desc); \
70
+ uint32_t vma = vext_vma(desc); \
71
uint32_t i; \
72
\
73
for (i = env->vstart; i < vl; i++) { \
74
ETYPE s1 = *((ETYPE *)vs1 + H(i)); \
75
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
76
if (!vm && !vext_elem_mask(v0, i)) { \
77
+ /* set masked-off elements to 1s */ \
78
+ if (vma) { \
79
+ vext_set_elem_mask(vd, i, 1); \
80
+ } \
81
continue; \
82
} \
83
vext_set_elem_mask(vd, i, \
84
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \
85
uint32_t vl = env->vl; \
86
uint32_t total_elems = env_archcpu(env)->cfg.vlen; \
87
uint32_t vta_all_1s = vext_vta_all_1s(desc); \
88
+ uint32_t vma = vext_vma(desc); \
89
uint32_t i; \
90
\
91
for (i = env->vstart; i < vl; i++) { \
92
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
93
if (!vm && !vext_elem_mask(v0, i)) { \
94
+ /* set masked-off elements to 1s */ \
95
+ if (vma) { \
96
+ vext_set_elem_mask(vd, i, 1); \
97
+ } \
98
continue; \
99
} \
100
vext_set_elem_mask(vd, i, \
101
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \
102
uint32_t total_elems = \
103
vext_get_total_elems(env, desc, ESZ); \
104
uint32_t vta = vext_vta(desc); \
105
+ uint32_t vma = vext_vma(desc); \
106
uint32_t i; \
107
\
108
for (i = env->vstart; i < vl; i++) { \
109
if (!vm && !vext_elem_mask(v0, i)) { \
110
+ /* set masked-off elements to 1s */ \
111
+ vext_set_elems_1s(vd, vma, i * ESZ, \
112
+ (i + 1) * ESZ); \
113
continue; \
114
} \
115
do_##NAME(vd, vs2, i); \
116
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
117
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
118
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
--- a/target/riscv/insn_trans/trans_rvv.c.inc
119
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
120
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
20
@@ -XXX,XX +XXX,XX @@ static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
121
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
21
return require_rvv(s) &&
122
data = \
22
require_rvf(s) &&
123
FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
23
require_scale_rvf(s) &&
124
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
24
- (s->sew != MO_8) &&
125
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
25
vext_check_isa_ill(s) &&
126
vreg_ofs(s, a->rs1), \
26
vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
127
vreg_ofs(s, a->rs2), cpu_env, \
27
}
128
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
28
@@ -XXX,XX +XXX,XX @@ static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
129
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
29
return require_rvv(s) &&
130
data = FIELD_DP32(data, VDATA, VTA_ALL_1S, \
30
require_rvf(s) &&
131
s->cfg_vta_all_1s); \
31
require_scale_rvf(s) &&
132
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
32
- (s->sew != MO_8) &&
133
return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
33
vext_check_isa_ill(s) &&
134
fns[s->sew - 1], s); \
34
vext_check_ds(s, a->rd, a->rs2, a->vm);
135
} \
35
}
136
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
36
@@ -XXX,XX +XXX,XX @@ static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
137
data = FIELD_DP32(data, VDATA, VM, a->vm); \
37
return require_rvv(s) &&
138
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
38
require_rvf(s) &&
139
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
39
require_scale_rvf(s) &&
140
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
40
- (s->sew != MO_8) &&
141
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
41
vext_check_isa_ill(s) &&
142
vreg_ofs(s, a->rs1), \
42
vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
143
vreg_ofs(s, a->rs2), cpu_env, \
43
}
144
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
44
@@ -XXX,XX +XXX,XX @@ static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
145
data = FIELD_DP32(data, VDATA, VM, a->vm); \
45
return require_rvv(s) &&
146
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
46
require_rvf(s) &&
147
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
47
require_scale_rvf(s) &&
148
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
48
- (s->sew != MO_8) &&
149
return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
49
vext_check_isa_ill(s) &&
150
fns[s->sew - 1], s); \
50
vext_check_dd(s, a->rd, a->rs2, a->vm);
151
} \
51
}
152
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
52
@@ -XXX,XX +XXX,XX @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
153
data = FIELD_DP32(data, VDATA, VM, a->vm); \
53
{
154
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
54
return opfv_widen_check(s, a) &&
155
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
55
require_rvfmin(s) &&
156
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
56
- require_scale_rvfmin(s) &&
157
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
57
- (s->sew != MO_8);
158
vreg_ofs(s, a->rs1), \
58
+ require_scale_rvfmin(s);
159
vreg_ofs(s, a->rs2), cpu_env, \
59
}
160
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
60
161
data = FIELD_DP32(data, VDATA, VM, a->vm); \
61
#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
162
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
62
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
163
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
63
{
164
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
64
return opfv_narrow_check(s, a) &&
165
return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
65
require_rvfmin(s) &&
166
fns[s->sew - 1], s); \
66
- require_scale_rvfmin(s) &&
167
} \
67
- (s->sew != MO_8);
168
@@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
68
+ require_scale_rvfmin(s);
169
data = FIELD_DP32(data, VDATA, VM, a->vm);
69
}
170
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
70
171
data = FIELD_DP32(data, VDATA, VTA, s->vta);
71
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
172
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
72
{
173
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
73
return opfv_narrow_check(s, a) &&
174
vreg_ofs(s, a->rs2), cpu_env,
74
require_rvf(s) &&
175
s->cfg_ptr->vlen / 8,
75
- require_scale_rvf(s) &&
176
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
76
- (s->sew != MO_8);
177
TCGv_i32 desc;
77
+ require_scale_rvf(s);
178
uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
78
}
179
data = FIELD_DP32(data, VDATA, VTA, s->vta);
79
180
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
80
#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \
181
static gen_helper_vmv_vx * const fns[3] = {
81
@@ -XXX,XX +XXX,XX @@ static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
182
gen_helper_vmv_v_x_h,
82
{
183
gen_helper_vmv_v_x_w,
83
return reduction_widen_check(s, a) &&
184
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
84
require_rvf(s) &&
185
data = FIELD_DP32(data, VDATA, VM, a->vm); \
85
- require_scale_rvf(s) &&
186
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
86
- (s->sew != MO_8);
187
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
87
+ require_scale_rvf(s);
188
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
88
}
189
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
89
190
vreg_ofs(s, a->rs2), cpu_env, \
90
GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check)
191
s->cfg_ptr->vlen / 8, \
192
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
193
data = FIELD_DP32(data, VDATA, VM, a->vm); \
194
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
195
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
196
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
197
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
198
vreg_ofs(s, a->rs2), cpu_env, \
199
s->cfg_ptr->vlen / 8, \
200
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
201
data = FIELD_DP32(data, VDATA, VM, a->vm); \
202
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
203
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
204
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
205
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
206
vreg_ofs(s, a->rs2), cpu_env, \
207
s->cfg_ptr->vlen / 8, \
208
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
209
data = FIELD_DP32(data, VDATA, VM, a->vm); \
210
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
211
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
212
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
213
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
214
vreg_ofs(s, a->rs2), cpu_env, \
215
s->cfg_ptr->vlen / 8, \
216
--
91
--
217
2.37.2
92
2.45.1
diff view generated by jsdifflib
1
From: Anup Patel <apatel@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
We should write transformed instruction encoding of the trapped
3
raise_mmu_exception(), as is today, is prioritizing guest page faults by
4
instruction in [m|h]tinst CSR at time of taking trap as defined
4
checking first if virt_enabled && !first_stage, and then considering the
5
by the RISC-V privileged specification v1.12.
5
regular inst/load/store faults.
6
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>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
30
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
31
Message-ID: <20240413105929.7030-1-alexei.filippov@syntacore.com>
9
Acked-by: dramforever <dramforever@live.com>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
10
Message-Id: <20220630061150.905174-2-apatel@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
34
---
13
target/riscv/cpu.h | 5 +
35
target/riscv/cpu_helper.c | 22 ++++++++++++----------
14
target/riscv/instmap.h | 45 +++++++
36
1 file changed, 12 insertions(+), 10 deletions(-)
15
target/riscv/cpu_helper.c | 252 +++++++++++++++++++++++++++++++++++++-
16
3 files changed, 296 insertions(+), 6 deletions(-)
17
37
18
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/cpu.h
21
+++ b/target/riscv/cpu.h
22
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
23
/* Signals whether the current exception occurred with two-stage address
24
translation active. */
25
bool two_stage_lookup;
26
+ /*
27
+ * Signals whether the current exception occurred while doing two-stage
28
+ * address translation for the VS-stage page table walk.
29
+ */
30
+ bool two_stage_indirect_lookup;
31
32
target_ulong scounteren;
33
target_ulong mcounteren;
34
diff --git a/target/riscv/instmap.h b/target/riscv/instmap.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/riscv/instmap.h
37
+++ b/target/riscv/instmap.h
38
@@ -XXX,XX +XXX,XX @@ enum {
39
OPC_RISC_CSRRWI = OPC_RISC_SYSTEM | (0x5 << 12),
40
OPC_RISC_CSRRSI = OPC_RISC_SYSTEM | (0x6 << 12),
41
OPC_RISC_CSRRCI = OPC_RISC_SYSTEM | (0x7 << 12),
42
+
43
+ OPC_RISC_HLVHSV = OPC_RISC_SYSTEM | (0x4 << 12),
44
};
45
46
#define MASK_OP_FP_LOAD(op) (MASK_OP_MAJOR(op) | (op & (0x7 << 12)))
47
@@ -XXX,XX +XXX,XX @@ enum {
48
| (extract32(inst, 12, 8) << 12) \
49
| (sextract64(inst, 31, 1) << 20))
50
51
+#define GET_FUNCT3(inst) extract32(inst, 12, 3)
52
+#define GET_FUNCT7(inst) extract32(inst, 25, 7)
53
#define GET_RM(inst) extract32(inst, 12, 3)
54
#define GET_RS3(inst) extract32(inst, 27, 5)
55
#define GET_RS1(inst) extract32(inst, 15, 5)
56
#define GET_RS2(inst) extract32(inst, 20, 5)
57
#define GET_RD(inst) extract32(inst, 7, 5)
58
#define GET_IMM(inst) sextract64(inst, 20, 12)
59
+#define SET_RS1(inst, val) deposit32(inst, 15, 5, val)
60
+#define SET_RS2(inst, val) deposit32(inst, 20, 5, val)
61
+#define SET_RD(inst, val) deposit32(inst, 7, 5, val)
62
+#define SET_I_IMM(inst, val) deposit32(inst, 20, 12, val)
63
+#define SET_S_IMM(inst, val) \
64
+ deposit32(deposit32(inst, 7, 5, val), 25, 7, (val) >> 5)
65
66
/* RVC decoding macros */
67
#define GET_C_IMM(inst) (extract32(inst, 2, 5) \
68
@@ -XXX,XX +XXX,XX @@ enum {
69
| (extract32(inst, 5, 1) << 6))
70
#define GET_C_LD_IMM(inst) ((extract16(inst, 10, 3) << 3) \
71
| (extract16(inst, 5, 2) << 6))
72
+#define GET_C_SW_IMM(inst) GET_C_LW_IMM(inst)
73
+#define GET_C_SD_IMM(inst) GET_C_LD_IMM(inst)
74
#define GET_C_J_IMM(inst) ((extract32(inst, 3, 3) << 1) \
75
| (extract32(inst, 11, 1) << 4) \
76
| (extract32(inst, 2, 1) << 5) \
77
@@ -XXX,XX +XXX,XX @@ enum {
78
#define GET_C_RS1S(inst) (8 + extract16(inst, 7, 3))
79
#define GET_C_RS2S(inst) (8 + extract16(inst, 2, 3))
80
81
+#define GET_C_FUNC(inst) extract32(inst, 13, 3)
82
+#define GET_C_OP(inst) extract32(inst, 0, 2)
83
+
84
+enum {
85
+ /* RVC Quadrants */
86
+ OPC_RISC_C_OP_QUAD0 = 0x0,
87
+ OPC_RISC_C_OP_QUAD1 = 0x1,
88
+ OPC_RISC_C_OP_QUAD2 = 0x2
89
+};
90
+
91
+enum {
92
+ /* RVC Quadrant 0 */
93
+ OPC_RISC_C_FUNC_ADDI4SPN = 0x0,
94
+ OPC_RISC_C_FUNC_FLD_LQ = 0x1,
95
+ OPC_RISC_C_FUNC_LW = 0x2,
96
+ OPC_RISC_C_FUNC_FLW_LD = 0x3,
97
+ OPC_RISC_C_FUNC_FSD_SQ = 0x5,
98
+ OPC_RISC_C_FUNC_SW = 0x6,
99
+ OPC_RISC_C_FUNC_FSW_SD = 0x7
100
+};
101
+
102
+enum {
103
+ /* RVC Quadrant 2 */
104
+ OPC_RISC_C_FUNC_SLLI_SLLI64 = 0x0,
105
+ OPC_RISC_C_FUNC_FLDSP_LQSP = 0x1,
106
+ OPC_RISC_C_FUNC_LWSP = 0x2,
107
+ OPC_RISC_C_FUNC_FLWSP_LDSP = 0x3,
108
+ OPC_RISC_C_FUNC_JR_MV_EBREAK_JALR_ADD = 0x4,
109
+ OPC_RISC_C_FUNC_FSDSP_SQSP = 0x5,
110
+ OPC_RISC_C_FUNC_SWSP = 0x6,
111
+ OPC_RISC_C_FUNC_FSWSP_SDSP = 0x7
112
+};
113
+
114
#endif
115
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
116
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
117
--- a/target/riscv/cpu_helper.c
40
--- a/target/riscv/cpu_helper.c
118
+++ b/target/riscv/cpu_helper.c
41
+++ b/target/riscv/cpu_helper.c
119
@@ -XXX,XX +XXX,XX @@
120
#include "qemu/main-loop.h"
121
#include "cpu.h"
122
#include "exec/exec-all.h"
123
+#include "instmap.h"
124
#include "tcg/tcg-op.h"
125
#include "trace.h"
126
#include "semihosting/common-semi.h"
127
@@ -XXX,XX +XXX,XX @@ restart:
128
129
static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
130
MMUAccessType access_type, bool pmp_violation,
131
- bool first_stage, bool two_stage)
132
+ bool first_stage, bool two_stage,
133
+ bool two_stage_indirect)
134
{
135
CPUState *cs = env_cpu(env);
136
int page_fault_exceptions, vm;
137
@@ -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,
138
}
43
139
env->badaddr = address;
44
switch (access_type) {
140
env->two_stage_lookup = two_stage;
45
case MMU_INST_FETCH:
141
+ env->two_stage_indirect_lookup = two_stage_indirect;
46
- if (env->virt_enabled && !first_stage) {
142
}
47
+ if (pmp_violation) {
143
48
+ cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT;
144
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
49
+ } else if (env->virt_enabled && !first_stage) {
145
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
50
cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT;
146
env->badaddr = addr;
51
} else {
147
env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
52
- cs->exception_index = pmp_violation ?
148
riscv_cpu_two_stage_lookup(mmu_idx);
53
- RISCV_EXCP_INST_ACCESS_FAULT : RISCV_EXCP_INST_PAGE_FAULT;
149
+ env->two_stage_indirect_lookup = false;
54
+ cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT;
150
cpu_loop_exit_restore(cs, retaddr);
151
}
152
153
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
154
env->badaddr = addr;
155
env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
156
riscv_cpu_two_stage_lookup(mmu_idx);
157
+ env->two_stage_indirect_lookup = false;
158
cpu_loop_exit_restore(cs, retaddr);
159
}
160
161
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
162
bool pmp_violation = false;
163
bool first_stage_error = true;
164
bool two_stage_lookup = false;
165
+ bool two_stage_indirect_error = false;
166
int ret = TRANSLATE_FAIL;
167
int mode = mmu_idx;
168
/* default TLB page size */
169
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
170
*/
171
if (ret == TRANSLATE_G_STAGE_FAIL) {
172
first_stage_error = false;
173
+ two_stage_indirect_error = true;
174
access_type = MMU_DATA_LOAD;
175
}
55
}
176
56
break;
177
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
57
case MMU_DATA_LOAD:
178
raise_mmu_exception(env, address, access_type, pmp_violation,
58
- if (two_stage && !first_stage) {
179
first_stage_error,
59
+ if (pmp_violation) {
180
riscv_cpu_virt_enabled(env) ||
60
+ cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT;
181
- riscv_cpu_two_stage_lookup(mmu_idx));
61
+ } else if (two_stage && !first_stage) {
182
+ riscv_cpu_two_stage_lookup(mmu_idx),
62
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
183
+ two_stage_indirect_error);
63
} else {
184
cpu_loop_exit_restore(cs, retaddr);
64
- cs->exception_index = pmp_violation ?
185
}
65
- RISCV_EXCP_LOAD_ACCESS_FAULT : RISCV_EXCP_LOAD_PAGE_FAULT;
186
66
+ cs->exception_index = RISCV_EXCP_LOAD_PAGE_FAULT;
187
return true;
67
}
188
}
68
break;
189
+
69
case MMU_DATA_STORE:
190
+static target_ulong riscv_transformed_insn(CPURISCVState *env,
70
- if (two_stage && !first_stage) {
191
+ target_ulong insn,
71
+ if (pmp_violation) {
192
+ target_ulong taddr)
72
+ cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
193
+{
73
+ } else if (two_stage && !first_stage) {
194
+ target_ulong xinsn = 0;
74
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
195
+ target_ulong access_rs1 = 0, access_imm = 0, access_size = 0;
75
} else {
196
+
76
- cs->exception_index = pmp_violation ?
197
+ /*
77
- RISCV_EXCP_STORE_AMO_ACCESS_FAULT :
198
+ * Only Quadrant 0 and Quadrant 2 of RVC instruction space need to
78
- RISCV_EXCP_STORE_PAGE_FAULT;
199
+ * be uncompressed. The Quadrant 1 of RVC instruction space need
79
+ cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
200
+ * not be transformed because these instructions won't generate
80
}
201
+ * any load/store trap.
81
break;
202
+ */
82
default:
203
+
204
+ if ((insn & 0x3) != 0x3) {
205
+ /* Transform 16bit instruction into 32bit instruction */
206
+ switch (GET_C_OP(insn)) {
207
+ case OPC_RISC_C_OP_QUAD0: /* Quadrant 0 */
208
+ switch (GET_C_FUNC(insn)) {
209
+ case OPC_RISC_C_FUNC_FLD_LQ:
210
+ if (riscv_cpu_xlen(env) != 128) { /* C.FLD (RV32/64) */
211
+ xinsn = OPC_RISC_FLD;
212
+ xinsn = SET_RD(xinsn, GET_C_RS2S(insn));
213
+ access_rs1 = GET_C_RS1S(insn);
214
+ access_imm = GET_C_LD_IMM(insn);
215
+ access_size = 8;
216
+ }
217
+ break;
218
+ case OPC_RISC_C_FUNC_LW: /* C.LW */
219
+ xinsn = OPC_RISC_LW;
220
+ xinsn = SET_RD(xinsn, GET_C_RS2S(insn));
221
+ access_rs1 = GET_C_RS1S(insn);
222
+ access_imm = GET_C_LW_IMM(insn);
223
+ access_size = 4;
224
+ break;
225
+ case OPC_RISC_C_FUNC_FLW_LD:
226
+ if (riscv_cpu_xlen(env) == 32) { /* C.FLW (RV32) */
227
+ xinsn = OPC_RISC_FLW;
228
+ xinsn = SET_RD(xinsn, GET_C_RS2S(insn));
229
+ access_rs1 = GET_C_RS1S(insn);
230
+ access_imm = GET_C_LW_IMM(insn);
231
+ access_size = 4;
232
+ } else { /* C.LD (RV64/RV128) */
233
+ xinsn = OPC_RISC_LD;
234
+ xinsn = SET_RD(xinsn, GET_C_RS2S(insn));
235
+ access_rs1 = GET_C_RS1S(insn);
236
+ access_imm = GET_C_LD_IMM(insn);
237
+ access_size = 8;
238
+ }
239
+ break;
240
+ case OPC_RISC_C_FUNC_FSD_SQ:
241
+ if (riscv_cpu_xlen(env) != 128) { /* C.FSD (RV32/64) */
242
+ xinsn = OPC_RISC_FSD;
243
+ xinsn = SET_RS2(xinsn, GET_C_RS2S(insn));
244
+ access_rs1 = GET_C_RS1S(insn);
245
+ access_imm = GET_C_SD_IMM(insn);
246
+ access_size = 8;
247
+ }
248
+ break;
249
+ case OPC_RISC_C_FUNC_SW: /* C.SW */
250
+ xinsn = OPC_RISC_SW;
251
+ xinsn = SET_RS2(xinsn, GET_C_RS2S(insn));
252
+ access_rs1 = GET_C_RS1S(insn);
253
+ access_imm = GET_C_SW_IMM(insn);
254
+ access_size = 4;
255
+ break;
256
+ case OPC_RISC_C_FUNC_FSW_SD:
257
+ if (riscv_cpu_xlen(env) == 32) { /* C.FSW (RV32) */
258
+ xinsn = OPC_RISC_FSW;
259
+ xinsn = SET_RS2(xinsn, GET_C_RS2S(insn));
260
+ access_rs1 = GET_C_RS1S(insn);
261
+ access_imm = GET_C_SW_IMM(insn);
262
+ access_size = 4;
263
+ } else { /* C.SD (RV64/RV128) */
264
+ xinsn = OPC_RISC_SD;
265
+ xinsn = SET_RS2(xinsn, GET_C_RS2S(insn));
266
+ access_rs1 = GET_C_RS1S(insn);
267
+ access_imm = GET_C_SD_IMM(insn);
268
+ access_size = 8;
269
+ }
270
+ break;
271
+ default:
272
+ break;
273
+ }
274
+ break;
275
+ case OPC_RISC_C_OP_QUAD2: /* Quadrant 2 */
276
+ switch (GET_C_FUNC(insn)) {
277
+ case OPC_RISC_C_FUNC_FLDSP_LQSP:
278
+ if (riscv_cpu_xlen(env) != 128) { /* C.FLDSP (RV32/64) */
279
+ xinsn = OPC_RISC_FLD;
280
+ xinsn = SET_RD(xinsn, GET_C_RD(insn));
281
+ access_rs1 = 2;
282
+ access_imm = GET_C_LDSP_IMM(insn);
283
+ access_size = 8;
284
+ }
285
+ break;
286
+ case OPC_RISC_C_FUNC_LWSP: /* C.LWSP */
287
+ xinsn = OPC_RISC_LW;
288
+ xinsn = SET_RD(xinsn, GET_C_RD(insn));
289
+ access_rs1 = 2;
290
+ access_imm = GET_C_LWSP_IMM(insn);
291
+ access_size = 4;
292
+ break;
293
+ case OPC_RISC_C_FUNC_FLWSP_LDSP:
294
+ if (riscv_cpu_xlen(env) == 32) { /* C.FLWSP (RV32) */
295
+ xinsn = OPC_RISC_FLW;
296
+ xinsn = SET_RD(xinsn, GET_C_RD(insn));
297
+ access_rs1 = 2;
298
+ access_imm = GET_C_LWSP_IMM(insn);
299
+ access_size = 4;
300
+ } else { /* C.LDSP (RV64/RV128) */
301
+ xinsn = OPC_RISC_LD;
302
+ xinsn = SET_RD(xinsn, GET_C_RD(insn));
303
+ access_rs1 = 2;
304
+ access_imm = GET_C_LDSP_IMM(insn);
305
+ access_size = 8;
306
+ }
307
+ break;
308
+ case OPC_RISC_C_FUNC_FSDSP_SQSP:
309
+ if (riscv_cpu_xlen(env) != 128) { /* C.FSDSP (RV32/64) */
310
+ xinsn = OPC_RISC_FSD;
311
+ xinsn = SET_RS2(xinsn, GET_C_RS2(insn));
312
+ access_rs1 = 2;
313
+ access_imm = GET_C_SDSP_IMM(insn);
314
+ access_size = 8;
315
+ }
316
+ break;
317
+ case OPC_RISC_C_FUNC_SWSP: /* C.SWSP */
318
+ xinsn = OPC_RISC_SW;
319
+ xinsn = SET_RS2(xinsn, GET_C_RS2(insn));
320
+ access_rs1 = 2;
321
+ access_imm = GET_C_SWSP_IMM(insn);
322
+ access_size = 4;
323
+ break;
324
+ case 7:
325
+ if (riscv_cpu_xlen(env) == 32) { /* C.FSWSP (RV32) */
326
+ xinsn = OPC_RISC_FSW;
327
+ xinsn = SET_RS2(xinsn, GET_C_RS2(insn));
328
+ access_rs1 = 2;
329
+ access_imm = GET_C_SWSP_IMM(insn);
330
+ access_size = 4;
331
+ } else { /* C.SDSP (RV64/RV128) */
332
+ xinsn = OPC_RISC_SD;
333
+ xinsn = SET_RS2(xinsn, GET_C_RS2(insn));
334
+ access_rs1 = 2;
335
+ access_imm = GET_C_SDSP_IMM(insn);
336
+ access_size = 8;
337
+ }
338
+ break;
339
+ default:
340
+ break;
341
+ }
342
+ break;
343
+ default:
344
+ break;
345
+ }
346
+
347
+ /*
348
+ * Clear Bit1 of transformed instruction to indicate that
349
+ * original insruction was a 16bit instruction
350
+ */
351
+ xinsn &= ~((target_ulong)0x2);
352
+ } else {
353
+ /* Transform 32bit (or wider) instructions */
354
+ switch (MASK_OP_MAJOR(insn)) {
355
+ case OPC_RISC_ATOMIC:
356
+ xinsn = insn;
357
+ access_rs1 = GET_RS1(insn);
358
+ access_size = 1 << GET_FUNCT3(insn);
359
+ break;
360
+ case OPC_RISC_LOAD:
361
+ case OPC_RISC_FP_LOAD:
362
+ xinsn = SET_I_IMM(insn, 0);
363
+ access_rs1 = GET_RS1(insn);
364
+ access_imm = GET_IMM(insn);
365
+ access_size = 1 << GET_FUNCT3(insn);
366
+ break;
367
+ case OPC_RISC_STORE:
368
+ case OPC_RISC_FP_STORE:
369
+ xinsn = SET_S_IMM(insn, 0);
370
+ access_rs1 = GET_RS1(insn);
371
+ access_imm = GET_STORE_IMM(insn);
372
+ access_size = 1 << GET_FUNCT3(insn);
373
+ break;
374
+ case OPC_RISC_SYSTEM:
375
+ if (MASK_OP_SYSTEM(insn) == OPC_RISC_HLVHSV) {
376
+ xinsn = insn;
377
+ access_rs1 = GET_RS1(insn);
378
+ access_size = 1 << ((GET_FUNCT7(insn) >> 1) & 0x3);
379
+ access_size = 1 << access_size;
380
+ }
381
+ break;
382
+ default:
383
+ break;
384
+ }
385
+ }
386
+
387
+ if (access_size) {
388
+ xinsn = SET_RS1(xinsn, (taddr - (env->gpr[access_rs1] + access_imm)) &
389
+ (access_size - 1));
390
+ }
391
+
392
+ return xinsn;
393
+}
394
#endif /* !CONFIG_USER_ONLY */
395
396
/*
397
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
398
target_ulong cause = cs->exception_index & RISCV_EXCP_INT_MASK;
399
uint64_t deleg = async ? env->mideleg : env->medeleg;
400
target_ulong tval = 0;
401
+ target_ulong tinst = 0;
402
target_ulong htval = 0;
403
target_ulong mtval2 = 0;
404
405
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
406
if (!async) {
407
/* set tval to badaddr for traps with address information */
408
switch (cause) {
409
- case RISCV_EXCP_INST_GUEST_PAGE_FAULT:
410
case RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT:
411
case RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT:
412
- case RISCV_EXCP_INST_ADDR_MIS:
413
- case RISCV_EXCP_INST_ACCESS_FAULT:
414
case RISCV_EXCP_LOAD_ADDR_MIS:
415
case RISCV_EXCP_STORE_AMO_ADDR_MIS:
416
case RISCV_EXCP_LOAD_ACCESS_FAULT:
417
case RISCV_EXCP_STORE_AMO_ACCESS_FAULT:
418
- case RISCV_EXCP_INST_PAGE_FAULT:
419
case RISCV_EXCP_LOAD_PAGE_FAULT:
420
case RISCV_EXCP_STORE_PAGE_FAULT:
421
write_gva = env->two_stage_lookup;
422
tval = env->badaddr;
423
+ if (env->two_stage_indirect_lookup) {
424
+ /*
425
+ * special pseudoinstruction for G-stage fault taken while
426
+ * doing VS-stage page table walk.
427
+ */
428
+ tinst = (riscv_cpu_xlen(env) == 32) ? 0x00002000 : 0x00003000;
429
+ } else {
430
+ /*
431
+ * The "Addr. Offset" field in transformed instruction is
432
+ * non-zero only for misaligned access.
433
+ */
434
+ tinst = riscv_transformed_insn(env, env->bins, tval);
435
+ }
436
+ break;
437
+ case RISCV_EXCP_INST_GUEST_PAGE_FAULT:
438
+ case RISCV_EXCP_INST_ADDR_MIS:
439
+ case RISCV_EXCP_INST_ACCESS_FAULT:
440
+ case RISCV_EXCP_INST_PAGE_FAULT:
441
+ write_gva = env->two_stage_lookup;
442
+ tval = env->badaddr;
443
+ if (env->two_stage_indirect_lookup) {
444
+ /*
445
+ * special pseudoinstruction for G-stage fault taken while
446
+ * doing VS-stage page table walk.
447
+ */
448
+ tinst = (riscv_cpu_xlen(env) == 32) ? 0x00002000 : 0x00003000;
449
+ }
450
break;
451
case RISCV_EXCP_ILLEGAL_INST:
452
case RISCV_EXCP_VIRT_INSTRUCTION_FAULT:
453
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
454
env->sepc = env->pc;
455
env->stval = tval;
456
env->htval = htval;
457
+ env->htinst = tinst;
458
env->pc = (env->stvec >> 2 << 2) +
459
((async && (env->stvec & 3) == 1) ? cause * 4 : 0);
460
riscv_cpu_set_mode(env, PRV_S);
461
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
462
env->mepc = env->pc;
463
env->mtval = tval;
464
env->mtval2 = mtval2;
465
+ env->mtinst = tinst;
466
env->pc = (env->mtvec >> 2 << 2) +
467
((async && (env->mtvec & 3) == 1) ? cause * 4 : 0);
468
riscv_cpu_set_mode(env, PRV_M);
469
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
470
*/
471
472
env->two_stage_lookup = false;
473
+ env->two_stage_indirect_lookup = false;
474
#endif
475
cs->exception_index = RISCV_EXCP_NONE; /* mark handled to qemu */
476
}
477
--
83
--
478
2.37.2
84
2.45.1
diff view generated by jsdifflib
1
From: Atish Patra <atish.patra@wdc.com>
1
From: Alexei Filippov <alexei.filippov@syntacore.com>
2
2
3
Qemu can monitor the following cache related PMU events through
3
Previous patch fixed the PMP priority in raise_mmu_exception() but we're still
4
tlb_fill functions.
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.
5
7
6
1. DTLB load/store miss
8
In this case we gonna set mtval2 via env->guest_phys_fault_addr in context of
7
3. ITLB prefetch miss
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...*
8
14
9
Increment the PMU counter in tlb_fill function.
15
Signed-off-by: Alexei Filippov <alexei.filippov@syntacore.com>
10
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Tested-by: Heiko Stuebner <heiko@sntech.de>
18
Message-ID: <20240503103052.6819-1-alexei.filippov@syntacore.com>
13
Signed-off-by: Atish Patra <atish.patra@wdc.com>
19
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Signed-off-by: Atish Patra <atishp@rivosinc.com>
15
Message-Id: <20220824221701.41932-4-atishp@rivosinc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
21
---
18
target/riscv/cpu_helper.c | 25 +++++++++++++++++++++++++
22
target/riscv/cpu_helper.c | 12 ++++++------
19
1 file changed, 25 insertions(+)
23
1 file changed, 6 insertions(+), 6 deletions(-)
20
24
21
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
22
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu_helper.c
27
--- a/target/riscv/cpu_helper.c
24
+++ b/target/riscv/cpu_helper.c
28
+++ b/target/riscv/cpu_helper.c
25
@@ -XXX,XX +XXX,XX @@
26
#include "qemu/log.h"
27
#include "qemu/main-loop.h"
28
#include "cpu.h"
29
+#include "pmu.h"
30
#include "exec/exec-all.h"
31
#include "instmap.h"
32
#include "tcg/tcg-op.h"
33
#include "trace.h"
34
#include "semihosting/common-semi.h"
35
+#include "cpu_bits.h"
36
37
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
38
{
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
40
cpu_loop_exit_restore(cs, retaddr);
41
}
42
43
+
44
+static void pmu_tlb_fill_incr_ctr(RISCVCPU *cpu, MMUAccessType access_type)
45
+{
46
+ enum riscv_pmu_event_idx pmu_event_type;
47
+
48
+ switch (access_type) {
49
+ case MMU_INST_FETCH:
50
+ pmu_event_type = RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS;
51
+ break;
52
+ case MMU_DATA_LOAD:
53
+ pmu_event_type = RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS;
54
+ break;
55
+ case MMU_DATA_STORE:
56
+ pmu_event_type = RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS;
57
+ break;
58
+ default:
59
+ return;
60
+ }
61
+
62
+ riscv_pmu_incr_ctr(cpu, pmu_event_type);
63
+}
64
+
65
bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
66
MMUAccessType access_type, int mmu_idx,
67
bool probe, uintptr_t retaddr)
68
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
29
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
30
__func__, pa, ret, prot_pmp, tlb_size);
31
32
prot &= prot_pmp;
33
- }
34
-
35
- if (ret != TRANSLATE_SUCCESS) {
36
+ } else {
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;
49
+ }
69
}
50
}
70
}
51
}
71
} else {
52
} else {
72
+ pmu_tlb_fill_incr_ctr(cpu, access_type);
73
/* Single stage lookup */
74
ret = get_physical_address(env, &pa, &prot, address, NULL,
75
access_type, mmu_idx, true, false, false);
76
--
53
--
77
2.37.2
54
2.45.1
diff view generated by jsdifflib
1
From: eopXD <eop.chen@sifive.com>
1
From: Rob Bradford <rbradford@rivosinc.com>
2
2
3
According to v-spec, mask agnostic behavior can be either kept as
3
This extension has now been ratified:
4
undisturbed or set elements' bits to all 1s. To distinguish the
4
https://jira.riscv.org/browse/RVS-2006 so the "x-" prefix can be
5
difference of mask policies, QEMU should be able to simulate the mask
5
removed.
6
agnostic behavior as "set mask elements' bits to all 1s".
7
6
8
There are multiple possibility for agnostic elements according to
7
Since this is now a ratified extension add it to the list of extensions
9
v-spec. The main intent of this patch-set tries to add option that
8
included in the "max" CPU variant.
10
can distinguish between mask policies. Setting agnostic elements to
11
all 1s allows QEMU to express this.
12
9
13
This commit adds option 'rvv_ma_all_1s' is added to enable the
10
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
14
behavior, it is default as disabled.
11
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
15
16
Signed-off-by: eop Chen <eop.chen@sifive.com>
17
Reviewed-by: Frank Chang <frank.chang@sifive.com>
18
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
19
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
20
Message-Id: <165570784143.17634.35095816584573691-10@git.sr.ht>
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>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
---
17
---
23
target/riscv/cpu.c | 1 +
18
target/riscv/cpu.c | 2 +-
24
1 file changed, 1 insertion(+)
19
target/riscv/tcg/tcg-cpu.c | 2 +-
20
2 files changed, 2 insertions(+), 2 deletions(-)
25
21
26
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
22
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
27
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/cpu.c
24
--- a/target/riscv/cpu.c
29
+++ b/target/riscv/cpu.c
25
+++ b/target/riscv/cpu.c
30
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = {
26
@@ -XXX,XX +XXX,XX @@ static const MISAExtInfo misa_ext_info_arr[] = {
31
DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false),
27
MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
32
28
MISA_EXT_INFO(RVV, "v", "Vector operations"),
33
DEFINE_PROP_BOOL("rvv_ta_all_1s", RISCVCPU, cfg.rvv_ta_all_1s, false),
29
MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
34
+ DEFINE_PROP_BOOL("rvv_ma_all_1s", RISCVCPU, cfg.rvv_ma_all_1s, false),
30
- MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)")
35
DEFINE_PROP_END_OF_LIST(),
31
+ MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
36
};
32
};
37
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);
38
--
48
--
39
2.37.2
49
2.45.1
diff view generated by jsdifflib
1
From: Atish Patra <atishp@rivosinc.com>
1
From: Alistair Francis <alistair23@gmail.com>
2
2
3
Historically, The mtime/mtimecmp has been part of the CPU because
3
When running the instruction
4
they are per hart entities. However, they actually belong to aclint
5
which is a MMIO device.
6
4
7
Move them to the ACLINT device. This also emulates the real hardware
5
```
8
more closely.
6
cbo.flush 0(x0)
7
```
9
8
10
Reviewed-by: Anup Patel <anup@brainfault.org>
9
QEMU would segfault.
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
12
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
11
The issue was in cpu_gpr[a->rs1] as QEMU does not have cpu_gpr[0]
13
Signed-off-by: Atish Patra <atishp@rivosinc.com>
12
allocated.
14
Message-Id: <20220824221357.41070-2-atishp@rivosinc.com>
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.
26
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
Reported-by: Fabian Thomas <fabian.thomas@cispa.de>
29
Fixes: e05da09b7cfd ("target/riscv: implement Zicbom extension")
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Cc: qemu-stable <qemu-stable@nongnu.org>
32
Message-ID: <20240514023910.301766-1-alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
34
---
17
include/hw/intc/riscv_aclint.h | 2 ++
35
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++++++++++++----
18
include/hw/timer/ibex_timer.h | 2 ++
36
1 file changed, 12 insertions(+), 4 deletions(-)
19
target/riscv/cpu.h | 2 --
20
hw/intc/riscv_aclint.c | 48 ++++++++++++++++++++++++----------
21
hw/timer/ibex_timer.c | 18 +++++--------
22
target/riscv/machine.c | 5 ++--
23
6 files changed, 47 insertions(+), 30 deletions(-)
24
37
25
diff --git a/include/hw/intc/riscv_aclint.h b/include/hw/intc/riscv_aclint.h
38
diff --git a/target/riscv/insn_trans/trans_rvzicbo.c.inc b/target/riscv/insn_trans/trans_rvzicbo.c.inc
26
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/intc/riscv_aclint.h
40
--- a/target/riscv/insn_trans/trans_rvzicbo.c.inc
28
+++ b/include/hw/intc/riscv_aclint.h
41
+++ b/target/riscv/insn_trans/trans_rvzicbo.c.inc
29
@@ -XXX,XX +XXX,XX @@ typedef struct RISCVAclintMTimerState {
30
/*< private >*/
31
SysBusDevice parent_obj;
32
uint64_t time_delta;
33
+ uint64_t *timecmp;
34
+ QEMUTimer **timers;
35
36
/*< public >*/
37
MemoryRegion mmio;
38
diff --git a/include/hw/timer/ibex_timer.h b/include/hw/timer/ibex_timer.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/include/hw/timer/ibex_timer.h
41
+++ b/include/hw/timer/ibex_timer.h
42
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(IbexTimerState, IBEX_TIMER)
43
struct IbexTimerState {
44
/* <private> */
45
SysBusDevice parent_obj;
46
+ uint64_t mtimecmp;
47
+ QEMUTimer *mtimer; /* Internal timer for M-mode interrupt */
48
49
/* <public> */
50
MemoryRegion mmio;
51
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/cpu.h
54
+++ b/target/riscv/cpu.h
55
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
56
/* temporary htif regs */
57
uint64_t mfromhost;
58
uint64_t mtohost;
59
- uint64_t timecmp;
60
61
/* physical memory protection */
62
pmp_table_t pmp_state;
63
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
64
float_status fp_status;
65
66
/* Fields from here on are preserved across CPU reset. */
67
- QEMUTimer *timer; /* Internal timer */
68
69
hwaddr kernel_addr;
70
hwaddr fdt_addr;
71
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/hw/intc/riscv_aclint.c
74
+++ b/hw/intc/riscv_aclint.c
75
@@ -XXX,XX +XXX,XX @@
42
@@ -XXX,XX +XXX,XX @@
76
#include "hw/intc/riscv_aclint.h"
43
static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a)
77
#include "qemu/timer.h"
44
{
78
#include "hw/irq.h"
45
REQUIRE_ZICBOM(ctx);
79
+#include "migration/vmstate.h"
46
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
80
47
+ TCGv src = get_address(ctx, a->rs1, 0);
81
typedef struct riscv_aclint_mtimer_callback {
82
RISCVAclintMTimerState *s;
83
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
84
85
uint64_t rtc_r = cpu_riscv_read_rtc(mtimer);
86
87
- cpu->env.timecmp = value;
88
- if (cpu->env.timecmp <= rtc_r) {
89
+ /* Compute the relative hartid w.r.t the socket */
90
+ hartid = hartid - mtimer->hartid_base;
91
+
48
+
92
+ mtimer->timecmp[hartid] = value;
49
+ gen_helper_cbo_clean_flush(tcg_env, src);
93
+ if (mtimer->timecmp[hartid] <= rtc_r) {
50
return true;
94
/*
95
* If we're setting an MTIMECMP value in the "past",
96
* immediately raise the timer interrupt
97
*/
98
- qemu_irq_raise(mtimer->timer_irqs[hartid - mtimer->hartid_base]);
99
+ qemu_irq_raise(mtimer->timer_irqs[hartid]);
100
return;
101
}
102
103
/* otherwise, set up the future timer interrupt */
104
- qemu_irq_lower(mtimer->timer_irqs[hartid - mtimer->hartid_base]);
105
- diff = cpu->env.timecmp - rtc_r;
106
+ qemu_irq_lower(mtimer->timer_irqs[hartid]);
107
+ diff = mtimer->timecmp[hartid] - rtc_r;
108
/* back to ns (note args switched in muldiv64) */
109
uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
110
111
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
112
next = MIN(next, INT64_MAX);
113
}
114
115
- timer_mod(cpu->env.timer, next);
116
+ timer_mod(mtimer->timers[hartid], next);
117
}
51
}
118
52
119
/*
53
static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a)
120
@@ -XXX,XX +XXX,XX @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr,
54
{
121
"aclint-mtimer: invalid hartid: %zu", hartid);
55
REQUIRE_ZICBOM(ctx);
122
} else if ((addr & 0x7) == 0) {
56
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
123
/* timecmp_lo for RV32/RV64 or timecmp for RV64 */
57
+ TCGv src = get_address(ctx, a->rs1, 0);
124
- uint64_t timecmp = env->timecmp;
58
+
125
+ uint64_t timecmp = mtimer->timecmp[hartid];
59
+ gen_helper_cbo_clean_flush(tcg_env, src);
126
return (size == 4) ? (timecmp & 0xFFFFFFFF) : timecmp;
60
return true;
127
} else if ((addr & 0x7) == 4) {
128
/* timecmp_hi */
129
- uint64_t timecmp = env->timecmp;
130
+ uint64_t timecmp = mtimer->timecmp[hartid];
131
return (timecmp >> 32) & 0xFFFFFFFF;
132
} else {
133
qemu_log_mask(LOG_UNIMP,
134
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
135
} else if ((addr & 0x7) == 0) {
136
if (size == 4) {
137
/* timecmp_lo for RV32/RV64 */
138
- uint64_t timecmp_hi = env->timecmp >> 32;
139
+ uint64_t timecmp_hi = mtimer->timecmp[hartid] >> 32;
140
riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
141
timecmp_hi << 32 | (value & 0xFFFFFFFF));
142
} else {
143
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
144
} else if ((addr & 0x7) == 4) {
145
if (size == 4) {
146
/* timecmp_hi for RV32/RV64 */
147
- uint64_t timecmp_lo = env->timecmp;
148
+ uint64_t timecmp_lo = mtimer->timecmp[hartid];
149
riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
150
value << 32 | (timecmp_lo & 0xFFFFFFFF));
151
} else {
152
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
153
}
154
riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu),
155
mtimer->hartid_base + i,
156
- env->timecmp);
157
+ mtimer->timecmp[i]);
158
}
159
return;
160
}
161
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp)
162
s->timer_irqs = g_new(qemu_irq, s->num_harts);
163
qdev_init_gpio_out(dev, s->timer_irqs, s->num_harts);
164
165
+ s->timers = g_new0(QEMUTimer *, s->num_harts);
166
+ s->timecmp = g_new0(uint64_t, s->num_harts);
167
/* Claim timer interrupt bits */
168
for (i = 0; i < s->num_harts; i++) {
169
RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i));
170
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_reset_enter(Object *obj, ResetType type)
171
riscv_aclint_mtimer_write(mtimer, mtimer->time_base, 0, 8);
172
}
61
}
173
62
174
+static const VMStateDescription vmstate_riscv_mtimer = {
63
static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a)
175
+ .name = "riscv_mtimer",
64
{
176
+ .version_id = 1,
65
REQUIRE_ZICBOM(ctx);
177
+ .minimum_version_id = 1,
66
- gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]);
178
+ .fields = (VMStateField[]) {
67
+ TCGv src = get_address(ctx, a->rs1, 0);
179
+ VMSTATE_VARRAY_UINT32(timecmp, RISCVAclintMTimerState,
180
+ num_harts, 0,
181
+ vmstate_info_uint64, uint64_t),
182
+ VMSTATE_END_OF_LIST()
183
+ }
184
+};
185
+
68
+
186
static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data)
69
+ gen_helper_cbo_inval(tcg_env, src);
70
return true;
71
}
72
73
static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)
187
{
74
{
188
DeviceClass *dc = DEVICE_CLASS(klass);
75
REQUIRE_ZICBOZ(ctx);
189
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data)
76
- gen_helper_cbo_zero(tcg_env, cpu_gpr[a->rs1]);
190
device_class_set_props(dc, riscv_aclint_mtimer_properties);
77
+ TCGv src = get_address(ctx, a->rs1, 0);
191
ResettableClass *rc = RESETTABLE_CLASS(klass);
78
+
192
rc->phases.enter = riscv_aclint_mtimer_reset_enter;
79
+ gen_helper_cbo_zero(tcg_env, src);
193
+ dc->vmsd = &vmstate_riscv_mtimer;
80
return true;
194
}
81
}
195
196
static const TypeInfo riscv_aclint_mtimer_info = {
197
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size,
198
{
199
int i;
200
DeviceState *dev = qdev_new(TYPE_RISCV_ACLINT_MTIMER);
201
+ RISCVAclintMTimerState *s = RISCV_ACLINT_MTIMER(dev);
202
203
assert(num_harts <= RISCV_ACLINT_MAX_HARTS);
204
assert(!(addr & 0x7));
205
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size,
206
riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, dev);
207
}
208
209
- cb->s = RISCV_ACLINT_MTIMER(dev);
210
+ cb->s = s;
211
cb->num = i;
212
- env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
213
+ s->timers[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
214
&riscv_aclint_mtimer_cb, cb);
215
- env->timecmp = 0;
216
+ s->timecmp[i] = 0;
217
218
qdev_connect_gpio_out(dev, i,
219
qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER));
220
diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
221
index XXXXXXX..XXXXXXX 100644
222
--- a/hw/timer/ibex_timer.c
223
+++ b/hw/timer/ibex_timer.c
224
@@ -XXX,XX +XXX,XX @@ static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
225
226
static void ibex_timer_update_irqs(IbexTimerState *s)
227
{
228
- CPUState *cs = qemu_get_cpu(0);
229
- RISCVCPU *cpu = RISCV_CPU(cs);
230
uint64_t value = s->timer_compare_lower0 |
231
((uint64_t)s->timer_compare_upper0 << 32);
232
uint64_t next, diff;
233
@@ -XXX,XX +XXX,XX @@ static void ibex_timer_update_irqs(IbexTimerState *s)
234
}
235
236
/* Update the CPUs mtimecmp */
237
- cpu->env.timecmp = value;
238
+ s->mtimecmp = value;
239
240
- if (cpu->env.timecmp <= now) {
241
+ if (s->mtimecmp <= now) {
242
/*
243
* If the mtimecmp was in the past raise the interrupt now.
244
*/
245
@@ -XXX,XX +XXX,XX @@ static void ibex_timer_update_irqs(IbexTimerState *s)
246
qemu_irq_lower(s->m_timer_irq);
247
qemu_set_irq(s->irq, false);
248
249
- diff = cpu->env.timecmp - now;
250
+ diff = s->mtimecmp - now;
251
next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
252
muldiv64(diff,
253
NANOSECONDS_PER_SECOND,
254
@@ -XXX,XX +XXX,XX @@ static void ibex_timer_update_irqs(IbexTimerState *s)
255
256
if (next < qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) {
257
/* We overflowed the timer, just set it as large as we can */
258
- timer_mod(cpu->env.timer, 0x7FFFFFFFFFFFFFFF);
259
+ timer_mod(s->mtimer, 0x7FFFFFFFFFFFFFFF);
260
} else {
261
- timer_mod(cpu->env.timer, next);
262
+ timer_mod(s->mtimer, next);
263
}
264
}
265
266
@@ -XXX,XX +XXX,XX @@ static void ibex_timer_reset(DeviceState *dev)
267
{
268
IbexTimerState *s = IBEX_TIMER(dev);
269
270
- CPUState *cpu = qemu_get_cpu(0);
271
- CPURISCVState *env = cpu->env_ptr;
272
- env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
273
+ s->mtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
274
&ibex_timer_cb, s);
275
- env->timecmp = 0;
276
+ s->mtimecmp = 0;
277
278
s->timer_ctrl = 0x00000000;
279
s->timer_cfg0 = 0x00010000;
280
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
281
index XXXXXXX..XXXXXXX 100644
282
--- a/target/riscv/machine.c
283
+++ b/target/riscv/machine.c
284
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmu_ctr_state = {
285
286
const VMStateDescription vmstate_riscv_cpu = {
287
.name = "cpu",
288
- .version_id = 3,
289
- .minimum_version_id = 3,
290
+ .version_id = 4,
291
+ .minimum_version_id = 4,
292
.post_load = riscv_cpu_post_load,
293
.fields = (VMStateField[]) {
294
VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
295
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
296
VMSTATE_UINTTL(env.mscratch, RISCVCPU),
297
VMSTATE_UINT64(env.mfromhost, RISCVCPU),
298
VMSTATE_UINT64(env.mtohost, RISCVCPU),
299
- VMSTATE_UINT64(env.timecmp, RISCVCPU),
300
301
VMSTATE_END_OF_LIST()
302
},
303
--
82
--
304
2.37.2
83
2.45.1
diff view generated by jsdifflib
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Add umode/umode32 predicate for mcounteren, menvcfg/menvcfgh
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.
4
8
5
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
However, if the largest hart number among groups is a power of 2, QEMU
6
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
10
will pass an inaccurate hart-index-bit setting to Linux. For example, when
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
the guest OS has 4 harts, only ceil(log2(3 + 1)) = 2 bits are sufficient
12
to represent 4 harts, but we passes 3 to Linux. The code needs to be
13
updated to ensure accurate hart-index-bit settings.
14
15
Additionally, a Linux patch[1] is necessary to correctly recover the hart
16
index when the guest OS has only 1 hart, where the hart-index-bit is 0.
17
18
[1] https://lore.kernel.org/lkml/20240415064905.25184-1-yongxuan.wang@sifive.com/t/
19
20
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
21
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
9
Message-Id: <20220718130955.11899-5-liweiwei@iscas.ac.cn>
22
Cc: qemu-stable <qemu-stable@nongnu.org>
23
Message-ID: <20240515091129.28116-1-yongxuan.wang@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
25
---
12
target/riscv/csr.c | 24 +++++++++++++++++++++---
26
target/riscv/kvm/kvm-cpu.c | 9 ++++++++-
13
1 file changed, 21 insertions(+), 3 deletions(-)
27
1 file changed, 8 insertions(+), 1 deletion(-)
14
28
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
29
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
16
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/csr.c
31
--- a/target/riscv/kvm/kvm-cpu.c
18
+++ b/target/riscv/csr.c
32
+++ b/target/riscv/kvm/kvm-cpu.c
19
@@ -XXX,XX +XXX,XX @@ static RISCVException hmode32(CPURISCVState *env, int csrno)
33
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
20
34
}
21
}
35
}
22
36
23
+static RISCVException umode(CPURISCVState *env, int csrno)
37
- hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
24
+{
38
+
25
+ if (riscv_has_ext(env, RVU)) {
39
+ if (max_hart_per_socket > 1) {
26
+ return RISCV_EXCP_NONE;
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;
27
+ }
44
+ }
28
+
45
+
29
+ return RISCV_EXCP_ILLEGAL_INST;
46
ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
30
+}
47
KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
31
+
48
&hart_bits, true, NULL);
32
+static RISCVException umode32(CPURISCVState *env, int csrno)
33
+{
34
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
35
+ return RISCV_EXCP_ILLEGAL_INST;
36
+ }
37
+
38
+ return umode(env, csrno);
39
+}
40
+
41
/* Checks if PointerMasking registers could be accessed */
42
static RISCVException pointer_masking(CPURISCVState *env, int csrno)
43
{
44
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
45
[CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg },
46
[CSR_MIE] = { "mie", any, NULL, NULL, rmw_mie },
47
[CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec },
48
- [CSR_MCOUNTEREN] = { "mcounteren", any, read_mcounteren,
49
+ [CSR_MCOUNTEREN] = { "mcounteren", umode, read_mcounteren,
50
write_mcounteren },
51
52
[CSR_MSTATUSH] = { "mstatush", any32, read_mstatush,
53
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
54
[CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph },
55
56
/* Execution environment configuration */
57
- [CSR_MENVCFG] = { "menvcfg", any, read_menvcfg, write_menvcfg,
58
+ [CSR_MENVCFG] = { "menvcfg", umode, read_menvcfg, write_menvcfg,
59
.min_priv_ver = PRIV_VERSION_1_12_0 },
60
- [CSR_MENVCFGH] = { "menvcfgh", any32, read_menvcfgh, write_menvcfgh,
61
+ [CSR_MENVCFGH] = { "menvcfgh", umode32, read_menvcfgh, write_menvcfgh,
62
.min_priv_ver = PRIV_VERSION_1_12_0 },
63
[CSR_SENVCFG] = { "senvcfg", smode, read_senvcfg, write_senvcfg,
64
.min_priv_ver = PRIV_VERSION_1_12_0 },
65
--
49
--
66
2.37.2
50
2.45.1
diff view generated by jsdifflib
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Just add 1 to the effective privledge level when in HS mode, then reuse
3
Commit 33a24910ae changed 'reg_width' to use 'vlenb', i.e. vector length
4
the check of 'effective_priv < csr_priv' in riscv_csrrw_check to replace
4
in bytes, when in this context we want 'reg_width' as the length in
5
the privilege level related check in hmode. Then, hmode will only check
5
bits.
6
whether H extension is supported.
7
6
8
When accessing Hypervior CSRs:
7
Fix 'reg_width' back to the value in bits like 7cb59921c05a
9
1) If accessing from M privilege level, the check of
8
("target/riscv/gdbstub.c: use 'vlenb' instead of shifting 'vlen'") set
10
'effective_priv< csr_priv' passes, returns hmode(...) which will return
9
beforehand.
11
RISCV_EXCP_ILLEGAL_INST when H extension is not supported and return
12
RISCV_EXCP_NONE otherwise.
13
2) If accessing from HS privilege level, effective_priv will add 1,
14
the check passes and also returns hmode(...) too.
15
3) If accessing from VS/VU privilege level, the check fails, and
16
returns RISCV_EXCP_VIRT_INSTRUCTION_FAULT
17
4) If accessing from U privilege level, the check fails, and returns
18
RISCV_EXCP_ILLEGAL_INST
19
10
20
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
11
While we're at it, rename 'reg_width' to 'bitsize' to provide a bit more
21
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
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>
22
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
24
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
25
Cc: qemu-stable <qemu-stable@nongnu.org>
24
Message-Id: <20220718130955.11899-7-liweiwei@iscas.ac.cn>
26
Message-ID: <20240517203054.880861-2-dbarboza@ventanamicro.com>
25
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
26
---
28
---
27
target/riscv/csr.c | 18 +++++-------------
29
target/riscv/gdbstub.c | 6 +++---
28
1 file changed, 5 insertions(+), 13 deletions(-)
30
1 file changed, 3 insertions(+), 3 deletions(-)
29
31
30
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
32
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
31
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
32
--- a/target/riscv/csr.c
34
--- a/target/riscv/gdbstub.c
33
+++ b/target/riscv/csr.c
35
+++ b/target/riscv/gdbstub.c
34
@@ -XXX,XX +XXX,XX @@ static int aia_smode32(CPURISCVState *env, int csrno)
36
@@ -XXX,XX +XXX,XX @@ static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg)
35
static RISCVException hmode(CPURISCVState *env, int csrno)
37
static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
36
{
38
{
37
if (riscv_has_ext(env, RVH)) {
39
RISCVCPU *cpu = RISCV_CPU(cs);
38
- /* Hypervisor extension is supported */
40
- int reg_width = cpu->cfg.vlenb;
39
- if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
41
+ int bitsize = cpu->cfg.vlenb << 3;
40
- env->priv == PRV_M) {
42
GDBFeatureBuilder builder;
41
- return RISCV_EXCP_NONE;
43
int i;
42
- } else {
44
43
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
45
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
44
- }
46
45
+ return RISCV_EXCP_NONE;
47
/* First define types and totals in a whole VL */
48
for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
49
- int count = reg_width / vec_lanes[i].size;
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");
46
}
60
}
47
61
48
return RISCV_EXCP_ILLEGAL_INST;
62
gdb_feature_builder_end(&builder);
49
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
50
#if !defined(CONFIG_USER_ONLY)
51
int csr_priv, effective_priv = env->priv;
52
53
- if (riscv_has_ext(env, RVH) && env->priv == PRV_S) {
54
+ if (riscv_has_ext(env, RVH) && env->priv == PRV_S &&
55
+ !riscv_cpu_virt_enabled(env)) {
56
/*
57
- * We are in either HS or VS mode.
58
- * Add 1 to the effective privledge level to allow us to access the
59
- * Hypervisor CSRs. The `hmode` predicate will determine if access
60
- * should be allowed(HS) or if a virtual instruction exception should be
61
- * raised(VS).
62
+ * We are in HS mode. Add 1 to the effective privledge level to
63
+ * allow us to access the Hypervisor CSRs.
64
*/
65
effective_priv++;
66
}
67
--
63
--
68
2.37.2
64
2.45.1
65
66
diff view generated by jsdifflib
1
From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
1
From: Alistair Francis <alistair23@gmail.com>
2
2
3
For rv128c shifts, a shamt of 0 is a shamt of 64, while for rv32c/rv64c
3
Previously we only listed a single pmpcfg CSR and the first 16 pmpaddr
4
it stays 0 and is a hint instruction that does not change processor state.
4
CSRs. This patch fixes this to list all 16 pmpcfg and all 64 pmpaddr
5
For rv128c right shifts, the 6-bit shamt is in addition sign extended to
5
CSRs are part of the disassembly.
6
7 bits.
7
6
8
Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
7
Reported-by: Eric DeVolder <eric_devolder@yahoo.com>
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Fixes: ea10325917 ("RISC-V Disassembler")
11
Message-Id: <20220710110451.245567-1-frederic.petrot@univ-grenoble-alpes.fr>
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>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
---
14
target/riscv/insn16.decode | 7 ++++---
15
disas/riscv.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-
15
disas/riscv.c | 27 +++++++++++++++++++++------
16
1 file changed, 64 insertions(+), 1 deletion(-)
16
target/riscv/translate.c | 20 ++++++++++++++++++--
17
3 files changed, 43 insertions(+), 11 deletions(-)
18
17
19
diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/insn16.decode
22
+++ b/target/riscv/insn16.decode
23
@@ -XXX,XX +XXX,XX @@
24
%imm_cb 12:s1 5:2 2:1 10:2 3:2 !function=ex_shift_1
25
%imm_cj 12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1
26
27
-%shimm_6bit 12:1 2:5 !function=ex_rvc_shifti
28
+%shlimm_6bit 12:1 2:5 !function=ex_rvc_shiftli
29
+%shrimm_6bit 12:1 2:5 !function=ex_rvc_shiftri
30
%uimm_6bit_lq 2:4 12:1 6:1 !function=ex_shift_4
31
%uimm_6bit_ld 2:3 12:1 5:2 !function=ex_shift_3
32
%uimm_6bit_lw 2:2 12:1 4:3 !function=ex_shift_2
33
@@ -XXX,XX +XXX,XX @@
34
@c_addi16sp ... . ..... ..... .. &i imm=%imm_addi16sp rs1=2 rd=2
35
36
@c_shift ... . .. ... ..... .. \
37
- &shift rd=%rs1_3 rs1=%rs1_3 shamt=%shimm_6bit
38
+ &shift rd=%rs1_3 rs1=%rs1_3 shamt=%shrimm_6bit
39
@c_shift2 ... . .. ... ..... .. \
40
- &shift rd=%rd rs1=%rd shamt=%shimm_6bit
41
+ &shift rd=%rd rs1=%rd shamt=%shlimm_6bit
42
43
@c_andi ... . .. ... ..... .. &i imm=%imm_ci rs1=%rs1_3 rd=%rs1_3
44
45
diff --git a/disas/riscv.c b/disas/riscv.c
18
diff --git a/disas/riscv.c b/disas/riscv.c
46
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
47
--- a/disas/riscv.c
20
--- a/disas/riscv.c
48
+++ b/disas/riscv.c
21
+++ b/disas/riscv.c
49
@@ -XXX,XX +XXX,XX @@ static int32_t operand_sbimm12(rv_inst inst)
22
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
50
((inst << 56) >> 63) << 11;
23
case 0x0383: return "mibound";
51
}
24
case 0x0384: return "mdbase";
52
25
case 0x0385: return "mdbound";
53
-static uint32_t operand_cimmsh6(rv_inst inst)
26
- case 0x03a0: return "pmpcfg3";
54
+static uint32_t operand_cimmshl6(rv_inst inst, rv_isa isa)
27
+ case 0x03a0: return "pmpcfg0";
55
{
28
+ case 0x03a1: return "pmpcfg1";
56
- return ((inst << 51) >> 63) << 5 |
29
+ case 0x03a2: return "pmpcfg2";
57
+ int imm = ((inst << 51) >> 63) << 5 |
30
+ case 0x03a3: return "pmpcfg3";
58
(inst << 57) >> 59;
31
+ case 0x03a4: return "pmpcfg4";
59
+ if (isa == rv128) {
32
+ case 0x03a5: return "pmpcfg5";
60
+ imm = imm ? imm : 64;
33
+ case 0x03a6: return "pmpcfg6";
61
+ }
34
+ case 0x03a7: return "pmpcfg7";
62
+ return imm;
35
+ case 0x03a8: return "pmpcfg8";
63
+}
36
+ case 0x03a9: return "pmpcfg9";
64
+
37
+ case 0x03aa: return "pmpcfg10";
65
+static uint32_t operand_cimmshr6(rv_inst inst, rv_isa isa)
38
+ case 0x03ab: return "pmpcfg11";
66
+{
39
+ case 0x03ac: return "pmpcfg12";
67
+ int imm = ((inst << 51) >> 63) << 5 |
40
+ case 0x03ad: return "pmpcfg13";
68
+ (inst << 57) >> 59;
41
+ case 0x03ae: return "pmpcfg14";
69
+ if (isa == rv128) {
42
+ case 0x03af: return "pmpcfg15";
70
+ imm = imm | (imm & 32) << 1;
43
case 0x03b0: return "pmpaddr0";
71
+ imm = imm ? imm : 64;
44
case 0x03b1: return "pmpaddr1";
72
+ }
45
case 0x03b2: return "pmpaddr2";
73
+ return imm;
46
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
74
}
47
case 0x03bd: return "pmpaddr13";
75
48
case 0x03be: return "pmpaddr14";
76
static int32_t operand_cimmi(rv_inst inst)
49
case 0x03bf: return "pmpaddr15";
77
@@ -XXX,XX +XXX,XX @@ static uint32_t operand_rnum(rv_inst inst)
50
+ case 0x03c0: return "pmpaddr16";
78
51
+ case 0x03c1: return "pmpaddr17";
79
/* decode operands */
52
+ case 0x03c2: return "pmpaddr18";
80
53
+ case 0x03c3: return "pmpaddr19";
81
-static void decode_inst_operands(rv_decode *dec)
54
+ case 0x03c4: return "pmpaddr20";
82
+static void decode_inst_operands(rv_decode *dec, rv_isa isa)
55
+ case 0x03c5: return "pmpaddr21";
83
{
56
+ case 0x03c6: return "pmpaddr22";
84
rv_inst inst = dec->inst;
57
+ case 0x03c7: return "pmpaddr23";
85
dec->codec = opcode_data[dec->op].codec;
58
+ case 0x03c8: return "pmpaddr24";
86
@@ -XXX,XX +XXX,XX @@ static void decode_inst_operands(rv_decode *dec)
59
+ case 0x03c9: return "pmpaddr25";
87
case rv_codec_cb_sh6:
60
+ case 0x03ca: return "pmpaddr26";
88
dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8;
61
+ case 0x03cb: return "pmpaddr27";
89
dec->rs2 = rv_ireg_zero;
62
+ case 0x03cc: return "pmpaddr28";
90
- dec->imm = operand_cimmsh6(inst);
63
+ case 0x03cd: return "pmpaddr29";
91
+ dec->imm = operand_cimmshr6(inst, isa);
64
+ case 0x03ce: return "pmpaddr30";
92
break;
65
+ case 0x03cf: return "pmpaddr31";
93
case rv_codec_ci:
66
+ case 0x03d0: return "pmpaddr32";
94
dec->rd = dec->rs1 = operand_crs1rd(inst);
67
+ case 0x03d1: return "pmpaddr33";
95
@@ -XXX,XX +XXX,XX @@ static void decode_inst_operands(rv_decode *dec)
68
+ case 0x03d2: return "pmpaddr34";
96
case rv_codec_ci_sh6:
69
+ case 0x03d3: return "pmpaddr35";
97
dec->rd = dec->rs1 = operand_crs1rd(inst);
70
+ case 0x03d4: return "pmpaddr36";
98
dec->rs2 = rv_ireg_zero;
71
+ case 0x03d5: return "pmpaddr37";
99
- dec->imm = operand_cimmsh6(inst);
72
+ case 0x03d6: return "pmpaddr38";
100
+ dec->imm = operand_cimmshl6(inst, isa);
73
+ case 0x03d7: return "pmpaddr39";
101
break;
74
+ case 0x03d8: return "pmpaddr40";
102
case rv_codec_ci_16sp:
75
+ case 0x03d9: return "pmpaddr41";
103
dec->rd = rv_ireg_sp;
76
+ case 0x03da: return "pmpaddr42";
104
@@ -XXX,XX +XXX,XX @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst)
77
+ case 0x03db: return "pmpaddr43";
105
dec.pc = pc;
78
+ case 0x03dc: return "pmpaddr44";
106
dec.inst = inst;
79
+ case 0x03dd: return "pmpaddr45";
107
decode_inst_opcode(&dec, isa);
80
+ case 0x03de: return "pmpaddr46";
108
- decode_inst_operands(&dec);
81
+ case 0x03df: return "pmpaddr47";
109
+ decode_inst_operands(&dec, isa);
82
+ case 0x03e0: return "pmpaddr48";
110
decode_inst_decompress(&dec, isa);
83
+ case 0x03e1: return "pmpaddr49";
111
decode_inst_lift_pseudo(&dec);
84
+ case 0x03e2: return "pmpaddr50";
112
format_inst(buf, buflen, 16, &dec);
85
+ case 0x03e3: return "pmpaddr51";
113
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
86
+ case 0x03e4: return "pmpaddr52";
114
index XXXXXXX..XXXXXXX 100644
87
+ case 0x03e5: return "pmpaddr53";
115
--- a/target/riscv/translate.c
88
+ case 0x03e6: return "pmpaddr54";
116
+++ b/target/riscv/translate.c
89
+ case 0x03e7: return "pmpaddr55";
117
@@ -XXX,XX +XXX,XX @@ static int ex_rvc_register(DisasContext *ctx, int reg)
90
+ case 0x03e8: return "pmpaddr56";
118
return 8 + reg;
91
+ case 0x03e9: return "pmpaddr57";
119
}
92
+ case 0x03ea: return "pmpaddr58";
120
93
+ case 0x03eb: return "pmpaddr59";
121
-static int ex_rvc_shifti(DisasContext *ctx, int imm)
94
+ case 0x03ec: return "pmpaddr60";
122
+static int ex_rvc_shiftli(DisasContext *ctx, int imm)
95
+ case 0x03ed: return "pmpaddr61";
123
{
96
+ case 0x03ee: return "pmpaddr62";
124
/* For RV128 a shamt of 0 means a shift by 64. */
97
+ case 0x03ef: return "pmpaddr63";
125
- return imm ? imm : 64;
98
case 0x0780: return "mtohost";
126
+ if (get_ol(ctx) == MXL_RV128) {
99
case 0x0781: return "mfromhost";
127
+ imm = imm ? imm : 64;
100
case 0x0782: return "mreset";
128
+ }
129
+ return imm;
130
+}
131
+
132
+static int ex_rvc_shiftri(DisasContext *ctx, int imm)
133
+{
134
+ /*
135
+ * For RV128 a shamt of 0 means a shift by 64, furthermore, for right
136
+ * shifts, the shamt is sign-extended.
137
+ */
138
+ if (get_ol(ctx) == MXL_RV128) {
139
+ imm = imm | (imm & 32) << 1;
140
+ imm = imm ? imm : 64;
141
+ }
142
+ return imm;
143
}
144
145
/* Include the auto-generated decoder for 32 bit insn */
146
--
101
--
147
2.37.2
102
2.45.1
148
149
diff view generated by jsdifflib
Deleted patch
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
2
1
3
- Zmmul is ratified and is now version 1.0
4
5
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20220710101546.3907-1-liweiwei@iscas.ac.cn>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/cpu.c | 3 ++-
12
1 file changed, 2 insertions(+), 1 deletion(-)
13
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu.c
17
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
19
DEFINE_PROP_BOOL("zhinx", RISCVCPU, cfg.ext_zhinx, false),
20
DEFINE_PROP_BOOL("zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false),
21
22
+ DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false),
23
+
24
/* Vendor-specific custom extensions */
25
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
26
27
/* These are experimental so mark with 'x-' */
28
DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
29
- DEFINE_PROP_BOOL("x-zmmul", RISCVCPU, cfg.ext_zmmul, false),
30
/* ePMP 0.9.3 */
31
DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
32
DEFINE_PROP_BOOL("x-aia", RISCVCPU, cfg.aia, false),
33
--
34
2.37.2
diff view generated by jsdifflib
Deleted patch
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
2
1
3
There are 3 suggested privilege mode combinations listed in section 1.2
4
of the riscv-privileged spec(draft-20220717):
5
1) M, 2) M, U 3) M, S, U
6
7
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
11
Message-Id: <20220718130955.11899-2-liweiwei@iscas.ac.cn>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/cpu.c | 6 ++++++
15
1 file changed, 6 insertions(+)
16
17
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu.c
20
+++ b/target/riscv/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
22
return;
23
}
24
25
+ if (cpu->cfg.ext_s && !cpu->cfg.ext_u) {
26
+ error_setg(errp,
27
+ "Setting S extension without U extension is illegal");
28
+ return;
29
+ }
30
+
31
if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) {
32
error_setg(errp, "F extension requires Zicsr");
33
return;
34
--
35
2.37.2
diff view generated by jsdifflib
Deleted patch
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
2
1
3
Add check for "H depends on an I base integer ISA with 32 x registers"
4
which is stated at the beginning of chapter 8 of the riscv-privileged
5
spec(draft-20220717)
6
7
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
11
Message-Id: <20220718130955.11899-3-liweiwei@iscas.ac.cn>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/cpu.c | 6 ++++++
15
1 file changed, 6 insertions(+)
16
17
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu.c
20
+++ b/target/riscv/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
22
return;
23
}
24
25
+ if (cpu->cfg.ext_h && !cpu->cfg.ext_i) {
26
+ error_setg(errp,
27
+ "H depends on an I base integer ISA with 32 x registers");
28
+ return;
29
+ }
30
+
31
if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) {
32
error_setg(errp, "F extension requires Zicsr");
33
return;
34
--
35
2.37.2
diff view generated by jsdifflib
Deleted patch
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
2
1
3
Fix the lines with over 80 characters
4
5
Fix the lines which are obviously misalgined with other lines in the
6
same group
7
8
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
12
Message-Id: <20220718130955.11899-4-liweiwei@iscas.ac.cn>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/csr.c | 441 ++++++++++++++++++++++++---------------------
16
1 file changed, 234 insertions(+), 207 deletions(-)
17
18
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/csr.c
21
+++ b/target/riscv/csr.c
22
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
23
[CSR_FRM] = { "frm", fs, read_frm, write_frm },
24
[CSR_FCSR] = { "fcsr", fs, read_fcsr, write_fcsr },
25
/* Vector CSRs */
26
- [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart,
27
- .min_priv_ver = PRIV_VERSION_1_12_0 },
28
- [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat,
29
- .min_priv_ver = PRIV_VERSION_1_12_0 },
30
- [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm,
31
- .min_priv_ver = PRIV_VERSION_1_12_0 },
32
- [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr,
33
- .min_priv_ver = PRIV_VERSION_1_12_0 },
34
- [CSR_VL] = { "vl", vs, read_vl,
35
- .min_priv_ver = PRIV_VERSION_1_12_0 },
36
- [CSR_VTYPE] = { "vtype", vs, read_vtype,
37
- .min_priv_ver = PRIV_VERSION_1_12_0 },
38
- [CSR_VLENB] = { "vlenb", vs, read_vlenb,
39
- .min_priv_ver = PRIV_VERSION_1_12_0 },
40
+ [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart,
41
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
42
+ [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat,
43
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
44
+ [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm,
45
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
46
+ [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr,
47
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
48
+ [CSR_VL] = { "vl", vs, read_vl,
49
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
50
+ [CSR_VTYPE] = { "vtype", vs, read_vtype,
51
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
52
+ [CSR_VLENB] = { "vlenb", vs, read_vlenb,
53
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
54
/* User Timers and Counters */
55
[CSR_CYCLE] = { "cycle", ctr, read_hpmcounter },
56
[CSR_INSTRET] = { "instret", ctr, read_hpmcounter },
57
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
58
59
#if !defined(CONFIG_USER_ONLY)
60
/* Machine Timers and Counters */
61
- [CSR_MCYCLE] = { "mcycle", any, read_hpmcounter, write_mhpmcounter},
62
- [CSR_MINSTRET] = { "minstret", any, read_hpmcounter, write_mhpmcounter},
63
- [CSR_MCYCLEH] = { "mcycleh", any32, read_hpmcounterh, write_mhpmcounterh},
64
- [CSR_MINSTRETH] = { "minstreth", any32, read_hpmcounterh, write_mhpmcounterh},
65
+ [CSR_MCYCLE] = { "mcycle", any, read_hpmcounter,
66
+ write_mhpmcounter },
67
+ [CSR_MINSTRET] = { "minstret", any, read_hpmcounter,
68
+ write_mhpmcounter },
69
+ [CSR_MCYCLEH] = { "mcycleh", any32, read_hpmcounterh,
70
+ write_mhpmcounterh },
71
+ [CSR_MINSTRETH] = { "minstreth", any32, read_hpmcounterh,
72
+ write_mhpmcounterh },
73
74
/* Machine Information Registers */
75
[CSR_MVENDORID] = { "mvendorid", any, read_mvendorid },
76
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
77
[CSR_MHARTID] = { "mhartid", any, read_mhartid },
78
79
[CSR_MCONFIGPTR] = { "mconfigptr", any, read_zero,
80
- .min_priv_ver = PRIV_VERSION_1_12_0 },
81
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
82
/* Machine Trap Setup */
83
- [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus, NULL,
84
- read_mstatus_i128 },
85
- [CSR_MISA] = { "misa", any, read_misa, write_misa, NULL,
86
- read_misa_i128 },
87
- [CSR_MIDELEG] = { "mideleg", any, NULL, NULL, rmw_mideleg },
88
- [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg },
89
- [CSR_MIE] = { "mie", any, NULL, NULL, rmw_mie },
90
- [CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec },
91
- [CSR_MCOUNTEREN] = { "mcounteren", any, read_mcounteren, write_mcounteren },
92
-
93
- [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush, write_mstatush },
94
+ [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus,
95
+ NULL, read_mstatus_i128 },
96
+ [CSR_MISA] = { "misa", any, read_misa, write_misa,
97
+ NULL, read_misa_i128 },
98
+ [CSR_MIDELEG] = { "mideleg", any, NULL, NULL, rmw_mideleg },
99
+ [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg },
100
+ [CSR_MIE] = { "mie", any, NULL, NULL, rmw_mie },
101
+ [CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec },
102
+ [CSR_MCOUNTEREN] = { "mcounteren", any, read_mcounteren,
103
+ write_mcounteren },
104
+
105
+ [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush,
106
+ write_mstatush },
107
108
/* Machine Trap Handling */
109
- [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch, NULL,
110
- read_mscratch_i128, write_mscratch_i128 },
111
+ [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch,
112
+ NULL, read_mscratch_i128, write_mscratch_i128 },
113
[CSR_MEPC] = { "mepc", any, read_mepc, write_mepc },
114
[CSR_MCAUSE] = { "mcause", any, read_mcause, write_mcause },
115
[CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval },
116
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
117
[CSR_MIREG] = { "mireg", aia_any, NULL, NULL, rmw_xireg },
118
119
/* Machine-Level Interrupts (AIA) */
120
- [CSR_MTOPEI] = { "mtopei", aia_any, NULL, NULL, rmw_xtopei },
121
- [CSR_MTOPI] = { "mtopi", aia_any, read_mtopi },
122
+ [CSR_MTOPEI] = { "mtopei", aia_any, NULL, NULL, rmw_xtopei },
123
+ [CSR_MTOPI] = { "mtopi", aia_any, read_mtopi },
124
125
/* Virtual Interrupts for Supervisor Level (AIA) */
126
- [CSR_MVIEN] = { "mvien", aia_any, read_zero, write_ignore },
127
- [CSR_MVIP] = { "mvip", aia_any, read_zero, write_ignore },
128
+ [CSR_MVIEN] = { "mvien", aia_any, read_zero, write_ignore },
129
+ [CSR_MVIP] = { "mvip", aia_any, read_zero, write_ignore },
130
131
/* Machine-Level High-Half CSRs (AIA) */
132
[CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh },
133
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
134
135
/* Execution environment configuration */
136
[CSR_MENVCFG] = { "menvcfg", any, read_menvcfg, write_menvcfg,
137
- .min_priv_ver = PRIV_VERSION_1_12_0 },
138
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
139
[CSR_MENVCFGH] = { "menvcfgh", any32, read_menvcfgh, write_menvcfgh,
140
- .min_priv_ver = PRIV_VERSION_1_12_0 },
141
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
142
[CSR_SENVCFG] = { "senvcfg", smode, read_senvcfg, write_senvcfg,
143
- .min_priv_ver = PRIV_VERSION_1_12_0 },
144
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
145
[CSR_HENVCFG] = { "henvcfg", hmode, read_henvcfg, write_henvcfg,
146
- .min_priv_ver = PRIV_VERSION_1_12_0 },
147
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
148
[CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
149
- .min_priv_ver = PRIV_VERSION_1_12_0 },
150
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
151
152
/* Supervisor Trap Setup */
153
- [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus, NULL,
154
- read_sstatus_i128 },
155
- [CSR_SIE] = { "sie", smode, NULL, NULL, rmw_sie },
156
- [CSR_STVEC] = { "stvec", smode, read_stvec, write_stvec },
157
- [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren, write_scounteren },
158
+ [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus,
159
+ NULL, read_sstatus_i128 },
160
+ [CSR_SIE] = { "sie", smode, NULL, NULL, rmw_sie },
161
+ [CSR_STVEC] = { "stvec", smode, read_stvec, write_stvec },
162
+ [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren,
163
+ write_scounteren },
164
165
/* Supervisor Trap Handling */
166
- [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch, NULL,
167
- read_sscratch_i128, write_sscratch_i128 },
168
+ [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch,
169
+ NULL, read_sscratch_i128, write_sscratch_i128 },
170
[CSR_SEPC] = { "sepc", smode, read_sepc, write_sepc },
171
[CSR_SCAUSE] = { "scause", smode, read_scause, write_scause },
172
- [CSR_STVAL] = { "stval", smode, read_stval, write_stval },
173
+ [CSR_STVAL] = { "stval", smode, read_stval, write_stval },
174
[CSR_SIP] = { "sip", smode, NULL, NULL, rmw_sip },
175
176
/* Supervisor Protection and Translation */
177
- [CSR_SATP] = { "satp", smode, read_satp, write_satp },
178
+ [CSR_SATP] = { "satp", smode, read_satp, write_satp },
179
180
/* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
181
[CSR_SISELECT] = { "siselect", aia_smode, NULL, NULL, rmw_xiselect },
182
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
183
[CSR_SIEH] = { "sieh", aia_smode32, NULL, NULL, rmw_sieh },
184
[CSR_SIPH] = { "siph", aia_smode32, NULL, NULL, rmw_siph },
185
186
- [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus,
187
- .min_priv_ver = PRIV_VERSION_1_12_0 },
188
- [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg,
189
- .min_priv_ver = PRIV_VERSION_1_12_0 },
190
+ [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus,
191
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
192
+ [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg,
193
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
194
[CSR_HIDELEG] = { "hideleg", hmode, NULL, NULL, rmw_hideleg,
195
- .min_priv_ver = PRIV_VERSION_1_12_0 },
196
- [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip,
197
- .min_priv_ver = PRIV_VERSION_1_12_0 },
198
- [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip,
199
- .min_priv_ver = PRIV_VERSION_1_12_0 },
200
- [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie,
201
- .min_priv_ver = PRIV_VERSION_1_12_0 },
202
- [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren, write_hcounteren,
203
- .min_priv_ver = PRIV_VERSION_1_12_0 },
204
- [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie,
205
- .min_priv_ver = PRIV_VERSION_1_12_0 },
206
- [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval,
207
- .min_priv_ver = PRIV_VERSION_1_12_0 },
208
- [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst,
209
- .min_priv_ver = PRIV_VERSION_1_12_0 },
210
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
211
+ [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip,
212
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
213
+ [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip,
214
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
215
+ [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie,
216
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
217
+ [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren,
218
+ write_hcounteren,
219
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
220
+ [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie,
221
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
222
+ [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval,
223
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
224
+ [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst,
225
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
226
[CSR_HGEIP] = { "hgeip", hmode, read_hgeip,
227
- .min_priv_ver = PRIV_VERSION_1_12_0 },
228
- [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp,
229
- .min_priv_ver = PRIV_VERSION_1_12_0 },
230
- [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta, write_htimedelta,
231
- .min_priv_ver = PRIV_VERSION_1_12_0 },
232
- [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah, write_htimedeltah,
233
- .min_priv_ver = PRIV_VERSION_1_12_0 },
234
-
235
- [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus, write_vsstatus,
236
- .min_priv_ver = PRIV_VERSION_1_12_0 },
237
- [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip,
238
- .min_priv_ver = PRIV_VERSION_1_12_0 },
239
- [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie ,
240
- .min_priv_ver = PRIV_VERSION_1_12_0 },
241
- [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec,
242
- .min_priv_ver = PRIV_VERSION_1_12_0 },
243
- [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch, write_vsscratch,
244
- .min_priv_ver = PRIV_VERSION_1_12_0 },
245
- [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc,
246
- .min_priv_ver = PRIV_VERSION_1_12_0 },
247
- [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause,
248
- .min_priv_ver = PRIV_VERSION_1_12_0 },
249
- [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval,
250
- .min_priv_ver = PRIV_VERSION_1_12_0 },
251
- [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp,
252
- .min_priv_ver = PRIV_VERSION_1_12_0 },
253
-
254
- [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2,
255
- .min_priv_ver = PRIV_VERSION_1_12_0 },
256
- [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst,
257
- .min_priv_ver = PRIV_VERSION_1_12_0 },
258
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
259
+ [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp,
260
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
261
+ [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta,
262
+ write_htimedelta,
263
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
264
+ [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah,
265
+ write_htimedeltah,
266
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
267
+
268
+ [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus,
269
+ write_vsstatus,
270
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
271
+ [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip,
272
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
273
+ [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie ,
274
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
275
+ [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec,
276
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
277
+ [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch,
278
+ write_vsscratch,
279
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
280
+ [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc,
281
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
282
+ [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause,
283
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
284
+ [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval,
285
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
286
+ [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp,
287
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
288
+
289
+ [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2,
290
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
291
+ [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst,
292
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
293
294
/* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
295
[CSR_HVIEN] = { "hvien", aia_hmode, read_zero, write_ignore },
296
- [CSR_HVICTL] = { "hvictl", aia_hmode, read_hvictl, write_hvictl },
297
- [CSR_HVIPRIO1] = { "hviprio1", aia_hmode, read_hviprio1, write_hviprio1 },
298
- [CSR_HVIPRIO2] = { "hviprio2", aia_hmode, read_hviprio2, write_hviprio2 },
299
+ [CSR_HVICTL] = { "hvictl", aia_hmode, read_hvictl,
300
+ write_hvictl },
301
+ [CSR_HVIPRIO1] = { "hviprio1", aia_hmode, read_hviprio1,
302
+ write_hviprio1 },
303
+ [CSR_HVIPRIO2] = { "hviprio2", aia_hmode, read_hviprio2,
304
+ write_hviprio2 },
305
306
/*
307
* VS-Level Window to Indirectly Accessed Registers (H-extension with AIA)
308
*/
309
- [CSR_VSISELECT] = { "vsiselect", aia_hmode, NULL, NULL, rmw_xiselect },
310
- [CSR_VSIREG] = { "vsireg", aia_hmode, NULL, NULL, rmw_xireg },
311
+ [CSR_VSISELECT] = { "vsiselect", aia_hmode, NULL, NULL,
312
+ rmw_xiselect },
313
+ [CSR_VSIREG] = { "vsireg", aia_hmode, NULL, NULL, rmw_xireg },
314
315
/* VS-Level Interrupts (H-extension with AIA) */
316
[CSR_VSTOPEI] = { "vstopei", aia_hmode, NULL, NULL, rmw_xtopei },
317
[CSR_VSTOPI] = { "vstopi", aia_hmode, read_vstopi },
318
319
/* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
320
- [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL, rmw_hidelegh },
321
- [CSR_HVIENH] = { "hvienh", aia_hmode32, read_zero, write_ignore },
322
+ [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL,
323
+ rmw_hidelegh },
324
+ [CSR_HVIENH] = { "hvienh", aia_hmode32, read_zero,
325
+ write_ignore },
326
[CSR_HVIPH] = { "hviph", aia_hmode32, NULL, NULL, rmw_hviph },
327
- [CSR_HVIPRIO1H] = { "hviprio1h", aia_hmode32, read_hviprio1h, write_hviprio1h },
328
- [CSR_HVIPRIO2H] = { "hviprio2h", aia_hmode32, read_hviprio2h, write_hviprio2h },
329
+ [CSR_HVIPRIO1H] = { "hviprio1h", aia_hmode32, read_hviprio1h,
330
+ write_hviprio1h },
331
+ [CSR_HVIPRIO2H] = { "hviprio2h", aia_hmode32, read_hviprio2h,
332
+ write_hviprio2h },
333
[CSR_VSIEH] = { "vsieh", aia_hmode32, NULL, NULL, rmw_vsieh },
334
[CSR_VSIPH] = { "vsiph", aia_hmode32, NULL, NULL, rmw_vsiph },
335
336
/* Physical Memory Protection */
337
[CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg,
338
- .min_priv_ver = PRIV_VERSION_1_11_0 },
339
+ .min_priv_ver = PRIV_VERSION_1_11_0 },
340
[CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg },
341
[CSR_PMPCFG1] = { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg },
342
[CSR_PMPCFG2] = { "pmpcfg2", pmp, read_pmpcfg, write_pmpcfg },
343
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
344
[CSR_TDATA3] = { "tdata3", debug, read_tdata, write_tdata },
345
346
/* User Pointer Masking */
347
- [CSR_UMTE] = { "umte", pointer_masking, read_umte, write_umte },
348
- [CSR_UPMMASK] = { "upmmask", pointer_masking, read_upmmask, write_upmmask },
349
- [CSR_UPMBASE] = { "upmbase", pointer_masking, read_upmbase, write_upmbase },
350
+ [CSR_UMTE] = { "umte", pointer_masking, read_umte, write_umte },
351
+ [CSR_UPMMASK] = { "upmmask", pointer_masking, read_upmmask,
352
+ write_upmmask },
353
+ [CSR_UPMBASE] = { "upmbase", pointer_masking, read_upmbase,
354
+ write_upmbase },
355
/* Machine Pointer Masking */
356
- [CSR_MMTE] = { "mmte", pointer_masking, read_mmte, write_mmte },
357
- [CSR_MPMMASK] = { "mpmmask", pointer_masking, read_mpmmask, write_mpmmask },
358
- [CSR_MPMBASE] = { "mpmbase", pointer_masking, read_mpmbase, write_mpmbase },
359
+ [CSR_MMTE] = { "mmte", pointer_masking, read_mmte, write_mmte },
360
+ [CSR_MPMMASK] = { "mpmmask", pointer_masking, read_mpmmask,
361
+ write_mpmmask },
362
+ [CSR_MPMBASE] = { "mpmbase", pointer_masking, read_mpmbase,
363
+ write_mpmbase },
364
/* Supervisor Pointer Masking */
365
- [CSR_SMTE] = { "smte", pointer_masking, read_smte, write_smte },
366
- [CSR_SPMMASK] = { "spmmask", pointer_masking, read_spmmask, write_spmmask },
367
- [CSR_SPMBASE] = { "spmbase", pointer_masking, read_spmbase, write_spmbase },
368
+ [CSR_SMTE] = { "smte", pointer_masking, read_smte, write_smte },
369
+ [CSR_SPMMASK] = { "spmmask", pointer_masking, read_spmmask,
370
+ write_spmmask },
371
+ [CSR_SPMBASE] = { "spmbase", pointer_masking, read_spmbase,
372
+ write_spmbase },
373
374
/* Performance Counters */
375
[CSR_HPMCOUNTER3] = { "hpmcounter3", ctr, read_hpmcounter },
376
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
377
[CSR_HPMCOUNTER31] = { "hpmcounter31", ctr, read_hpmcounter },
378
379
[CSR_MHPMCOUNTER3] = { "mhpmcounter3", mctr, read_hpmcounter,
380
- write_mhpmcounter },
381
+ write_mhpmcounter },
382
[CSR_MHPMCOUNTER4] = { "mhpmcounter4", mctr, read_hpmcounter,
383
- write_mhpmcounter },
384
+ write_mhpmcounter },
385
[CSR_MHPMCOUNTER5] = { "mhpmcounter5", mctr, read_hpmcounter,
386
- write_mhpmcounter },
387
+ write_mhpmcounter },
388
[CSR_MHPMCOUNTER6] = { "mhpmcounter6", mctr, read_hpmcounter,
389
- write_mhpmcounter },
390
+ write_mhpmcounter },
391
[CSR_MHPMCOUNTER7] = { "mhpmcounter7", mctr, read_hpmcounter,
392
- write_mhpmcounter },
393
+ write_mhpmcounter },
394
[CSR_MHPMCOUNTER8] = { "mhpmcounter8", mctr, read_hpmcounter,
395
- write_mhpmcounter },
396
+ write_mhpmcounter },
397
[CSR_MHPMCOUNTER9] = { "mhpmcounter9", mctr, read_hpmcounter,
398
- write_mhpmcounter },
399
+ write_mhpmcounter },
400
[CSR_MHPMCOUNTER10] = { "mhpmcounter10", mctr, read_hpmcounter,
401
- write_mhpmcounter },
402
+ write_mhpmcounter },
403
[CSR_MHPMCOUNTER11] = { "mhpmcounter11", mctr, read_hpmcounter,
404
- write_mhpmcounter },
405
+ write_mhpmcounter },
406
[CSR_MHPMCOUNTER12] = { "mhpmcounter12", mctr, read_hpmcounter,
407
- write_mhpmcounter },
408
+ write_mhpmcounter },
409
[CSR_MHPMCOUNTER13] = { "mhpmcounter13", mctr, read_hpmcounter,
410
- write_mhpmcounter },
411
+ write_mhpmcounter },
412
[CSR_MHPMCOUNTER14] = { "mhpmcounter14", mctr, read_hpmcounter,
413
- write_mhpmcounter },
414
+ write_mhpmcounter },
415
[CSR_MHPMCOUNTER15] = { "mhpmcounter15", mctr, read_hpmcounter,
416
- write_mhpmcounter },
417
+ write_mhpmcounter },
418
[CSR_MHPMCOUNTER16] = { "mhpmcounter16", mctr, read_hpmcounter,
419
- write_mhpmcounter },
420
+ write_mhpmcounter },
421
[CSR_MHPMCOUNTER17] = { "mhpmcounter17", mctr, read_hpmcounter,
422
- write_mhpmcounter },
423
+ write_mhpmcounter },
424
[CSR_MHPMCOUNTER18] = { "mhpmcounter18", mctr, read_hpmcounter,
425
- write_mhpmcounter },
426
+ write_mhpmcounter },
427
[CSR_MHPMCOUNTER19] = { "mhpmcounter19", mctr, read_hpmcounter,
428
- write_mhpmcounter },
429
+ write_mhpmcounter },
430
[CSR_MHPMCOUNTER20] = { "mhpmcounter20", mctr, read_hpmcounter,
431
- write_mhpmcounter },
432
+ write_mhpmcounter },
433
[CSR_MHPMCOUNTER21] = { "mhpmcounter21", mctr, read_hpmcounter,
434
- write_mhpmcounter },
435
+ write_mhpmcounter },
436
[CSR_MHPMCOUNTER22] = { "mhpmcounter22", mctr, read_hpmcounter,
437
- write_mhpmcounter },
438
+ write_mhpmcounter },
439
[CSR_MHPMCOUNTER23] = { "mhpmcounter23", mctr, read_hpmcounter,
440
- write_mhpmcounter },
441
+ write_mhpmcounter },
442
[CSR_MHPMCOUNTER24] = { "mhpmcounter24", mctr, read_hpmcounter,
443
- write_mhpmcounter },
444
+ write_mhpmcounter },
445
[CSR_MHPMCOUNTER25] = { "mhpmcounter25", mctr, read_hpmcounter,
446
- write_mhpmcounter },
447
+ write_mhpmcounter },
448
[CSR_MHPMCOUNTER26] = { "mhpmcounter26", mctr, read_hpmcounter,
449
- write_mhpmcounter },
450
+ write_mhpmcounter },
451
[CSR_MHPMCOUNTER27] = { "mhpmcounter27", mctr, read_hpmcounter,
452
- write_mhpmcounter },
453
+ write_mhpmcounter },
454
[CSR_MHPMCOUNTER28] = { "mhpmcounter28", mctr, read_hpmcounter,
455
- write_mhpmcounter },
456
+ write_mhpmcounter },
457
[CSR_MHPMCOUNTER29] = { "mhpmcounter29", mctr, read_hpmcounter,
458
- write_mhpmcounter },
459
+ write_mhpmcounter },
460
[CSR_MHPMCOUNTER30] = { "mhpmcounter30", mctr, read_hpmcounter,
461
- write_mhpmcounter },
462
+ write_mhpmcounter },
463
[CSR_MHPMCOUNTER31] = { "mhpmcounter31", mctr, read_hpmcounter,
464
- write_mhpmcounter },
465
+ write_mhpmcounter },
466
467
[CSR_MCOUNTINHIBIT] = { "mcountinhibit", any, read_mcountinhibit,
468
- write_mcountinhibit, .min_priv_ver = PRIV_VERSION_1_11_0 },
469
+ write_mcountinhibit,
470
+ .min_priv_ver = PRIV_VERSION_1_11_0 },
471
472
[CSR_MHPMEVENT3] = { "mhpmevent3", any, read_mhpmevent,
473
- write_mhpmevent },
474
+ write_mhpmevent },
475
[CSR_MHPMEVENT4] = { "mhpmevent4", any, read_mhpmevent,
476
- write_mhpmevent },
477
+ write_mhpmevent },
478
[CSR_MHPMEVENT5] = { "mhpmevent5", any, read_mhpmevent,
479
- write_mhpmevent },
480
+ write_mhpmevent },
481
[CSR_MHPMEVENT6] = { "mhpmevent6", any, read_mhpmevent,
482
- write_mhpmevent },
483
+ write_mhpmevent },
484
[CSR_MHPMEVENT7] = { "mhpmevent7", any, read_mhpmevent,
485
- write_mhpmevent },
486
+ write_mhpmevent },
487
[CSR_MHPMEVENT8] = { "mhpmevent8", any, read_mhpmevent,
488
- write_mhpmevent },
489
+ write_mhpmevent },
490
[CSR_MHPMEVENT9] = { "mhpmevent9", any, read_mhpmevent,
491
- write_mhpmevent },
492
+ write_mhpmevent },
493
[CSR_MHPMEVENT10] = { "mhpmevent10", any, read_mhpmevent,
494
- write_mhpmevent },
495
+ write_mhpmevent },
496
[CSR_MHPMEVENT11] = { "mhpmevent11", any, read_mhpmevent,
497
- write_mhpmevent },
498
+ write_mhpmevent },
499
[CSR_MHPMEVENT12] = { "mhpmevent12", any, read_mhpmevent,
500
- write_mhpmevent },
501
+ write_mhpmevent },
502
[CSR_MHPMEVENT13] = { "mhpmevent13", any, read_mhpmevent,
503
- write_mhpmevent },
504
+ write_mhpmevent },
505
[CSR_MHPMEVENT14] = { "mhpmevent14", any, read_mhpmevent,
506
- write_mhpmevent },
507
+ write_mhpmevent },
508
[CSR_MHPMEVENT15] = { "mhpmevent15", any, read_mhpmevent,
509
- write_mhpmevent },
510
+ write_mhpmevent },
511
[CSR_MHPMEVENT16] = { "mhpmevent16", any, read_mhpmevent,
512
- write_mhpmevent },
513
+ write_mhpmevent },
514
[CSR_MHPMEVENT17] = { "mhpmevent17", any, read_mhpmevent,
515
- write_mhpmevent },
516
+ write_mhpmevent },
517
[CSR_MHPMEVENT18] = { "mhpmevent18", any, read_mhpmevent,
518
- write_mhpmevent },
519
+ write_mhpmevent },
520
[CSR_MHPMEVENT19] = { "mhpmevent19", any, read_mhpmevent,
521
- write_mhpmevent },
522
+ write_mhpmevent },
523
[CSR_MHPMEVENT20] = { "mhpmevent20", any, read_mhpmevent,
524
- write_mhpmevent },
525
+ write_mhpmevent },
526
[CSR_MHPMEVENT21] = { "mhpmevent21", any, read_mhpmevent,
527
- write_mhpmevent },
528
+ write_mhpmevent },
529
[CSR_MHPMEVENT22] = { "mhpmevent22", any, read_mhpmevent,
530
- write_mhpmevent },
531
+ write_mhpmevent },
532
[CSR_MHPMEVENT23] = { "mhpmevent23", any, read_mhpmevent,
533
- write_mhpmevent },
534
+ write_mhpmevent },
535
[CSR_MHPMEVENT24] = { "mhpmevent24", any, read_mhpmevent,
536
- write_mhpmevent },
537
+ write_mhpmevent },
538
[CSR_MHPMEVENT25] = { "mhpmevent25", any, read_mhpmevent,
539
- write_mhpmevent },
540
+ write_mhpmevent },
541
[CSR_MHPMEVENT26] = { "mhpmevent26", any, read_mhpmevent,
542
- write_mhpmevent },
543
+ write_mhpmevent },
544
[CSR_MHPMEVENT27] = { "mhpmevent27", any, read_mhpmevent,
545
- write_mhpmevent },
546
+ write_mhpmevent },
547
[CSR_MHPMEVENT28] = { "mhpmevent28", any, read_mhpmevent,
548
- write_mhpmevent },
549
+ write_mhpmevent },
550
[CSR_MHPMEVENT29] = { "mhpmevent29", any, read_mhpmevent,
551
- write_mhpmevent },
552
+ write_mhpmevent },
553
[CSR_MHPMEVENT30] = { "mhpmevent30", any, read_mhpmevent,
554
- write_mhpmevent },
555
+ write_mhpmevent },
556
[CSR_MHPMEVENT31] = { "mhpmevent31", any, read_mhpmevent,
557
- write_mhpmevent },
558
+ write_mhpmevent },
559
560
[CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_hpmcounterh },
561
[CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_hpmcounterh },
562
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
563
[CSR_HPMCOUNTER31H] = { "hpmcounter31h", ctr32, read_hpmcounterh },
564
565
[CSR_MHPMCOUNTER3H] = { "mhpmcounter3h", mctr32, read_hpmcounterh,
566
- write_mhpmcounterh },
567
+ write_mhpmcounterh },
568
[CSR_MHPMCOUNTER4H] = { "mhpmcounter4h", mctr32, read_hpmcounterh,
569
- write_mhpmcounterh },
570
+ write_mhpmcounterh },
571
[CSR_MHPMCOUNTER5H] = { "mhpmcounter5h", mctr32, read_hpmcounterh,
572
- write_mhpmcounterh },
573
+ write_mhpmcounterh },
574
[CSR_MHPMCOUNTER6H] = { "mhpmcounter6h", mctr32, read_hpmcounterh,
575
- write_mhpmcounterh },
576
+ write_mhpmcounterh },
577
[CSR_MHPMCOUNTER7H] = { "mhpmcounter7h", mctr32, read_hpmcounterh,
578
- write_mhpmcounterh },
579
+ write_mhpmcounterh },
580
[CSR_MHPMCOUNTER8H] = { "mhpmcounter8h", mctr32, read_hpmcounterh,
581
- write_mhpmcounterh },
582
+ write_mhpmcounterh },
583
[CSR_MHPMCOUNTER9H] = { "mhpmcounter9h", mctr32, read_hpmcounterh,
584
- write_mhpmcounterh },
585
+ write_mhpmcounterh },
586
[CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", mctr32, read_hpmcounterh,
587
- write_mhpmcounterh },
588
+ write_mhpmcounterh },
589
[CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", mctr32, read_hpmcounterh,
590
- write_mhpmcounterh },
591
+ write_mhpmcounterh },
592
[CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", mctr32, read_hpmcounterh,
593
- write_mhpmcounterh },
594
+ write_mhpmcounterh },
595
[CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", mctr32, read_hpmcounterh,
596
- write_mhpmcounterh },
597
+ write_mhpmcounterh },
598
[CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", mctr32, read_hpmcounterh,
599
- write_mhpmcounterh },
600
+ write_mhpmcounterh },
601
[CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", mctr32, read_hpmcounterh,
602
- write_mhpmcounterh },
603
+ write_mhpmcounterh },
604
[CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", mctr32, read_hpmcounterh,
605
- write_mhpmcounterh },
606
+ write_mhpmcounterh },
607
[CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", mctr32, read_hpmcounterh,
608
- write_mhpmcounterh },
609
+ write_mhpmcounterh },
610
[CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", mctr32, read_hpmcounterh,
611
- write_mhpmcounterh },
612
+ write_mhpmcounterh },
613
[CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", mctr32, read_hpmcounterh,
614
- write_mhpmcounterh },
615
+ write_mhpmcounterh },
616
[CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", mctr32, read_hpmcounterh,
617
- write_mhpmcounterh },
618
+ write_mhpmcounterh },
619
[CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", mctr32, read_hpmcounterh,
620
- write_mhpmcounterh },
621
+ write_mhpmcounterh },
622
[CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", mctr32, read_hpmcounterh,
623
- write_mhpmcounterh },
624
+ write_mhpmcounterh },
625
[CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", mctr32, read_hpmcounterh,
626
- write_mhpmcounterh },
627
+ write_mhpmcounterh },
628
[CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", mctr32, read_hpmcounterh,
629
- write_mhpmcounterh },
630
+ write_mhpmcounterh },
631
[CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", mctr32, read_hpmcounterh,
632
- write_mhpmcounterh },
633
+ write_mhpmcounterh },
634
[CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", mctr32, read_hpmcounterh,
635
- write_mhpmcounterh },
636
+ write_mhpmcounterh },
637
[CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", mctr32, read_hpmcounterh,
638
- write_mhpmcounterh },
639
+ write_mhpmcounterh },
640
[CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", mctr32, read_hpmcounterh,
641
- write_mhpmcounterh },
642
+ write_mhpmcounterh },
643
[CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", mctr32, read_hpmcounterh,
644
- write_mhpmcounterh },
645
+ write_mhpmcounterh },
646
[CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", mctr32, read_hpmcounterh,
647
- write_mhpmcounterh },
648
+ write_mhpmcounterh },
649
[CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32, read_hpmcounterh,
650
- write_mhpmcounterh },
651
+ write_mhpmcounterh },
652
#endif /* !CONFIG_USER_ONLY */
653
};
654
--
655
2.37.2
diff view generated by jsdifflib
Deleted patch
1
From: Bin Meng <bmeng.cn@gmail.com>
2
1
3
Upgrade OpenSBI from v1.0 to v1.1 and the pre-built bios images.
4
5
The v1.1 release includes the following commits:
6
7
5b99603 lib: utils/ipi: Fix size check in aclint_mswi_cold_init()
8
6dde435 lib: utils/sys: Extend HTIF library to allow custom base address
9
8257262 platform: sifive_fu740: do not use a global in da9063_reset/shutdown
10
fb688d9 platform: sifive_fu740: fix reset when watchdog is running
11
5d025eb lib: fix pointer of type 'void *' used in arithmetic
12
632f593 lib: sbi: Map only the counters enabled in hardware
13
3b7c204 lib: sbi: Disable interrupt during config matching
14
a26dc60 lib: sbi: Disable interrupt and inhibit counting in M-mode during init
15
5d53b55 Makefile: fix build with binutils 2.38
16
6ad8917 lib: fix compilation when strings.h is included
17
ce4c018 lib: utils/serial: Round UART8250 baud rate divisor to nearest integer
18
01250d0 include: sbi: Add AIA related CSR defines
19
8f96070 lib: sbi: Detect AIA CSRs at boot-time
20
65b4c7c lib: sbi: Use AIA CSRs for local interrupts when available
21
222132f lib: sbi: Add sbi_trap_set_external_irqfn() API
22
5f56314 lib: utils/irqchip: Allow multiple FDT irqchip drivers
23
1050940 include: sbi: Introduce nascent_init() platform callback
24
55e79f8 lib: sbi: Enable mie.MEIE bit for IPIs based on external interrupts.
25
9f73669 lib: utils/irqchip: Add IMSIC library
26
811da5c lib: utils/irqchip: Add FDT based driver for IMSIC
27
7127aaa lib: utils: Disable appropriate IMSIC DT nodes in fdt_fixups()
28
9979265 lib: utils/irqchip: Add APLIC initialization library
29
3461219 lib: utils/irqchip: Add FDT based driver for APLIC
30
8e2ef4f lib: utils: Disable appropriate APLIC DT nodes in fdt_fixups()
31
3a69cc1 lib: sbi: fix typo in is_region_subset
32
f2ccf2f lib: sbi: verbose sbi_domain_root_add_memregion
33
f3f4604 lib: sbi: Add a simple external interrupt handling framework
34
4998a71 lib: utils: serial: Initial commit of xlnx-uartlite
35
2dfbd3c lib: pmp_set/pmp_get moved errors from runtime to compile time
36
b6b7220 firmware: Fix code for accessing hart_count and stack_size
37
d552fc8 lib: Add error messages via conditional compilation for the future
38
555bdb1 include: Use static asserts for SBI_PLATFORM_xxx_OFFSET defines
39
1b42d3a include: Use static asserts for SBI_SCRATCH_xxx_OFFSET defines
40
7924a0b include: Use static asserts for FW_DYNAMIC_INFO_xxx_OFFSET defines
41
722f80d include: Add defines for [m|h|s]envcfg CSRs
42
31fecad lib: sbi: Detect menvcfg CSR at boot time
43
47d6765 lib: sbi: Enable Zicbo[m|z] extensions in the menvcfg CSR
44
794986f lib: sbi: Enable Svpbmt extension in the menvcfg CSR
45
499601a lib: sbi: Add Smstateen extension defines
46
d44568a lib: sbi: Detect Smstateen CSRs at boot-time
47
3383d6a lib: irqchip/imsic: configure mstateen
48
5c5cbb5 lib: utils/serial: support 'reg-offset' property
49
c1e47d0 include: correct the definition of MSTATUS_VS
50
9cd95e1 lib: sbi/hart: preserve csr validation value
51
4035ae9 docs: pmu: Improve the PMU DT bindings
52
d62f6da lib: sbi: Implement Sstc extension
53
474a9d4 lib: sbi: Fix mstatus_init() for RV32 when Sscofpmf is not available
54
e576b3e include: sbi: Define SBI_PMU_HW_EVENT_MAX to 256
55
b0c9df5 lib: sbi: Fix mhpmeventh access for rv32 in absence of sscofpmf
56
1a754bb lib: sbi: Detect and print privileged spec version
57
5a6be99 lib: sbi: Remove 's' and 'u' from misa_string() output
58
5b8b377 lib: sbi: Update the name of ISA string printed at boot time
59
d4b563c lib: sbi: Remove MCOUNTEREN and SCOUNTEREN hart features
60
dbc3d8f lib: sbi: Remove MCOUNTINHIBT hart feature
61
97a17c2 lib: sbi: Remove MENVCFG hart feature
62
a6ab94f lib: sbi: Fix AIA feature detection
63
cad6c91 lib: sbi: Convert hart features into hart extensions
64
be4903a lib: sbi: Detect hart features only once for each hart
65
994ace3 lib: sbi: Add sbi_hart_update_extension() function
66
023f0ad lib: sbi_platform: Add callback to populate HART extensions
67
f726f2d Makefile: Allow generated C source to be anywhere in build directory
68
7fb474b Makefile: Add support for generating C array at compile time
69
73cf511 lib: utils/reset: Generate FDT reset driver list at compile-time
70
1e62705 lib: utils/serial: Generate FDT serial driver list at compile-time
71
bfeb305 lib: utils/timer: Generate FDT timer driver list at compile-time
72
3a69d12 lib: utils/irqchip: Generate FDT irqchip driver list at compile-time
73
4ee0c57 lib: utils/ipi: Generate FDT ipi driver list at compile-time
74
998ed43 lib: utils/i2c: Generate FDT i2c adapter driver list at compile-time
75
4eacd82 lib: utils/gpio: Generate FDT gpio driver list at compile-time
76
a3a3c60 platform: generic: Generate platform override module list at compile-time
77
9a7a677 platform: generic: Move Sifive platform overrides into own directory
78
851c14d lib: utils/irqchip: fix typo when checking for CPU node
79
90a9dd2 lib: utils/fdt: introduce fdt_node_is_enabled()
80
616da52 lib: utils: check if CPU node is enabled
81
575bb4e platform: generic: check if CPU node is enabled
82
1bc67db lib: utils/fdt: rename fdt_parse_max_hart_id
83
f067bb8 lib: sbi: fix system_opcode_insn
84
fab0379 lib: utils/fdt: Require match data to be const
85
295e5f3 lib: sbi_timer: Drop unnecessary get_platform_ticks wrapper
86
ff65bfe lib: sbi_illegal_insn: Constify illegal_insn_table
87
cb8271c lib: sbi_illegal_insn: Add emulation for fence.tso
88
adc3388 lib: sbi_trap: Redirect exception based on hedeleg
89
ce1d618 platform: generic: add overrides for vendor extensions
90
b20ed9f lib: sbi_hsm: Call a device hook during hart resume
91
79e42eb lib: sbi_hsm: Assume a consistent resume address
92
2ea7799 lib: irqchip/plic: Constify plic_data pointers
93
8c362e7 lib: irqchip/plic: Factor out a context init function
94
415ecf2 lib: irqchip/plic: Add context save/restore helpers
95
2b79b69 lib: irqchip/plic: Add priority save/restore helpers
96
69be3df lib: utils/irqchip: Add FDT wrappers for PLIC save/restore functions
97
5e56758 lib: utils/irqchip: Add wrapper for T-HEAD PLIC delegation
98
9dc5ec5 platform: Add HSM implementation for Allwinner D1
99
551c70c include: sbi: Add mtinst/htinst psuedoinstructions
100
187127f lib: sbi: Fixup tinst for exceptions in sbi_misaligned_*()
101
a07402a lib: sbi: Fix tval and tinst for sbi_get_insn()
102
c653001 lib: utils: Remove CSRs that set/clear an IMSIC interrupt file bits
103
7738345 lib: utils/timer: Add a separate compatible for the D1 CLINT
104
d76a196 lib: irqchip/plic: fix typo in plic_warm_irqchip_init
105
6f1fe98 lib: utils/timer: Remove Allwinner D1 CLINT compatibles
106
c6fdbcf include: sbi: Change spec version to 1.0
107
3f66465 lib: pmu: allow to use the highest available counter
108
4489876 include: Bump-up version to 1.1
109
110
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
111
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
112
Message-Id: <20220713090613.204046-1-bmeng.cn@gmail.com>
113
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
114
---
115
.../opensbi-riscv32-generic-fw_dynamic.bin | Bin 108504 -> 117704 bytes
116
.../opensbi-riscv64-generic-fw_dynamic.bin | Bin 105296 -> 115344 bytes
117
roms/opensbi | 2 +-
118
3 files changed, 1 insertion(+), 1 deletion(-)
119
120
diff --git a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
121
index XXXXXXX..XXXXXXX 100644
122
Binary files a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin differ
123
diff --git a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin
124
index XXXXXXX..XXXXXXX 100644
125
Binary files a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin differ
126
diff --git a/roms/opensbi b/roms/opensbi
127
index XXXXXXX..XXXXXXX 160000
128
--- a/roms/opensbi
129
+++ b/roms/opensbi
130
@@ -1 +1 @@
131
-Subproject commit 48f91ee9c960f048c4a7d1da4447d31e04931e38
132
+Subproject commit 4489876e933d8ba0d8bc6c64bae71e295d45faac
133
--
134
2.37.2
diff view generated by jsdifflib
Deleted patch
1
From: Bin Meng <bin.meng@windriver.com>
2
1
3
Since commit fbf43c7dbf18 ("target/riscv: enable riscv kvm accel"),
4
KVM accelerator is supported on RISC-V. Let's document it.
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20220719082635.3741878-1-bin.meng@windriver.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
docs/about/build-platforms.rst | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/docs/about/build-platforms.rst b/docs/about/build-platforms.rst
16
index XXXXXXX..XXXXXXX 100644
17
--- a/docs/about/build-platforms.rst
18
+++ b/docs/about/build-platforms.rst
19
@@ -XXX,XX +XXX,XX @@ Those hosts are officially supported, with various accelerators:
20
* - PPC
21
- kvm, tcg
22
* - RISC-V
23
- - tcg
24
+ - kvm, tcg
25
* - s390x
26
- kvm, tcg
27
* - SPARC
28
--
29
2.37.2
diff view generated by jsdifflib
Deleted patch
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
2
1
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <165570784143.17634.35095816584573691-3@git.sr.ht>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/vector_helper.c | 3 +++
11
target/riscv/insn_trans/trans_rvv.c.inc | 2 ++
12
2 files changed, 5 insertions(+)
13
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ static void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
19
uint32_t vl = env->vl;
20
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
21
uint32_t vta = vext_vta(desc);
22
+ uint32_t vma = vext_vma(desc);
23
uint32_t i;
24
25
for (i = env->vstart; i < vl; i++) {
26
if (!vm && !vext_elem_mask(v0, i)) {
27
+ /* set masked-off elements to 1s */
28
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
29
continue;
30
}
31
fn(vd, s1, vs2, i);
32
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/insn_trans/trans_rvv.c.inc
35
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
36
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
37
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
38
data = FIELD_DP32(data, VDATA, VTA, s->vta);
39
data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
40
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
41
desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8,
42
s->cfg_ptr->vlen / 8, data));
43
44
@@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
45
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
46
data = FIELD_DP32(data, VDATA, VTA, s->vta);
47
data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
48
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
49
desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8,
50
s->cfg_ptr->vlen / 8, data));
51
52
--
53
2.37.2
diff view generated by jsdifflib
Deleted patch
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
2
1
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <165570784143.17634.35095816584573691-4@git.sr.ht>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/vector_helper.c | 7 +++++++
11
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
12
2 files changed, 8 insertions(+)
13
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \
19
uint32_t esz = sizeof(TS1); \
20
uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
21
uint32_t vta = vext_vta(desc); \
22
+ uint32_t vma = vext_vma(desc); \
23
uint32_t i; \
24
\
25
for (i = env->vstart; i < vl; i++) { \
26
if (!vm && !vext_elem_mask(v0, i)) { \
27
+ /* set masked-off elements to 1s */ \
28
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \
29
continue; \
30
} \
31
TS1 s1 = *((TS1 *)vs1 + HS1(i)); \
32
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
33
uint32_t total_elems = \
34
vext_get_total_elems(env, desc, esz); \
35
uint32_t vta = vext_vta(desc); \
36
+ uint32_t vma = vext_vma(desc); \
37
uint32_t i; \
38
\
39
for (i = env->vstart; i < vl; i++) { \
40
if (!vm && !vext_elem_mask(v0, i)) { \
41
+ /* set masked-off elements to 1s */ \
42
+ vext_set_elems_1s(vd, vma, i * esz, \
43
+ (i + 1) * esz); \
44
continue; \
45
} \
46
TS2 s2 = *((TS2 *)vs2 + HS2(i)); \
47
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/riscv/insn_trans/trans_rvv.c.inc
50
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
51
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
52
data = FIELD_DP32(data, VDATA, VM, a->vm); \
53
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
54
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
55
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
56
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
57
vreg_ofs(s, a->rs1), \
58
vreg_ofs(s, a->rs2), cpu_env, \
59
--
60
2.37.2
diff view generated by jsdifflib
Deleted patch
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
2
1
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <165570784143.17634.35095816584573691-5@git.sr.ht>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/vector_helper.c | 10 ++++++++++
11
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
12
2 files changed, 11 insertions(+)
13
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
19
uint32_t vl = env->vl; \
20
uint32_t total_elems = env_archcpu(env)->cfg.vlen; \
21
uint32_t vta_all_1s = vext_vta_all_1s(desc); \
22
+ uint32_t vma = vext_vma(desc); \
23
uint32_t i; \
24
\
25
for (i = env->vstart; i < vl; i++) { \
26
ETYPE s1 = *((ETYPE *)vs1 + H(i)); \
27
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
28
if (!vm && !vext_elem_mask(v0, i)) { \
29
+ /* set masked-off elements to 1s */ \
30
+ if (vma) { \
31
+ vext_set_elem_mask(vd, i, 1); \
32
+ } \
33
continue; \
34
} \
35
vext_set_elem_mask(vd, i, DO_OP(s2, s1)); \
36
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
37
uint32_t vl = env->vl; \
38
uint32_t total_elems = env_archcpu(env)->cfg.vlen; \
39
uint32_t vta_all_1s = vext_vta_all_1s(desc); \
40
+ uint32_t vma = vext_vma(desc); \
41
uint32_t i; \
42
\
43
for (i = env->vstart; i < vl; i++) { \
44
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
45
if (!vm && !vext_elem_mask(v0, i)) { \
46
+ /* set masked-off elements to 1s */ \
47
+ if (vma) { \
48
+ vext_set_elem_mask(vd, i, 1); \
49
+ } \
50
continue; \
51
} \
52
vext_set_elem_mask(vd, i, \
53
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/riscv/insn_trans/trans_rvv.c.inc
56
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
57
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
58
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
59
data = \
60
FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
61
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
62
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
63
vreg_ofs(s, a->rs1), \
64
vreg_ofs(s, a->rs2), cpu_env, \
65
--
66
2.37.2
diff view generated by jsdifflib
Deleted patch
1
From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com>
2
1
3
Signed-off-by: eop Chen <eop.chen@sifive.com>
4
Reviewed-by: Frank Chang <frank.chang@sifive.com>
5
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <165570784143.17634.35095816584573691-6@git.sr.ht>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/vector_helper.c | 26 ++++++++++++++++----------
11
1 file changed, 16 insertions(+), 10 deletions(-)
12
13
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/vector_helper.c
16
+++ b/target/riscv/vector_helper.c
17
@@ -XXX,XX +XXX,XX @@ static inline void
18
vext_vv_rm_1(void *vd, void *v0, void *vs1, void *vs2,
19
CPURISCVState *env,
20
uint32_t vl, uint32_t vm, int vxrm,
21
- opivv2_rm_fn *fn)
22
+ opivv2_rm_fn *fn, uint32_t vma, uint32_t esz)
23
{
24
for (uint32_t i = env->vstart; i < vl; i++) {
25
if (!vm && !vext_elem_mask(v0, i)) {
26
+ /* set masked-off elements to 1s */
27
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
28
continue;
29
}
30
fn(vd, vs1, vs2, i, env, vxrm);
31
@@ -XXX,XX +XXX,XX @@ vext_vv_rm_2(void *vd, void *v0, void *vs1, void *vs2,
32
uint32_t vl = env->vl;
33
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
34
uint32_t vta = vext_vta(desc);
35
+ uint32_t vma = vext_vma(desc);
36
37
switch (env->vxrm) {
38
case 0: /* rnu */
39
vext_vv_rm_1(vd, v0, vs1, vs2,
40
- env, vl, vm, 0, fn);
41
+ env, vl, vm, 0, fn, vma, esz);
42
break;
43
case 1: /* rne */
44
vext_vv_rm_1(vd, v0, vs1, vs2,
45
- env, vl, vm, 1, fn);
46
+ env, vl, vm, 1, fn, vma, esz);
47
break;
48
case 2: /* rdn */
49
vext_vv_rm_1(vd, v0, vs1, vs2,
50
- env, vl, vm, 2, fn);
51
+ env, vl, vm, 2, fn, vma, esz);
52
break;
53
default: /* rod */
54
vext_vv_rm_1(vd, v0, vs1, vs2,
55
- env, vl, vm, 3, fn);
56
+ env, vl, vm, 3, fn, vma, esz);
57
break;
58
}
59
/* set tail elements to 1s */
60
@@ -XXX,XX +XXX,XX @@ static inline void
61
vext_vx_rm_1(void *vd, void *v0, target_long s1, void *vs2,
62
CPURISCVState *env,
63
uint32_t vl, uint32_t vm, int vxrm,
64
- opivx2_rm_fn *fn)
65
+ opivx2_rm_fn *fn, uint32_t vma, uint32_t esz)
66
{
67
for (uint32_t i = env->vstart; i < vl; i++) {
68
if (!vm && !vext_elem_mask(v0, i)) {
69
+ /* set masked-off elements to 1s */
70
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
71
continue;
72
}
73
fn(vd, s1, vs2, i, env, vxrm);
74
@@ -XXX,XX +XXX,XX @@ vext_vx_rm_2(void *vd, void *v0, target_long s1, void *vs2,
75
uint32_t vl = env->vl;
76
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
77
uint32_t vta = vext_vta(desc);
78
+ uint32_t vma = vext_vma(desc);
79
80
switch (env->vxrm) {
81
case 0: /* rnu */
82
vext_vx_rm_1(vd, v0, s1, vs2,
83
- env, vl, vm, 0, fn);
84
+ env, vl, vm, 0, fn, vma, esz);
85
break;
86
case 1: /* rne */
87
vext_vx_rm_1(vd, v0, s1, vs2,
88
- env, vl, vm, 1, fn);
89
+ env, vl, vm, 1, fn, vma, esz);
90
break;
91
case 2: /* rdn */
92
vext_vx_rm_1(vd, v0, s1, vs2,
93
- env, vl, vm, 2, fn);
94
+ env, vl, vm, 2, fn, vma, esz);
95
break;
96
default: /* rod */
97
vext_vx_rm_1(vd, v0, s1, vs2,
98
- env, vl, vm, 3, fn);
99
+ env, vl, vm, 3, fn, vma, esz);
100
break;
101
}
102
/* set tail elements to 1s */
103
--
104
2.37.2
diff view generated by jsdifflib
Deleted patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
2
1
3
The following patch updates opentitan to match the new configuration,
4
as per, lowRISC/opentitan@217a0168ba118503c166a9587819e3811eeb0c0c
5
6
Note: with this patch we now skip the usage of the opentitan
7
`boot_rom`. The Opentitan boot rom contains hw verification
8
for devies which we are currently not supporting in qemu. As of now,
9
the `boot_rom` has no major significance, however, would be good to
10
support in the future.
11
12
Tested by running utests from the latest tock [1]
13
(that supports this version of OT).
14
15
[1] https://github.com/tock/tock/pull/3056
16
17
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
19
Message-Id: <20220812005229.358850-1-wilfred.mallawa@opensource.wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
22
include/hw/riscv/opentitan.h | 11 ++++++-----
23
hw/riscv/opentitan.c | 12 ++++++++----
24
2 files changed, 14 insertions(+), 9 deletions(-)
25
26
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/riscv/opentitan.h
29
+++ b/include/hw/riscv/opentitan.h
30
@@ -XXX,XX +XXX,XX @@ enum {
31
IBEX_DEV_TIMER,
32
IBEX_DEV_SENSOR_CTRL,
33
IBEX_DEV_OTP_CTRL,
34
+ IBEX_DEV_LC_CTRL,
35
IBEX_DEV_PWRMGR,
36
IBEX_DEV_RSTMGR,
37
IBEX_DEV_CLKMGR,
38
@@ -XXX,XX +XXX,XX @@ enum {
39
IBEX_UART0_RX_BREAK_ERR_IRQ = 6,
40
IBEX_UART0_RX_TIMEOUT_IRQ = 7,
41
IBEX_UART0_RX_PARITY_ERR_IRQ = 8,
42
- IBEX_TIMER_TIMEREXPIRED0_0 = 126,
43
- IBEX_SPI_HOST0_ERR_IRQ = 150,
44
- IBEX_SPI_HOST0_SPI_EVENT_IRQ = 151,
45
- IBEX_SPI_HOST1_ERR_IRQ = 152,
46
- IBEX_SPI_HOST1_SPI_EVENT_IRQ = 153,
47
+ IBEX_TIMER_TIMEREXPIRED0_0 = 127,
48
+ IBEX_SPI_HOST0_ERR_IRQ = 151,
49
+ IBEX_SPI_HOST0_SPI_EVENT_IRQ = 152,
50
+ IBEX_SPI_HOST1_ERR_IRQ = 153,
51
+ IBEX_SPI_HOST1_SPI_EVENT_IRQ = 154,
52
};
53
54
#endif
55
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/riscv/opentitan.c
58
+++ b/hw/riscv/opentitan.c
59
@@ -XXX,XX +XXX,XX @@
60
#include "sysemu/sysemu.h"
61
62
static const MemMapEntry ibex_memmap[] = {
63
- [IBEX_DEV_ROM] = { 0x00008000, 16 * KiB },
64
- [IBEX_DEV_RAM] = { 0x10000000, 0x10000 },
65
- [IBEX_DEV_FLASH] = { 0x20000000, 0x80000 },
66
+ [IBEX_DEV_ROM] = { 0x00008000, 0x8000 },
67
+ [IBEX_DEV_RAM] = { 0x10000000, 0x20000 },
68
+ [IBEX_DEV_FLASH] = { 0x20000000, 0x100000 },
69
[IBEX_DEV_UART] = { 0x40000000, 0x1000 },
70
[IBEX_DEV_GPIO] = { 0x40040000, 0x1000 },
71
[IBEX_DEV_SPI_DEVICE] = { 0x40050000, 0x1000 },
72
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
73
[IBEX_DEV_TIMER] = { 0x40100000, 0x1000 },
74
[IBEX_DEV_SENSOR_CTRL] = { 0x40110000, 0x1000 },
75
[IBEX_DEV_OTP_CTRL] = { 0x40130000, 0x4000 },
76
+ [IBEX_DEV_LC_CTRL] = { 0x40140000, 0x1000 },
77
[IBEX_DEV_USBDEV] = { 0x40150000, 0x1000 },
78
[IBEX_DEV_SPI_HOST0] = { 0x40300000, 0x1000 },
79
[IBEX_DEV_SPI_HOST1] = { 0x40310000, 0x1000 },
80
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
81
&error_abort);
82
object_property_set_int(OBJECT(&s->cpus), "num-harts", ms->smp.cpus,
83
&error_abort);
84
- object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x8080, &error_abort);
85
+ object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x20000490,
86
+ &error_abort);
87
sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_fatal);
88
89
/* Boot ROM */
90
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
91
memmap[IBEX_DEV_SENSOR_CTRL].base, memmap[IBEX_DEV_SENSOR_CTRL].size);
92
create_unimplemented_device("riscv.lowrisc.ibex.otp_ctrl",
93
memmap[IBEX_DEV_OTP_CTRL].base, memmap[IBEX_DEV_OTP_CTRL].size);
94
+ create_unimplemented_device("riscv.lowrisc.ibex.lc_ctrl",
95
+ memmap[IBEX_DEV_LC_CTRL].base, memmap[IBEX_DEV_LC_CTRL].size);
96
create_unimplemented_device("riscv.lowrisc.ibex.pwrmgr",
97
memmap[IBEX_DEV_PWRMGR].base, memmap[IBEX_DEV_PWRMGR].size);
98
create_unimplemented_device("riscv.lowrisc.ibex.rstmgr",
99
--
100
2.37.2
diff view generated by jsdifflib
Deleted patch
1
From: Conor Dooley <conor.dooley@microchip.com>
2
1
3
Booting using "Direct Kernel Boot" for PolarFire SoC & skipping u-boot
4
entirely is probably not advisable, but it does at least show signs of
5
life. Recent Linux kernel versions make use of peripherals that are
6
missing definitions in QEMU and lead to kernel panics. These issues
7
almost certain rear their head for other methods of booting, but I was
8
unable to figure out a suitable HSS version that is recent enough to
9
support these peripherals & works with QEMU.
10
11
With these peripherals added, booting a kernel with the following hangs
12
hangs waiting for the system controller's hwrng, but the kernel no
13
longer panics. With the Linux driver for hwrng disabled, it boots to
14
console.
15
16
qemu-system-riscv64 -M microchip-icicle-kit \
17
    -m 2G -smp 5 \
18
    -kernel $(vmlinux_bin) \
19
    -dtb $(dtb)\
20
    -initrd $(initramfs) \
21
    -display none -serial null \
22
    -serial stdio
23
24
More peripherals are added than strictly required to fix the panics in
25
the hopes of avoiding a replication of this problem in the future.
26
Some of the peripherals which are in the device tree for recent kernels
27
are implemented in the FPGA fabric. The eMMC/SD mux, which exists as
28
an unimplemented device is replaced by a wider entry. This updated
29
entry covers both the mux & the remainder of the FPGA fabric connected
30
to the MSS using Fabric Interrconnect (FIC) 3.
31
32
Link: https://github.com/polarfire-soc/icicle-kit-reference-design#fabric-memory-map
33
Link: https://ww1.microchip.com/downloads/aemDocuments/documents/FPGA/ProductDocuments/SupportingCollateral/V1_4_Register_Map.zip
34
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
35
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
36
Message-Id: <20220813135127.2971754-1-mail@conchuod.ie>
37
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
38
---
39
include/hw/riscv/microchip_pfsoc.h | 14 ++++++-
40
hw/riscv/microchip_pfsoc.c | 67 +++++++++++++++++++++++++++---
41
2 files changed, 74 insertions(+), 7 deletions(-)
42
43
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/include/hw/riscv/microchip_pfsoc.h
46
+++ b/include/hw/riscv/microchip_pfsoc.h
47
@@ -XXX,XX +XXX,XX @@ enum {
48
MICROCHIP_PFSOC_L2LIM,
49
MICROCHIP_PFSOC_PLIC,
50
MICROCHIP_PFSOC_MMUART0,
51
+ MICROCHIP_PFSOC_WDOG0,
52
MICROCHIP_PFSOC_SYSREG,
53
+ MICROCHIP_PFSOC_AXISW,
54
MICROCHIP_PFSOC_MPUCFG,
55
+ MICROCHIP_PFSOC_FMETER,
56
MICROCHIP_PFSOC_DDR_SGMII_PHY,
57
MICROCHIP_PFSOC_EMMC_SD,
58
MICROCHIP_PFSOC_DDR_CFG,
59
@@ -XXX,XX +XXX,XX @@ enum {
60
MICROCHIP_PFSOC_MMUART2,
61
MICROCHIP_PFSOC_MMUART3,
62
MICROCHIP_PFSOC_MMUART4,
63
+ MICROCHIP_PFSOC_WDOG1,
64
+ MICROCHIP_PFSOC_WDOG2,
65
+ MICROCHIP_PFSOC_WDOG3,
66
+ MICROCHIP_PFSOC_WDOG4,
67
MICROCHIP_PFSOC_SPI0,
68
MICROCHIP_PFSOC_SPI1,
69
+ MICROCHIP_PFSOC_I2C0,
70
MICROCHIP_PFSOC_I2C1,
71
+ MICROCHIP_PFSOC_CAN0,
72
+ MICROCHIP_PFSOC_CAN1,
73
MICROCHIP_PFSOC_GEM0,
74
MICROCHIP_PFSOC_GEM1,
75
MICROCHIP_PFSOC_GPIO0,
76
MICROCHIP_PFSOC_GPIO1,
77
MICROCHIP_PFSOC_GPIO2,
78
+ MICROCHIP_PFSOC_RTC,
79
MICROCHIP_PFSOC_ENVM_CFG,
80
MICROCHIP_PFSOC_ENVM_DATA,
81
+ MICROCHIP_PFSOC_USB,
82
MICROCHIP_PFSOC_QSPI_XIP,
83
MICROCHIP_PFSOC_IOSCB,
84
- MICROCHIP_PFSOC_EMMC_SD_MUX,
85
+ MICROCHIP_PFSOC_FABRIC_FIC3,
86
MICROCHIP_PFSOC_DRAM_LO,
87
MICROCHIP_PFSOC_DRAM_LO_ALIAS,
88
MICROCHIP_PFSOC_DRAM_HI,
89
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/hw/riscv/microchip_pfsoc.c
92
+++ b/hw/riscv/microchip_pfsoc.c
93
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry microchip_pfsoc_memmap[] = {
94
[MICROCHIP_PFSOC_L2LIM] = { 0x8000000, 0x2000000 },
95
[MICROCHIP_PFSOC_PLIC] = { 0xc000000, 0x4000000 },
96
[MICROCHIP_PFSOC_MMUART0] = { 0x20000000, 0x1000 },
97
+ [MICROCHIP_PFSOC_WDOG0] = { 0x20001000, 0x1000 },
98
[MICROCHIP_PFSOC_SYSREG] = { 0x20002000, 0x2000 },
99
+ [MICROCHIP_PFSOC_AXISW] = { 0x20004000, 0x1000 },
100
[MICROCHIP_PFSOC_MPUCFG] = { 0x20005000, 0x1000 },
101
+ [MICROCHIP_PFSOC_FMETER] = { 0x20006000, 0x1000 },
102
[MICROCHIP_PFSOC_DDR_SGMII_PHY] = { 0x20007000, 0x1000 },
103
[MICROCHIP_PFSOC_EMMC_SD] = { 0x20008000, 0x1000 },
104
[MICROCHIP_PFSOC_DDR_CFG] = { 0x20080000, 0x40000 },
105
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry microchip_pfsoc_memmap[] = {
106
[MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
107
[MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
108
[MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
109
+ [MICROCHIP_PFSOC_WDOG1] = { 0x20101000, 0x1000 },
110
+ [MICROCHIP_PFSOC_WDOG2] = { 0x20103000, 0x1000 },
111
+ [MICROCHIP_PFSOC_WDOG3] = { 0x20105000, 0x1000 },
112
+ [MICROCHIP_PFSOC_WDOG4] = { 0x20106000, 0x1000 },
113
[MICROCHIP_PFSOC_SPI0] = { 0x20108000, 0x1000 },
114
[MICROCHIP_PFSOC_SPI1] = { 0x20109000, 0x1000 },
115
+ [MICROCHIP_PFSOC_I2C0] = { 0x2010a000, 0x1000 },
116
[MICROCHIP_PFSOC_I2C1] = { 0x2010b000, 0x1000 },
117
+ [MICROCHIP_PFSOC_CAN0] = { 0x2010c000, 0x1000 },
118
+ [MICROCHIP_PFSOC_CAN1] = { 0x2010d000, 0x1000 },
119
[MICROCHIP_PFSOC_GEM0] = { 0x20110000, 0x2000 },
120
[MICROCHIP_PFSOC_GEM1] = { 0x20112000, 0x2000 },
121
[MICROCHIP_PFSOC_GPIO0] = { 0x20120000, 0x1000 },
122
[MICROCHIP_PFSOC_GPIO1] = { 0x20121000, 0x1000 },
123
[MICROCHIP_PFSOC_GPIO2] = { 0x20122000, 0x1000 },
124
+ [MICROCHIP_PFSOC_RTC] = { 0x20124000, 0x1000 },
125
[MICROCHIP_PFSOC_ENVM_CFG] = { 0x20200000, 0x1000 },
126
[MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
127
+ [MICROCHIP_PFSOC_USB] = { 0x20201000, 0x1000 },
128
[MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
129
[MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
130
- [MICROCHIP_PFSOC_EMMC_SD_MUX] = { 0x4f000000, 0x4 },
131
+ [MICROCHIP_PFSOC_FABRIC_FIC3] = { 0x40000000, 0x20000000 },
132
[MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
133
[MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
134
[MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
135
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
136
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysreg), 0,
137
memmap[MICROCHIP_PFSOC_SYSREG].base);
138
139
+ /* AXISW */
140
+ create_unimplemented_device("microchip.pfsoc.axisw",
141
+ memmap[MICROCHIP_PFSOC_AXISW].base,
142
+ memmap[MICROCHIP_PFSOC_AXISW].size);
143
+
144
/* MPUCFG */
145
create_unimplemented_device("microchip.pfsoc.mpucfg",
146
memmap[MICROCHIP_PFSOC_MPUCFG].base,
147
memmap[MICROCHIP_PFSOC_MPUCFG].size);
148
149
+ /* FMETER */
150
+ create_unimplemented_device("microchip.pfsoc.fmeter",
151
+ memmap[MICROCHIP_PFSOC_FMETER].base,
152
+ memmap[MICROCHIP_PFSOC_FMETER].size);
153
+
154
/* DDR SGMII PHY */
155
sysbus_realize(SYS_BUS_DEVICE(&s->ddr_sgmii_phy), errp);
156
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ddr_sgmii_phy), 0,
157
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
158
qdev_get_gpio_in(DEVICE(s->plic), MICROCHIP_PFSOC_MMUART4_IRQ),
159
serial_hd(4));
160
161
+ /* Watchdogs */
162
+ create_unimplemented_device("microchip.pfsoc.watchdog0",
163
+ memmap[MICROCHIP_PFSOC_WDOG0].base,
164
+ memmap[MICROCHIP_PFSOC_WDOG0].size);
165
+ create_unimplemented_device("microchip.pfsoc.watchdog1",
166
+ memmap[MICROCHIP_PFSOC_WDOG1].base,
167
+ memmap[MICROCHIP_PFSOC_WDOG1].size);
168
+ create_unimplemented_device("microchip.pfsoc.watchdog2",
169
+ memmap[MICROCHIP_PFSOC_WDOG2].base,
170
+ memmap[MICROCHIP_PFSOC_WDOG2].size);
171
+ create_unimplemented_device("microchip.pfsoc.watchdog3",
172
+ memmap[MICROCHIP_PFSOC_WDOG3].base,
173
+ memmap[MICROCHIP_PFSOC_WDOG3].size);
174
+ create_unimplemented_device("microchip.pfsoc.watchdog4",
175
+ memmap[MICROCHIP_PFSOC_WDOG4].base,
176
+ memmap[MICROCHIP_PFSOC_WDOG4].size);
177
+
178
/* SPI */
179
create_unimplemented_device("microchip.pfsoc.spi0",
180
memmap[MICROCHIP_PFSOC_SPI0].base,
181
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
182
memmap[MICROCHIP_PFSOC_SPI1].base,
183
memmap[MICROCHIP_PFSOC_SPI1].size);
184
185
- /* I2C1 */
186
+ /* I2C */
187
+ create_unimplemented_device("microchip.pfsoc.i2c0",
188
+ memmap[MICROCHIP_PFSOC_I2C0].base,
189
+ memmap[MICROCHIP_PFSOC_I2C0].size);
190
create_unimplemented_device("microchip.pfsoc.i2c1",
191
memmap[MICROCHIP_PFSOC_I2C1].base,
192
memmap[MICROCHIP_PFSOC_I2C1].size);
193
194
+ /* CAN */
195
+ create_unimplemented_device("microchip.pfsoc.can0",
196
+ memmap[MICROCHIP_PFSOC_CAN0].base,
197
+ memmap[MICROCHIP_PFSOC_CAN0].size);
198
+ create_unimplemented_device("microchip.pfsoc.can1",
199
+ memmap[MICROCHIP_PFSOC_CAN1].base,
200
+ memmap[MICROCHIP_PFSOC_CAN1].size);
201
+
202
+ /* USB */
203
+ create_unimplemented_device("microchip.pfsoc.usb",
204
+ memmap[MICROCHIP_PFSOC_USB].base,
205
+ memmap[MICROCHIP_PFSOC_USB].size);
206
+
207
/* GEMs */
208
209
nd = &nd_table[0];
210
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
211
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0,
212
memmap[MICROCHIP_PFSOC_IOSCB].base);
213
214
- /* eMMC/SD mux */
215
- create_unimplemented_device("microchip.pfsoc.emmc_sd_mux",
216
- memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].base,
217
- memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].size);
218
+ /* FPGA Fabric */
219
+ create_unimplemented_device("microchip.pfsoc.fabricfic3",
220
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC3].base,
221
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC3].size);
222
223
/* QSPI Flash */
224
memory_region_init_rom(qspi_xip_mem, OBJECT(dev),
225
--
226
2.37.2
diff view generated by jsdifflib
Deleted patch
1
From: Atish Patra <atishp@rivosinc.com>
2
1
3
With .min_priv_version, additiona priv version check is uncessary
4
for mcountinhibit read/write functions.
5
6
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
7
Tested-by: Heiko Stuebner <heiko@sntech.de>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Atish Patra <atishp@rivosinc.com>
10
Message-Id: <20220816232321.558250-7-atishp@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/csr.c | 8 --------
14
1 file changed, 8 deletions(-)
15
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/csr.c
19
+++ b/target/riscv/csr.c
20
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mtvec(CPURISCVState *env, int csrno,
21
static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno,
22
target_ulong *val)
23
{
24
- if (env->priv_ver < PRIV_VERSION_1_11_0) {
25
- return RISCV_EXCP_ILLEGAL_INST;
26
- }
27
-
28
*val = env->mcountinhibit;
29
return RISCV_EXCP_NONE;
30
}
31
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
32
int cidx;
33
PMUCTRState *counter;
34
35
- if (env->priv_ver < PRIV_VERSION_1_11_0) {
36
- return RISCV_EXCP_ILLEGAL_INST;
37
- }
38
-
39
env->mcountinhibit = val;
40
41
/* Check if any other counter is also monitoring cycles/instructions */
42
--
43
2.37.2
diff view generated by jsdifflib
Deleted patch
1
From: Conor Dooley <conor.dooley@microchip.com>
2
1
3
"uart" is not a node name that complies with the dt-schema.
4
Change the node name to "serial" to ix warnings seen during
5
dt-validate on a dtbdump of the virt machine such as:
6
/stuff/qemu/qemu.dtb: uart@10000000: $nodename:0: 'uart@10000000' does not match '^serial(@.*)?$'
7
From schema: /stuff/linux/Documentation/devicetree/bindings/serial/8250.yaml
8
9
Reported-by: Rob Herring <robh@kernel.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
12
Message-id: 20220810184612.157317-2-mail@conchuod.ie
13
Link: https://lore.kernel.org/linux-riscv/20220803170552.GA2250266-robh@kernel.org/
14
Fixes: 04331d0b56 ("RISC-V VirtIO Machine")
15
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
hw/riscv/virt.c | 2 +-
19
1 file changed, 1 insertion(+), 1 deletion(-)
20
21
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/riscv/virt.c
24
+++ b/hw/riscv/virt.c
25
@@ -XXX,XX +XXX,XX @@ static void create_fdt_uart(RISCVVirtState *s, const MemMapEntry *memmap,
26
char *name;
27
MachineState *mc = MACHINE(s);
28
29
- name = g_strdup_printf("/soc/uart@%lx", (long)memmap[VIRT_UART0].base);
30
+ name = g_strdup_printf("/soc/serial@%lx", (long)memmap[VIRT_UART0].base);
31
qemu_fdt_add_subnode(mc->fdt, name);
32
qemu_fdt_setprop_string(mc->fdt, name, "compatible", "ns16550a");
33
qemu_fdt_setprop_cells(mc->fdt, name, "reg",
34
--
35
2.37.2
diff view generated by jsdifflib
Deleted patch
1
From: Conor Dooley <conor.dooley@microchip.com>
2
1
3
When optional AIA PLIC support was added the to the virt machine, the
4
address cells property was removed leading the issues with dt-validate
5
on a dump from the virt machine:
6
/stuff/qemu/qemu.dtb: plic@c000000: '#address-cells' is a required property
7
From schema: /stuff/linux/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
8
Add back the property to suppress the warning.
9
10
Reported-by: Rob Herring <robh@kernel.org>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
13
Message-id: 20220810184612.157317-3-mail@conchuod.ie
14
Link: https://lore.kernel.org/linux-riscv/20220803170552.GA2250266-robh@kernel.org/
15
Fixes: e6faee6585 ("hw/riscv: virt: Add optional AIA APLIC support to virt machine")
16
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
19
include/hw/riscv/virt.h | 1 +
20
hw/riscv/virt.c | 2 ++
21
2 files changed, 3 insertions(+)
22
23
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/riscv/virt.h
26
+++ b/include/hw/riscv/virt.h
27
@@ -XXX,XX +XXX,XX @@ enum {
28
29
#define FDT_PCI_ADDR_CELLS 3
30
#define FDT_PCI_INT_CELLS 1
31
+#define FDT_PLIC_ADDR_CELLS 0
32
#define FDT_PLIC_INT_CELLS 1
33
#define FDT_APLIC_INT_CELLS 2
34
#define FDT_IMSIC_INT_CELLS 0
35
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/riscv/virt.c
38
+++ b/hw/riscv/virt.c
39
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s,
40
qemu_fdt_add_subnode(mc->fdt, plic_name);
41
qemu_fdt_setprop_cell(mc->fdt, plic_name,
42
"#interrupt-cells", FDT_PLIC_INT_CELLS);
43
+ qemu_fdt_setprop_cell(mc->fdt, plic_name,
44
+ "#address-cells", FDT_PLIC_ADDR_CELLS);
45
qemu_fdt_setprop_string_array(mc->fdt, plic_name, "compatible",
46
(char **)&plic_compat,
47
ARRAY_SIZE(plic_compat));
48
--
49
2.37.2
diff view generated by jsdifflib
Deleted patch
1
From: Conor Dooley <conor.dooley@microchip.com>
2
1
3
The reset and poweroff features of the syscon were originally added to
4
top level, which is a valid path for a syscon subnode. Subsequently a
5
reorganisation was carried out while implementing NUMA in which the
6
subnodes were moved into the /soc node. As /soc is a "simple-bus", this
7
path is invalid, and so dt-validate produces the following warnings:
8
9
/stuff/qemu/qemu.dtb: soc: poweroff: {'value': [[21845]], 'offset': [[0]], 'regmap': [[4]], 'compatible': ['syscon-poweroff']} should not be valid under {'type': 'object'}
10
From schema: /home/conor/.local/lib/python3.9/site-packages/dtschema/schemas/simple-bus.yaml
11
/stuff/qemu/qemu.dtb: soc: reboot: {'value': [[30583]], 'offset': [[0]], 'regmap': [[4]], 'compatible': ['syscon-reboot']} should not be valid under {'type': 'object'}
12
From schema: /home/conor/.local/lib/python3.9/site-packages/dtschema/schemas/simple-bus.yaml
13
14
Move the syscon subnodes back to the top level and silence the warnings.
15
16
Reported-by: Rob Herring <robh@kernel.org>
17
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
19
Message-id: 20220810184612.157317-4-mail@conchuod.ie
20
Link: https://lore.kernel.org/linux-riscv/20220803170552.GA2250266-robh@kernel.org/
21
Fixes: 18df0b4695 ("hw/riscv: virt: Allow creating multiple NUMA sockets")
22
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
23
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
---
25
hw/riscv/virt.c | 4 ++--
26
1 file changed, 2 insertions(+), 2 deletions(-)
27
28
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/riscv/virt.c
31
+++ b/hw/riscv/virt.c
32
@@ -XXX,XX +XXX,XX @@ static void create_fdt_reset(RISCVVirtState *s, const MemMapEntry *memmap,
33
test_phandle = qemu_fdt_get_phandle(mc->fdt, name);
34
g_free(name);
35
36
- name = g_strdup_printf("/soc/reboot");
37
+ name = g_strdup_printf("/reboot");
38
qemu_fdt_add_subnode(mc->fdt, name);
39
qemu_fdt_setprop_string(mc->fdt, name, "compatible", "syscon-reboot");
40
qemu_fdt_setprop_cell(mc->fdt, name, "regmap", test_phandle);
41
@@ -XXX,XX +XXX,XX @@ static void create_fdt_reset(RISCVVirtState *s, const MemMapEntry *memmap,
42
qemu_fdt_setprop_cell(mc->fdt, name, "value", FINISHER_RESET);
43
g_free(name);
44
45
- name = g_strdup_printf("/soc/poweroff");
46
+ name = g_strdup_printf("/poweroff");
47
qemu_fdt_add_subnode(mc->fdt, name);
48
qemu_fdt_setprop_string(mc->fdt, name, "compatible", "syscon-poweroff");
49
qemu_fdt_setprop_cell(mc->fdt, name, "regmap", test_phandle);
50
--
51
2.37.2
diff view generated by jsdifflib
1
From: Atish Patra <atishp@rivosinc.com>
1
From: Yu-Ming Chang <yumin686@andestech.com>
2
2
3
vstimecmp CSR allows the guest OS or to program the next guest timer
3
Both CSRRS and CSRRC always read the addressed CSR and cause any read side
4
interrupt directly. Thus, hypervisor no longer need to inject the
4
effects regardless of rs1 and rd fields. Note that if rs1 specifies a register
5
timer interrupt to the guest if vstimecmp is used. This was ratified
5
holding a zero value other than x0, the instruction will still attempt to write
6
as a part of the Sstc extension.
6
the unmodified value back to the CSR and will cause any attendant side effects.
7
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>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Atish Patra <atishp@rivosinc.com>
14
Message-ID: <20240403070823.80897-1-yumin686@andestech.com>
10
Message-Id: <20220824221357.41070-4-atishp@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
16
---
13
target/riscv/cpu.h | 4 ++
17
target/riscv/cpu.h | 4 ++++
14
target/riscv/cpu_bits.h | 4 ++
18
target/riscv/csr.c | 51 ++++++++++++++++++++++++++++++++++++----
15
target/riscv/cpu_helper.c | 11 +++--
19
target/riscv/op_helper.c | 6 ++---
16
target/riscv/csr.c | 88 ++++++++++++++++++++++++++++++++++++--
20
3 files changed, 53 insertions(+), 8 deletions(-)
17
target/riscv/machine.c | 1 +
18
target/riscv/time_helper.c | 16 +++++++
19
6 files changed, 118 insertions(+), 6 deletions(-)
20
21
21
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
22
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu.h
24
--- a/target/riscv/cpu.h
24
+++ b/target/riscv/cpu.h
25
+++ b/target/riscv/cpu.h
25
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
26
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
26
/* Sstc CSRs */
27
void riscv_cpu_update_mask(CPURISCVState *env);
27
uint64_t stimecmp;
28
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
28
29
29
+ uint64_t vstimecmp;
30
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
30
+
31
+ target_ulong *ret_value);
31
/* physical memory protection */
32
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
32
pmp_table_t pmp_state;
33
target_ulong *ret_value,
33
target_ulong mseccfg;
34
target_ulong new_value, target_ulong write_mask);
34
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
35
@@ -XXX,XX +XXX,XX @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
35
36
target_ulong new_value,
36
/* Fields from here on are preserved across CPU reset. */
37
target_ulong write_mask);
37
QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
38
38
+ QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */
39
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
39
+ bool vstime_irq;
40
+ Int128 *ret_value);
40
41
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
41
hwaddr kernel_addr;
42
Int128 *ret_value,
42
hwaddr fdt_addr;
43
Int128 new_value, Int128 write_mask);
43
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/cpu_bits.h
46
+++ b/target/riscv/cpu_bits.h
47
@@ -XXX,XX +XXX,XX @@
48
#define CSR_VSIP 0x244
49
#define CSR_VSATP 0x280
50
51
+/* Sstc virtual CSRs */
52
+#define CSR_VSTIMECMP 0x24D
53
+#define CSR_VSTIMECMPH 0x25D
54
+
55
#define CSR_MTINST 0x34a
56
#define CSR_MTVAL2 0x34b
57
58
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/riscv/cpu_helper.c
61
+++ b/target/riscv/cpu_helper.c
62
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_all_pending(CPURISCVState *env)
63
{
64
uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN);
65
uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
66
+ uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0;
67
68
- return (env->mip | vsgein) & env->mie;
69
+ return (env->mip | vsgein | vstip) & env->mie;
70
}
71
72
int riscv_cpu_mirq_pending(CPURISCVState *env)
73
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value)
74
{
75
CPURISCVState *env = &cpu->env;
76
CPUState *cs = CPU(cpu);
77
- uint64_t gein, vsgein = 0, old = env->mip;
78
+ uint64_t gein, vsgein = 0, vstip = 0, old = env->mip;
79
bool locked = false;
80
81
if (riscv_cpu_virt_enabled(env)) {
82
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value)
83
vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
84
}
85
86
+ /* No need to update mip for VSTIP */
87
+ mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask;
88
+ vstip = env->vstime_irq ? MIP_VSTIP : 0;
89
+
90
if (!qemu_mutex_iothread_locked()) {
91
locked = true;
92
qemu_mutex_lock_iothread();
93
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value)
94
95
env->mip = (env->mip & ~mask) | (value & mask);
96
97
- if (env->mip | vsgein) {
98
+ if (env->mip | vsgein | vstip) {
99
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
100
} else {
101
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
102
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
44
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
103
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
104
--- a/target/riscv/csr.c
46
--- a/target/riscv/csr.c
105
+++ b/target/riscv/csr.c
47
+++ b/target/riscv/csr.c
106
@@ -XXX,XX +XXX,XX @@ static RISCVException sstc(CPURISCVState *env, int csrno)
48
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
49
50
static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
51
int csrno,
52
- bool write_mask)
53
+ bool write)
107
{
54
{
108
CPUState *cs = env_cpu(env);
55
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
109
RISCVCPU *cpu = RISCV_CPU(cs);
56
bool read_only = get_field(csrno, 0xC00) == 3;
110
+ bool hmode_check = false;
57
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
111
58
}
112
if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
59
113
return RISCV_EXCP_ILLEGAL_INST;
60
/* read / write check */
114
@@ -XXX,XX +XXX,XX @@ static RISCVException sstc(CPURISCVState *env, int csrno)
61
- if (write_mask && read_only) {
62
+ if (write && read_only) {
115
return RISCV_EXCP_ILLEGAL_INST;
63
return RISCV_EXCP_ILLEGAL_INST;
116
}
64
}
117
65
118
- return smode(env, csrno);
66
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
119
+ if (riscv_cpu_virt_enabled(env)) {
67
return RISCV_EXCP_NONE;
120
+ if (!(get_field(env->hcounteren, COUNTEREN_TM) &
68
}
121
+ get_field(env->henvcfg, HENVCFG_STCE))) {
69
122
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
70
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
123
+ }
71
+ target_ulong *ret_value)
72
+{
73
+ RISCVException ret = riscv_csrrw_check(env, csrno, false);
74
+ if (ret != RISCV_EXCP_NONE) {
75
+ return ret;
124
+ }
76
+ }
125
+
77
+
126
+ if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
78
+ return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
127
+ hmode_check = true;
79
+}
80
+
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)
96
+{
97
+ RISCVException ret;
98
+
99
+ ret = riscv_csrrw_check(env, csrno, false);
100
+ if (ret != RISCV_EXCP_NONE) {
101
+ return ret;
128
+ }
102
+ }
129
+
103
+
130
+ return hmode_check ? hmode(env, csrno) : smode(env, csrno);
104
+ if (csr_ops[csrno].read128) {
131
}
105
+ return riscv_csrrw_do128(env, csrno, ret_value,
132
106
+ int128_zero(), int128_zero());
133
static RISCVException sstc_32(CPURISCVState *env, int csrno)
107
+ }
134
@@ -XXX,XX +XXX,XX @@ static RISCVException sstc_32(CPURISCVState *env, int csrno)
135
return sstc(env, csrno);
136
}
137
138
+static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,
139
+ target_ulong *val)
140
+{
141
+ *val = env->vstimecmp;
142
+
108
+
143
+ return RISCV_EXCP_NONE;
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;
144
+}
124
+}
145
+
125
+
146
+static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
126
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
147
+ target_ulong *val)
127
Int128 *ret_value,
148
+{
128
Int128 new_value, Int128 write_mask)
149
+ *val = env->vstimecmp >> 32;
150
+
151
+ return RISCV_EXCP_NONE;
152
+}
153
+
154
+static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
155
+ target_ulong val)
156
+{
157
+ RISCVCPU *cpu = env_archcpu(env);
158
+
159
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
160
+ env->vstimecmp = deposit64(env->vstimecmp, 0, 32, (uint64_t)val);
161
+ } else {
162
+ env->vstimecmp = val;
163
+ }
164
+
165
+ riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
166
+ env->htimedelta, MIP_VSTIP);
167
+
168
+ return RISCV_EXCP_NONE;
169
+}
170
+
171
+static RISCVException write_vstimecmph(CPURISCVState *env, int csrno,
172
+ target_ulong val)
173
+{
174
+ RISCVCPU *cpu = env_archcpu(env);
175
+
176
+ env->vstimecmp = deposit64(env->vstimecmp, 32, 32, (uint64_t)val);
177
+ riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
178
+ env->htimedelta, MIP_VSTIP);
179
+
180
+ return RISCV_EXCP_NONE;
181
+}
182
+
183
static RISCVException read_stimecmp(CPURISCVState *env, int csrno,
184
target_ulong *val)
185
{
129
{
186
- *val = env->stimecmp;
130
RISCVException ret;
187
+ if (riscv_cpu_virt_enabled(env)) {
131
188
+ *val = env->vstimecmp;
132
- ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask));
189
+ } else {
133
+ ret = riscv_csrrw_check(env, csrno, true);
190
+ *val = env->stimecmp;
134
if (ret != RISCV_EXCP_NONE) {
191
+ }
135
return ret;
192
+
136
}
193
return RISCV_EXCP_NONE;
137
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
194
}
138
index XXXXXXX..XXXXXXX 100644
195
139
--- a/target/riscv/op_helper.c
196
static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
140
+++ b/target/riscv/op_helper.c
197
target_ulong *val)
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)
198
{
152
{
199
- *val = env->stimecmp >> 32;
153
Int128 rv = int128_zero();
200
+ if (riscv_cpu_virt_enabled(env)) {
154
- RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
201
+ *val = env->vstimecmp >> 32;
155
- int128_zero(),
202
+ } else {
156
- int128_zero());
203
+ *val = env->stimecmp >> 32;
157
+ RISCVException ret = riscv_csrr_i128(env, csr, &rv);
204
+ }
158
205
+
159
if (ret != RISCV_EXCP_NONE) {
206
return RISCV_EXCP_NONE;
160
riscv_raise_exception(env, ret, GETPC());
207
}
208
209
@@ -XXX,XX +XXX,XX @@ static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
210
{
211
RISCVCPU *cpu = env_archcpu(env);
212
213
+ if (riscv_cpu_virt_enabled(env)) {
214
+ return write_vstimecmp(env, csrno, val);
215
+ }
216
+
217
if (riscv_cpu_mxl(env) == MXL_RV32) {
218
env->stimecmp = deposit64(env->stimecmp, 0, 32, (uint64_t)val);
219
} else {
220
@@ -XXX,XX +XXX,XX @@ static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
221
{
222
RISCVCPU *cpu = env_archcpu(env);
223
224
+ if (riscv_cpu_virt_enabled(env)) {
225
+ return write_vstimecmph(env, csrno, val);
226
+ }
227
+
228
env->stimecmp = deposit64(env->stimecmp, 32, 32, (uint64_t)val);
229
riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP);
230
231
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
232
if (csrno != CSR_HVIP) {
233
gin = get_field(env->hstatus, HSTATUS_VGEIN);
234
old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0;
235
+ old_mip |= env->vstime_irq ? MIP_VSTIP : 0;
236
}
237
238
if (ret_val) {
239
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
240
.min_priv_ver = PRIV_VERSION_1_12_0 },
241
[CSR_STIMECMPH] = { "stimecmph", sstc_32, read_stimecmph, write_stimecmph,
242
.min_priv_ver = PRIV_VERSION_1_12_0 },
243
+ [CSR_VSTIMECMP] = { "vstimecmp", sstc, read_vstimecmp,
244
+ write_vstimecmp,
245
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
246
+ [CSR_VSTIMECMPH] = { "vstimecmph", sstc_32, read_vstimecmph,
247
+ write_vstimecmph,
248
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
249
250
/* Supervisor Protection and Translation */
251
[CSR_SATP] = { "satp", smode, read_satp, write_satp },
252
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
253
index XXXXXXX..XXXXXXX 100644
254
--- a/target/riscv/machine.c
255
+++ b/target/riscv/machine.c
256
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_hyper = {
257
VMSTATE_UINTTL(env.hgeie, RISCVCPU),
258
VMSTATE_UINTTL(env.hgeip, RISCVCPU),
259
VMSTATE_UINT64(env.htimedelta, RISCVCPU),
260
+ VMSTATE_UINT64(env.vstimecmp, RISCVCPU),
261
262
VMSTATE_UINTTL(env.hvictl, RISCVCPU),
263
VMSTATE_UINT8_ARRAY(env.hviprio, RISCVCPU, 64),
264
diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
265
index XXXXXXX..XXXXXXX 100644
266
--- a/target/riscv/time_helper.c
267
+++ b/target/riscv/time_helper.c
268
@@ -XXX,XX +XXX,XX @@
269
#include "time_helper.h"
270
#include "hw/intc/riscv_aclint.h"
271
272
+static void riscv_vstimer_cb(void *opaque)
273
+{
274
+ RISCVCPU *cpu = opaque;
275
+ CPURISCVState *env = &cpu->env;
276
+ env->vstime_irq = 1;
277
+ riscv_cpu_update_mip(cpu, MIP_VSTIP, BOOL_TO_MASK(1));
278
+}
279
+
280
static void riscv_stimer_cb(void *opaque)
281
{
282
RISCVCPU *cpu = opaque;
283
@@ -XXX,XX +XXX,XX @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer,
284
* If we're setting an stimecmp value in the "past",
285
* immediately raise the timer interrupt
286
*/
287
+ if (timer_irq == MIP_VSTIP) {
288
+ env->vstime_irq = 1;
289
+ }
290
riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(1));
291
return;
292
}
293
294
+ if (timer_irq == MIP_VSTIP) {
295
+ env->vstime_irq = 0;
296
+ }
297
/* Clear the [V]STIP bit in mip */
298
riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
299
300
@@ -XXX,XX +XXX,XX @@ void riscv_timer_init(RISCVCPU *cpu)
301
env->stimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_stimer_cb, cpu);
302
env->stimecmp = 0;
303
304
+ env->vstimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_vstimer_cb, cpu);
305
+ env->vstimecmp = 0;
306
}
307
--
161
--
308
2.37.2
162
2.45.1
diff view generated by jsdifflib