1
The following changes since commit c95bd5ff1660883d15ad6e0005e4c8571604f51a:
1
The following changes since commit fea445e8fe9acea4f775a832815ee22bdf2b0222:
2
2
3
Merge remote-tracking branch 'remotes/philmd/tags/mips-fixes-20210322' into staging (2021-03-22 14:26:13 +0000)
3
Merge tag 'pull-maintainer-final-for-real-this-time-200324-1' of https://gitlab.com/stsquad/qemu into staging (2024-03-21 10:31:56 +0000)
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-20210322-2
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240322
8
8
9
for you to fetch changes up to 9a27f69bd668d9d71674407badc412ce1231c7d5:
9
for you to fetch changes up to 385e575cd5ab2436c123e4b7f8c9b383a64c0dbe:
10
10
11
target/riscv: Prevent lost illegal instruction exceptions (2021-03-22 21:54:40 -0400)
11
target/riscv/kvm: fix timebase-frequency when using KVM acceleration (2024-03-22 15:41:01 +1000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
RISC-V PR for 6.0
14
RISC-V PR for 9.0
15
15
16
This PR includes:
16
* Do not enable all named features by default
17
- Fix for vector CSR access
17
* A range of Vector fixes
18
- Improvements to the Ibex UART device
18
* Update APLIC IDC after claiming iforce register
19
- PMP improvements and bug fixes
19
* Remove the dependency of Zvfbfmin to Zfbfmin
20
- Hypervisor extension bug fixes
20
* Fix mode in riscv_tlb_fill
21
- ramfb support for the virt machine
21
* Fix timebase-frequency when using KVM acceleration
22
- Fast read support for SST flash
23
- Improvements to the microchip_pfsoc machine
24
22
25
----------------------------------------------------------------
23
----------------------------------------------------------------
26
Alexander Wagner (1):
24
Daniel Henrique Barboza (10):
27
hw/char: disable ibex uart receive if the buffer is full
25
target/riscv: do not enable all named features by default
28
26
target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX()
29
Asherah Connor (2):
27
trans_rvv.c.inc: set vstart = 0 in int scalar move insns
30
hw/riscv: Add fw_cfg support to virt
28
target/riscv/vector_helper.c: fix 'vmvr_v' memcpy endianess
31
hw/riscv: allow ramfb on virt
29
target/riscv: always clear vstart in whole vec move insns
32
30
target/riscv: always clear vstart for ldst_whole insns
33
Bin Meng (3):
31
target/riscv/vector_helpers: do early exit when vstart >= vl
34
hw/block: m25p80: Support fast read for SST flashes
32
target/riscv: remove 'over' brconds from vector trans
35
hw/riscv: microchip_pfsoc: Map EMMC/SD mux register
33
trans_rvv.c.inc: remove redundant mark_vs_dirty() calls
36
docs/system: riscv: Add documentation for 'microchip-icicle-kit' machine
34
target/riscv/vector_helper.c: optimize loops in ldst helpers
37
35
38
Frank Chang (1):
36
Frank Chang (1):
39
target/riscv: fix vs() to return proper error code
37
hw/intc: Update APLIC IDC after claiming iforce register
40
38
41
Georg Kotheimer (6):
39
Irina Ryapolova (1):
42
target/riscv: Adjust privilege level for HLV(X)/HSV instructions
40
target/riscv: Fix mode in riscv_tlb_fill
43
target/riscv: Make VSTIP and VSEIP read-only in hip
44
target/riscv: Use background registers also for MSTATUS_MPV
45
target/riscv: Fix read and write accesses to vsip and vsie
46
target/riscv: Add proper two-stage lookup exception detection
47
target/riscv: Prevent lost illegal instruction exceptions
48
41
49
Jim Shu (3):
42
Ivan Klokov (1):
50
target/riscv: propagate PMP permission to TLB page
43
target/riscv: enable 'vstart_eq_zero' in the end of insns
51
target/riscv: add log of PMP permission checking
52
target/riscv: flush TLB pages if PMP permission has been changed
53
44
54
docs/system/riscv/microchip-icicle-kit.rst | 89 ++++++++++++++
45
Max Chou (1):
55
docs/system/target-riscv.rst | 1 +
46
target/riscv: rvv: Remove the dependency of Zvfbfmin to Zfbfmin
56
include/hw/char/ibex_uart.h | 4 +
57
include/hw/riscv/microchip_pfsoc.h | 1 +
58
include/hw/riscv/virt.h | 2 +
59
target/riscv/cpu.h | 4 +
60
target/riscv/pmp.h | 4 +-
61
hw/block/m25p80.c | 3 +
62
hw/char/ibex_uart.c | 23 +++-
63
hw/riscv/microchip_pfsoc.c | 6 +
64
hw/riscv/virt.c | 33 ++++++
65
target/riscv/cpu.c | 1 +
66
target/riscv/cpu_helper.c | 144 +++++++++++++++--------
67
target/riscv/csr.c | 77 +++++++------
68
target/riscv/pmp.c | 84 ++++++++++----
69
target/riscv/translate.c | 179 +----------------------------
70
hw/riscv/Kconfig | 1 +
71
17 files changed, 367 insertions(+), 289 deletions(-)
72
create mode 100644 docs/system/riscv/microchip-icicle-kit.rst
73
47
48
Yong-Xuan Wang (1):
49
target/riscv/kvm: fix timebase-frequency when using KVM acceleration
50
51
target/riscv/cpu_cfg.h | 8 +-
52
target/riscv/kvm/kvm_riscv.h | 1 +
53
target/riscv/vector_internals.h | 9 ++
54
hw/intc/riscv_aplic.c | 1 +
55
hw/riscv/virt.c | 2 +
56
target/riscv/cpu.c | 40 ++---
57
target/riscv/cpu_helper.c | 2 +-
58
target/riscv/kvm/kvm-cpu.c | 9 ++
59
target/riscv/tcg/tcg-cpu.c | 19 ++-
60
target/riscv/translate.c | 6 +
61
target/riscv/vcrypto_helper.c | 32 ++++
62
target/riscv/vector_helper.c | 93 ++++++++++-
63
target/riscv/vector_internals.c | 4 +
64
target/riscv/insn_trans/trans_rvbf16.c.inc | 18 +--
65
target/riscv/insn_trans/trans_rvv.c.inc | 244 +++++++++--------------------
66
target/riscv/insn_trans/trans_rvvk.c.inc | 30 +---
67
16 files changed, 259 insertions(+), 259 deletions(-)
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
The current two-stage lookup detection in riscv_cpu_do_interrupt falls
3
Commit 3b8022269c added the capability of named features/profile
4
short of its purpose, as all it checks is whether two-stage address
4
extensions to be added in riscv,isa. To do that we had to assign priv
5
translation either via the hypervisor-load store instructions or the
5
versions for each one of them in isa_edata_arr[]. But this resulted in a
6
MPRV feature would be allowed.
6
side-effect: vendor CPUs that aren't running priv_version_latest started
7
to experience warnings for these profile extensions [1]:
7
8
8
What we really need instead is whether two-stage address translation was
9
| $ qemu-system-riscv32 -M sifive_e
9
active when the exception was raised. However, in riscv_cpu_do_interrupt
10
| qemu-system-riscv32: warning: disabling zic64b extension for hart
10
we do not have the information to reliably detect this. Therefore, when
11
0x00000000 because privilege spec version does not match
11
we raise a memory fault exception we have to record whether two-stage
12
| qemu-system-riscv32: warning: disabling ziccamoa extension for
12
address translation is active.
13
hart 0x00000000 because privilege spec version does not match
13
14
14
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
15
This is benign as far as the CPU behavior is concerned since disabling
16
both extensions is a no-op (aside from riscv,isa). But the warnings are
17
unpleasant to deal with, especially because we're sending user warnings
18
for extensions that users can't enable/disable.
19
20
Instead of enabling all named features all the time, separate them by
21
priv version. During finalize() time, after we decided which
22
priv_version the CPU is running, enable/disable all the named extensions
23
based on the priv spec chosen. This will be enough for a bug fix, but as
24
a future work we should look into how we can name these extensions in a
25
way that we don't need an explicit ext_name => priv_ver as we're doing
26
here.
27
28
The named extensions being added in isa_edata_arr[] that will be
29
enabled/disabled based solely on priv version can be removed from
30
riscv_cpu_named_features[]. 'zic64b' is an extension that can be
31
disabled based on block sizes so it'll retain its own flag and entry.
32
33
[1] https://lists.gnu.org/archive/html/qemu-devel/2024-03/msg02592.html
34
35
Reported-by: Clément Chigot <chigot@adacore.com>
36
Fixes: 3b8022269c ("target/riscv: add riscv,isa to named features")
37
Suggested-by: Andrew Jones <ajones@ventanamicro.com>
38
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
39
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-id: 20210319141459.1196741-1-georg.kotheimer@kernkonzept.com
40
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
41
Tested-by: Clément Chigot <chigot@adacore.com>
42
Message-ID: <20240312203214.350980-1-dbarboza@ventanamicro.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
43
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
44
---
19
target/riscv/cpu.h | 4 ++++
45
target/riscv/cpu_cfg.h | 8 +++++---
20
target/riscv/cpu.c | 1 +
46
target/riscv/cpu.c | 40 +++++++++-----------------------------
21
target/riscv/cpu_helper.c | 21 ++++++++-------------
47
target/riscv/tcg/tcg-cpu.c | 14 ++++++++++---
22
3 files changed, 13 insertions(+), 13 deletions(-)
48
3 files changed, 25 insertions(+), 37 deletions(-)
23
49
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
50
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
25
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
52
--- a/target/riscv/cpu_cfg.h
27
+++ b/target/riscv/cpu.h
53
+++ b/target/riscv/cpu_cfg.h
28
@@ -XXX,XX +XXX,XX @@ struct CPURISCVState {
54
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
29
target_ulong satp_hs;
55
bool ext_zic64b;
30
uint64_t mstatus_hs;
56
31
57
/*
32
+ /* Signals whether the current exception occurred with two-stage address
58
- * Always 'true' boolean for named features
33
+ translation active. */
59
- * TCG always implement/can't be disabled.
34
+ bool two_stage_lookup;
60
+ * Always 'true' booleans for named features
35
+
61
+ * TCG always implement/can't be user disabled,
36
target_ulong scounteren;
62
+ * based on spec version.
37
target_ulong mcounteren;
63
*/
38
64
- bool ext_always_enabled;
65
+ bool has_priv_1_12;
66
+ bool has_priv_1_11;
67
68
/* Vendor-specific custom extensions */
69
bool ext_xtheadba;
39
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
70
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
40
index XXXXXXX..XXXXXXX 100644
71
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/cpu.c
72
--- a/target/riscv/cpu.c
42
+++ b/target/riscv/cpu.c
73
+++ b/target/riscv/cpu.c
43
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev)
74
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
44
env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
75
ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_zicbom),
45
env->mcause = 0;
76
ISA_EXT_DATA_ENTRY(zicbop, PRIV_VERSION_1_12_0, ext_zicbop),
46
env->pc = env->resetvec;
77
ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_zicboz),
47
+ env->two_stage_lookup = false;
78
- ISA_EXT_DATA_ENTRY(ziccamoa, PRIV_VERSION_1_11_0, ext_always_enabled),
48
#endif
79
- ISA_EXT_DATA_ENTRY(ziccif, PRIV_VERSION_1_11_0, ext_always_enabled),
49
cs->exception_index = EXCP_NONE;
80
- ISA_EXT_DATA_ENTRY(zicclsm, PRIV_VERSION_1_11_0, ext_always_enabled),
50
env->load_res = -1;
81
- ISA_EXT_DATA_ENTRY(ziccrse, PRIV_VERSION_1_11_0, ext_always_enabled),
51
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
82
+ ISA_EXT_DATA_ENTRY(ziccamoa, PRIV_VERSION_1_11_0, has_priv_1_11),
83
+ ISA_EXT_DATA_ENTRY(ziccif, PRIV_VERSION_1_11_0, has_priv_1_11),
84
+ ISA_EXT_DATA_ENTRY(zicclsm, PRIV_VERSION_1_11_0, has_priv_1_11),
85
+ ISA_EXT_DATA_ENTRY(ziccrse, PRIV_VERSION_1_11_0, has_priv_1_11),
86
ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
87
ISA_EXT_DATA_ENTRY(zicntr, PRIV_VERSION_1_12_0, ext_zicntr),
88
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_zicsr),
89
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
90
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
91
ISA_EXT_DATA_ENTRY(zihpm, PRIV_VERSION_1_12_0, ext_zihpm),
92
ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
93
- ISA_EXT_DATA_ENTRY(za64rs, PRIV_VERSION_1_12_0, ext_always_enabled),
94
+ ISA_EXT_DATA_ENTRY(za64rs, PRIV_VERSION_1_12_0, has_priv_1_11),
95
ISA_EXT_DATA_ENTRY(zaamo, PRIV_VERSION_1_12_0, ext_zaamo),
96
ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas),
97
ISA_EXT_DATA_ENTRY(zalrsc, PRIV_VERSION_1_12_0, ext_zalrsc),
98
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
99
ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
100
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
101
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
102
- ISA_EXT_DATA_ENTRY(ssccptr, PRIV_VERSION_1_11_0, ext_always_enabled),
103
+ ISA_EXT_DATA_ENTRY(ssccptr, PRIV_VERSION_1_11_0, has_priv_1_11),
104
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
105
- ISA_EXT_DATA_ENTRY(sscounterenw, PRIV_VERSION_1_12_0, ext_always_enabled),
106
+ ISA_EXT_DATA_ENTRY(sscounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
107
ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
108
- ISA_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, ext_always_enabled),
109
- ISA_EXT_DATA_ENTRY(sstvecd, PRIV_VERSION_1_12_0, ext_always_enabled),
110
+ ISA_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
111
+ ISA_EXT_DATA_ENTRY(sstvecd, PRIV_VERSION_1_12_0, has_priv_1_12),
112
ISA_EXT_DATA_ENTRY(svade, PRIV_VERSION_1_11_0, ext_svade),
113
ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu),
114
ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
115
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
116
DEFINE_PROP_END_OF_LIST(),
117
};
118
119
-#define ALWAYS_ENABLED_FEATURE(_name) \
120
- {.name = _name, \
121
- .offset = CPU_CFG_OFFSET(ext_always_enabled), \
122
- .enabled = true}
123
-
124
/*
125
* 'Named features' is the name we give to extensions that we
126
* don't want to expose to users. They are either immutable
127
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
128
const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = {
129
MULTI_EXT_CFG_BOOL("zic64b", ext_zic64b, true),
130
131
- /*
132
- * cache-related extensions that are always enabled
133
- * in TCG since QEMU RISC-V does not have a cache
134
- * model.
135
- */
136
- ALWAYS_ENABLED_FEATURE("za64rs"),
137
- ALWAYS_ENABLED_FEATURE("ziccif"),
138
- ALWAYS_ENABLED_FEATURE("ziccrse"),
139
- ALWAYS_ENABLED_FEATURE("ziccamoa"),
140
- ALWAYS_ENABLED_FEATURE("zicclsm"),
141
- ALWAYS_ENABLED_FEATURE("ssccptr"),
142
-
143
- /* Other named features that TCG always implements */
144
- ALWAYS_ENABLED_FEATURE("sstvecd"),
145
- ALWAYS_ENABLED_FEATURE("sstvala"),
146
- ALWAYS_ENABLED_FEATURE("sscounterenw"),
147
-
148
DEFINE_PROP_END_OF_LIST(),
149
};
150
151
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
52
index XXXXXXX..XXXXXXX 100644
152
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/cpu_helper.c
153
--- a/target/riscv/tcg/tcg-cpu.c
54
+++ b/target/riscv/cpu_helper.c
154
+++ b/target/riscv/tcg/tcg-cpu.c
55
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
155
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
56
g_assert_not_reached();
156
57
}
157
static void riscv_cpu_update_named_features(RISCVCPU *cpu)
58
env->badaddr = address;
158
{
59
+ env->two_stage_lookup = two_stage;
159
+ if (cpu->env.priv_ver >= PRIV_VERSION_1_11_0) {
160
+ cpu->cfg.has_priv_1_11 = true;
161
+ }
162
+
163
+ if (cpu->env.priv_ver >= PRIV_VERSION_1_12_0) {
164
+ cpu->cfg.has_priv_1_12 = true;
165
+ }
166
+
167
+ /* zic64b is 1.12 or later */
168
cpu->cfg.ext_zic64b = cpu->cfg.cbom_blocksize == 64 &&
169
cpu->cfg.cbop_blocksize == 64 &&
170
- cpu->cfg.cboz_blocksize == 64;
171
+ cpu->cfg.cboz_blocksize == 64 &&
172
+ cpu->cfg.has_priv_1_12;
60
}
173
}
61
174
62
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
175
static void riscv_cpu_validate_g(RISCVCPU *cpu)
63
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
176
@@ -XXX,XX +XXX,XX @@ static void riscv_tcg_cpu_instance_init(CPUState *cs)
64
}
177
RISCVCPU *cpu = RISCV_CPU(cs);
65
178
Object *obj = OBJECT(cpu);
66
env->badaddr = addr;
179
67
+ env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
180
- cpu->cfg.ext_always_enabled = true;
68
+ riscv_cpu_two_stage_lookup(mmu_idx);
69
riscv_raise_exception(&cpu->env, cs->exception_index, retaddr);
70
}
71
72
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
73
g_assert_not_reached();
74
}
75
env->badaddr = addr;
76
+ env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
77
+ riscv_cpu_two_stage_lookup(mmu_idx);
78
riscv_raise_exception(env, cs->exception_index, retaddr);
79
}
80
#endif /* !CONFIG_USER_ONLY */
81
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
82
/* handle the trap in S-mode */
83
if (riscv_has_ext(env, RVH)) {
84
target_ulong hdeleg = async ? env->hideleg : env->hedeleg;
85
- bool two_stage_lookup = false;
86
87
- if (env->priv == PRV_M ||
88
- (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
89
- (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
90
- get_field(env->hstatus, HSTATUS_HU))) {
91
- two_stage_lookup = true;
92
- }
93
-
181
-
94
- if ((riscv_cpu_virt_enabled(env) || two_stage_lookup) && write_tval) {
182
misa_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
95
+ if (env->two_stage_lookup && write_tval) {
183
multi_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
96
/*
184
riscv_cpu_add_user_properties(obj);
97
* If we are writing a guest virtual address to stval, set
98
* this to 1. If we are trapping to VS we will set this to 0
99
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
100
riscv_cpu_set_force_hs_excep(env, 0);
101
} else {
102
/* Trap into HS mode */
103
- if (!two_stage_lookup) {
104
- env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
105
- riscv_cpu_virt_enabled(env));
106
- }
107
+ env->hstatus = set_field(env->hstatus, HSTATUS_SPV, false);
108
htval = env->guest_phys_fault_addr;
109
}
110
}
111
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
112
* RISC-V ISA Specification.
113
*/
114
115
+ env->two_stage_lookup = false;
116
#endif
117
cs->exception_index = EXCP_NONE; /* mark handled to qemu */
118
}
119
--
185
--
120
2.30.1
186
2.44.0
121
187
122
188
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
This adds the documentation to describe what is supported for the
3
The helper isn't setting env->vstart = 0 after its execution, as it is
4
'microchip-icicle-kit' machine, and how to boot the machine in QEMU.
4
expected from every vector instruction that completes successfully.
5
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210322075248.136255-2-bmeng.cn@gmail.com
9
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
10
Message-ID: <20240314175704.478276-2-dbarboza@ventanamicro.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
12
---
11
docs/system/riscv/microchip-icicle-kit.rst | 89 ++++++++++++++++++++++
13
target/riscv/vector_helper.c | 1 +
12
docs/system/target-riscv.rst | 1 +
14
1 file changed, 1 insertion(+)
13
2 files changed, 90 insertions(+)
14
create mode 100644 docs/system/riscv/microchip-icicle-kit.rst
15
15
16
diff --git a/docs/system/riscv/microchip-icicle-kit.rst b/docs/system/riscv/microchip-icicle-kit.rst
16
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
17
new file mode 100644
18
index XXXXXXX..XXXXXXX
19
--- /dev/null
20
+++ b/docs/system/riscv/microchip-icicle-kit.rst
21
@@ -XXX,XX +XXX,XX @@
22
+Microchip PolarFire SoC Icicle Kit (``microchip-icicle-kit``)
23
+=============================================================
24
+
25
+Microchip PolarFire SoC Icicle Kit integrates a PolarFire SoC, with one
26
+SiFive's E51 plus four U54 cores and many on-chip peripherals and an FPGA.
27
+
28
+For more details about Microchip PolarFire SoC, please see:
29
+https://www.microsemi.com/product-directory/soc-fpgas/5498-polarfire-soc-fpga
30
+
31
+The Icicle Kit board information can be found here:
32
+https://www.microsemi.com/existing-parts/parts/152514
33
+
34
+Supported devices
35
+-----------------
36
+
37
+The ``microchip-icicle-kit`` machine supports the following devices:
38
+
39
+ * 1 E51 core
40
+ * 4 U54 cores
41
+ * Core Level Interruptor (CLINT)
42
+ * Platform-Level Interrupt Controller (PLIC)
43
+ * L2 Loosely Integrated Memory (L2-LIM)
44
+ * DDR memory controller
45
+ * 5 MMUARTs
46
+ * 1 DMA controller
47
+ * 2 GEM Ethernet controllers
48
+ * 1 SDHC storage controller
49
+
50
+Boot options
51
+------------
52
+
53
+The ``microchip-icicle-kit`` machine can start using the standard -bios
54
+functionality for loading its BIOS image, aka Hart Software Services (HSS_).
55
+HSS loads the second stage bootloader U-Boot from an SD card. It does not
56
+support direct kernel loading via the -kernel option. One has to load kernel
57
+from U-Boot.
58
+
59
+The memory is set to 1537 MiB by default which is the minimum required high
60
+memory size by HSS. A sanity check on ram size is performed in the machine
61
+init routine to prompt user to increase the RAM size to > 1537 MiB when less
62
+than 1537 MiB ram is detected.
63
+
64
+Boot the machine
65
+----------------
66
+
67
+HSS 2020.12 release is tested at the time of writing. To build an HSS image
68
+that can be booted by the ``microchip-icicle-kit`` machine, type the following
69
+in the HSS source tree:
70
+
71
+.. code-block:: bash
72
+
73
+ $ export CROSS_COMPILE=riscv64-linux-
74
+ $ cp boards/mpfs-icicle-kit-es/def_config .config
75
+ $ make BOARD=mpfs-icicle-kit-es
76
+
77
+Download the official SD card image released by Microchip and prepare it for
78
+QEMU usage:
79
+
80
+.. code-block:: bash
81
+
82
+ $ wget ftp://ftpsoc.microsemi.com/outgoing/core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic.gz
83
+ $ gunzip core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic.gz
84
+ $ qemu-img resize core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic 4G
85
+
86
+Then we can boot the machine by:
87
+
88
+.. code-block:: bash
89
+
90
+ $ qemu-system-riscv64 -M microchip-icicle-kit -smp 5 \
91
+ -bios path/to/hss.bin -sd path/to/sdcard.img \
92
+ -nic user,model=cadence_gem \
93
+ -nic tap,ifname=tap,model=cadence_gem,script=no \
94
+ -display none -serial stdio \
95
+ -chardev socket,id=serial1,path=serial1.sock,server=on,wait=on \
96
+ -serial chardev:serial1
97
+
98
+With above command line, current terminal session will be used for the first
99
+serial port. Open another terminal window, and use `minicom` to connect the
100
+second serial port.
101
+
102
+.. code-block:: bash
103
+
104
+ $ minicom -D unix\#serial1.sock
105
+
106
+HSS output is on the first serial port (stdio) and U-Boot outputs on the
107
+second serial port. U-Boot will automatically load the Linux kernel from
108
+the SD card image.
109
+
110
+.. _HSS: https://github.com/polarfire-soc/hart-software-services
111
diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
112
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
113
--- a/docs/system/target-riscv.rst
18
--- a/target/riscv/vector_helper.c
114
+++ b/docs/system/target-riscv.rst
19
+++ b/target/riscv/vector_helper.c
115
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
20
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
116
.. toctree::
21
} \
117
:maxdepth: 1
22
*((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - offset)); \
118
23
} \
119
+ riscv/microchip-icicle-kit
24
+ env->vstart = 0; \
120
riscv/sifive_u
25
/* set tail elements to 1s */ \
121
26
vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz); \
122
RISC-V CPU features
27
}
123
--
28
--
124
2.30.1
29
2.44.0
125
126
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Since HSS commit c20a89f8dcac, the Icicle Kit reference design has
3
trans_vmv_x_s, trans_vmv_s_x, trans_vfmv_f_s and trans_vfmv_s_f aren't
4
been updated to use a register mapped at 0x4f000000 instead of a
4
setting vstart = 0 after execution. This is usually done by a helper in
5
GPIO to control whether eMMC or SD card is to be used. With this
5
vector_helper.c but these functions don't use helpers.
6
support the same HSS image can be used for both eMMC and SD card
7
boot flow, while previously two different board configurations were
8
used. This is undocumented but one can take a look at the HSS code
9
HSS_MMCInit() in services/mmc/mmc_api.c.
10
6
11
With this commit, HSS image built from 2020.12 release boots again.
7
We'll set vstart after any potential 'over' brconds, and that will also
8
mandate a mark_vs_dirty() too.
12
9
13
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
Fixes: dedc53cbc9 ("target/riscv: rvv-1.0: integer scalar move instructions")
11
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-id: 20210322075248.136255-1-bmeng.cn@gmail.com
14
Message-ID: <20240314175704.478276-3-dbarboza@ventanamicro.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
16
---
18
include/hw/riscv/microchip_pfsoc.h | 1 +
17
target/riscv/insn_trans/trans_rvv.c.inc | 10 ++++++++--
19
hw/riscv/microchip_pfsoc.c | 6 ++++++
18
1 file changed, 8 insertions(+), 2 deletions(-)
20
2 files changed, 7 insertions(+)
21
19
22
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
23
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/riscv/microchip_pfsoc.h
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
25
+++ b/include/hw/riscv/microchip_pfsoc.h
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
26
@@ -XXX,XX +XXX,XX @@ enum {
24
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_x_s(DisasContext *s, arg_vmv_x_s *a)
27
MICROCHIP_PFSOC_ENVM_DATA,
25
vec_element_loadi(s, t1, a->rs2, 0, true);
28
MICROCHIP_PFSOC_QSPI_XIP,
26
tcg_gen_trunc_i64_tl(dest, t1);
29
MICROCHIP_PFSOC_IOSCB,
27
gen_set_gpr(s, a->rd, dest);
30
+ MICROCHIP_PFSOC_EMMC_SD_MUX,
28
+ tcg_gen_movi_tl(cpu_vstart, 0);
31
MICROCHIP_PFSOC_DRAM_LO,
29
+ mark_vs_dirty(s);
32
MICROCHIP_PFSOC_DRAM_LO_ALIAS,
30
return true;
33
MICROCHIP_PFSOC_DRAM_HI,
31
}
34
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
32
return false;
35
index XXXXXXX..XXXXXXX 100644
33
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
36
--- a/hw/riscv/microchip_pfsoc.c
34
s1 = get_gpr(s, a->rs1, EXT_NONE);
37
+++ b/hw/riscv/microchip_pfsoc.c
35
tcg_gen_ext_tl_i64(t1, s1);
38
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry microchip_pfsoc_memmap[] = {
36
vec_element_storei(s, a->rd, 0, t1);
39
[MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
37
- mark_vs_dirty(s);
40
[MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
38
gen_set_label(over);
41
[MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
39
+ tcg_gen_movi_tl(cpu_vstart, 0);
42
+ [MICROCHIP_PFSOC_EMMC_SD_MUX] = { 0x4f000000, 0x4 },
40
+ mark_vs_dirty(s);
43
[MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
41
return true;
44
[MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
42
}
45
[MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
43
return false;
46
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
44
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a)
47
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0,
45
}
48
memmap[MICROCHIP_PFSOC_IOSCB].base);
46
49
47
mark_fs_dirty(s);
50
+ /* eMMC/SD mux */
48
+ tcg_gen_movi_tl(cpu_vstart, 0);
51
+ create_unimplemented_device("microchip.pfsoc.emmc_sd_mux",
49
+ mark_vs_dirty(s);
52
+ memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].base,
50
return true;
53
+ memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].size);
51
}
54
+
52
return false;
55
/* QSPI Flash */
53
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
56
memory_region_init_rom(qspi_xip_mem, OBJECT(dev),
54
do_nanbox(s, t1, cpu_fpr[a->rs1]);
57
"microchip.pfsoc.qspi_xip",
55
56
vec_element_storei(s, a->rd, 0, t1);
57
- mark_vs_dirty(s);
58
gen_set_label(over);
59
+ tcg_gen_movi_tl(cpu_vstart, 0);
60
+ mark_vs_dirty(s);
61
return true;
62
}
63
return false;
58
--
64
--
59
2.30.1
65
2.44.0
60
61
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
3
vmvr_v isn't handling the case where the host might be big endian and
4
the bytes to be copied aren't sequential.
5
6
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
7
Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR")
8
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Message-id: 20210311094902.1377593-1-georg.kotheimer@kernkonzept.com
10
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-ID: <20240314175704.478276-4-dbarboza@ventanamicro.com>
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
---
14
---
8
target/riscv/csr.c | 7 ++++---
15
target/riscv/vector_helper.c | 10 +++++++++-
9
1 file changed, 4 insertions(+), 3 deletions(-)
16
1 file changed, 9 insertions(+), 1 deletion(-)
10
17
11
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
18
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
12
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
13
--- a/target/riscv/csr.c
20
--- a/target/riscv/vector_helper.c
14
+++ b/target/riscv/csr.c
21
+++ b/target/riscv/vector_helper.c
15
@@ -XXX,XX +XXX,XX @@ static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
22
@@ -XXX,XX +XXX,XX @@ void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
16
SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
23
uint32_t startb = env->vstart * sewb;
17
SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD;
24
uint32_t i = startb;
18
static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
25
19
-static const target_ulong hip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
26
+ if (HOST_BIG_ENDIAN && i % 8 != 0) {
20
+static const target_ulong hip_writable_mask = MIP_VSSIP;
27
+ uint32_t j = ROUND_UP(i, 8);
21
+static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
28
+ memcpy((uint8_t *)vd + H1(j - 1),
22
static const target_ulong vsip_writable_mask = MIP_VSSIP;
29
+ (uint8_t *)vs2 + H1(j - 1),
23
30
+ j - i);
24
static const char valid_vm_1_10_32[16] = {
31
+ i = j;
25
@@ -XXX,XX +XXX,XX @@ static int rmw_hvip(CPURISCVState *env, int csrno, target_ulong *ret_value,
32
+ }
26
target_ulong new_value, target_ulong write_mask)
33
+
27
{
34
memcpy((uint8_t *)vd + H1(i),
28
int ret = rmw_mip(env, 0, ret_value, new_value,
35
(uint8_t *)vs2 + H1(i),
29
- write_mask & hip_writable_mask);
36
- maxsz - startb);
30
+ write_mask & hvip_writable_mask);
37
+ maxsz - i);
31
38
32
- *ret_value &= hip_writable_mask;
39
env->vstart = 0;
33
+ *ret_value &= hvip_writable_mask;
34
35
return ret;
36
}
40
}
37
--
41
--
38
2.30.1
42
2.44.0
39
40
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Per SST25VF016B datasheet [1], SST flash requires a dummy byte after
3
These insns have 2 paths: we'll either have vstart already cleared if
4
the address bytes. Note only SPI mode is supported by SST flashes.
4
vstart_eq_zero or we'll do a brcond to check if vstart >= maxsz to call
5
the 'vmvr_v' helper. The helper will clear vstart if it executes until
6
the end, or if vstart >= vl.
5
7
6
[1] http://ww1.microchip.com/downloads/en/devicedoc/s71271_04.pdf
8
For starters, the check itself is wrong: we're checking vstart >= maxsz,
9
when in fact we should use vstart in bytes, or 'startb' like 'vmvr_v' is
10
calling, to do the comparison. But even after fixing the comparison we'll
11
still need to clear vstart in the end, which isn't happening too.
7
12
8
Signed-off-by: Bin Meng <bin.meng@windriver.com>
13
We want to make the helpers responsible to manage vstart, including
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
14
these corner cases, precisely to avoid these situations:
10
Message-id: 20210306060152.7250-1-bmeng.cn@gmail.com
15
16
- remove the wrong vstart >= maxsz cond from the translation;
17
- add a 'startb >= maxsz' cond in 'vmvr_v', and clear vstart if that
18
happens.
19
20
This way we're now sure that vstart is being cleared in the end of the
21
execution, regardless of the path taken.
22
23
Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR")
24
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
25
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
26
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
27
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
28
Message-ID: <20240314175704.478276-5-dbarboza@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
30
---
13
hw/block/m25p80.c | 3 +++
31
target/riscv/vector_helper.c | 5 +++++
14
1 file changed, 3 insertions(+)
32
target/riscv/insn_trans/trans_rvv.c.inc | 3 ---
33
2 files changed, 5 insertions(+), 3 deletions(-)
15
34
16
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
35
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
17
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/block/m25p80.c
37
--- a/target/riscv/vector_helper.c
19
+++ b/hw/block/m25p80.c
38
+++ b/target/riscv/vector_helper.c
20
@@ -XXX,XX +XXX,XX @@ static void decode_fast_read_cmd(Flash *s)
39
@@ -XXX,XX +XXX,XX @@ void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
21
s->needed_bytes = get_addr_length(s);
40
uint32_t startb = env->vstart * sewb;
22
switch (get_man(s)) {
41
uint32_t i = startb;
23
/* Dummy cycles - modeled with bytes writes instead of bits */
42
24
+ case MAN_SST:
43
+ if (startb >= maxsz) {
25
+ s->needed_bytes += 1;
44
+ env->vstart = 0;
26
+ break;
45
+ return;
27
case MAN_WINBOND:
46
+ }
28
s->needed_bytes += 8;
47
+
29
break;
48
if (HOST_BIG_ENDIAN && i % 8 != 0) {
49
uint32_t j = ROUND_UP(i, 8);
50
memcpy((uint8_t *)vd + H1(j - 1),
51
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/insn_trans/trans_rvv.c.inc
54
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
55
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
56
vreg_ofs(s, a->rs2), maxsz, maxsz); \
57
mark_vs_dirty(s); \
58
} else { \
59
- TCGLabel *over = gen_new_label(); \
60
- tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, maxsz, over); \
61
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \
62
tcg_env, maxsz, maxsz, 0, gen_helper_vmvr_v); \
63
mark_vs_dirty(s); \
64
- gen_set_label(over); \
65
} \
66
return true; \
67
} \
30
--
68
--
31
2.30.1
69
2.44.0
32
33
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
The previous implementation was broken in many ways:
3
Commit 8ff8ac6329 added a conditional to guard the vext_ldst_whole()
4
- Used mideleg instead of hideleg to mask accesses
4
helper if vstart >= evl. But by skipping the helper we're also not
5
- Used MIP_VSSIP instead of VS_MODE_INTERRUPTS to mask writes to vsie
5
setting vstart = 0 at the end of the insns, which is incorrect.
6
- Did not shift between S bits and VS bits (VSEIP <-> SEIP, ...)
7
6
8
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
7
We'll move the conditional to vext_ldst_whole(), following in line with
8
the removal of all brconds vstart >= vl that the next patch will do. The
9
idea is to make the helpers responsible for their own vstart management.
10
11
Fix ldst_whole isns by:
12
13
- remove the brcond that skips the helper if vstart is >= evl;
14
15
- vext_ldst_whole() now does an early exit with the same check, where
16
evl = (vlenb * nf) >> log2_esz, but the early exit will also clear
17
vstart.
18
19
The 'width' param is now unneeded in ldst_whole_trans() and is also
20
removed. It was used for the evl calculation for the brcond and has no
21
other use now. The 'width' is reflected in vext_ldst_whole() via
22
log2_esz, which is encoded by GEN_VEXT_LD_WHOLE() as
23
"ctzl(sizeof(ETYPE))".
24
25
Suggested-by: Max Chou <max.chou@sifive.com>
26
Fixes: 8ff8ac6329 ("target/riscv: rvv: Add missing early exit condition for whole register load/store")
27
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
28
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20210311094738.1376795-1-georg.kotheimer@kernkonzept.com
29
Reviewed-by: Max Chou <max.chou@sifive.com>
30
Message-ID: <20240314175704.478276-6-dbarboza@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
31
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
32
---
13
target/riscv/csr.c | 68 +++++++++++++++++++++++-----------------------
33
target/riscv/vector_helper.c | 5 +++
14
1 file changed, 34 insertions(+), 34 deletions(-)
34
target/riscv/insn_trans/trans_rvv.c.inc | 52 +++++++++++--------------
35
2 files changed, 28 insertions(+), 29 deletions(-)
15
36
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
37
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
17
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/csr.c
39
--- a/target/riscv/vector_helper.c
19
+++ b/target/riscv/csr.c
40
+++ b/target/riscv/vector_helper.c
20
@@ -XXX,XX +XXX,XX @@ static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
41
@@ -XXX,XX +XXX,XX @@ vext_ldst_whole(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
21
return write_mstatus(env, CSR_MSTATUS, newval);
42
uint32_t vlenb = riscv_cpu_cfg(env)->vlenb;
43
uint32_t max_elems = vlenb >> log2_esz;
44
45
+ if (env->vstart >= ((vlenb * nf) >> log2_esz)) {
46
+ env->vstart = 0;
47
+ return;
48
+ }
49
+
50
k = env->vstart / max_elems;
51
off = env->vstart % max_elems;
52
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 @@ GEN_VEXT_TRANS(vle64ff_v, MO_64, r2nfvm, ldff_op, ld_us_check)
58
typedef void gen_helper_ldst_whole(TCGv_ptr, TCGv, TCGv_env, TCGv_i32);
59
60
static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
61
- uint32_t width, gen_helper_ldst_whole *fn,
62
+ gen_helper_ldst_whole *fn,
63
DisasContext *s)
64
{
65
- uint32_t evl = s->cfg_ptr->vlenb * nf / width;
66
- TCGLabel *over = gen_new_label();
67
- tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, evl, over);
68
-
69
TCGv_ptr dest;
70
TCGv base;
71
TCGv_i32 desc;
72
@@ -XXX,XX +XXX,XX @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
73
74
fn(dest, base, tcg_env, desc);
75
76
- gen_set_label(over);
77
-
78
return true;
22
}
79
}
23
80
24
+static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
81
@@ -XXX,XX +XXX,XX @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
25
+{
82
* load and store whole register instructions ignore vtype and vl setting.
26
+ /* Shift the VS bits to their S bit location in vsie */
83
* Thus, we don't need to check vill bit. (Section 7.9)
27
+ *val = (env->mie & env->hideleg & VS_MODE_INTERRUPTS) >> 1;
84
*/
28
+ return 0;
85
-#define GEN_LDST_WHOLE_TRANS(NAME, ARG_NF, WIDTH) \
29
+}
86
+#define GEN_LDST_WHOLE_TRANS(NAME, ARG_NF) \
30
+
87
static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
31
static int read_sie(CPURISCVState *env, int csrno, target_ulong *val)
88
{ \
32
{
89
if (require_rvv(s) && \
33
if (riscv_cpu_virt_enabled(env)) {
90
QEMU_IS_ALIGNED(a->rd, ARG_NF)) { \
34
- /* Tell the guest the VS bits, shifted to the S bit locations */
91
- return ldst_whole_trans(a->rd, a->rs1, ARG_NF, WIDTH, \
35
- *val = (env->mie & env->mideleg & VS_MODE_INTERRUPTS) >> 1;
92
+ return ldst_whole_trans(a->rd, a->rs1, ARG_NF, \
36
+ read_vsie(env, CSR_VSIE, val);
93
gen_helper_##NAME, s); \
37
} else {
94
} \
38
*val = env->mie & env->mideleg;
95
return false; \
39
}
40
return 0;
41
}
96
}
42
97
43
-static int write_sie(CPURISCVState *env, int csrno, target_ulong val)
98
-GEN_LDST_WHOLE_TRANS(vl1re8_v, 1, 1)
44
+static int write_vsie(CPURISCVState *env, int csrno, target_ulong val)
99
-GEN_LDST_WHOLE_TRANS(vl1re16_v, 1, 2)
45
{
100
-GEN_LDST_WHOLE_TRANS(vl1re32_v, 1, 4)
46
- target_ulong newval;
101
-GEN_LDST_WHOLE_TRANS(vl1re64_v, 1, 8)
47
+ /* Shift the S bits to their VS bit location in mie */
102
-GEN_LDST_WHOLE_TRANS(vl2re8_v, 2, 1)
48
+ target_ulong newval = (env->mie & ~VS_MODE_INTERRUPTS) |
103
-GEN_LDST_WHOLE_TRANS(vl2re16_v, 2, 2)
49
+ ((val << 1) & env->hideleg & VS_MODE_INTERRUPTS);
104
-GEN_LDST_WHOLE_TRANS(vl2re32_v, 2, 4)
50
+ return write_mie(env, CSR_MIE, newval);
105
-GEN_LDST_WHOLE_TRANS(vl2re64_v, 2, 8)
51
+}
106
-GEN_LDST_WHOLE_TRANS(vl4re8_v, 4, 1)
52
107
-GEN_LDST_WHOLE_TRANS(vl4re16_v, 4, 2)
53
+static int write_sie(CPURISCVState *env, int csrno, target_ulong val)
108
-GEN_LDST_WHOLE_TRANS(vl4re32_v, 4, 4)
54
+{
109
-GEN_LDST_WHOLE_TRANS(vl4re64_v, 4, 8)
55
if (riscv_cpu_virt_enabled(env)) {
110
-GEN_LDST_WHOLE_TRANS(vl8re8_v, 8, 1)
56
- /* Shift the guests S bits to VS */
111
-GEN_LDST_WHOLE_TRANS(vl8re16_v, 8, 2)
57
- newval = (env->mie & ~VS_MODE_INTERRUPTS) |
112
-GEN_LDST_WHOLE_TRANS(vl8re32_v, 8, 4)
58
- ((val << 1) & VS_MODE_INTERRUPTS);
113
-GEN_LDST_WHOLE_TRANS(vl8re64_v, 8, 8)
59
+ write_vsie(env, CSR_VSIE, val);
114
+GEN_LDST_WHOLE_TRANS(vl1re8_v, 1)
60
} else {
115
+GEN_LDST_WHOLE_TRANS(vl1re16_v, 1)
61
- newval = (env->mie & ~S_MODE_INTERRUPTS) | (val & S_MODE_INTERRUPTS);
116
+GEN_LDST_WHOLE_TRANS(vl1re32_v, 1)
62
+ target_ulong newval = (env->mie & ~S_MODE_INTERRUPTS) |
117
+GEN_LDST_WHOLE_TRANS(vl1re64_v, 1)
63
+ (val & S_MODE_INTERRUPTS);
118
+GEN_LDST_WHOLE_TRANS(vl2re8_v, 2)
64
+ write_mie(env, CSR_MIE, newval);
119
+GEN_LDST_WHOLE_TRANS(vl2re16_v, 2)
65
}
120
+GEN_LDST_WHOLE_TRANS(vl2re32_v, 2)
66
121
+GEN_LDST_WHOLE_TRANS(vl2re64_v, 2)
67
- return write_mie(env, CSR_MIE, newval);
122
+GEN_LDST_WHOLE_TRANS(vl4re8_v, 4)
68
+ return 0;
123
+GEN_LDST_WHOLE_TRANS(vl4re16_v, 4)
69
}
124
+GEN_LDST_WHOLE_TRANS(vl4re32_v, 4)
70
125
+GEN_LDST_WHOLE_TRANS(vl4re64_v, 4)
71
static int read_stvec(CPURISCVState *env, int csrno, target_ulong *val)
126
+GEN_LDST_WHOLE_TRANS(vl8re8_v, 8)
72
@@ -XXX,XX +XXX,XX @@ static int write_sbadaddr(CPURISCVState *env, int csrno, target_ulong val)
127
+GEN_LDST_WHOLE_TRANS(vl8re16_v, 8)
73
return 0;
128
+GEN_LDST_WHOLE_TRANS(vl8re32_v, 8)
74
}
129
+GEN_LDST_WHOLE_TRANS(vl8re64_v, 8)
75
130
76
+static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
131
/*
77
+ target_ulong new_value, target_ulong write_mask)
132
* The vector whole register store instructions are encoded similar to
78
+{
133
* unmasked unit-stride store of elements with EEW=8.
79
+ /* Shift the S bits to their VS bit location in mip */
134
*/
80
+ int ret = rmw_mip(env, 0, ret_value, new_value << 1,
135
-GEN_LDST_WHOLE_TRANS(vs1r_v, 1, 1)
81
+ (write_mask << 1) & vsip_writable_mask & env->hideleg);
136
-GEN_LDST_WHOLE_TRANS(vs2r_v, 2, 1)
82
+ *ret_value &= VS_MODE_INTERRUPTS;
137
-GEN_LDST_WHOLE_TRANS(vs4r_v, 4, 1)
83
+ /* Shift the VS bits to their S bit location in vsip */
138
-GEN_LDST_WHOLE_TRANS(vs8r_v, 8, 1)
84
+ *ret_value >>= 1;
139
+GEN_LDST_WHOLE_TRANS(vs1r_v, 1)
85
+ return ret;
140
+GEN_LDST_WHOLE_TRANS(vs2r_v, 2)
86
+}
141
+GEN_LDST_WHOLE_TRANS(vs4r_v, 4)
87
+
142
+GEN_LDST_WHOLE_TRANS(vs8r_v, 8)
88
static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
143
89
target_ulong new_value, target_ulong write_mask)
144
/*
90
{
145
*** Vector Integer Arithmetic Instructions
91
int ret;
92
93
if (riscv_cpu_virt_enabled(env)) {
94
- /* Shift the new values to line up with the VS bits */
95
- ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value << 1,
96
- (write_mask & sip_writable_mask) << 1 & env->mideleg);
97
- ret &= vsip_writable_mask;
98
- ret >>= 1;
99
+ ret = rmw_vsip(env, CSR_VSIP, ret_value, new_value, write_mask);
100
} else {
101
ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value,
102
write_mask & env->mideleg & sip_writable_mask);
103
@@ -XXX,XX +XXX,XX @@ static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val)
104
return 0;
105
}
106
107
-static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
108
- target_ulong new_value, target_ulong write_mask)
109
-{
110
- int ret = rmw_mip(env, 0, ret_value, new_value,
111
- write_mask & env->mideleg & vsip_writable_mask);
112
- return ret;
113
-}
114
-
115
-static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
116
-{
117
- *val = env->mie & env->mideleg & VS_MODE_INTERRUPTS;
118
- return 0;
119
-}
120
-
121
-static int write_vsie(CPURISCVState *env, int csrno, target_ulong val)
122
-{
123
- target_ulong newval = (env->mie & ~env->mideleg) | (val & env->mideleg & MIP_VSSIP);
124
- return write_mie(env, CSR_MIE, newval);
125
-}
126
-
127
static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
128
{
129
*val = env->vstvec;
130
--
146
--
131
2.30.1
147
2.44.0
132
133
diff view generated by jsdifflib
1
From: Asherah Connor <ashe@kivikakk.ee>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Allow ramfb on virt. This lets `-device ramfb' work.
3
We're going to make changes that will required each helper to be
4
4
responsible for the 'vstart' management, i.e. we will relieve the
5
Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
5
'vstart < vl' assumption that helpers have today.
6
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
6
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Helpers are usually able to deal with vstart >= vl, i.e. doing nothing
8
Message-id: 20210318235041.17175-3-ashe@kivikakk.ee
8
aside from setting vstart = 0 at the end, but the tail update functions
9
will update the tail regardless of vstart being valid or not. Unifying
10
the tail update process in a single function that would handle the
11
vstart >= vl case isn't trivial (see [1] for more info).
12
13
This patch takes a blunt approach: do an early exit in every single
14
vector helper if vstart >= vl, unless the helper is guarded with
15
vstart_eq_zero in the translation. For those cases the helper is ready
16
to deal with cases where vl might be zero, i.e. throwing exceptions
17
based on it like vcpop_m() and first_m().
18
19
Helpers that weren't changed:
20
21
- vcpop_m(), vfirst_m(), vmsetm(), GEN_VEXT_VIOTA_M(): these are guarded
22
directly with vstart_eq_zero;
23
24
- GEN_VEXT_VCOMPRESS_VM(): guarded with vcompress_vm_check() that checks
25
vstart_eq_zero;
26
27
- GEN_VEXT_RED(): guarded with either reduction_check() or
28
reduction_widen_check(), both check vstart_eq_zero;
29
30
- GEN_VEXT_FRED(): guarded with either freduction_check() or
31
freduction_widen_check(), both check vstart_eq_zero.
32
33
Another exception is vext_ldst_whole(), who operates on effective vector
34
length regardless of the current settings in vtype and vl.
35
36
[1] https://lore.kernel.org/qemu-riscv/1590234b-0291-432a-a0fa-c5a6876097bc@linux.alibaba.com/
37
38
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
39
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
40
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
41
Acked-by: Alistair Francis <alistair.francis@wdc.com>
42
Message-ID: <20240314175704.478276-7-dbarboza@ventanamicro.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
43
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
44
---
11
hw/riscv/virt.c | 3 +++
45
target/riscv/vector_internals.h | 9 +++++
12
1 file changed, 3 insertions(+)
46
target/riscv/vcrypto_helper.c | 32 ++++++++++++++++
13
47
target/riscv/vector_helper.c | 66 +++++++++++++++++++++++++++++++++
14
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
48
target/riscv/vector_internals.c | 4 ++
49
4 files changed, 111 insertions(+)
50
51
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
15
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/virt.c
53
--- a/target/riscv/vector_internals.h
17
+++ b/hw/riscv/virt.c
54
+++ b/target/riscv/vector_internals.h
18
@@ -XXX,XX +XXX,XX @@
55
@@ -XXX,XX +XXX,XX @@
19
#include "sysemu/sysemu.h"
56
#include "tcg/tcg-gvec-desc.h"
20
#include "hw/pci/pci.h"
57
#include "internals.h"
21
#include "hw/pci-host/gpex.h"
58
22
+#include "hw/display/ramfb.h"
59
+#define VSTART_CHECK_EARLY_EXIT(env) do { \
23
60
+ if (env->vstart >= env->vl) { \
24
static const MemMapEntry virt_memmap[] = {
61
+ env->vstart = 0; \
25
[VIRT_DEBUG] = { 0x0, 0x100 },
62
+ return; \
26
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
63
+ } \
27
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
64
+} while (0)
28
mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
65
+
29
mc->numa_mem_supported = true;
66
static inline uint32_t vext_nf(uint32_t desc)
30
+
67
{
31
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
68
return FIELD_EX32(simd_data(desc), VDATA, NF);
32
}
69
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \
33
70
uint32_t vma = vext_vma(desc); \
34
static const TypeInfo virt_machine_typeinfo = {
71
uint32_t i; \
72
\
73
+ VSTART_CHECK_EARLY_EXIT(env); \
74
+ \
75
for (i = env->vstart; i < vl; i++) { \
76
if (!vm && !vext_elem_mask(v0, i)) { \
77
/* set masked-off elements to 1s */ \
78
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/riscv/vcrypto_helper.c
81
+++ b/target/riscv/vcrypto_helper.c
82
@@ -XXX,XX +XXX,XX @@ static inline void xor_round_key(AESState *round_state, AESState *round_key)
83
uint32_t total_elems = vext_get_total_elems(env, desc, 4); \
84
uint32_t vta = vext_vta(desc); \
85
\
86
+ VSTART_CHECK_EARLY_EXIT(env); \
87
+ \
88
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \
89
AESState round_key; \
90
round_key.d[0] = *((uint64_t *)vs2 + H8(i * 2 + 0)); \
91
@@ -XXX,XX +XXX,XX @@ static inline void xor_round_key(AESState *round_state, AESState *round_key)
92
uint32_t total_elems = vext_get_total_elems(env, desc, 4); \
93
uint32_t vta = vext_vta(desc); \
94
\
95
+ VSTART_CHECK_EARLY_EXIT(env); \
96
+ \
97
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \
98
AESState round_key; \
99
round_key.d[0] = *((uint64_t *)vs2 + H8(0)); \
100
@@ -XXX,XX +XXX,XX @@ void HELPER(vaeskf1_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
101
uint32_t total_elems = vext_get_total_elems(env, desc, 4);
102
uint32_t vta = vext_vta(desc);
103
104
+ VSTART_CHECK_EARLY_EXIT(env);
105
+
106
uimm &= 0b1111;
107
if (uimm > 10 || uimm == 0) {
108
uimm ^= 0b1000;
109
@@ -XXX,XX +XXX,XX @@ void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
110
uint32_t total_elems = vext_get_total_elems(env, desc, 4);
111
uint32_t vta = vext_vta(desc);
112
113
+ VSTART_CHECK_EARLY_EXIT(env);
114
+
115
uimm &= 0b1111;
116
if (uimm > 14 || uimm < 2) {
117
uimm ^= 0b1000;
118
@@ -XXX,XX +XXX,XX @@ void HELPER(vsha2ms_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
119
uint32_t total_elems;
120
uint32_t vta = vext_vta(desc);
121
122
+ VSTART_CHECK_EARLY_EXIT(env);
123
+
124
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
125
if (sew == MO_32) {
126
vsha2ms_e32(((uint32_t *)vd) + i * 4, ((uint32_t *)vs1) + i * 4,
127
@@ -XXX,XX +XXX,XX @@ void HELPER(vsha2ch32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
128
uint32_t total_elems;
129
uint32_t vta = vext_vta(desc);
130
131
+ VSTART_CHECK_EARLY_EXIT(env);
132
+
133
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
134
vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
135
((uint32_t *)vs1) + 4 * i + 2);
136
@@ -XXX,XX +XXX,XX @@ void HELPER(vsha2ch64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
137
uint32_t total_elems;
138
uint32_t vta = vext_vta(desc);
139
140
+ VSTART_CHECK_EARLY_EXIT(env);
141
+
142
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
143
vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
144
((uint64_t *)vs1) + 4 * i + 2);
145
@@ -XXX,XX +XXX,XX @@ void HELPER(vsha2cl32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
146
uint32_t total_elems;
147
uint32_t vta = vext_vta(desc);
148
149
+ VSTART_CHECK_EARLY_EXIT(env);
150
+
151
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
152
vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
153
(((uint32_t *)vs1) + 4 * i));
154
@@ -XXX,XX +XXX,XX @@ void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
155
uint32_t total_elems;
156
uint32_t vta = vext_vta(desc);
157
158
+ VSTART_CHECK_EARLY_EXIT(env);
159
+
160
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
161
vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
162
(((uint64_t *)vs1) + 4 * i));
163
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm3me_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
164
uint32_t *vs1 = vs1_vptr;
165
uint32_t *vs2 = vs2_vptr;
166
167
+ VSTART_CHECK_EARLY_EXIT(env);
168
+
169
for (int i = env->vstart / 8; i < env->vl / 8; i++) {
170
uint32_t w[24];
171
for (int j = 0; j < 8; j++) {
172
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
173
uint32_t *vs2 = vs2_vptr;
174
uint32_t v1[8], v2[8], v3[8];
175
176
+ VSTART_CHECK_EARLY_EXIT(env);
177
+
178
for (int i = env->vstart / 8; i < env->vl / 8; i++) {
179
for (int k = 0; k < 8; k++) {
180
v2[k] = bswap32(vd[H4(i * 8 + k)]);
181
@@ -XXX,XX +XXX,XX @@ void HELPER(vghsh_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
182
uint32_t vta = vext_vta(desc);
183
uint32_t total_elems = vext_get_total_elems(env, desc, 4);
184
185
+ VSTART_CHECK_EARLY_EXIT(env);
186
+
187
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
188
uint64_t Y[2] = {vd[i * 2 + 0], vd[i * 2 + 1]};
189
uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
190
@@ -XXX,XX +XXX,XX @@ void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env,
191
uint32_t vta = vext_vta(desc);
192
uint32_t total_elems = vext_get_total_elems(env, desc, 4);
193
194
+ VSTART_CHECK_EARLY_EXIT(env);
195
+
196
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
197
uint64_t Y[2] = {brev8(vd[i * 2 + 0]), brev8(vd[i * 2 + 1])};
198
uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
199
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm4k_vi)(void *vd, void *vs2, uint32_t uimm5, CPURISCVState *env,
200
uint32_t esz = sizeof(uint32_t);
201
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
202
203
+ VSTART_CHECK_EARLY_EXIT(env);
204
+
205
for (uint32_t i = group_start; i < group_end; ++i) {
206
uint32_t vstart = i * egs;
207
uint32_t vend = (i + 1) * egs;
208
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm4r_vv)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
209
uint32_t esz = sizeof(uint32_t);
210
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
211
212
+ VSTART_CHECK_EARLY_EXIT(env);
213
+
214
for (uint32_t i = group_start; i < group_end; ++i) {
215
uint32_t vstart = i * egs;
216
uint32_t vend = (i + 1) * egs;
217
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm4r_vs)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
218
uint32_t esz = sizeof(uint32_t);
219
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
220
221
+ VSTART_CHECK_EARLY_EXIT(env);
222
+
223
for (uint32_t i = group_start; i < group_end; ++i) {
224
uint32_t vstart = i * egs;
225
uint32_t vend = (i + 1) * egs;
226
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
227
index XXXXXXX..XXXXXXX 100644
228
--- a/target/riscv/vector_helper.c
229
+++ b/target/riscv/vector_helper.c
230
@@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
231
uint32_t esz = 1 << log2_esz;
232
uint32_t vma = vext_vma(desc);
233
234
+ VSTART_CHECK_EARLY_EXIT(env);
235
+
236
for (i = env->vstart; i < env->vl; i++, env->vstart++) {
237
k = 0;
238
while (k < nf) {
239
@@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
240
uint32_t max_elems = vext_max_elems(desc, log2_esz);
241
uint32_t esz = 1 << log2_esz;
242
243
+ VSTART_CHECK_EARLY_EXIT(env);
244
+
245
/* load bytes from guest memory */
246
for (i = env->vstart; i < evl; i++, env->vstart++) {
247
k = 0;
248
@@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
249
uint32_t esz = 1 << log2_esz;
250
uint32_t vma = vext_vma(desc);
251
252
+ VSTART_CHECK_EARLY_EXIT(env);
253
+
254
/* load bytes from guest memory */
255
for (i = env->vstart; i < env->vl; i++, env->vstart++) {
256
k = 0;
257
@@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base,
258
target_ulong addr, offset, remain;
259
int mmu_index = riscv_env_mmu_index(env, false);
260
261
+ VSTART_CHECK_EARLY_EXIT(env);
262
+
263
/* probe every access */
264
for (i = env->vstart; i < env->vl; i++) {
265
if (!vm && !vext_elem_mask(v0, i)) {
266
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
267
uint32_t vta = vext_vta(desc); \
268
uint32_t i; \
269
\
270
+ VSTART_CHECK_EARLY_EXIT(env); \
271
+ \
272
for (i = env->vstart; i < vl; i++) { \
273
ETYPE s1 = *((ETYPE *)vs1 + H(i)); \
274
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
275
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
276
uint32_t vta = vext_vta(desc); \
277
uint32_t i; \
278
\
279
+ VSTART_CHECK_EARLY_EXIT(env); \
280
+ \
281
for (i = env->vstart; i < vl; i++) { \
282
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
283
ETYPE carry = vext_elem_mask(v0, i); \
284
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
285
uint32_t vta_all_1s = vext_vta_all_1s(desc); \
286
uint32_t i; \
287
\
288
+ VSTART_CHECK_EARLY_EXIT(env); \
289
+ \
290
for (i = env->vstart; i < vl; i++) { \
291
ETYPE s1 = *((ETYPE *)vs1 + H(i)); \
292
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
293
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
294
uint32_t vta_all_1s = vext_vta_all_1s(desc); \
295
uint32_t i; \
296
\
297
+ VSTART_CHECK_EARLY_EXIT(env); \
298
+ \
299
for (i = env->vstart; i < vl; i++) { \
300
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
301
ETYPE carry = !vm && vext_elem_mask(v0, i); \
302
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \
303
uint32_t vma = vext_vma(desc); \
304
uint32_t i; \
305
\
306
+ VSTART_CHECK_EARLY_EXIT(env); \
307
+ \
308
for (i = env->vstart; i < vl; i++) { \
309
if (!vm && !vext_elem_mask(v0, i)) { \
310
/* set masked-off elements to 1s */ \
311
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
312
uint32_t vma = vext_vma(desc); \
313
uint32_t i; \
314
\
315
+ VSTART_CHECK_EARLY_EXIT(env); \
316
+ \
317
for (i = env->vstart; i < vl; i++) { \
318
if (!vm && !vext_elem_mask(v0, i)) { \
319
/* set masked-off elements to 1s */ \
320
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
321
uint32_t vma = vext_vma(desc); \
322
uint32_t i; \
323
\
324
+ VSTART_CHECK_EARLY_EXIT(env); \
325
+ \
326
for (i = env->vstart; i < vl; i++) { \
327
ETYPE s1 = *((ETYPE *)vs1 + H(i)); \
328
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
329
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
330
uint32_t vma = vext_vma(desc); \
331
uint32_t i; \
332
\
333
+ VSTART_CHECK_EARLY_EXIT(env); \
334
+ \
335
for (i = env->vstart; i < vl; i++) { \
336
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
337
if (!vm && !vext_elem_mask(v0, i)) { \
338
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vs1, CPURISCVState *env, \
339
uint32_t vta = vext_vta(desc); \
340
uint32_t i; \
341
\
342
+ VSTART_CHECK_EARLY_EXIT(env); \
343
+ \
344
for (i = env->vstart; i < vl; i++) { \
345
ETYPE s1 = *((ETYPE *)vs1 + H(i)); \
346
*((ETYPE *)vd + H(i)) = s1; \
347
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, uint64_t s1, CPURISCVState *env, \
348
uint32_t vta = vext_vta(desc); \
349
uint32_t i; \
350
\
351
+ VSTART_CHECK_EARLY_EXIT(env); \
352
+ \
353
for (i = env->vstart; i < vl; i++) { \
354
*((ETYPE *)vd + H(i)) = (ETYPE)s1; \
355
} \
356
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
357
uint32_t vta = vext_vta(desc); \
358
uint32_t i; \
359
\
360
+ VSTART_CHECK_EARLY_EXIT(env); \
361
+ \
362
for (i = env->vstart; i < vl; i++) { \
363
ETYPE *vt = (!vext_elem_mask(v0, i) ? vs2 : vs1); \
364
*((ETYPE *)vd + H(i)) = *(vt + H(i)); \
365
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
366
uint32_t vta = vext_vta(desc); \
367
uint32_t i; \
368
\
369
+ VSTART_CHECK_EARLY_EXIT(env); \
370
+ \
371
for (i = env->vstart; i < vl; i++) { \
372
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
373
ETYPE d = (!vext_elem_mask(v0, i) ? s2 : \
374
@@ -XXX,XX +XXX,XX @@ vext_vv_rm_1(void *vd, void *v0, void *vs1, void *vs2,
375
uint32_t vl, uint32_t vm, int vxrm,
376
opivv2_rm_fn *fn, uint32_t vma, uint32_t esz)
377
{
378
+ VSTART_CHECK_EARLY_EXIT(env);
379
+
380
for (uint32_t i = env->vstart; i < vl; i++) {
381
if (!vm && !vext_elem_mask(v0, i)) {
382
/* set masked-off elements to 1s */
383
@@ -XXX,XX +XXX,XX @@ vext_vx_rm_1(void *vd, void *v0, target_long s1, void *vs2,
384
uint32_t vl, uint32_t vm, int vxrm,
385
opivx2_rm_fn *fn, uint32_t vma, uint32_t esz)
386
{
387
+ VSTART_CHECK_EARLY_EXIT(env);
388
+
389
for (uint32_t i = env->vstart; i < vl; i++) {
390
if (!vm && !vext_elem_mask(v0, i)) {
391
/* set masked-off elements to 1s */
392
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \
393
uint32_t vma = vext_vma(desc); \
394
uint32_t i; \
395
\
396
+ VSTART_CHECK_EARLY_EXIT(env); \
397
+ \
398
for (i = env->vstart; i < vl; i++) { \
399
if (!vm && !vext_elem_mask(v0, i)) { \
400
/* set masked-off elements to 1s */ \
401
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, \
402
uint32_t vma = vext_vma(desc); \
403
uint32_t i; \
404
\
405
+ VSTART_CHECK_EARLY_EXIT(env); \
406
+ \
407
for (i = env->vstart; i < vl; i++) { \
408
if (!vm && !vext_elem_mask(v0, i)) { \
409
/* set masked-off elements to 1s */ \
410
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \
411
uint32_t vma = vext_vma(desc); \
412
uint32_t i; \
413
\
414
+ VSTART_CHECK_EARLY_EXIT(env); \
415
+ \
416
if (vl == 0) { \
417
return; \
418
} \
419
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
420
uint32_t vma = vext_vma(desc); \
421
uint32_t i; \
422
\
423
+ VSTART_CHECK_EARLY_EXIT(env); \
424
+ \
425
for (i = env->vstart; i < vl; i++) { \
426
ETYPE s1 = *((ETYPE *)vs1 + H(i)); \
427
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
428
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \
429
uint32_t vma = vext_vma(desc); \
430
uint32_t i; \
431
\
432
+ VSTART_CHECK_EARLY_EXIT(env); \
433
+ \
434
for (i = env->vstart; i < vl; i++) { \
435
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
436
if (!vm && !vext_elem_mask(v0, i)) { \
437
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \
438
uint32_t vta = vext_vta(desc); \
439
uint32_t i; \
440
\
441
+ VSTART_CHECK_EARLY_EXIT(env); \
442
+ \
443
for (i = env->vstart; i < vl; i++) { \
444
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
445
*((ETYPE *)vd + H(i)) = \
446
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \
447
uint32_t i; \
448
int a, b; \
449
\
450
+ VSTART_CHECK_EARLY_EXIT(env); \
451
+ \
452
for (i = env->vstart; i < vl; i++) { \
453
a = vext_elem_mask(vs1, i); \
454
b = vext_elem_mask(vs2, i); \
455
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, CPURISCVState *env, uint32_t desc) \
456
uint32_t vma = vext_vma(desc); \
457
int i; \
458
\
459
+ VSTART_CHECK_EARLY_EXIT(env); \
460
+ \
461
for (i = env->vstart; i < vl; i++) { \
462
if (!vm && !vext_elem_mask(v0, i)) { \
463
/* set masked-off elements to 1s */ \
464
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
465
uint32_t vma = vext_vma(desc); \
466
target_ulong offset = s1, i_min, i; \
467
\
468
+ VSTART_CHECK_EARLY_EXIT(env); \
469
+ \
470
i_min = MAX(env->vstart, offset); \
471
for (i = i_min; i < vl; i++) { \
472
if (!vm && !vext_elem_mask(v0, i)) { \
473
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
474
uint32_t vma = vext_vma(desc); \
475
target_ulong i_max, i_min, i; \
476
\
477
+ VSTART_CHECK_EARLY_EXIT(env); \
478
+ \
479
i_min = MIN(s1 < vlmax ? vlmax - s1 : 0, vl); \
480
i_max = MAX(i_min, env->vstart); \
481
for (i = env->vstart; i < i_max; ++i) { \
482
@@ -XXX,XX +XXX,XX @@ static void vslide1up_##BITWIDTH(void *vd, void *v0, uint64_t s1, \
483
uint32_t vma = vext_vma(desc); \
484
uint32_t i; \
485
\
486
+ VSTART_CHECK_EARLY_EXIT(env); \
487
+ \
488
for (i = env->vstart; i < vl; i++) { \
489
if (!vm && !vext_elem_mask(v0, i)) { \
490
/* set masked-off elements to 1s */ \
491
@@ -XXX,XX +XXX,XX @@ static void vslide1down_##BITWIDTH(void *vd, void *v0, uint64_t s1, \
492
uint32_t vma = vext_vma(desc); \
493
uint32_t i; \
494
\
495
+ VSTART_CHECK_EARLY_EXIT(env); \
496
+ \
497
for (i = env->vstart; i < vl; i++) { \
498
if (!vm && !vext_elem_mask(v0, i)) { \
499
/* set masked-off elements to 1s */ \
500
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
501
uint64_t index; \
502
uint32_t i; \
503
\
504
+ VSTART_CHECK_EARLY_EXIT(env); \
505
+ \
506
for (i = env->vstart; i < vl; i++) { \
507
if (!vm && !vext_elem_mask(v0, i)) { \
508
/* set masked-off elements to 1s */ \
509
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
510
uint64_t index = s1; \
511
uint32_t i; \
512
\
513
+ VSTART_CHECK_EARLY_EXIT(env); \
514
+ \
515
for (i = env->vstart; i < vl; i++) { \
516
if (!vm && !vext_elem_mask(v0, i)) { \
517
/* set masked-off elements to 1s */ \
518
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \
519
uint32_t vma = vext_vma(desc); \
520
uint32_t i; \
521
\
522
+ VSTART_CHECK_EARLY_EXIT(env); \
523
+ \
524
for (i = env->vstart; i < vl; i++) { \
525
if (!vm && !vext_elem_mask(v0, i)) { \
526
/* set masked-off elements to 1s */ \
527
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
528
index XXXXXXX..XXXXXXX 100644
529
--- a/target/riscv/vector_internals.c
530
+++ b/target/riscv/vector_internals.c
531
@@ -XXX,XX +XXX,XX @@ void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
532
uint32_t vma = vext_vma(desc);
533
uint32_t i;
534
535
+ VSTART_CHECK_EARLY_EXIT(env);
536
+
537
for (i = env->vstart; i < vl; i++) {
538
if (!vm && !vext_elem_mask(v0, i)) {
539
/* set masked-off elements to 1s */
540
@@ -XXX,XX +XXX,XX @@ void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
541
uint32_t vma = vext_vma(desc);
542
uint32_t i;
543
544
+ VSTART_CHECK_EARLY_EXIT(env);
545
+
546
for (i = env->vstart; i < vl; i++) {
547
if (!vm && !vext_elem_mask(v0, i)) {
548
/* set masked-off elements to 1s */
35
--
549
--
36
2.30.1
550
2.44.0
37
38
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Currently, PMP permission checking of TLB page is bypassed if TLB hits
3
All helpers that rely on vstart >= vl are now doing early exits using
4
Fix it by propagating PMP permission to TLB page permission.
4
the VSTART_CHECK_EARLY_EXIT() macro. This macro will not only exit the
5
helper but also clear vstart.
5
6
6
PMP permission checking also use MMU-style API to change TLB permission
7
We're still left with brconds that are skipping the helper, which is the
7
and size.
8
only place where we're clearing vstart. The pattern goes like this:
8
9
9
Signed-off-by: Jim Shu <cwshu@andestech.com>
10
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
11
(... calls helper that clears vstart ...)
12
gen_set_label(over);
13
return true;
14
15
This means that every time we jump to 'over' we're not clearing vstart,
16
which is an oversight that we're doing across the board.
17
18
Instead of setting vstart = 0 manually after each 'over' jump, remove
19
those brconds that are skipping helpers. The exception will be
20
trans_vmv_s_x() and trans_vfmv_s_f(): they don't use a helper and are
21
already clearing vstart manually in the 'over' label.
22
23
While we're at it, remove the (vl == 0) brconds from trans_rvbf16.c.inc
24
too since they're unneeded.
25
26
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
27
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
29
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 1613916082-19528-2-git-send-email-cwshu@andestech.com
30
Message-ID: <20240314175704.478276-8-dbarboza@ventanamicro.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
31
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
32
---
14
target/riscv/pmp.h | 4 +-
33
target/riscv/insn_trans/trans_rvbf16.c.inc | 12 ---
15
target/riscv/cpu_helper.c | 84 +++++++++++++++++++++++++++++----------
34
target/riscv/insn_trans/trans_rvv.c.inc | 99 ----------------------
16
target/riscv/pmp.c | 80 +++++++++++++++++++++++++++----------
35
target/riscv/insn_trans/trans_rvvk.c.inc | 18 ----
17
3 files changed, 125 insertions(+), 43 deletions(-)
36
3 files changed, 129 deletions(-)
18
37
19
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
38
diff --git a/target/riscv/insn_trans/trans_rvbf16.c.inc b/target/riscv/insn_trans/trans_rvbf16.c.inc
20
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/pmp.h
40
--- a/target/riscv/insn_trans/trans_rvbf16.c.inc
22
+++ b/target/riscv/pmp.h
41
+++ b/target/riscv/insn_trans/trans_rvbf16.c.inc
23
@@ -XXX,XX +XXX,XX @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
42
@@ -XXX,XX +XXX,XX @@ static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, arg_vfncvtbf16_f_f_w *a)
24
target_ulong val);
43
25
target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
44
if (opfv_narrow_check(ctx, a) && (ctx->sew == MO_16)) {
26
bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
45
uint32_t data = 0;
27
- target_ulong size, pmp_priv_t priv, target_ulong mode);
46
- TCGLabel *over = gen_new_label();
28
+ target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
47
29
+ target_ulong mode);
48
gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);
30
bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
49
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
31
target_ulong *tlb_size);
50
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
32
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
51
33
void pmp_update_rule_nums(CPURISCVState *env);
52
data = FIELD_DP32(data, VDATA, VM, a->vm);
34
uint32_t pmp_get_num_rules(CPURISCVState *env);
53
data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
35
+int pmp_priv_to_page_prot(pmp_priv_t pmp_priv);
54
@@ -XXX,XX +XXX,XX @@ static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, arg_vfncvtbf16_f_f_w *a)
36
55
ctx->cfg_ptr->vlenb, data,
37
#endif
56
gen_helper_vfncvtbf16_f_f_w);
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
57
mark_vs_dirty(ctx);
58
- gen_set_label(over);
59
return true;
60
}
61
return false;
62
@@ -XXX,XX +XXX,XX @@ static bool trans_vfwcvtbf16_f_f_v(DisasContext *ctx, arg_vfwcvtbf16_f_f_v *a)
63
64
if (opfv_widen_check(ctx, a) && (ctx->sew == MO_16)) {
65
uint32_t data = 0;
66
- TCGLabel *over = gen_new_label();
67
68
gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);
69
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
70
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
71
72
data = FIELD_DP32(data, VDATA, VM, a->vm);
73
data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
74
@@ -XXX,XX +XXX,XX @@ static bool trans_vfwcvtbf16_f_f_v(DisasContext *ctx, arg_vfwcvtbf16_f_f_v *a)
75
ctx->cfg_ptr->vlenb, data,
76
gen_helper_vfwcvtbf16_f_f_v);
77
mark_vs_dirty(ctx);
78
- gen_set_label(over);
79
return true;
80
}
81
return false;
82
@@ -XXX,XX +XXX,XX @@ static bool trans_vfwmaccbf16_vv(DisasContext *ctx, arg_vfwmaccbf16_vv *a)
83
if (require_rvv(ctx) && vext_check_isa_ill(ctx) && (ctx->sew == MO_16) &&
84
vext_check_dss(ctx, a->rd, a->rs1, a->rs2, a->vm)) {
85
uint32_t data = 0;
86
- TCGLabel *over = gen_new_label();
87
88
gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);
89
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
90
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
91
92
data = FIELD_DP32(data, VDATA, VM, a->vm);
93
data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
94
@@ -XXX,XX +XXX,XX @@ static bool trans_vfwmaccbf16_vv(DisasContext *ctx, arg_vfwmaccbf16_vv *a)
95
ctx->cfg_ptr->vlenb, data,
96
gen_helper_vfwmaccbf16_vv);
97
mark_vs_dirty(ctx);
98
- gen_set_label(over);
99
return true;
100
}
101
return false;
102
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
39
index XXXXXXX..XXXXXXX 100644
103
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/cpu_helper.c
104
--- a/target/riscv/insn_trans/trans_rvv.c.inc
41
+++ b/target/riscv/cpu_helper.c
105
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
42
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
106
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
43
env->load_res = -1;
107
TCGv base;
44
}
108
TCGv_i32 desc;
45
109
46
+/*
110
- TCGLabel *over = gen_new_label();
47
+ * get_physical_address_pmp - check PMP permission for this physical address
111
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
48
+ *
112
-
49
+ * Match the PMP region and check permission for this physical address and it's
113
dest = tcg_temp_new_ptr();
50
+ * TLB page. Returns 0 if the permission checking was successful
114
mask = tcg_temp_new_ptr();
51
+ *
115
base = get_gpr(s, rs1, EXT_NONE);
52
+ * @env: CPURISCVState
116
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
53
+ * @prot: The returned protection attributes
117
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
54
+ * @tlb_size: TLB page size containing addr. It could be modified after PMP
118
}
55
+ * permission checking. NULL if not set TLB page for addr.
119
56
+ * @addr: The physical address to be checked permission
120
- gen_set_label(over);
57
+ * @access_type: The type of MMU access
121
return true;
58
+ * @mode: Indicates current privilege level.
122
}
59
+ */
123
60
+static int get_physical_address_pmp(CPURISCVState *env, int *prot,
124
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
61
+ target_ulong *tlb_size, hwaddr addr,
125
TCGv base, stride;
62
+ int size, MMUAccessType access_type,
126
TCGv_i32 desc;
63
+ int mode)
127
64
+{
128
- TCGLabel *over = gen_new_label();
65
+ pmp_priv_t pmp_priv;
129
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
66
+ target_ulong tlb_size_pmp = 0;
130
-
67
+
131
dest = tcg_temp_new_ptr();
68
+ if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
132
mask = tcg_temp_new_ptr();
69
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
133
base = get_gpr(s, rs1, EXT_NONE);
70
+ return TRANSLATE_SUCCESS;
134
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
71
+ }
135
72
+
136
fn(dest, mask, base, stride, tcg_env, desc);
73
+ if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
137
74
+ mode)) {
138
- gen_set_label(over);
75
+ *prot = 0;
139
return true;
76
+ return TRANSLATE_PMP_FAIL;
140
}
77
+ }
141
78
+
142
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
79
+ *prot = pmp_priv_to_page_prot(pmp_priv);
143
TCGv base;
80
+ if (tlb_size != NULL) {
144
TCGv_i32 desc;
81
+ if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
145
82
+ *tlb_size = tlb_size_pmp;
146
- TCGLabel *over = gen_new_label();
83
+ }
147
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
84
+ }
148
-
85
+
149
dest = tcg_temp_new_ptr();
86
+ return TRANSLATE_SUCCESS;
150
mask = tcg_temp_new_ptr();
87
+}
151
index = tcg_temp_new_ptr();
88
+
152
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
89
/* get_physical_address - get the physical address for this virtual address
153
90
*
154
fn(dest, mask, base, index, tcg_env, desc);
91
* Do a page table walk to obtain the physical address corresponding to a
155
92
@@ -XXX,XX +XXX,XX @@ restart:
156
- gen_set_label(over);
93
pte_addr = base + idx * ptesize;
157
return true;
158
}
159
160
@@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
161
TCGv base;
162
TCGv_i32 desc;
163
164
- TCGLabel *over = gen_new_label();
165
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
166
-
167
dest = tcg_temp_new_ptr();
168
mask = tcg_temp_new_ptr();
169
base = get_gpr(s, rs1, EXT_NONE);
170
@@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
171
fn(dest, mask, base, tcg_env, desc);
172
173
mark_vs_dirty(s);
174
- gen_set_label(over);
175
return true;
176
}
177
178
@@ -XXX,XX +XXX,XX @@ static inline bool
179
do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
180
gen_helper_gvec_4_ptr *fn)
181
{
182
- TCGLabel *over = gen_new_label();
183
-
184
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
185
-
186
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
187
gvec_fn(s->sew, vreg_ofs(s, a->rd),
188
vreg_ofs(s, a->rs2), vreg_ofs(s, a->rs1),
189
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
190
s->cfg_ptr->vlenb, data, fn);
191
}
192
mark_vs_dirty(s);
193
- gen_set_label(over);
194
return true;
195
}
196
197
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
198
TCGv_i32 desc;
199
uint32_t data = 0;
200
201
- TCGLabel *over = gen_new_label();
202
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
203
-
204
dest = tcg_temp_new_ptr();
205
mask = tcg_temp_new_ptr();
206
src2 = tcg_temp_new_ptr();
207
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
208
fn(dest, mask, src1, src2, tcg_env, desc);
209
210
mark_vs_dirty(s);
211
- gen_set_label(over);
212
return true;
213
}
214
215
@@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
216
TCGv_i32 desc;
217
uint32_t data = 0;
218
219
- TCGLabel *over = gen_new_label();
220
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
221
-
222
dest = tcg_temp_new_ptr();
223
mask = tcg_temp_new_ptr();
224
src2 = tcg_temp_new_ptr();
225
@@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
226
fn(dest, mask, src1, src2, tcg_env, desc);
227
228
mark_vs_dirty(s);
229
- gen_set_label(over);
230
return true;
231
}
232
233
@@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
234
{
235
if (checkfn(s, a)) {
236
uint32_t data = 0;
237
- TCGLabel *over = gen_new_label();
238
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
239
240
data = FIELD_DP32(data, VDATA, VM, a->vm);
241
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
242
@@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
243
s->cfg_ptr->vlenb,
244
data, fn);
245
mark_vs_dirty(s);
246
- gen_set_label(over);
247
return true;
248
}
249
return false;
250
@@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
251
{
252
if (opiwv_widen_check(s, a)) {
253
uint32_t data = 0;
254
- TCGLabel *over = gen_new_label();
255
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
256
257
data = FIELD_DP32(data, VDATA, VM, a->vm);
258
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
259
@@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
260
tcg_env, s->cfg_ptr->vlenb,
261
s->cfg_ptr->vlenb, data, fn);
262
mark_vs_dirty(s);
263
- gen_set_label(over);
264
return true;
265
}
266
return false;
267
@@ -XXX,XX +XXX,XX @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
268
gen_helper_gvec_4_ptr *fn, DisasContext *s)
269
{
270
uint32_t data = 0;
271
- TCGLabel *over = gen_new_label();
272
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
273
274
data = FIELD_DP32(data, VDATA, VM, vm);
275
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
276
@@ -XXX,XX +XXX,XX @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
277
vreg_ofs(s, vs2), tcg_env, s->cfg_ptr->vlenb,
278
s->cfg_ptr->vlenb, data, fn);
279
mark_vs_dirty(s);
280
- gen_set_label(over);
281
return true;
282
}
283
284
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
285
gen_helper_##NAME##_h, \
286
gen_helper_##NAME##_w, \
287
}; \
288
- TCGLabel *over = gen_new_label(); \
289
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
290
\
291
data = FIELD_DP32(data, VDATA, VM, a->vm); \
292
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
293
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
294
s->cfg_ptr->vlenb, data, \
295
fns[s->sew]); \
296
mark_vs_dirty(s); \
297
- gen_set_label(over); \
298
return true; \
299
} \
300
return false; \
301
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
302
gen_helper_vmv_v_v_b, gen_helper_vmv_v_v_h,
303
gen_helper_vmv_v_v_w, gen_helper_vmv_v_v_d,
304
};
305
- TCGLabel *over = gen_new_label();
306
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
307
308
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
309
tcg_env, s->cfg_ptr->vlenb,
310
s->cfg_ptr->vlenb, data,
311
fns[s->sew]);
312
- gen_set_label(over);
94
}
313
}
95
314
mark_vs_dirty(s);
96
- if (riscv_feature(env, RISCV_FEATURE_PMP) &&
315
return true;
97
- !pmp_hart_has_privs(env, pte_addr, sizeof(target_ulong),
316
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
98
- 1 << MMU_DATA_LOAD, PRV_S)) {
317
/* vmv.v.x has rs2 = 0 and vm = 1 */
99
+ int pmp_prot;
318
vext_check_ss(s, a->rd, 0, 1)) {
100
+ int pmp_ret = get_physical_address_pmp(env, &pmp_prot, NULL, pte_addr,
319
TCGv s1;
101
+ sizeof(target_ulong),
320
- TCGLabel *over = gen_new_label();
102
+ MMU_DATA_LOAD, PRV_S);
321
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
103
+ if (pmp_ret != TRANSLATE_SUCCESS) {
322
104
return TRANSLATE_PMP_FAIL;
323
s1 = get_gpr(s, a->rs1, EXT_SIGN);
324
325
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
105
}
326
}
106
327
107
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
328
mark_vs_dirty(s);
108
#ifndef CONFIG_USER_ONLY
329
- gen_set_label(over);
109
vaddr im_address;
330
return true;
110
hwaddr pa = 0;
331
}
111
- int prot, prot2;
332
return false;
112
+ int prot, prot2, prot_pmp;
333
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
113
bool pmp_violation = false;
334
gen_helper_vmv_v_x_b, gen_helper_vmv_v_x_h,
114
bool first_stage_error = true;
335
gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d,
115
bool two_stage_lookup = false;
336
};
116
int ret = TRANSLATE_FAIL;
337
- TCGLabel *over = gen_new_label();
117
int mode = mmu_idx;
338
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
118
- target_ulong tlb_size = 0;
339
119
+ /* default TLB page size */
340
s1 = tcg_constant_i64(simm);
120
+ target_ulong tlb_size = TARGET_PAGE_SIZE;
341
dest = tcg_temp_new_ptr();
121
342
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
122
env->guest_phys_fault_addr = 0;
343
fns[s->sew](dest, s1, tcg_env, desc);
123
344
124
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
345
mark_vs_dirty(s);
125
346
- gen_set_label(over);
126
prot &= prot2;
347
}
127
348
return true;
128
- if (riscv_feature(env, RISCV_FEATURE_PMP) &&
349
}
129
- (ret == TRANSLATE_SUCCESS) &&
350
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
130
- !pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
351
gen_helper_##NAME##_w, \
131
- ret = TRANSLATE_PMP_FAIL;
352
gen_helper_##NAME##_d, \
132
+ if (ret == TRANSLATE_SUCCESS) {
353
}; \
133
+ ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
354
- TCGLabel *over = gen_new_label(); \
134
+ size, access_type, mode);
355
gen_set_rm(s, RISCV_FRM_DYN); \
135
+ prot &= prot_pmp;
356
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
136
}
357
\
137
358
data = FIELD_DP32(data, VDATA, VM, a->vm); \
138
if (ret != TRANSLATE_SUCCESS) {
359
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
139
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
360
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
140
"%s address=%" VADDR_PRIx " ret %d physical "
361
s->cfg_ptr->vlenb, data, \
141
TARGET_FMT_plx " prot %d\n",
362
fns[s->sew - 1]); \
142
__func__, address, ret, pa, prot);
363
mark_vs_dirty(s); \
143
- }
364
- gen_set_label(over); \
144
365
return true; \
145
- if (riscv_feature(env, RISCV_FEATURE_PMP) &&
366
} \
146
- (ret == TRANSLATE_SUCCESS) &&
367
return false; \
147
- !pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
368
@@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
148
- ret = TRANSLATE_PMP_FAIL;
369
TCGv_i32 desc;
149
+ if (ret == TRANSLATE_SUCCESS) {
370
TCGv_i64 t1;
150
+ ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
371
151
+ size, access_type, mode);
372
- TCGLabel *over = gen_new_label();
152
+ prot &= prot_pmp;
373
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
153
+ }
374
-
154
}
375
dest = tcg_temp_new_ptr();
155
+
376
mask = tcg_temp_new_ptr();
156
if (ret == TRANSLATE_PMP_FAIL) {
377
src2 = tcg_temp_new_ptr();
157
pmp_violation = true;
378
@@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
158
}
379
fn(dest, mask, t1, src2, tcg_env, desc);
159
380
160
if (ret == TRANSLATE_SUCCESS) {
381
mark_vs_dirty(s);
161
- if (pmp_is_range_in_tlb(env, pa & TARGET_PAGE_MASK, &tlb_size)) {
382
- gen_set_label(over);
162
- tlb_set_page(cs, address & ~(tlb_size - 1), pa & ~(tlb_size - 1),
383
return true;
163
- prot, mmu_idx, tlb_size);
384
}
164
- } else {
385
165
- tlb_set_page(cs, address & TARGET_PAGE_MASK, pa & TARGET_PAGE_MASK,
386
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
166
- prot, mmu_idx, TARGET_PAGE_SIZE);
387
static gen_helper_gvec_4_ptr * const fns[2] = { \
167
- }
388
gen_helper_##NAME##_h, gen_helper_##NAME##_w, \
168
+ tlb_set_page(cs, address & ~(tlb_size - 1), pa & ~(tlb_size - 1),
389
}; \
169
+ prot, mmu_idx, tlb_size);
390
- TCGLabel *over = gen_new_label(); \
170
return true;
391
gen_set_rm(s, RISCV_FRM_DYN); \
171
} else if (probe) {
392
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);\
172
return false;
393
\
173
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
394
data = FIELD_DP32(data, VDATA, VM, a->vm); \
395
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
396
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
397
s->cfg_ptr->vlenb, data, \
398
fns[s->sew - 1]); \
399
mark_vs_dirty(s); \
400
- gen_set_label(over); \
401
return true; \
402
} \
403
return false; \
404
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
405
static gen_helper_gvec_4_ptr * const fns[2] = { \
406
gen_helper_##NAME##_h, gen_helper_##NAME##_w, \
407
}; \
408
- TCGLabel *over = gen_new_label(); \
409
gen_set_rm(s, RISCV_FRM_DYN); \
410
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
411
\
412
data = FIELD_DP32(data, VDATA, VM, a->vm); \
413
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
414
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
415
s->cfg_ptr->vlenb, data, \
416
fns[s->sew - 1]); \
417
mark_vs_dirty(s); \
418
- gen_set_label(over); \
419
return true; \
420
} \
421
return false; \
422
@@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
423
{
424
if (checkfn(s, a)) {
425
uint32_t data = 0;
426
- TCGLabel *over = gen_new_label();
427
gen_set_rm_chkfrm(s, rm);
428
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
429
430
data = FIELD_DP32(data, VDATA, VM, a->vm);
431
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
432
@@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
433
s->cfg_ptr->vlenb,
434
s->cfg_ptr->vlenb, data, fn);
435
mark_vs_dirty(s);
436
- gen_set_label(over);
437
return true;
438
}
439
return false;
440
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
441
gen_helper_vmv_v_x_w,
442
gen_helper_vmv_v_x_d,
443
};
444
- TCGLabel *over = gen_new_label();
445
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
446
447
t1 = tcg_temp_new_i64();
448
/* NaN-box f[rs1] */
449
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
450
fns[s->sew - 1](dest, t1, tcg_env, desc);
451
452
mark_vs_dirty(s);
453
- gen_set_label(over);
454
}
455
return true;
456
}
457
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
458
gen_helper_##HELPER##_h, \
459
gen_helper_##HELPER##_w, \
460
}; \
461
- TCGLabel *over = gen_new_label(); \
462
gen_set_rm_chkfrm(s, FRM); \
463
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
464
\
465
data = FIELD_DP32(data, VDATA, VM, a->vm); \
466
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
467
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
468
s->cfg_ptr->vlenb, data, \
469
fns[s->sew - 1]); \
470
mark_vs_dirty(s); \
471
- gen_set_label(over); \
472
return true; \
473
} \
474
return false; \
475
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
476
gen_helper_##NAME##_h, \
477
gen_helper_##NAME##_w, \
478
}; \
479
- TCGLabel *over = gen_new_label(); \
480
gen_set_rm(s, RISCV_FRM_DYN); \
481
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
482
\
483
data = FIELD_DP32(data, VDATA, VM, a->vm); \
484
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
485
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
486
s->cfg_ptr->vlenb, data, \
487
fns[s->sew]); \
488
mark_vs_dirty(s); \
489
- gen_set_label(over); \
490
return true; \
491
} \
492
return false; \
493
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
494
gen_helper_##HELPER##_h, \
495
gen_helper_##HELPER##_w, \
496
}; \
497
- TCGLabel *over = gen_new_label(); \
498
gen_set_rm_chkfrm(s, FRM); \
499
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
500
\
501
data = FIELD_DP32(data, VDATA, VM, a->vm); \
502
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
503
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
504
s->cfg_ptr->vlenb, data, \
505
fns[s->sew - 1]); \
506
mark_vs_dirty(s); \
507
- gen_set_label(over); \
508
return true; \
509
} \
510
return false; \
511
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
512
gen_helper_##HELPER##_h, \
513
gen_helper_##HELPER##_w, \
514
}; \
515
- TCGLabel *over = gen_new_label(); \
516
gen_set_rm_chkfrm(s, FRM); \
517
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
518
\
519
data = FIELD_DP32(data, VDATA, VM, a->vm); \
520
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
521
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
522
s->cfg_ptr->vlenb, data, \
523
fns[s->sew]); \
524
mark_vs_dirty(s); \
525
- gen_set_label(over); \
526
return true; \
527
} \
528
return false; \
529
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \
530
vext_check_isa_ill(s)) { \
531
uint32_t data = 0; \
532
gen_helper_gvec_4_ptr *fn = gen_helper_##NAME; \
533
- TCGLabel *over = gen_new_label(); \
534
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
535
\
536
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
537
data = \
538
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \
539
s->cfg_ptr->vlenb, \
540
s->cfg_ptr->vlenb, data, fn); \
541
mark_vs_dirty(s); \
542
- gen_set_label(over); \
543
return true; \
544
} \
545
return false; \
546
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
547
s->vstart_eq_zero) { \
548
uint32_t data = 0; \
549
gen_helper_gvec_3_ptr *fn = gen_helper_##NAME; \
550
- TCGLabel *over = gen_new_label(); \
551
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
552
\
553
data = FIELD_DP32(data, VDATA, VM, a->vm); \
554
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
555
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
556
s->cfg_ptr->vlenb, \
557
data, fn); \
558
mark_vs_dirty(s); \
559
- gen_set_label(over); \
560
return true; \
561
} \
562
return false; \
563
@@ -XXX,XX +XXX,XX @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
564
require_align(a->rd, s->lmul) &&
565
s->vstart_eq_zero) {
566
uint32_t data = 0;
567
- TCGLabel *over = gen_new_label();
568
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
569
570
data = FIELD_DP32(data, VDATA, VM, a->vm);
571
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
572
@@ -XXX,XX +XXX,XX @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
573
s->cfg_ptr->vlenb,
574
s->cfg_ptr->vlenb, data, fns[s->sew]);
575
mark_vs_dirty(s);
576
- gen_set_label(over);
577
return true;
578
}
579
return false;
580
@@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
581
require_align(a->rd, s->lmul) &&
582
require_vm(a->vm, a->rd)) {
583
uint32_t data = 0;
584
- TCGLabel *over = gen_new_label();
585
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
586
587
data = FIELD_DP32(data, VDATA, VM, a->vm);
588
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
589
@@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
590
s->cfg_ptr->vlenb,
591
data, fns[s->sew]);
592
mark_vs_dirty(s);
593
- gen_set_label(over);
594
return true;
595
}
596
return false;
597
@@ -XXX,XX +XXX,XX @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
598
gen_helper_vcompress_vm_b, gen_helper_vcompress_vm_h,
599
gen_helper_vcompress_vm_w, gen_helper_vcompress_vm_d,
600
};
601
- TCGLabel *over = gen_new_label();
602
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
603
604
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
605
data = FIELD_DP32(data, VDATA, VTA, s->vta);
606
@@ -XXX,XX +XXX,XX @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
607
s->cfg_ptr->vlenb, data,
608
fns[s->sew]);
609
mark_vs_dirty(s);
610
- gen_set_label(over);
611
return true;
612
}
613
return false;
614
@@ -XXX,XX +XXX,XX @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
615
{
616
uint32_t data = 0;
617
gen_helper_gvec_3_ptr *fn;
618
- TCGLabel *over = gen_new_label();
619
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
620
621
static gen_helper_gvec_3_ptr * const fns[6][4] = {
622
{
623
@@ -XXX,XX +XXX,XX @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
624
s->cfg_ptr->vlenb, data, fn);
625
626
mark_vs_dirty(s);
627
- gen_set_label(over);
628
return true;
629
}
630
631
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
174
index XXXXXXX..XXXXXXX 100644
632
index XXXXXXX..XXXXXXX 100644
175
--- a/target/riscv/pmp.c
633
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
176
+++ b/target/riscv/pmp.c
634
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
177
@@ -XXX,XX +XXX,XX @@ static int pmp_is_in_range(CPURISCVState *env, int pmp_index, target_ulong addr)
635
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvkb_vx_check)
178
return result;
636
gen_helper_##NAME##_w, \
179
}
637
gen_helper_##NAME##_d, \
180
638
}; \
181
+/*
639
- TCGLabel *over = gen_new_label(); \
182
+ * Check if the address has required RWX privs when no PMP entry is matched.
640
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
183
+ */
641
\
184
+static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
642
data = FIELD_DP32(data, VDATA, VM, a->vm); \
185
+ target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
643
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
186
+ target_ulong mode)
644
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvkb_vx_check)
187
+{
645
s->cfg_ptr->vlenb, s->cfg_ptr->vlenb, \
188
+ bool ret;
646
data, fns[s->sew]); \
189
+
647
mark_vs_dirty(s); \
190
+ if ((!riscv_feature(env, RISCV_FEATURE_PMP)) || (mode == PRV_M)) {
648
- gen_set_label(over); \
191
+ /*
649
return true; \
192
+ * Privileged spec v1.10 states if HW doesn't implement any PMP entry
650
} \
193
+ * or no PMP entry matches an M-Mode access, the access succeeds.
651
return false; \
194
+ */
652
@@ -XXX,XX +XXX,XX @@ GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
195
+ ret = true;
653
TCGv_ptr rd_v, rs2_v; \
196
+ *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
654
TCGv_i32 desc, egs; \
197
+ } else {
655
uint32_t data = 0; \
198
+ /*
656
- TCGLabel *over = gen_new_label(); \
199
+ * Other modes are not allowed to succeed if they don't * match a rule,
657
\
200
+ * but there are rules. We've checked for no rule earlier in this
658
if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
201
+ * function.
659
/* save opcode for unwinding in case we throw an exception */ \
202
+ */
660
decode_save_opc(s); \
203
+ ret = false;
661
egs = tcg_constant_i32(EGS); \
204
+ *allowed_privs = 0;
662
gen_helper_egs_check(egs, tcg_env); \
205
+ }
663
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
206
+
664
} \
207
+ return ret;
665
\
208
+}
666
data = FIELD_DP32(data, VDATA, VM, a->vm); \
209
+
667
@@ -XXX,XX +XXX,XX @@ GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
210
668
tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2)); \
211
/*
669
gen_helper_##NAME(rd_v, rs2_v, tcg_env, desc); \
212
* Public Interface
670
mark_vs_dirty(s); \
213
@@ -XXX,XX +XXX,XX @@ static int pmp_is_in_range(CPURISCVState *env, int pmp_index, target_ulong addr)
671
- gen_set_label(over); \
214
* Check if the address has required RWX privs to complete desired operation
672
return true; \
215
*/
673
} \
216
bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
674
return false; \
217
- target_ulong size, pmp_priv_t privs, target_ulong mode)
675
@@ -XXX,XX +XXX,XX @@ GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
218
+ target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
676
TCGv_ptr rd_v, rs2_v; \
219
+ target_ulong mode)
677
TCGv_i32 uimm_v, desc, egs; \
678
uint32_t data = 0; \
679
- TCGLabel *over = gen_new_label(); \
680
\
681
if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
682
/* save opcode for unwinding in case we throw an exception */ \
683
decode_save_opc(s); \
684
egs = tcg_constant_i32(EGS); \
685
gen_helper_egs_check(egs, tcg_env); \
686
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
687
} \
688
\
689
data = FIELD_DP32(data, VDATA, VM, a->vm); \
690
@@ -XXX,XX +XXX,XX @@ GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
691
tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2)); \
692
gen_helper_##NAME(rd_v, rs2_v, uimm_v, tcg_env, desc); \
693
mark_vs_dirty(s); \
694
- gen_set_label(over); \
695
return true; \
696
} \
697
return false; \
698
@@ -XXX,XX +XXX,XX @@ GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
699
{ \
700
if (CHECK(s, a)) { \
701
uint32_t data = 0; \
702
- TCGLabel *over = gen_new_label(); \
703
TCGv_i32 egs; \
704
\
705
if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
706
@@ -XXX,XX +XXX,XX @@ GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
707
decode_save_opc(s); \
708
egs = tcg_constant_i32(EGS); \
709
gen_helper_egs_check(egs, tcg_env); \
710
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
711
} \
712
\
713
data = FIELD_DP32(data, VDATA, VM, a->vm); \
714
@@ -XXX,XX +XXX,XX @@ GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
715
data, gen_helper_##NAME); \
716
\
717
mark_vs_dirty(s); \
718
- gen_set_label(over); \
719
return true; \
720
} \
721
return false; \
722
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
220
{
723
{
221
int i = 0;
724
if (vsha_check(s, a)) {
222
int ret = -1;
725
uint32_t data = 0;
223
int pmp_size = 0;
726
- TCGLabel *over = gen_new_label();
224
target_ulong s = 0;
727
TCGv_i32 egs;
225
target_ulong e = 0;
728
226
- pmp_priv_t allowed_privs = 0;
729
if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
227
730
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
228
/* Short cut if no rules */
731
decode_save_opc(s);
229
if (0 == pmp_get_num_rules(env)) {
732
egs = tcg_constant_i32(ZVKNH_EGS);
230
- return (env->priv == PRV_M) ? true : false;
733
gen_helper_egs_check(egs, tcg_env);
231
+ return pmp_hart_has_privs_default(env, addr, size, privs,
734
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
232
+ allowed_privs, mode);
233
}
234
235
if (size == 0) {
236
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
237
* check
238
*/
239
if (((s + e) == 2) && (PMP_AMATCH_OFF != a_field)) {
240
- allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
241
+ *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
242
if ((mode != PRV_M) || pmp_is_locked(env, i)) {
243
- allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
244
+ *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
245
}
246
247
- if ((privs & allowed_privs) == privs) {
248
- ret = 1;
249
- break;
250
- } else {
251
- ret = 0;
252
- break;
253
- }
254
+ ret = ((privs & *allowed_privs) == privs);
255
+ break;
256
}
735
}
257
}
736
258
737
data = FIELD_DP32(data, VDATA, VM, a->vm);
259
/* No rule matched */
738
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
260
if (ret == -1) {
739
gen_helper_vsha2cl32_vv : gen_helper_vsha2cl64_vv);
261
- if (mode == PRV_M) {
740
262
- ret = 1; /* Privileged spec v1.10 states if no PMP entry matches an
741
mark_vs_dirty(s);
263
- * M-Mode access, the access succeeds */
742
- gen_set_label(over);
264
- } else {
743
return true;
265
- ret = 0; /* Other modes are not allowed to succeed if they don't
744
}
266
- * match a rule, but there are rules. We've checked for
745
return false;
267
- * no rule earlier in this function. */
746
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
268
- }
747
{
269
+ return pmp_hart_has_privs_default(env, addr, size, privs,
748
if (vsha_check(s, a)) {
270
+ allowed_privs, mode);
749
uint32_t data = 0;
271
}
750
- TCGLabel *over = gen_new_label();
272
751
TCGv_i32 egs;
273
return ret == 1 ? true : false;
752
274
}
753
if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
275
754
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
276
-
755
decode_save_opc(s);
277
/*
756
egs = tcg_constant_i32(ZVKNH_EGS);
278
* Handle a write to a pmpcfg CSP
757
gen_helper_egs_check(egs, tcg_env);
279
*/
758
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
280
@@ -XXX,XX +XXX,XX @@ bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
759
}
281
760
282
return false;
761
data = FIELD_DP32(data, VDATA, VM, a->vm);
283
}
762
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
284
+
763
gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv);
285
+/*
764
286
+ * Convert PMP privilege to TLB page privilege.
765
mark_vs_dirty(s);
287
+ */
766
- gen_set_label(over);
288
+int pmp_priv_to_page_prot(pmp_priv_t pmp_priv)
767
return true;
289
+{
768
}
290
+ int prot = 0;
769
return false;
291
+
292
+ if (pmp_priv & PMP_READ) {
293
+ prot |= PAGE_READ;
294
+ }
295
+ if (pmp_priv & PMP_WRITE) {
296
+ prot |= PAGE_WRITE;
297
+ }
298
+ if (pmp_priv & PMP_EXEC) {
299
+ prot |= PAGE_EXEC;
300
+ }
301
+
302
+ return prot;
303
+}
304
--
770
--
305
2.30.1
771
2.44.0
306
307
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
If PMP permission of any address has been changed by updating PMP entry,
3
trans_vmv_v_i , trans_vfmv_v_f and the trans_##NAME macro from
4
flush all TLB pages to prevent from getting old permission.
4
GEN_VMV_WHOLE_TRANS() are calling mark_vs_dirty() in both branches of
5
their 'ifs'. conditionals.
5
6
6
Signed-off-by: Jim Shu <cwshu@andestech.com>
7
Call it just once in the end like other functions are doing.
8
9
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1613916082-19528-4-git-send-email-cwshu@andestech.com
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Message-ID: <20240314175704.478276-9-dbarboza@ventanamicro.com>
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/pmp.c | 4 ++++
16
target/riscv/insn_trans/trans_rvv.c.inc | 11 +++--------
12
1 file changed, 4 insertions(+)
17
1 file changed, 3 insertions(+), 8 deletions(-)
13
18
14
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
19
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/pmp.c
21
--- a/target/riscv/insn_trans/trans_rvv.c.inc
17
+++ b/target/riscv/pmp.c
22
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
18
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
19
#include "qapi/error.h"
24
if (s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
20
#include "cpu.h"
25
tcg_gen_gvec_dup_imm(s->sew, vreg_ofs(s, a->rd),
21
#include "trace.h"
26
MAXSZ(s), MAXSZ(s), simm);
22
+#include "exec/exec-all.h"
27
- mark_vs_dirty(s);
23
28
} else {
24
static void pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
29
TCGv_i32 desc;
25
uint8_t val);
30
TCGv_i64 s1;
26
@@ -XXX,XX +XXX,XX @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
31
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
27
cfg_val = (val >> 8 * i) & 0xff;
32
s->cfg_ptr->vlenb, data));
28
pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
33
tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, a->rd));
34
fns[s->sew](dest, s1, tcg_env, desc);
35
-
36
- mark_vs_dirty(s);
37
}
38
+ mark_vs_dirty(s);
39
return true;
29
}
40
}
30
+
41
return false;
31
+ /* If PMP permission of any addr has been changed, flush TLB pages. */
42
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
32
+ tlb_flush(env_cpu(env));
43
33
}
44
tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd),
34
45
MAXSZ(s), MAXSZ(s), t1);
35
46
- mark_vs_dirty(s);
47
} else {
48
TCGv_ptr dest;
49
TCGv_i32 desc;
50
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
51
tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, a->rd));
52
53
fns[s->sew - 1](dest, t1, tcg_env, desc);
54
-
55
- mark_vs_dirty(s);
56
}
57
+ mark_vs_dirty(s);
58
return true;
59
}
60
return false;
61
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
62
if (s->vstart_eq_zero) { \
63
tcg_gen_gvec_mov(s->sew, vreg_ofs(s, a->rd), \
64
vreg_ofs(s, a->rs2), maxsz, maxsz); \
65
- mark_vs_dirty(s); \
66
} else { \
67
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \
68
tcg_env, maxsz, maxsz, 0, gen_helper_vmvr_v); \
69
- mark_vs_dirty(s); \
70
} \
71
+ mark_vs_dirty(s); \
72
return true; \
73
} \
74
return false; \
36
--
75
--
37
2.30.1
76
2.44.0
38
77
39
78
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Ivan Klokov <ivan.klokov@syntacore.com>
2
2
3
When decode_insn16() fails, we fall back to decode_RV32_64C() for
3
The vstart_eq_zero flag is updated at the beginning of the translation
4
further compressed instruction decoding. However, prior to this change,
4
phase from the env->vstart variable. During the execution phase all
5
we did not raise an illegal instruction exception, if decode_RV32_64C()
5
functions will set env->vstart = 0 after a successful execution, but the
6
fails to decode the instruction. This means that we skipped illegal
6
vstart_eq_zero flag remains the same as at the start of the block. This
7
compressed instructions instead of raising an illegal instruction
7
will wrongly cause SIGILLs in translations that requires env->vstart = 0
8
exception.
8
and might be reading vstart_eq_zero = false.
9
9
10
Instead of patching decode_RV32_64C(), we can just remove it,
10
This patch adds a new finalize_rvv_inst() helper that is called at the
11
as it is dead code since f330433b363 anyway.
11
end of each vector instruction that will both update vstart_eq_zero and
12
do a mark_vs_dirty().
12
13
13
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
14
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1976
15
Signed-off-by: Ivan Klokov <ivan.klokov@syntacore.com>
16
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-ID: <20240314175704.478276-10-dbarboza@ventanamicro.com>
16
Message-id: 20210322121609.3097928-1-georg.kotheimer@kernkonzept.com
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
21
---
19
target/riscv/translate.c | 179 +--------------------------------------
22
target/riscv/translate.c | 6 ++
20
1 file changed, 1 insertion(+), 178 deletions(-)
23
target/riscv/insn_trans/trans_rvbf16.c.inc | 6 +-
24
target/riscv/insn_trans/trans_rvv.c.inc | 83 ++++++++++++----------
25
target/riscv/insn_trans/trans_rvvk.c.inc | 12 ++--
26
4 files changed, 59 insertions(+), 48 deletions(-)
21
27
22
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
28
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
23
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/translate.c
30
--- a/target/riscv/translate.c
25
+++ b/target/riscv/translate.c
31
+++ b/target/riscv/translate.c
26
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
32
@@ -XXX,XX +XXX,XX @@ static void mark_vs_dirty(DisasContext *ctx)
27
CPUState *cs;
33
static inline void mark_vs_dirty(DisasContext *ctx) { }
28
} DisasContext;
29
30
-#ifdef TARGET_RISCV64
31
-/* convert riscv funct3 to qemu memop for load/store */
32
-static const int tcg_memop_lookup[8] = {
33
- [0 ... 7] = -1,
34
- [0] = MO_SB,
35
- [1] = MO_TESW,
36
- [2] = MO_TESL,
37
- [3] = MO_TEQ,
38
- [4] = MO_UB,
39
- [5] = MO_TEUW,
40
- [6] = MO_TEUL,
41
-};
42
-#endif
43
-
44
#ifdef TARGET_RISCV64
45
#define CASE_OP_32_64(X) case X: case glue(X, W)
46
#else
47
@@ -XXX,XX +XXX,XX @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
48
ctx->base.is_jmp = DISAS_NORETURN;
49
}
50
51
-#ifdef TARGET_RISCV64
52
-static void gen_load_c(DisasContext *ctx, uint32_t opc, int rd, int rs1,
53
- target_long imm)
54
-{
55
- TCGv t0 = tcg_temp_new();
56
- TCGv t1 = tcg_temp_new();
57
- gen_get_gpr(t0, rs1);
58
- tcg_gen_addi_tl(t0, t0, imm);
59
- int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
60
-
61
- if (memop < 0) {
62
- gen_exception_illegal(ctx);
63
- return;
64
- }
65
-
66
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
67
- gen_set_gpr(rd, t1);
68
- tcg_temp_free(t0);
69
- tcg_temp_free(t1);
70
-}
71
-
72
-static void gen_store_c(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
73
- target_long imm)
74
-{
75
- TCGv t0 = tcg_temp_new();
76
- TCGv dat = tcg_temp_new();
77
- gen_get_gpr(t0, rs1);
78
- tcg_gen_addi_tl(t0, t0, imm);
79
- gen_get_gpr(dat, rs2);
80
- int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
81
-
82
- if (memop < 0) {
83
- gen_exception_illegal(ctx);
84
- return;
85
- }
86
-
87
- tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
88
- tcg_temp_free(t0);
89
- tcg_temp_free(dat);
90
-}
91
-#endif
92
-
93
#ifndef CONFIG_USER_ONLY
94
/* The states of mstatus_fs are:
95
* 0 = disabled, 1 = initial, 2 = clean, 3 = dirty
96
@@ -XXX,XX +XXX,XX @@ static void mark_fs_dirty(DisasContext *ctx)
97
static inline void mark_fs_dirty(DisasContext *ctx) { }
98
#endif
34
#endif
99
35
100
-#if !defined(TARGET_RISCV64)
36
+static void finalize_rvv_inst(DisasContext *ctx)
101
-static void gen_fp_load(DisasContext *ctx, uint32_t opc, int rd,
37
+{
102
- int rs1, target_long imm)
38
+ mark_vs_dirty(ctx);
103
-{
39
+ ctx->vstart_eq_zero = true;
104
- TCGv t0;
40
+}
105
-
41
+
106
- if (ctx->mstatus_fs == 0) {
107
- gen_exception_illegal(ctx);
108
- return;
109
- }
110
-
111
- t0 = tcg_temp_new();
112
- gen_get_gpr(t0, rs1);
113
- tcg_gen_addi_tl(t0, t0, imm);
114
-
115
- switch (opc) {
116
- case OPC_RISC_FLW:
117
- if (!has_ext(ctx, RVF)) {
118
- goto do_illegal;
119
- }
120
- tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEUL);
121
- /* RISC-V requires NaN-boxing of narrower width floating point values */
122
- tcg_gen_ori_i64(cpu_fpr[rd], cpu_fpr[rd], 0xffffffff00000000ULL);
123
- break;
124
- case OPC_RISC_FLD:
125
- if (!has_ext(ctx, RVD)) {
126
- goto do_illegal;
127
- }
128
- tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEQ);
129
- break;
130
- do_illegal:
131
- default:
132
- gen_exception_illegal(ctx);
133
- break;
134
- }
135
- tcg_temp_free(t0);
136
-
137
- mark_fs_dirty(ctx);
138
-}
139
-
140
-static void gen_fp_store(DisasContext *ctx, uint32_t opc, int rs1,
141
- int rs2, target_long imm)
142
-{
143
- TCGv t0;
144
-
145
- if (ctx->mstatus_fs == 0) {
146
- gen_exception_illegal(ctx);
147
- return;
148
- }
149
-
150
- t0 = tcg_temp_new();
151
- gen_get_gpr(t0, rs1);
152
- tcg_gen_addi_tl(t0, t0, imm);
153
-
154
- switch (opc) {
155
- case OPC_RISC_FSW:
156
- if (!has_ext(ctx, RVF)) {
157
- goto do_illegal;
158
- }
159
- tcg_gen_qemu_st_i64(cpu_fpr[rs2], t0, ctx->mem_idx, MO_TEUL);
160
- break;
161
- case OPC_RISC_FSD:
162
- if (!has_ext(ctx, RVD)) {
163
- goto do_illegal;
164
- }
165
- tcg_gen_qemu_st_i64(cpu_fpr[rs2], t0, ctx->mem_idx, MO_TEQ);
166
- break;
167
- do_illegal:
168
- default:
169
- gen_exception_illegal(ctx);
170
- break;
171
- }
172
-
173
- tcg_temp_free(t0);
174
-}
175
-#endif
176
-
177
static void gen_set_rm(DisasContext *ctx, int rm)
42
static void gen_set_rm(DisasContext *ctx, int rm)
178
{
43
{
179
TCGv_i32 t0;
44
if (ctx->frm == rm) {
180
@@ -XXX,XX +XXX,XX @@ static void gen_set_rm(DisasContext *ctx, int rm)
45
diff --git a/target/riscv/insn_trans/trans_rvbf16.c.inc b/target/riscv/insn_trans/trans_rvbf16.c.inc
181
tcg_temp_free_i32(t0);
46
index XXXXXXX..XXXXXXX 100644
182
}
47
--- a/target/riscv/insn_trans/trans_rvbf16.c.inc
183
48
+++ b/target/riscv/insn_trans/trans_rvbf16.c.inc
184
-static void decode_RV32_64C0(DisasContext *ctx, uint16_t opcode)
49
@@ -XXX,XX +XXX,XX @@ static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, arg_vfncvtbf16_f_f_w *a)
185
-{
50
ctx->cfg_ptr->vlenb,
186
- uint8_t funct3 = extract16(opcode, 13, 3);
51
ctx->cfg_ptr->vlenb, data,
187
- uint8_t rd_rs2 = GET_C_RS2S(opcode);
52
gen_helper_vfncvtbf16_f_f_w);
188
- uint8_t rs1s = GET_C_RS1S(opcode);
53
- mark_vs_dirty(ctx);
189
-
54
+ finalize_rvv_inst(ctx);
190
- switch (funct3) {
55
return true;
191
- case 3:
56
}
192
-#if defined(TARGET_RISCV64)
57
return false;
193
- /* C.LD(RV64/128) -> ld rd', offset[7:3](rs1')*/
58
@@ -XXX,XX +XXX,XX @@ static bool trans_vfwcvtbf16_f_f_v(DisasContext *ctx, arg_vfwcvtbf16_f_f_v *a)
194
- gen_load_c(ctx, OPC_RISC_LD, rd_rs2, rs1s,
59
ctx->cfg_ptr->vlenb,
195
- GET_C_LD_IMM(opcode));
60
ctx->cfg_ptr->vlenb, data,
196
-#else
61
gen_helper_vfwcvtbf16_f_f_v);
197
- /* C.FLW (RV32) -> flw rd', offset[6:2](rs1')*/
62
- mark_vs_dirty(ctx);
198
- gen_fp_load(ctx, OPC_RISC_FLW, rd_rs2, rs1s,
63
+ finalize_rvv_inst(ctx);
199
- GET_C_LW_IMM(opcode));
64
return true;
200
-#endif
65
}
201
- break;
66
return false;
202
- case 7:
67
@@ -XXX,XX +XXX,XX @@ static bool trans_vfwmaccbf16_vv(DisasContext *ctx, arg_vfwmaccbf16_vv *a)
203
-#if defined(TARGET_RISCV64)
68
ctx->cfg_ptr->vlenb,
204
- /* C.SD (RV64/128) -> sd rs2', offset[7:3](rs1')*/
69
ctx->cfg_ptr->vlenb, data,
205
- gen_store_c(ctx, OPC_RISC_SD, rs1s, rd_rs2,
70
gen_helper_vfwmaccbf16_vv);
206
- GET_C_LD_IMM(opcode));
71
- mark_vs_dirty(ctx);
207
-#else
72
+ finalize_rvv_inst(ctx);
208
- /* C.FSW (RV32) -> fsw rs2', offset[6:2](rs1')*/
73
return true;
209
- gen_fp_store(ctx, OPC_RISC_FSW, rs1s, rd_rs2,
74
}
210
- GET_C_LW_IMM(opcode));
75
return false;
211
-#endif
76
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
212
- break;
77
index XXXXXXX..XXXXXXX 100644
213
- }
78
--- a/target/riscv/insn_trans/trans_rvv.c.inc
214
-}
79
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
215
-
80
@@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
216
-static void decode_RV32_64C(DisasContext *ctx, uint16_t opcode)
81
217
-{
82
gen_helper_vsetvl(dst, tcg_env, s1, s2);
218
- uint8_t op = extract16(opcode, 0, 2);
83
gen_set_gpr(s, rd, dst);
219
-
84
- mark_vs_dirty(s);
220
- switch (op) {
85
+ finalize_rvv_inst(s);
221
- case 0:
86
222
- decode_RV32_64C0(ctx, opcode);
87
gen_update_pc(s, s->cur_insn_len);
223
- break;
88
lookup_and_goto_ptr(s);
224
- }
89
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
225
-}
90
226
-
91
gen_helper_vsetvl(dst, tcg_env, s1, s2);
227
static int ex_plus_1(DisasContext *ctx, int nf)
92
gen_set_gpr(s, rd, dst);
228
{
93
- mark_vs_dirty(s);
229
return nf + 1;
94
+ finalize_rvv_inst(s);
230
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
95
gen_update_pc(s, s->cur_insn_len);
231
} else {
96
lookup_and_goto_ptr(s);
232
ctx->pc_succ_insn = ctx->base.pc_next + 2;
97
s->base.is_jmp = DISAS_NORETURN;
233
if (!decode_insn16(ctx, opcode)) {
98
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
234
- /* fall back to old decoder */
99
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
235
- decode_RV32_64C(ctx, opcode);
100
}
236
+ gen_exception_illegal(ctx);
101
237
}
102
+ finalize_rvv_inst(s);
103
return true;
104
}
105
106
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
107
108
fn(dest, mask, base, stride, tcg_env, desc);
109
110
+ finalize_rvv_inst(s);
111
return true;
112
}
113
114
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
115
116
fn(dest, mask, base, index, tcg_env, desc);
117
118
+ finalize_rvv_inst(s);
119
return true;
120
}
121
122
@@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
123
124
fn(dest, mask, base, tcg_env, desc);
125
126
- mark_vs_dirty(s);
127
+ finalize_rvv_inst(s);
128
return true;
129
}
130
131
@@ -XXX,XX +XXX,XX @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
132
133
fn(dest, base, tcg_env, desc);
134
135
+ finalize_rvv_inst(s);
136
return true;
137
}
138
139
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
140
tcg_env, s->cfg_ptr->vlenb,
141
s->cfg_ptr->vlenb, data, fn);
142
}
143
- mark_vs_dirty(s);
144
+ finalize_rvv_inst(s);
145
return true;
146
}
147
148
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
149
150
fn(dest, mask, src1, src2, tcg_env, desc);
151
152
- mark_vs_dirty(s);
153
+ finalize_rvv_inst(s);
154
return true;
155
}
156
157
@@ -XXX,XX +XXX,XX @@ do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
158
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
159
src1, MAXSZ(s), MAXSZ(s));
160
161
- mark_vs_dirty(s);
162
+ finalize_rvv_inst(s);
163
return true;
164
}
165
return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
166
@@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
167
168
fn(dest, mask, src1, src2, tcg_env, desc);
169
170
- mark_vs_dirty(s);
171
+ finalize_rvv_inst(s);
172
return true;
173
}
174
175
@@ -XXX,XX +XXX,XX @@ do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn,
176
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
177
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
178
extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s));
179
- mark_vs_dirty(s);
180
+ finalize_rvv_inst(s);
181
return true;
182
}
183
return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s, imm_mode);
184
@@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
185
tcg_env, s->cfg_ptr->vlenb,
186
s->cfg_ptr->vlenb,
187
data, fn);
188
- mark_vs_dirty(s);
189
+ finalize_rvv_inst(s);
190
return true;
191
}
192
return false;
193
@@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
194
vreg_ofs(s, a->rs2),
195
tcg_env, s->cfg_ptr->vlenb,
196
s->cfg_ptr->vlenb, data, fn);
197
- mark_vs_dirty(s);
198
+ finalize_rvv_inst(s);
199
return true;
200
}
201
return false;
202
@@ -XXX,XX +XXX,XX @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
203
tcg_gen_gvec_4_ptr(vreg_ofs(s, vd), vreg_ofs(s, 0), vreg_ofs(s, vs1),
204
vreg_ofs(s, vs2), tcg_env, s->cfg_ptr->vlenb,
205
s->cfg_ptr->vlenb, data, fn);
206
- mark_vs_dirty(s);
207
+ finalize_rvv_inst(s);
208
return true;
209
}
210
211
@@ -XXX,XX +XXX,XX @@ do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
212
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
213
src1, MAXSZ(s), MAXSZ(s));
214
215
- mark_vs_dirty(s);
216
+ finalize_rvv_inst(s);
217
return true;
218
}
219
return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
220
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
221
s->cfg_ptr->vlenb, \
222
s->cfg_ptr->vlenb, data, \
223
fns[s->sew]); \
224
- mark_vs_dirty(s); \
225
+ finalize_rvv_inst(s); \
226
return true; \
227
} \
228
return false; \
229
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
230
s->cfg_ptr->vlenb, data,
231
fns[s->sew]);
238
}
232
}
233
- mark_vs_dirty(s);
234
+ finalize_rvv_inst(s);
235
return true;
236
}
237
return false;
238
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
239
fns[s->sew](dest, s1_i64, tcg_env, desc);
240
}
241
242
- mark_vs_dirty(s);
243
+ finalize_rvv_inst(s);
244
return true;
245
}
246
return false;
247
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
248
tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, a->rd));
249
fns[s->sew](dest, s1, tcg_env, desc);
250
}
251
- mark_vs_dirty(s);
252
+ finalize_rvv_inst(s);
253
return true;
254
}
255
return false;
256
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
257
s->cfg_ptr->vlenb, \
258
s->cfg_ptr->vlenb, data, \
259
fns[s->sew - 1]); \
260
- mark_vs_dirty(s); \
261
+ finalize_rvv_inst(s); \
262
return true; \
263
} \
264
return false; \
265
@@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
266
267
fn(dest, mask, t1, src2, tcg_env, desc);
268
269
- mark_vs_dirty(s);
270
+ finalize_rvv_inst(s);
271
return true;
272
}
273
274
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
275
s->cfg_ptr->vlenb, \
276
s->cfg_ptr->vlenb, data, \
277
fns[s->sew - 1]); \
278
- mark_vs_dirty(s); \
279
+ finalize_rvv_inst(s); \
280
return true; \
281
} \
282
return false; \
283
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
284
s->cfg_ptr->vlenb, \
285
s->cfg_ptr->vlenb, data, \
286
fns[s->sew - 1]); \
287
- mark_vs_dirty(s); \
288
+ finalize_rvv_inst(s); \
289
return true; \
290
} \
291
return false; \
292
@@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
293
vreg_ofs(s, a->rs2), tcg_env,
294
s->cfg_ptr->vlenb,
295
s->cfg_ptr->vlenb, data, fn);
296
- mark_vs_dirty(s);
297
+ finalize_rvv_inst(s);
298
return true;
299
}
300
return false;
301
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
302
303
fns[s->sew - 1](dest, t1, tcg_env, desc);
304
}
305
- mark_vs_dirty(s);
306
+ finalize_rvv_inst(s);
307
return true;
308
}
309
return false;
310
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
311
s->cfg_ptr->vlenb, \
312
s->cfg_ptr->vlenb, data, \
313
fns[s->sew - 1]); \
314
- mark_vs_dirty(s); \
315
+ finalize_rvv_inst(s); \
316
return true; \
317
} \
318
return false; \
319
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
320
s->cfg_ptr->vlenb, \
321
s->cfg_ptr->vlenb, data, \
322
fns[s->sew]); \
323
- mark_vs_dirty(s); \
324
+ finalize_rvv_inst(s); \
325
return true; \
326
} \
327
return false; \
328
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
329
s->cfg_ptr->vlenb, \
330
s->cfg_ptr->vlenb, data, \
331
fns[s->sew - 1]); \
332
- mark_vs_dirty(s); \
333
+ finalize_rvv_inst(s); \
334
return true; \
335
} \
336
return false; \
337
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
338
s->cfg_ptr->vlenb, \
339
s->cfg_ptr->vlenb, data, \
340
fns[s->sew]); \
341
- mark_vs_dirty(s); \
342
+ finalize_rvv_inst(s); \
343
return true; \
344
} \
345
return false; \
346
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \
347
vreg_ofs(s, a->rs2), tcg_env, \
348
s->cfg_ptr->vlenb, \
349
s->cfg_ptr->vlenb, data, fn); \
350
- mark_vs_dirty(s); \
351
+ finalize_rvv_inst(s); \
352
return true; \
353
} \
354
return false; \
355
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
356
tcg_env, s->cfg_ptr->vlenb, \
357
s->cfg_ptr->vlenb, \
358
data, fn); \
359
- mark_vs_dirty(s); \
360
+ finalize_rvv_inst(s); \
361
return true; \
362
} \
363
return false; \
364
@@ -XXX,XX +XXX,XX @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
365
vreg_ofs(s, a->rs2), tcg_env,
366
s->cfg_ptr->vlenb,
367
s->cfg_ptr->vlenb, data, fns[s->sew]);
368
- mark_vs_dirty(s);
369
+ finalize_rvv_inst(s);
370
return true;
371
}
372
return false;
373
@@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
374
tcg_env, s->cfg_ptr->vlenb,
375
s->cfg_ptr->vlenb,
376
data, fns[s->sew]);
377
- mark_vs_dirty(s);
378
+ finalize_rvv_inst(s);
379
return true;
380
}
381
return false;
382
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_x_s(DisasContext *s, arg_vmv_x_s *a)
383
tcg_gen_trunc_i64_tl(dest, t1);
384
gen_set_gpr(s, a->rd, dest);
385
tcg_gen_movi_tl(cpu_vstart, 0);
386
- mark_vs_dirty(s);
387
+ finalize_rvv_inst(s);
388
return true;
389
}
390
return false;
391
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
392
vec_element_storei(s, a->rd, 0, t1);
393
gen_set_label(over);
394
tcg_gen_movi_tl(cpu_vstart, 0);
395
- mark_vs_dirty(s);
396
+ finalize_rvv_inst(s);
397
return true;
398
}
399
return false;
400
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a)
401
402
mark_fs_dirty(s);
403
tcg_gen_movi_tl(cpu_vstart, 0);
404
- mark_vs_dirty(s);
405
+ finalize_rvv_inst(s);
406
return true;
407
}
408
return false;
409
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
410
do_nanbox(s, t1, cpu_fpr[a->rs1]);
411
412
vec_element_storei(s, a->rd, 0, t1);
413
+
414
gen_set_label(over);
415
tcg_gen_movi_tl(cpu_vstart, 0);
416
- mark_vs_dirty(s);
417
+ finalize_rvv_inst(s);
418
return true;
419
}
420
return false;
421
@@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a)
422
423
tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd),
424
MAXSZ(s), MAXSZ(s), dest);
425
- mark_vs_dirty(s);
426
+ finalize_rvv_inst(s);
239
} else {
427
} else {
428
static gen_helper_opivx * const fns[4] = {
429
gen_helper_vrgather_vx_b, gen_helper_vrgather_vx_h,
430
@@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr *a)
431
endian_ofs(s, a->rs2, a->rs1),
432
MAXSZ(s), MAXSZ(s));
433
}
434
- mark_vs_dirty(s);
435
+ finalize_rvv_inst(s);
436
} else {
437
static gen_helper_opivx * const fns[4] = {
438
gen_helper_vrgather_vx_b, gen_helper_vrgather_vx_h,
439
@@ -XXX,XX +XXX,XX @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
440
tcg_env, s->cfg_ptr->vlenb,
441
s->cfg_ptr->vlenb, data,
442
fns[s->sew]);
443
- mark_vs_dirty(s);
444
+ finalize_rvv_inst(s);
445
return true;
446
}
447
return false;
448
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
449
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \
450
tcg_env, maxsz, maxsz, 0, gen_helper_vmvr_v); \
451
} \
452
- mark_vs_dirty(s); \
453
+ finalize_rvv_inst(s); \
454
return true; \
455
} \
456
return false; \
457
@@ -XXX,XX +XXX,XX @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
458
s->cfg_ptr->vlenb,
459
s->cfg_ptr->vlenb, data, fn);
460
461
- mark_vs_dirty(s);
462
+ finalize_rvv_inst(s);
463
return true;
464
}
465
466
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
467
index XXXXXXX..XXXXXXX 100644
468
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
469
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
470
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvkb_vx_check)
471
vreg_ofs(s, a->rs2), tcg_env, \
472
s->cfg_ptr->vlenb, s->cfg_ptr->vlenb, \
473
data, fns[s->sew]); \
474
- mark_vs_dirty(s); \
475
+ finalize_rvv_inst(s); \
476
return true; \
477
} \
478
return false; \
479
@@ -XXX,XX +XXX,XX @@ GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
480
tcg_gen_addi_ptr(rd_v, tcg_env, vreg_ofs(s, a->rd)); \
481
tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2)); \
482
gen_helper_##NAME(rd_v, rs2_v, tcg_env, desc); \
483
- mark_vs_dirty(s); \
484
+ finalize_rvv_inst(s); \
485
return true; \
486
} \
487
return false; \
488
@@ -XXX,XX +XXX,XX @@ GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
489
tcg_gen_addi_ptr(rd_v, tcg_env, vreg_ofs(s, a->rd)); \
490
tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2)); \
491
gen_helper_##NAME(rd_v, rs2_v, uimm_v, tcg_env, desc); \
492
- mark_vs_dirty(s); \
493
+ finalize_rvv_inst(s); \
494
return true; \
495
} \
496
return false; \
497
@@ -XXX,XX +XXX,XX @@ GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
498
s->cfg_ptr->vlenb, s->cfg_ptr->vlenb, \
499
data, gen_helper_##NAME); \
500
\
501
- mark_vs_dirty(s); \
502
+ finalize_rvv_inst(s); \
503
return true; \
504
} \
505
return false; \
506
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
507
s->sew == MO_32 ?
508
gen_helper_vsha2cl32_vv : gen_helper_vsha2cl64_vv);
509
510
- mark_vs_dirty(s);
511
+ finalize_rvv_inst(s);
512
return true;
513
}
514
return false;
515
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
516
s->sew == MO_32 ?
517
gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv);
518
519
- mark_vs_dirty(s);
520
+ finalize_rvv_inst(s);
521
return true;
522
}
523
return false;
240
--
524
--
241
2.30.1
525
2.44.0
242
243
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Like MMU translation, add qemu log of PMP permission checking for
3
Change the for loops in ldst helpers to do a single increment in the
4
debugging.
4
counter, and assign it env->vstart, to avoid re-reading from vstart
5
every time.
5
6
6
Signed-off-by: Jim Shu <cwshu@andestech.com>
7
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1613916082-19528-3-git-send-email-cwshu@andestech.com
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-ID: <20240314175704.478276-11-dbarboza@ventanamicro.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
13
---
11
target/riscv/cpu_helper.c | 12 ++++++++++++
14
target/riscv/vector_helper.c | 6 +++---
12
1 file changed, 12 insertions(+)
15
1 file changed, 3 insertions(+), 3 deletions(-)
13
16
14
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
17
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu_helper.c
19
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/cpu_helper.c
20
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
21
@@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
19
if (ret == TRANSLATE_SUCCESS) {
22
20
ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
23
VSTART_CHECK_EARLY_EXIT(env);
21
size, access_type, mode);
24
22
+
25
- for (i = env->vstart; i < env->vl; i++, env->vstart++) {
23
+ qemu_log_mask(CPU_LOG_MMU,
26
+ for (i = env->vstart; i < env->vl; env->vstart = ++i) {
24
+ "%s PMP address=" TARGET_FMT_plx " ret %d prot"
27
k = 0;
25
+ " %d tlb_size " TARGET_FMT_lu "\n",
28
while (k < nf) {
26
+ __func__, pa, ret, prot_pmp, tlb_size);
29
if (!vm && !vext_elem_mask(v0, i)) {
27
+
30
@@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
28
prot &= prot_pmp;
31
VSTART_CHECK_EARLY_EXIT(env);
29
}
32
30
33
/* load bytes from guest memory */
31
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
34
- for (i = env->vstart; i < evl; i++, env->vstart++) {
32
if (ret == TRANSLATE_SUCCESS) {
35
+ for (i = env->vstart; i < evl; env->vstart = ++i) {
33
ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
36
k = 0;
34
size, access_type, mode);
37
while (k < nf) {
35
+
38
target_ulong addr = base + ((i * nf + k) << log2_esz);
36
+ qemu_log_mask(CPU_LOG_MMU,
39
@@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
37
+ "%s PMP address=" TARGET_FMT_plx " ret %d prot"
40
VSTART_CHECK_EARLY_EXIT(env);
38
+ " %d tlb_size " TARGET_FMT_lu "\n",
41
39
+ __func__, pa, ret, prot_pmp, tlb_size);
42
/* load bytes from guest memory */
40
+
43
- for (i = env->vstart; i < env->vl; i++, env->vstart++) {
41
prot &= prot_pmp;
44
+ for (i = env->vstart; i < env->vl; env->vstart = ++i) {
42
}
45
k = 0;
43
}
46
while (k < nf) {
47
if (!vm && !vext_elem_mask(v0, i)) {
44
--
48
--
45
2.30.1
49
2.44.0
46
47
diff view generated by jsdifflib
1
From: Frank Chang <frank.chang@sifive.com>
1
From: Frank Chang <frank.chang@sifive.com>
2
2
3
vs() should return -RISCV_EXCP_ILLEGAL_INST instead of -1 if rvv feature
3
Currently, QEMU only sets the iforce register to 0 and returns early
4
is not enabled.
4
when claiming the iforce register. However, this may leave mip.meip
5
remains at 1 if a spurious external interrupt triggered by iforce
6
register is the only pending interrupt to be claimed, and the interrupt
7
cannot be lowered as expected.
5
8
6
If -1 is returned, exception will be raised and cs->exception_index will
9
This commit fixes this issue by calling riscv_aplic_idc_update() to
7
be set to the negative return value. The exception will then be treated
10
update the IDC status after the iforce register is claimed.
8
as an instruction access fault instead of illegal instruction fault.
9
11
10
Signed-off-by: Frank Chang <frank.chang@sifive.com>
12
Signed-off-by: Frank Chang <frank.chang@sifive.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Jim Shu <jim.shu@sifive.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-id: 20210223065935.20208-1-frank.chang@sifive.com
15
Message-ID: <20240321104951.12104-1-frank.chang@sifive.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
17
---
16
target/riscv/csr.c | 2 +-
18
hw/intc/riscv_aplic.c | 1 +
17
1 file changed, 1 insertion(+), 1 deletion(-)
19
1 file changed, 1 insertion(+)
18
20
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
21
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
20
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/csr.c
23
--- a/hw/intc/riscv_aplic.c
22
+++ b/target/riscv/csr.c
24
+++ b/hw/intc/riscv_aplic.c
23
@@ -XXX,XX +XXX,XX @@ static int vs(CPURISCVState *env, int csrno)
25
@@ -XXX,XX +XXX,XX @@ static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState *aplic, uint32_t idc)
24
if (env->misa & RVV) {
26
27
if (!topi) {
28
aplic->iforce[idc] = 0;
29
+ riscv_aplic_idc_update(aplic, idc);
25
return 0;
30
return 0;
26
}
31
}
27
- return -1;
32
28
+ return -RISCV_EXCP_ILLEGAL_INST;
29
}
30
31
static int ctr(CPURISCVState *env, int csrno)
32
--
33
--
33
2.30.1
34
2.44.0
34
35
diff view generated by jsdifflib
Deleted patch
1
From: Alexander Wagner <alexander.wagner@ulal.de>
2
1
3
Not disabling the UART leads to QEMU overwriting the UART receive buffer with
4
the newest received byte. The rx_level variable is added to allow the use of
5
the existing OpenTitan driver libraries.
6
7
Signed-off-by: Alexander Wagner <alexander.wagner@ulal.de>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210309152130.13038-1-alexander.wagner@ulal.de
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
include/hw/char/ibex_uart.h | 4 ++++
13
hw/char/ibex_uart.c | 23 ++++++++++++++++++-----
14
2 files changed, 22 insertions(+), 5 deletions(-)
15
16
diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/char/ibex_uart.h
19
+++ b/include/hw/char/ibex_uart.h
20
@@ -XXX,XX +XXX,XX @@ REG32(FIFO_CTRL, 0x1c)
21
FIELD(FIFO_CTRL, RXILVL, 2, 3)
22
FIELD(FIFO_CTRL, TXILVL, 5, 2)
23
REG32(FIFO_STATUS, 0x20)
24
+ FIELD(FIFO_STATUS, TXLVL, 0, 5)
25
+ FIELD(FIFO_STATUS, RXLVL, 16, 5)
26
REG32(OVRD, 0x24)
27
REG32(VAL, 0x28)
28
REG32(TIMEOUT_CTRL, 0x2c)
29
@@ -XXX,XX +XXX,XX @@ struct IbexUartState {
30
uint8_t tx_fifo[IBEX_UART_TX_FIFO_SIZE];
31
uint32_t tx_level;
32
33
+ uint32_t rx_level;
34
+
35
QEMUTimer *fifo_trigger_handle;
36
uint64_t char_tx_time;
37
38
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/char/ibex_uart.c
41
+++ b/hw/char/ibex_uart.c
42
@@ -XXX,XX +XXX,XX @@ static int ibex_uart_can_receive(void *opaque)
43
{
44
IbexUartState *s = opaque;
45
46
- if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) {
47
+ if ((s->uart_ctrl & R_CTRL_RX_ENABLE_MASK)
48
+ && !(s->uart_status & R_STATUS_RXFULL_MASK)) {
49
return 1;
50
}
51
52
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_receive(void *opaque, const uint8_t *buf, int size)
53
54
s->uart_status &= ~R_STATUS_RXIDLE_MASK;
55
s->uart_status &= ~R_STATUS_RXEMPTY_MASK;
56
+ /* The RXFULL is set after receiving a single byte
57
+ * as the FIFO buffers are not yet implemented.
58
+ */
59
+ s->uart_status |= R_STATUS_RXFULL_MASK;
60
+ s->rx_level += 1;
61
62
if (size > rx_fifo_level) {
63
s->uart_intr_state |= R_INTR_STATE_RX_WATERMARK_MASK;
64
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_reset(DeviceState *dev)
65
s->uart_timeout_ctrl = 0x00000000;
66
67
s->tx_level = 0;
68
+ s->rx_level = 0;
69
70
s->char_tx_time = (NANOSECONDS_PER_SECOND / 230400) * 10;
71
72
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
73
74
case R_RDATA:
75
retvalue = s->uart_rdata;
76
- if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) {
77
+ if ((s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) && (s->rx_level > 0)) {
78
qemu_chr_fe_accept_input(&s->chr);
79
80
- s->uart_status |= R_STATUS_RXIDLE_MASK;
81
- s->uart_status |= R_STATUS_RXEMPTY_MASK;
82
+ s->rx_level -= 1;
83
+ s->uart_status &= ~R_STATUS_RXFULL_MASK;
84
+ if (s->rx_level == 0) {
85
+ s->uart_status |= R_STATUS_RXIDLE_MASK;
86
+ s->uart_status |= R_STATUS_RXEMPTY_MASK;
87
+ }
88
}
89
break;
90
case R_WDATA:
91
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
92
case R_FIFO_STATUS:
93
retvalue = s->uart_fifo_status;
94
95
- retvalue |= s->tx_level & 0x1F;
96
+ retvalue |= (s->rx_level & 0x1F) << R_FIFO_STATUS_RXLVL_SHIFT;
97
+ retvalue |= (s->tx_level & 0x1F) << R_FIFO_STATUS_TXLVL_SHIFT;
98
99
qemu_log_mask(LOG_UNIMP,
100
"%s: RX fifos are not supported\n", __func__);
101
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_write(void *opaque, hwaddr addr,
102
s->uart_fifo_ctrl = value;
103
104
if (value & R_FIFO_CTRL_RXRST_MASK) {
105
+ s->rx_level = 0;
106
qemu_log_mask(LOG_UNIMP,
107
"%s: RX fifos are not supported\n", __func__);
108
}
109
--
110
2.30.1
111
112
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
According to the specification the "field SPVP of hstatus controls the
3
According to the Zvfbfmin definition in the RISC-V BF16 extensions spec,
4
privilege level of the access" for the hypervisor virtual-machine load
4
the Zvfbfmin extension only requires either the V extension or the
5
and store instructions HLV, HLVX and HSV.
5
Zve32f extension.
6
6
7
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
7
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210311103005.1400718-1-georg.kotheimer@kernkonzept.com
9
Message-ID: <20240321170929.1162507-1-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
11
---
12
target/riscv/cpu_helper.c | 25 ++++++++++++++-----------
12
target/riscv/tcg/tcg-cpu.c | 5 -----
13
1 file changed, 14 insertions(+), 11 deletions(-)
13
1 file changed, 5 deletions(-)
14
14
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
15
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
17
--- a/target/riscv/tcg/tcg-cpu.c
18
+++ b/target/riscv/cpu_helper.c
18
+++ b/target/riscv/tcg/tcg-cpu.c
19
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
19
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
20
use_background = true;
20
return;
21
}
21
}
22
22
23
- if (mode == PRV_M && access_type != MMU_INST_FETCH) {
23
- if (cpu->cfg.ext_zvfbfmin && !cpu->cfg.ext_zfbfmin) {
24
+ /* MPRV does not affect the virtual-machine load/store
24
- error_setg(errp, "Zvfbfmin extension depends on Zfbfmin extension");
25
+ instructions, HLV, HLVX, and HSV. */
25
- return;
26
+ if (riscv_cpu_two_stage_lookup(mmu_idx)) {
27
+ mode = get_field(env->hstatus, HSTATUS_SPVP);
28
+ } else if (mode == PRV_M && access_type != MMU_INST_FETCH) {
29
if (get_field(env->mstatus, MSTATUS_MPRV)) {
30
mode = get_field(env->mstatus, MSTATUS_MPP);
31
}
32
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
33
qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
34
__func__, address, access_type, mmu_idx);
35
36
- if (mode == PRV_M && access_type != MMU_INST_FETCH) {
37
- if (get_field(env->mstatus, MSTATUS_MPRV)) {
38
- mode = get_field(env->mstatus, MSTATUS_MPP);
39
+ /* MPRV does not affect the virtual-machine load/store
40
+ instructions, HLV, HLVX, and HSV. */
41
+ if (riscv_cpu_two_stage_lookup(mmu_idx)) {
42
+ mode = get_field(env->hstatus, HSTATUS_SPVP);
43
+ } else if (mode == PRV_M && access_type != MMU_INST_FETCH &&
44
+ get_field(env->mstatus, MSTATUS_MPRV)) {
45
+ mode = get_field(env->mstatus, MSTATUS_MPP);
46
+ if (riscv_has_ext(env, RVH) && get_field(env->mstatus, MSTATUS_MPV)) {
47
+ two_stage_lookup = true;
48
}
49
}
50
51
- if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
52
- access_type != MMU_INST_FETCH &&
53
- get_field(env->mstatus, MSTATUS_MPRV) &&
54
- get_field(env->mstatus, MSTATUS_MPV)) {
55
- two_stage_lookup = true;
56
- }
26
- }
57
-
27
-
58
if (riscv_cpu_virt_enabled(env) ||
28
if (cpu->cfg.ext_zvfbfmin && !cpu->cfg.ext_zve32f) {
59
((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
29
error_setg(errp, "Zvfbfmin extension depends on Zve32f extension");
60
access_type != MMU_INST_FETCH)) {
30
return;
61
--
31
--
62
2.30.1
32
2.44.0
63
64
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Irina Ryapolova <irina.ryapolova@syntacore.com>
2
2
3
The current condition for the use of background registers only
3
Need to convert mmu_idx to privilege mode for PMP function.
4
considers the hypervisor load and store instructions,
5
but not accesses from M mode via MSTATUS_MPRV+MPV.
6
4
7
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
5
Signed-off-by: Irina Ryapolova <irina.ryapolova@syntacore.com>
6
Fixes: b297129ae1 ("target/riscv: propagate PMP permission to TLB page")
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210311103036.1401073-1-georg.kotheimer@kernkonzept.com
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-ID: <20240320172828.23965-1-irina.ryapolova@syntacore.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
11
---
12
target/riscv/cpu_helper.c | 2 +-
12
target/riscv/cpu_helper.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
14
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
17
--- a/target/riscv/cpu_helper.c
18
+++ b/target/riscv/cpu_helper.c
18
+++ b/target/riscv/cpu_helper.c
19
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
19
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
20
* was called. Background registers will be used if the guest has
20
bool two_stage_lookup = mmuidx_2stage(mmu_idx);
21
* forced a two stage translation to be on (in HS or M mode).
21
bool two_stage_indirect_error = false;
22
*/
22
int ret = TRANSLATE_FAIL;
23
- if (!riscv_cpu_virt_enabled(env) && riscv_cpu_two_stage_lookup(mmu_idx)) {
23
- int mode = mmu_idx;
24
+ if (!riscv_cpu_virt_enabled(env) && two_stage) {
24
+ int mode = mmuidx_priv(mmu_idx);
25
use_background = true;
25
/* default TLB page size */
26
}
26
target_ulong tlb_size = TARGET_PAGE_SIZE;
27
27
28
--
28
--
29
2.30.1
29
2.44.0
30
31
diff view generated by jsdifflib
1
From: Asherah Connor <ashe@kivikakk.ee>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Provides fw_cfg for the virt machine on riscv. This enables
3
The timebase-frequency of guest OS should be the same with host
4
using e.g. ramfb later.
4
machine. The timebase-frequency value in DTS should be got from
5
hypervisor when using KVM acceleration.
5
6
6
Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
7
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Message-ID: <20240314061510.9800-1-yongxuan.wang@sifive.com>
9
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210318235041.17175-2-ashe@kivikakk.ee
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
13
---
12
include/hw/riscv/virt.h | 2 ++
14
target/riscv/kvm/kvm_riscv.h | 1 +
13
hw/riscv/virt.c | 30 ++++++++++++++++++++++++++++++
15
hw/riscv/virt.c | 2 ++
14
hw/riscv/Kconfig | 1 +
16
target/riscv/kvm/kvm-cpu.c | 9 +++++++++
15
3 files changed, 33 insertions(+)
17
3 files changed, 12 insertions(+)
16
18
17
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
19
diff --git a/target/riscv/kvm/kvm_riscv.h b/target/riscv/kvm/kvm_riscv.h
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/riscv/virt.h
21
--- a/target/riscv/kvm/kvm_riscv.h
20
+++ b/include/hw/riscv/virt.h
22
+++ b/target/riscv/kvm/kvm_riscv.h
21
@@ -XXX,XX +XXX,XX @@ struct RISCVVirtState {
23
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
22
RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
24
void riscv_kvm_aplic_request(void *opaque, int irq, int level);
23
DeviceState *plic[VIRT_SOCKETS_MAX];
25
int kvm_riscv_sync_mpstate_to_kvm(RISCVCPU *cpu, int state);
24
PFlashCFI01 *flash[2];
26
void riscv_kvm_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
25
+ FWCfgState *fw_cfg;
27
+uint64_t kvm_riscv_get_timebase_frequency(CPUState *cs);
26
28
27
int fdt_size;
29
#endif
28
};
29
@@ -XXX,XX +XXX,XX @@ enum {
30
VIRT_PLIC,
31
VIRT_UART0,
32
VIRT_VIRTIO,
33
+ VIRT_FW_CFG,
34
VIRT_FLASH,
35
VIRT_DRAM,
36
VIRT_PCIE_MMIO,
37
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
30
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
38
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/riscv/virt.c
32
--- a/hw/riscv/virt.c
40
+++ b/hw/riscv/virt.c
33
+++ b/hw/riscv/virt.c
41
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry virt_memmap[] = {
34
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
42
[VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) },
35
43
[VIRT_UART0] = { 0x10000000, 0x100 },
36
qemu_fdt_add_subnode(ms->fdt, "/cpus");
44
[VIRT_VIRTIO] = { 0x10001000, 0x1000 },
37
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "timebase-frequency",
45
+ [VIRT_FW_CFG] = { 0x10100000, 0x18 },
38
+ kvm_enabled() ?
46
[VIRT_FLASH] = { 0x20000000, 0x4000000 },
39
+ kvm_riscv_get_timebase_frequency(first_cpu) :
47
[VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 },
40
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);
48
[VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 },
41
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
49
@@ -XXX,XX +XXX,XX @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
42
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
50
return dev;
43
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/kvm/kvm-cpu.c
46
+++ b/target/riscv/kvm/kvm-cpu.c
47
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_put_regs_timer(CPUState *cs)
48
env->kvm_timer_dirty = false;
51
}
49
}
52
50
53
+static FWCfgState *create_fw_cfg(const MachineState *mc)
51
+uint64_t kvm_riscv_get_timebase_frequency(CPUState *cs)
54
+{
52
+{
55
+ hwaddr base = virt_memmap[VIRT_FW_CFG].base;
53
+ uint64_t reg;
56
+ hwaddr size = virt_memmap[VIRT_FW_CFG].size;
57
+ FWCfgState *fw_cfg;
58
+ char *nodename;
59
+
54
+
60
+ fw_cfg = fw_cfg_init_mem_wide(base + 8, base, 8, base + 16,
55
+ KVM_RISCV_GET_TIMER(cs, frequency, reg);
61
+ &address_space_memory);
62
+ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)mc->smp.cpus);
63
+
56
+
64
+ nodename = g_strdup_printf("/fw-cfg@%" PRIx64, base);
57
+ return reg;
65
+ qemu_fdt_add_subnode(mc->fdt, nodename);
66
+ qemu_fdt_setprop_string(mc->fdt, nodename,
67
+ "compatible", "qemu,fw-cfg-mmio");
68
+ qemu_fdt_setprop_sized_cells(mc->fdt, nodename, "reg",
69
+ 2, base, 2, size);
70
+ qemu_fdt_setprop(mc->fdt, nodename, "dma-coherent", NULL, 0);
71
+ g_free(nodename);
72
+ return fw_cfg;
73
+}
58
+}
74
+
59
+
75
static void virt_machine_init(MachineState *machine)
60
static int kvm_riscv_get_regs_vector(CPUState *cs)
76
{
61
{
77
const MemMapEntry *memmap = virt_memmap;
62
RISCVCPU *cpu = RISCV_CPU(cs);
78
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
79
start_addr = virt_memmap[VIRT_FLASH].base;
80
}
81
82
+ /*
83
+ * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the device
84
+ * tree cannot be altered and we get FDT_ERR_NOSPACE.
85
+ */
86
+ s->fw_cfg = create_fw_cfg(machine);
87
+ rom_set_fw(s->fw_cfg);
88
+
89
/* Compute the fdt load address in dram */
90
fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
91
machine->ram_size, machine->fdt);
92
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/riscv/Kconfig
95
+++ b/hw/riscv/Kconfig
96
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
97
select SIFIVE_PLIC
98
select SIFIVE_TEST
99
select VIRTIO_MMIO
100
+ select FW_CFG_DMA
101
102
config SIFIVE_E
103
bool
104
--
63
--
105
2.30.1
64
2.44.0
106
65
107
66
diff view generated by jsdifflib