1
The following changes since commit 3c8c36c9087da957f580a9bb5ebf7814a753d1c6:
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
Merge remote-tracking branch 'remotes/kraxel/tags/ui-20201104-pull-request' into staging (2020-11-04 16:52:17 +0000)
3
The following changes since commit c5fbdd60cf1fb52f01bdfe342b6fa65d5343e1b1:
4
5
Merge tag 'qemu-sparc-20211121' of git://github.com/mcayland/qemu into staging (2021-11-21 14:12:25 +0100)
4
6
5
are available in the Git repository at:
7
are available in the Git repository at:
6
8
7
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20201109
9
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20211122
8
10
9
for you to fetch changes up to 96338fefc19a143abdc91f6c44f37683274b08d4:
11
for you to fetch changes up to 526e7443027c71fe7b04c29df529e1f9f425f9e3:
10
12
11
hw/intc/ibex_plic: Clear the claim register when read (2020-11-09 15:09:53 -0800)
13
hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset (2021-11-22 10:46:22 +1000)
12
14
13
----------------------------------------------------------------
15
----------------------------------------------------------------
14
This fixes two bugs in the RISC-V port. One is a bug in the
16
Seventh RISC-V PR for QEMU 6.2
15
Ibex PLIC, the other fixes the Hypvervisor access functions.
17
18
- Deprecate IF_NONE for SiFive OTP
19
- Don't reset SiFive OTP content
16
20
17
----------------------------------------------------------------
21
----------------------------------------------------------------
18
Alistair Francis (6):
22
Philippe Mathieu-Daudé (1):
19
target/riscv: Add a virtualised MMU Mode
23
hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset
20
target/riscv: Set the virtualised MMU mode when doing hyp accesses
21
target/riscv: Remove the HS_TWO_STAGE flag
22
target/riscv: Remove the hyp load and store functions
23
target/riscv: Split the Hypervisor execute load helpers
24
hw/intc/ibex_plic: Clear the claim register when read
25
24
26
target/riscv/cpu-param.h | 11 ++-
25
Thomas Huth (1):
27
target/riscv/cpu.h | 19 ++++-
26
hw/misc/sifive_u_otp: Use IF_PFLASH for the OTP device instead of IF_NONE
28
target/riscv/cpu_bits.h | 1 -
29
target/riscv/helper.h | 5 +-
30
hw/intc/ibex_plic.c | 3 +
31
target/riscv/cpu_helper.c | 62 ++++++--------
32
target/riscv/op_helper.c | 124 ++-------------------------
33
target/riscv/translate.c | 2 +
34
target/riscv/insn_trans/trans_rvh.c.inc | 143 ++++++++++++--------------------
35
9 files changed, 115 insertions(+), 255 deletions(-)
36
27
28
docs/about/deprecated.rst | 6 ++++++
29
hw/misc/sifive_u_otp.c | 22 +++++++++++++---------
30
2 files changed, 19 insertions(+), 9 deletions(-)
31
diff view generated by jsdifflib
Deleted patch
1
Add a new MMU mode that includes the current virt mode.
2
1
3
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 4b301bc0ea36da962fc1605371b65019ac3073df.1604464950.git.alistair.francis@wdc.com
6
---
7
target/riscv/cpu-param.h | 11 ++++++++++-
8
target/riscv/cpu.h | 4 +++-
9
target/riscv/cpu_helper.c | 2 +-
10
3 files changed, 14 insertions(+), 3 deletions(-)
11
12
diff --git a/target/riscv/cpu-param.h b/target/riscv/cpu-param.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/riscv/cpu-param.h
15
+++ b/target/riscv/cpu-param.h
16
@@ -XXX,XX +XXX,XX @@
17
# define TARGET_VIRT_ADDR_SPACE_BITS 32 /* sv32 */
18
#endif
19
#define TARGET_PAGE_BITS 12 /* 4 KiB Pages */
20
-#define NB_MMU_MODES 4
21
+/*
22
+ * The current MMU Modes are:
23
+ * - U mode 0b000
24
+ * - S mode 0b001
25
+ * - M mode 0b011
26
+ * - U mode HLV/HLVX/HSV 0b100
27
+ * - S mode HLV/HLVX/HSV 0b101
28
+ * - M mode HLV/HLVX/HSV 0b111
29
+ */
30
+#define NB_MMU_MODES 8
31
32
#endif
33
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/riscv/cpu.h
36
+++ b/target/riscv/cpu.h
37
@@ -XXX,XX +XXX,XX @@ void QEMU_NORETURN riscv_raise_exception(CPURISCVState *env,
38
target_ulong riscv_cpu_get_fflags(CPURISCVState *env);
39
void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
40
41
-#define TB_FLAGS_MMU_MASK 3
42
+#define TB_FLAGS_MMU_MASK 7
43
+#define TB_FLAGS_PRIV_MMU_MASK 3
44
+#define TB_FLAGS_PRIV_HYP_ACCESS_MASK (1 << 2)
45
#define TB_FLAGS_MSTATUS_FS MSTATUS_FS
46
47
typedef CPURISCVState CPUArchState;
48
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/cpu_helper.c
51
+++ b/target/riscv/cpu_helper.c
52
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
53
* (riscv_cpu_do_interrupt) is correct */
54
MemTxResult res;
55
MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
56
- int mode = mmu_idx;
57
+ int mode = mmu_idx & TB_FLAGS_PRIV_MMU_MASK;
58
bool use_background = false;
59
60
/*
61
--
62
2.29.2
63
64
diff view generated by jsdifflib
Deleted patch
1
When performing the hypervisor load/store operations set the MMU mode to
2
indicate that we are virtualised.
3
1
4
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: e411c61a1452cad16853f13cac2fb86dc91ebee8.1604464950.git.alistair.francis@wdc.com
7
---
8
target/riscv/op_helper.c | 30 +++++++++++++++++-------------
9
1 file changed, 17 insertions(+), 13 deletions(-)
10
11
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/riscv/op_helper.c
14
+++ b/target/riscv/op_helper.c
15
@@ -XXX,XX +XXX,XX @@ target_ulong helper_hyp_load(CPURISCVState *env, target_ulong address,
16
(env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
17
get_field(env->hstatus, HSTATUS_HU))) {
18
target_ulong pte;
19
+ int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
20
21
riscv_cpu_set_two_stage_lookup(env, true);
22
23
switch (memop) {
24
case MO_SB:
25
- pte = cpu_ldsb_data_ra(env, address, GETPC());
26
+ pte = cpu_ldsb_mmuidx_ra(env, address, mmu_idx, GETPC());
27
break;
28
case MO_UB:
29
- pte = cpu_ldub_data_ra(env, address, GETPC());
30
+ pte = cpu_ldub_mmuidx_ra(env, address, mmu_idx, GETPC());
31
break;
32
case MO_TESW:
33
- pte = cpu_ldsw_data_ra(env, address, GETPC());
34
+ pte = cpu_ldsw_mmuidx_ra(env, address, mmu_idx, GETPC());
35
break;
36
case MO_TEUW:
37
- pte = cpu_lduw_data_ra(env, address, GETPC());
38
+ pte = cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
39
break;
40
case MO_TESL:
41
- pte = cpu_ldl_data_ra(env, address, GETPC());
42
+ pte = cpu_ldl_mmuidx_ra(env, address, mmu_idx, GETPC());
43
break;
44
case MO_TEUL:
45
- pte = cpu_ldl_data_ra(env, address, GETPC());
46
+ pte = cpu_ldl_mmuidx_ra(env, address, mmu_idx, GETPC());
47
break;
48
case MO_TEQ:
49
- pte = cpu_ldq_data_ra(env, address, GETPC());
50
+ pte = cpu_ldq_mmuidx_ra(env, address, mmu_idx, GETPC());
51
break;
52
default:
53
g_assert_not_reached();
54
@@ -XXX,XX +XXX,XX @@ void helper_hyp_store(CPURISCVState *env, target_ulong address,
55
(env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
56
(env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
57
get_field(env->hstatus, HSTATUS_HU))) {
58
+ int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
59
+
60
riscv_cpu_set_two_stage_lookup(env, true);
61
62
switch (memop) {
63
case MO_SB:
64
case MO_UB:
65
- cpu_stb_data_ra(env, address, val, GETPC());
66
+ cpu_stb_mmuidx_ra(env, address, val, mmu_idx, GETPC());
67
break;
68
case MO_TESW:
69
case MO_TEUW:
70
- cpu_stw_data_ra(env, address, val, GETPC());
71
+ cpu_stw_mmuidx_ra(env, address, val, mmu_idx, GETPC());
72
break;
73
case MO_TESL:
74
case MO_TEUL:
75
- cpu_stl_data_ra(env, address, val, GETPC());
76
+ cpu_stl_mmuidx_ra(env, address, val, mmu_idx, GETPC());
77
break;
78
case MO_TEQ:
79
- cpu_stq_data_ra(env, address, val, GETPC());
80
+ cpu_stq_mmuidx_ra(env, address, val, mmu_idx, GETPC());
81
break;
82
default:
83
g_assert_not_reached();
84
@@ -XXX,XX +XXX,XX @@ target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
85
(env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
86
get_field(env->hstatus, HSTATUS_HU))) {
87
target_ulong pte;
88
+ int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
89
90
riscv_cpu_set_two_stage_lookup(env, true);
91
92
switch (memop) {
93
case MO_TEUW:
94
- pte = cpu_lduw_data_ra(env, address, GETPC());
95
+ pte = cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
96
break;
97
case MO_TEUL:
98
- pte = cpu_ldl_data_ra(env, address, GETPC());
99
+ pte = cpu_ldl_mmuidx_ra(env, address, mmu_idx, GETPC());
100
break;
101
default:
102
g_assert_not_reached();
103
--
104
2.29.2
105
106
diff view generated by jsdifflib
1
Remove the special Virtulisation load and store functions and just use
1
From: Thomas Huth <thuth@redhat.com>
2
the standard tcg tcg_gen_qemu_ld_tl() and tcg_gen_qemu_st_tl() functions
3
instead.
4
2
5
As part of this change we ensure we still run an access check to make
3
Configuring a drive with "if=none" is meant for creation of a backend
6
sure we can perform the operations.
4
only, it should not get automatically assigned to a device frontend.
5
Use "if=pflash" for the One-Time-Programmable device instead (like
6
it is e.g. also done for the efuse device in hw/arm/xlnx-zcu102.c).
7
7
8
Since the old way of configuring the device has already been published
9
with the previous QEMU versions, we cannot remove this immediately, but
10
have to deprecate it and support it for at least two more releases.
11
12
Signed-off-by: Thomas Huth <thuth@redhat.com>
13
Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Reviewed-by: Markus Armbruster <armbru@redhat.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-id: 20211119102549.217755-1-thuth@redhat.com
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 189ac3e53ef2854824d18aad7074c6649f17de2c.1604464950.git.alistair.francis@wdc.com
11
---
18
---
12
target/riscv/cpu.h | 12 +++
19
docs/about/deprecated.rst | 6 ++++++
13
target/riscv/helper.h | 2 -
20
hw/misc/sifive_u_otp.c | 9 ++++++++-
14
target/riscv/op_helper.c | 86 -----------------
21
2 files changed, 14 insertions(+), 1 deletion(-)
15
target/riscv/translate.c | 2 +
16
target/riscv/insn_trans/trans_rvh.c.inc | 123 +++++++++---------------
17
5 files changed, 59 insertions(+), 166 deletions(-)
18
22
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
23
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
20
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.h
25
--- a/docs/about/deprecated.rst
22
+++ b/target/riscv/cpu.h
26
+++ b/docs/about/deprecated.rst
23
@@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, VL_EQ_VLMAX, 2, 1)
27
@@ -XXX,XX +XXX,XX @@ as short-form boolean values, and passed to plugins as ``arg_name=on``.
24
FIELD(TB_FLAGS, LMUL, 3, 2)
28
However, short-form booleans are deprecated and full explicit ``arg_name=on``
25
FIELD(TB_FLAGS, SEW, 5, 3)
29
form is preferred.
26
FIELD(TB_FLAGS, VILL, 8, 1)
30
27
+/* Is a Hypervisor instruction load/store allowed? */
31
+``-drive if=none`` for the sifive_u OTP device (since 6.2)
28
+FIELD(TB_FLAGS, HLSX, 9, 1)
32
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
29
30
/*
31
* A simplification for VLMAX
32
@@ -XXX,XX +XXX,XX @@ static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
33
if (riscv_cpu_fp_enabled(env)) {
34
flags |= env->mstatus & MSTATUS_FS;
35
}
36
+
33
+
37
+ if (riscv_has_ext(env, RVH)) {
34
+Using ``-drive if=none`` to configure the OTP device of the sifive_u
38
+ if (env->priv == PRV_M ||
35
+RISC-V machine is deprecated. Use ``-drive if=pflash`` instead.
39
+ (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
36
+
40
+ (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
37
41
+ get_field(env->hstatus, HSTATUS_HU))) {
38
QEMU Machine Protocol (QMP) commands
42
+ flags = FIELD_DP32(flags, TB_FLAGS, HLSX, 1);
39
------------------------------------
40
diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/misc/sifive_u_otp.c
43
+++ b/hw/misc/sifive_u_otp.c
44
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp)
45
TYPE_SIFIVE_U_OTP, SIFIVE_U_OTP_REG_SIZE);
46
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
47
48
- dinfo = drive_get_next(IF_NONE);
49
+ dinfo = drive_get_next(IF_PFLASH);
50
+ if (!dinfo) {
51
+ dinfo = drive_get_next(IF_NONE);
52
+ if (dinfo) {
53
+ warn_report("using \"-drive if=none\" for the OTP is deprecated, "
54
+ "use \"-drive if=pflash\" instead.");
43
+ }
55
+ }
44
+ }
56
+ }
45
#endif
57
if (dinfo) {
46
+
58
int ret;
47
*pflags = flags;
59
uint64_t perm;
48
}
49
50
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/riscv/helper.h
53
+++ b/target/riscv/helper.h
54
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(tlb_flush, void, env)
55
#ifndef CONFIG_USER_ONLY
56
DEF_HELPER_1(hyp_tlb_flush, void, env)
57
DEF_HELPER_1(hyp_gvma_tlb_flush, void, env)
58
-DEF_HELPER_4(hyp_load, tl, env, tl, tl, tl)
59
-DEF_HELPER_5(hyp_store, void, env, tl, tl, tl, tl)
60
DEF_HELPER_4(hyp_x_load, tl, env, tl, tl, tl)
61
#endif
62
63
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/riscv/op_helper.c
66
+++ b/target/riscv/op_helper.c
67
@@ -XXX,XX +XXX,XX @@ void helper_hyp_gvma_tlb_flush(CPURISCVState *env)
68
helper_hyp_tlb_flush(env);
69
}
70
71
-target_ulong helper_hyp_load(CPURISCVState *env, target_ulong address,
72
- target_ulong attrs, target_ulong memop)
73
-{
74
- if (env->priv == PRV_M ||
75
- (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
76
- (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
77
- get_field(env->hstatus, HSTATUS_HU))) {
78
- target_ulong pte;
79
- int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
80
-
81
- switch (memop) {
82
- case MO_SB:
83
- pte = cpu_ldsb_mmuidx_ra(env, address, mmu_idx, GETPC());
84
- break;
85
- case MO_UB:
86
- pte = cpu_ldub_mmuidx_ra(env, address, mmu_idx, GETPC());
87
- break;
88
- case MO_TESW:
89
- pte = cpu_ldsw_mmuidx_ra(env, address, mmu_idx, GETPC());
90
- break;
91
- case MO_TEUW:
92
- pte = cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
93
- break;
94
- case MO_TESL:
95
- pte = cpu_ldl_mmuidx_ra(env, address, mmu_idx, GETPC());
96
- break;
97
- case MO_TEUL:
98
- pte = cpu_ldl_mmuidx_ra(env, address, mmu_idx, GETPC());
99
- break;
100
- case MO_TEQ:
101
- pte = cpu_ldq_mmuidx_ra(env, address, mmu_idx, GETPC());
102
- break;
103
- default:
104
- g_assert_not_reached();
105
- }
106
-
107
- return pte;
108
- }
109
-
110
- if (riscv_cpu_virt_enabled(env)) {
111
- riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
112
- } else {
113
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
114
- }
115
- return 0;
116
-}
117
-
118
-void helper_hyp_store(CPURISCVState *env, target_ulong address,
119
- target_ulong val, target_ulong attrs, target_ulong memop)
120
-{
121
- if (env->priv == PRV_M ||
122
- (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
123
- (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
124
- get_field(env->hstatus, HSTATUS_HU))) {
125
- int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
126
-
127
- switch (memop) {
128
- case MO_SB:
129
- case MO_UB:
130
- cpu_stb_mmuidx_ra(env, address, val, mmu_idx, GETPC());
131
- break;
132
- case MO_TESW:
133
- case MO_TEUW:
134
- cpu_stw_mmuidx_ra(env, address, val, mmu_idx, GETPC());
135
- break;
136
- case MO_TESL:
137
- case MO_TEUL:
138
- cpu_stl_mmuidx_ra(env, address, val, mmu_idx, GETPC());
139
- break;
140
- case MO_TEQ:
141
- cpu_stq_mmuidx_ra(env, address, val, mmu_idx, GETPC());
142
- break;
143
- default:
144
- g_assert_not_reached();
145
- }
146
-
147
- return;
148
- }
149
-
150
- if (riscv_cpu_virt_enabled(env)) {
151
- riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
152
- } else {
153
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
154
- }
155
-}
156
-
157
target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
158
target_ulong attrs, target_ulong memop)
159
{
160
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
161
index XXXXXXX..XXXXXXX 100644
162
--- a/target/riscv/translate.c
163
+++ b/target/riscv/translate.c
164
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
165
to reset this known value. */
166
int frm;
167
bool ext_ifencei;
168
+ bool hlsx;
169
/* vector extension */
170
bool vill;
171
uint8_t lmul;
172
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
173
ctx->frm = -1; /* unknown rounding mode */
174
ctx->ext_ifencei = cpu->cfg.ext_ifencei;
175
ctx->vlen = cpu->cfg.vlen;
176
+ ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX);
177
ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL);
178
ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW);
179
ctx->lmul = FIELD_EX32(tb_flags, TB_FLAGS, LMUL);
180
diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
181
index XXXXXXX..XXXXXXX 100644
182
--- a/target/riscv/insn_trans/trans_rvh.c.inc
183
+++ b/target/riscv/insn_trans/trans_rvh.c.inc
184
@@ -XXX,XX +XXX,XX @@
185
* this program. If not, see <http://www.gnu.org/licenses/>.
186
*/
187
188
+#ifndef CONFIG_USER_ONLY
189
+static void check_access(DisasContext *ctx) {
190
+ if (!ctx->hlsx) {
191
+ if (ctx->virt_enabled) {
192
+ generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
193
+ } else {
194
+ generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
195
+ }
196
+ }
197
+}
198
+#endif
199
+
200
static bool trans_hlv_b(DisasContext *ctx, arg_hlv_b *a)
201
{
202
REQUIRE_EXT(ctx, RVH);
203
#ifndef CONFIG_USER_ONLY
204
TCGv t0 = tcg_temp_new();
205
TCGv t1 = tcg_temp_new();
206
- TCGv mem_idx = tcg_temp_new();
207
- TCGv memop = tcg_temp_new();
208
+
209
+ check_access(ctx);
210
211
gen_get_gpr(t0, a->rs1);
212
- tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
213
- tcg_gen_movi_tl(memop, MO_SB);
214
215
- gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop);
216
+ tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
217
gen_set_gpr(a->rd, t1);
218
219
tcg_temp_free(t0);
220
tcg_temp_free(t1);
221
- tcg_temp_free(mem_idx);
222
- tcg_temp_free(memop);
223
return true;
224
#else
225
return false;
226
@@ -XXX,XX +XXX,XX @@ static bool trans_hlv_h(DisasContext *ctx, arg_hlv_h *a)
227
#ifndef CONFIG_USER_ONLY
228
TCGv t0 = tcg_temp_new();
229
TCGv t1 = tcg_temp_new();
230
- TCGv mem_idx = tcg_temp_new();
231
- TCGv memop = tcg_temp_new();
232
+
233
+ check_access(ctx);
234
235
gen_get_gpr(t0, a->rs1);
236
- tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
237
- tcg_gen_movi_tl(memop, MO_TESW);
238
239
- gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop);
240
+ tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
241
gen_set_gpr(a->rd, t1);
242
243
tcg_temp_free(t0);
244
tcg_temp_free(t1);
245
- tcg_temp_free(mem_idx);
246
- tcg_temp_free(memop);
247
return true;
248
#else
249
return false;
250
@@ -XXX,XX +XXX,XX @@ static bool trans_hlv_w(DisasContext *ctx, arg_hlv_w *a)
251
#ifndef CONFIG_USER_ONLY
252
TCGv t0 = tcg_temp_new();
253
TCGv t1 = tcg_temp_new();
254
- TCGv mem_idx = tcg_temp_new();
255
- TCGv memop = tcg_temp_new();
256
+
257
+ check_access(ctx);
258
259
gen_get_gpr(t0, a->rs1);
260
- tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
261
- tcg_gen_movi_tl(memop, MO_TESL);
262
263
- gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop);
264
+ tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
265
gen_set_gpr(a->rd, t1);
266
267
tcg_temp_free(t0);
268
tcg_temp_free(t1);
269
- tcg_temp_free(mem_idx);
270
- tcg_temp_free(memop);
271
return true;
272
#else
273
return false;
274
@@ -XXX,XX +XXX,XX @@ static bool trans_hlv_bu(DisasContext *ctx, arg_hlv_bu *a)
275
#ifndef CONFIG_USER_ONLY
276
TCGv t0 = tcg_temp_new();
277
TCGv t1 = tcg_temp_new();
278
- TCGv mem_idx = tcg_temp_new();
279
- TCGv memop = tcg_temp_new();
280
+
281
+ check_access(ctx);
282
283
gen_get_gpr(t0, a->rs1);
284
- tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
285
- tcg_gen_movi_tl(memop, MO_UB);
286
287
- gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop);
288
+ tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_UB);
289
gen_set_gpr(a->rd, t1);
290
291
tcg_temp_free(t0);
292
tcg_temp_free(t1);
293
- tcg_temp_free(mem_idx);
294
- tcg_temp_free(memop);
295
return true;
296
#else
297
return false;
298
@@ -XXX,XX +XXX,XX @@ static bool trans_hlv_hu(DisasContext *ctx, arg_hlv_hu *a)
299
#ifndef CONFIG_USER_ONLY
300
TCGv t0 = tcg_temp_new();
301
TCGv t1 = tcg_temp_new();
302
- TCGv mem_idx = tcg_temp_new();
303
- TCGv memop = tcg_temp_new();
304
305
- gen_get_gpr(t0, a->rs1);
306
- tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
307
- tcg_gen_movi_tl(memop, MO_TEUW);
308
+ check_access(ctx);
309
310
- gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop);
311
+ gen_get_gpr(t0, a->rs1);
312
+ tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUW);
313
gen_set_gpr(a->rd, t1);
314
315
tcg_temp_free(t0);
316
tcg_temp_free(t1);
317
- tcg_temp_free(mem_idx);
318
- tcg_temp_free(memop);
319
return true;
320
#else
321
return false;
322
@@ -XXX,XX +XXX,XX @@ static bool trans_hsv_b(DisasContext *ctx, arg_hsv_b *a)
323
#ifndef CONFIG_USER_ONLY
324
TCGv t0 = tcg_temp_new();
325
TCGv dat = tcg_temp_new();
326
- TCGv mem_idx = tcg_temp_new();
327
- TCGv memop = tcg_temp_new();
328
+
329
+ check_access(ctx);
330
331
gen_get_gpr(t0, a->rs1);
332
gen_get_gpr(dat, a->rs2);
333
- tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
334
- tcg_gen_movi_tl(memop, MO_SB);
335
336
- gen_helper_hyp_store(cpu_env, t0, dat, mem_idx, memop);
337
+ tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
338
339
tcg_temp_free(t0);
340
tcg_temp_free(dat);
341
- tcg_temp_free(mem_idx);
342
- tcg_temp_free(memop);
343
return true;
344
#else
345
return false;
346
@@ -XXX,XX +XXX,XX @@ static bool trans_hsv_h(DisasContext *ctx, arg_hsv_h *a)
347
#ifndef CONFIG_USER_ONLY
348
TCGv t0 = tcg_temp_new();
349
TCGv dat = tcg_temp_new();
350
- TCGv mem_idx = tcg_temp_new();
351
- TCGv memop = tcg_temp_new();
352
+
353
+ check_access(ctx);
354
355
gen_get_gpr(t0, a->rs1);
356
gen_get_gpr(dat, a->rs2);
357
- tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
358
- tcg_gen_movi_tl(memop, MO_TESW);
359
360
- gen_helper_hyp_store(cpu_env, t0, dat, mem_idx, memop);
361
+ tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
362
363
tcg_temp_free(t0);
364
tcg_temp_free(dat);
365
- tcg_temp_free(mem_idx);
366
- tcg_temp_free(memop);
367
return true;
368
#else
369
return false;
370
@@ -XXX,XX +XXX,XX @@ static bool trans_hsv_w(DisasContext *ctx, arg_hsv_w *a)
371
#ifndef CONFIG_USER_ONLY
372
TCGv t0 = tcg_temp_new();
373
TCGv dat = tcg_temp_new();
374
- TCGv mem_idx = tcg_temp_new();
375
- TCGv memop = tcg_temp_new();
376
+
377
+ check_access(ctx);
378
379
gen_get_gpr(t0, a->rs1);
380
gen_get_gpr(dat, a->rs2);
381
- tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
382
- tcg_gen_movi_tl(memop, MO_TESL);
383
384
- gen_helper_hyp_store(cpu_env, t0, dat, mem_idx, memop);
385
+ tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
386
387
tcg_temp_free(t0);
388
tcg_temp_free(dat);
389
- tcg_temp_free(mem_idx);
390
- tcg_temp_free(memop);
391
return true;
392
#else
393
return false;
394
@@ -XXX,XX +XXX,XX @@ static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a)
395
#ifndef CONFIG_USER_ONLY
396
TCGv t0 = tcg_temp_new();
397
TCGv t1 = tcg_temp_new();
398
- TCGv mem_idx = tcg_temp_new();
399
- TCGv memop = tcg_temp_new();
400
+
401
+ check_access(ctx);
402
403
gen_get_gpr(t0, a->rs1);
404
- tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
405
- tcg_gen_movi_tl(memop, MO_TEUL);
406
407
- gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop);
408
+ tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUL);
409
gen_set_gpr(a->rd, t1);
410
411
tcg_temp_free(t0);
412
tcg_temp_free(t1);
413
- tcg_temp_free(mem_idx);
414
- tcg_temp_free(memop);
415
return true;
416
#else
417
return false;
418
@@ -XXX,XX +XXX,XX @@ static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a)
419
#ifndef CONFIG_USER_ONLY
420
TCGv t0 = tcg_temp_new();
421
TCGv t1 = tcg_temp_new();
422
- TCGv mem_idx = tcg_temp_new();
423
- TCGv memop = tcg_temp_new();
424
+
425
+ check_access(ctx);
426
427
gen_get_gpr(t0, a->rs1);
428
- tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
429
- tcg_gen_movi_tl(memop, MO_TEQ);
430
431
- gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop);
432
+ tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
433
gen_set_gpr(a->rd, t1);
434
435
tcg_temp_free(t0);
436
tcg_temp_free(t1);
437
- tcg_temp_free(mem_idx);
438
- tcg_temp_free(memop);
439
return true;
440
#else
441
return false;
442
@@ -XXX,XX +XXX,XX @@ static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a)
443
#ifndef CONFIG_USER_ONLY
444
TCGv t0 = tcg_temp_new();
445
TCGv dat = tcg_temp_new();
446
- TCGv mem_idx = tcg_temp_new();
447
- TCGv memop = tcg_temp_new();
448
+
449
+ check_access(ctx);
450
451
gen_get_gpr(t0, a->rs1);
452
gen_get_gpr(dat, a->rs2);
453
- tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
454
- tcg_gen_movi_tl(memop, MO_TEQ);
455
456
- gen_helper_hyp_store(cpu_env, t0, dat, mem_idx, memop);
457
+ tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
458
459
tcg_temp_free(t0);
460
tcg_temp_free(dat);
461
- tcg_temp_free(mem_idx);
462
- tcg_temp_free(memop);
463
return true;
464
#else
465
return false;
466
--
60
--
467
2.29.2
61
2.31.1
468
62
469
63
diff view generated by jsdifflib
1
The HS_TWO_STAGE flag is no longer required as the MMU index contains
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
the information if we are performing a two stage access.
3
2
3
Once a "One Time Programmable" is programmed, it shouldn't be reset.
4
5
Do not re-initialize the OTP content in the DeviceReset handler,
6
initialize it once in the DeviceRealize one.
7
8
Fixes: 9fb45c62ae8 ("riscv: sifive: Implement a model for SiFive FU540 OTP")
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20211119104757.331579-1-f4bug@amsat.org>
4
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: f514b128b1ff0fb41c85f914cee18f905007a922.1604464950.git.alistair.francis@wdc.com
7
---
13
---
8
target/riscv/cpu.h | 3 +-
14
hw/misc/sifive_u_otp.c | 13 +++++--------
9
target/riscv/cpu_bits.h | 1 -
15
1 file changed, 5 insertions(+), 8 deletions(-)
10
target/riscv/cpu_helper.c | 60 ++++++++++++++++-----------------------
11
target/riscv/op_helper.c | 12 --------
12
4 files changed, 25 insertions(+), 51 deletions(-)
13
16
14
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
17
diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu.h
19
--- a/hw/misc/sifive_u_otp.c
17
+++ b/target/riscv/cpu.h
20
+++ b/hw/misc/sifive_u_otp.c
18
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_virt_enabled(CPURISCVState *env);
21
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp)
19
void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
22
20
bool riscv_cpu_force_hs_excep_enabled(CPURISCVState *env);
23
if (blk_pread(s->blk, 0, s->fuse, filesize) != filesize) {
21
void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable);
24
error_setg(errp, "failed to read the initial flash content");
22
-bool riscv_cpu_two_stage_lookup(CPURISCVState *env);
25
+ return;
23
-void riscv_cpu_set_two_stage_lookup(CPURISCVState *env, bool enable);
26
}
24
+bool riscv_cpu_two_stage_lookup(int mmu_idx);
27
}
25
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
28
}
26
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
27
void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
28
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/riscv/cpu_bits.h
31
+++ b/target/riscv/cpu_bits.h
32
@@ -XXX,XX +XXX,XX @@
33
* page table fault.
34
*/
35
#define FORCE_HS_EXCEP 2
36
-#define HS_TWO_STAGE 4
37
38
/* RV32 satp CSR field masks */
39
#define SATP32_MODE 0x80000000
40
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/riscv/cpu_helper.c
43
+++ b/target/riscv/cpu_helper.c
44
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable)
45
env->virt = set_field(env->virt, FORCE_HS_EXCEP, enable);
46
}
47
48
-bool riscv_cpu_two_stage_lookup(CPURISCVState *env)
49
+bool riscv_cpu_two_stage_lookup(int mmu_idx)
50
{
51
- if (!riscv_has_ext(env, RVH)) {
52
- return false;
53
- }
54
-
55
- return get_field(env->virt, HS_TWO_STAGE);
56
-}
29
-}
57
-
30
-
58
-void riscv_cpu_set_two_stage_lookup(CPURISCVState *env, bool enable)
31
-static void sifive_u_otp_reset(DeviceState *dev)
59
-{
32
-{
60
- if (!riscv_has_ext(env, RVH)) {
33
- SiFiveUOTPState *s = SIFIVE_U_OTP(dev);
61
- return;
34
62
- }
35
/* Initialize all fuses' initial value to 0xFFs */
63
-
36
memset(s->fuse, 0xff, sizeof(s->fuse));
64
- env->virt = set_field(env->virt, HS_TWO_STAGE, enable);
37
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_reset(DeviceState *dev)
65
+ return mmu_idx & TB_FLAGS_PRIV_HYP_ACCESS_MASK;
38
serial_data = s->serial;
39
if (blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD,
40
&serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
41
- error_report("write error index<%d>", index);
42
+ error_setg(errp, "failed to write index<%d>", index);
43
+ return;
44
}
45
46
serial_data = ~(s->serial);
47
if (blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD,
48
&serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
49
- error_report("write error index<%d>", index + 1);
50
+ error_setg(errp, "failed to write index<%d>", index + 1);
51
+ return;
52
}
53
}
54
55
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_class_init(ObjectClass *klass, void *data)
56
57
device_class_set_props(dc, sifive_u_otp_properties);
58
dc->realize = sifive_u_otp_realize;
59
- dc->reset = sifive_u_otp_reset;
66
}
60
}
67
61
68
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts)
62
static const TypeInfo sifive_u_otp_info = {
69
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
70
* was called. Background registers will be used if the guest has
71
* forced a two stage translation to be on (in HS or M mode).
72
*/
73
- if (riscv_cpu_two_stage_lookup(env) && access_type != MMU_INST_FETCH) {
74
+ if (!riscv_cpu_virt_enabled(env) && riscv_cpu_two_stage_lookup(mmu_idx)) {
75
use_background = true;
76
}
77
78
@@ -XXX,XX +XXX,XX @@ restart:
79
80
static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
81
MMUAccessType access_type, bool pmp_violation,
82
- bool first_stage)
83
+ bool first_stage, bool two_stage)
84
{
85
CPUState *cs = env_cpu(env);
86
int page_fault_exceptions;
87
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
88
}
89
break;
90
case MMU_DATA_LOAD:
91
- if ((riscv_cpu_virt_enabled(env) || riscv_cpu_two_stage_lookup(env)) &&
92
- !first_stage) {
93
+ if (two_stage && !first_stage) {
94
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
95
} else {
96
cs->exception_index = page_fault_exceptions ?
97
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
98
}
99
break;
100
case MMU_DATA_STORE:
101
- if ((riscv_cpu_virt_enabled(env) || riscv_cpu_two_stage_lookup(env)) &&
102
- !first_stage) {
103
+ if (two_stage && !first_stage) {
104
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
105
} else {
106
cs->exception_index = page_fault_exceptions ?
107
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
108
int prot, prot2;
109
bool pmp_violation = false;
110
bool first_stage_error = true;
111
+ bool two_stage_lookup = false;
112
int ret = TRANSLATE_FAIL;
113
int mode = mmu_idx;
114
target_ulong tlb_size = 0;
115
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
116
access_type != MMU_INST_FETCH &&
117
get_field(env->mstatus, MSTATUS_MPRV) &&
118
get_field(env->mstatus, MSTATUS_MPV)) {
119
- riscv_cpu_set_two_stage_lookup(env, true);
120
+ two_stage_lookup = true;
121
}
122
123
if (riscv_cpu_virt_enabled(env) ||
124
- (riscv_cpu_two_stage_lookup(env) && access_type != MMU_INST_FETCH)) {
125
+ ((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
126
+ access_type != MMU_INST_FETCH)) {
127
/* Two stage lookup */
128
ret = get_physical_address(env, &pa, &prot, address,
129
&env->guest_phys_fault_addr, access_type,
130
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
131
__func__, address, ret, pa, prot);
132
}
133
134
- /* We did the two stage lookup based on MPRV, unset the lookup */
135
- if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
136
- access_type != MMU_INST_FETCH &&
137
- get_field(env->mstatus, MSTATUS_MPRV) &&
138
- get_field(env->mstatus, MSTATUS_MPV)) {
139
- riscv_cpu_set_two_stage_lookup(env, false);
140
- }
141
-
142
if (riscv_feature(env, RISCV_FEATURE_PMP) &&
143
(ret == TRANSLATE_SUCCESS) &&
144
!pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
145
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
146
} else if (probe) {
147
return false;
148
} else {
149
- raise_mmu_exception(env, address, access_type, pmp_violation, first_stage_error);
150
+ raise_mmu_exception(env, address, access_type, pmp_violation,
151
+ first_stage_error,
152
+ riscv_cpu_virt_enabled(env) ||
153
+ riscv_cpu_two_stage_lookup(mmu_idx));
154
riscv_raise_exception(env, cs->exception_index, retaddr);
155
}
156
157
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
158
/* handle the trap in S-mode */
159
if (riscv_has_ext(env, RVH)) {
160
target_ulong hdeleg = async ? env->hideleg : env->hedeleg;
161
+ bool two_stage_lookup = false;
162
+
163
+ if (env->priv == PRV_M ||
164
+ (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
165
+ (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
166
+ get_field(env->hstatus, HSTATUS_HU))) {
167
+ two_stage_lookup = true;
168
+ }
169
170
- if ((riscv_cpu_virt_enabled(env) ||
171
- riscv_cpu_two_stage_lookup(env)) && write_tval) {
172
+ if ((riscv_cpu_virt_enabled(env) || two_stage_lookup) && write_tval) {
173
/*
174
* If we are writing a guest virtual address to stval, set
175
* this to 1. If we are trapping to VS we will set this to 0
176
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
177
riscv_cpu_set_force_hs_excep(env, 0);
178
} else {
179
/* Trap into HS mode */
180
- if (!riscv_cpu_two_stage_lookup(env)) {
181
+ if (!two_stage_lookup) {
182
env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
183
riscv_cpu_virt_enabled(env));
184
}
185
- riscv_cpu_set_two_stage_lookup(env, false);
186
htval = env->guest_phys_fault_addr;
187
}
188
}
189
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
190
index XXXXXXX..XXXXXXX 100644
191
--- a/target/riscv/op_helper.c
192
+++ b/target/riscv/op_helper.c
193
@@ -XXX,XX +XXX,XX @@ target_ulong helper_hyp_load(CPURISCVState *env, target_ulong address,
194
target_ulong pte;
195
int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
196
197
- riscv_cpu_set_two_stage_lookup(env, true);
198
-
199
switch (memop) {
200
case MO_SB:
201
pte = cpu_ldsb_mmuidx_ra(env, address, mmu_idx, GETPC());
202
@@ -XXX,XX +XXX,XX @@ target_ulong helper_hyp_load(CPURISCVState *env, target_ulong address,
203
g_assert_not_reached();
204
}
205
206
- riscv_cpu_set_two_stage_lookup(env, false);
207
-
208
return pte;
209
}
210
211
@@ -XXX,XX +XXX,XX @@ void helper_hyp_store(CPURISCVState *env, target_ulong address,
212
get_field(env->hstatus, HSTATUS_HU))) {
213
int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
214
215
- riscv_cpu_set_two_stage_lookup(env, true);
216
-
217
switch (memop) {
218
case MO_SB:
219
case MO_UB:
220
@@ -XXX,XX +XXX,XX @@ void helper_hyp_store(CPURISCVState *env, target_ulong address,
221
g_assert_not_reached();
222
}
223
224
- riscv_cpu_set_two_stage_lookup(env, false);
225
-
226
return;
227
}
228
229
@@ -XXX,XX +XXX,XX @@ target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
230
target_ulong pte;
231
int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
232
233
- riscv_cpu_set_two_stage_lookup(env, true);
234
-
235
switch (memop) {
236
case MO_TEUW:
237
pte = cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
238
@@ -XXX,XX +XXX,XX @@ target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
239
g_assert_not_reached();
240
}
241
242
- riscv_cpu_set_two_stage_lookup(env, false);
243
-
244
return pte;
245
}
246
247
--
63
--
248
2.29.2
64
2.31.1
249
65
250
66
diff view generated by jsdifflib
Deleted patch
1
Split the hypervisor execute load functions into two seperate functions.
2
This avoids us having to pass the memop to the C helper functions.
3
1
4
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 5b1550f0faa3c435cc77f3c1ae811dea98ab9e36.1604464950.git.alistair.francis@wdc.com
7
---
8
target/riscv/helper.h | 3 ++-
9
target/riscv/op_helper.c | 36 +++++++------------------
10
target/riscv/insn_trans/trans_rvh.c.inc | 20 +++++---------
11
3 files changed, 17 insertions(+), 42 deletions(-)
12
13
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/helper.h
16
+++ b/target/riscv/helper.h
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(tlb_flush, void, env)
18
#ifndef CONFIG_USER_ONLY
19
DEF_HELPER_1(hyp_tlb_flush, void, env)
20
DEF_HELPER_1(hyp_gvma_tlb_flush, void, env)
21
-DEF_HELPER_4(hyp_x_load, tl, env, tl, tl, tl)
22
+DEF_HELPER_2(hyp_hlvx_hu, tl, env, tl)
23
+DEF_HELPER_2(hyp_hlvx_wu, tl, env, tl)
24
#endif
25
26
/* Vector functions */
27
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/riscv/op_helper.c
30
+++ b/target/riscv/op_helper.c
31
@@ -XXX,XX +XXX,XX @@ void helper_hyp_gvma_tlb_flush(CPURISCVState *env)
32
helper_hyp_tlb_flush(env);
33
}
34
35
-target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
36
- target_ulong attrs, target_ulong memop)
37
+target_ulong helper_hyp_hlvx_hu(CPURISCVState *env, target_ulong address)
38
{
39
- if (env->priv == PRV_M ||
40
- (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
41
- (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
42
- get_field(env->hstatus, HSTATUS_HU))) {
43
- target_ulong pte;
44
- int mmu_idx = cpu_mmu_index(env, false) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
45
-
46
- switch (memop) {
47
- case MO_TEUW:
48
- pte = cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
49
- break;
50
- case MO_TEUL:
51
- pte = cpu_ldl_mmuidx_ra(env, address, mmu_idx, GETPC());
52
- break;
53
- default:
54
- g_assert_not_reached();
55
- }
56
+ int mmu_idx = cpu_mmu_index(env, true) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
57
58
- return pte;
59
- }
60
+ return cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
61
+}
62
63
- if (riscv_cpu_virt_enabled(env)) {
64
- riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
65
- } else {
66
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
67
- }
68
- return 0;
69
+target_ulong helper_hyp_hlvx_wu(CPURISCVState *env, target_ulong address)
70
+{
71
+ int mmu_idx = cpu_mmu_index(env, true) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
72
+
73
+ return cpu_ldl_mmuidx_ra(env, address, mmu_idx, GETPC());
74
}
75
76
#endif /* !CONFIG_USER_ONLY */
77
diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/riscv/insn_trans/trans_rvh.c.inc
80
+++ b/target/riscv/insn_trans/trans_rvh.c.inc
81
@@ -XXX,XX +XXX,XX @@ static bool trans_hlvx_hu(DisasContext *ctx, arg_hlvx_hu *a)
82
#ifndef CONFIG_USER_ONLY
83
TCGv t0 = tcg_temp_new();
84
TCGv t1 = tcg_temp_new();
85
- TCGv mem_idx = tcg_temp_new();
86
- TCGv memop = tcg_temp_new();
87
+
88
+ check_access(ctx);
89
90
gen_get_gpr(t0, a->rs1);
91
- tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
92
- tcg_gen_movi_tl(memop, MO_TEUW);
93
94
- gen_helper_hyp_x_load(t1, cpu_env, t0, mem_idx, memop);
95
+ gen_helper_hyp_hlvx_hu(t1, cpu_env, t0);
96
gen_set_gpr(a->rd, t1);
97
98
tcg_temp_free(t0);
99
tcg_temp_free(t1);
100
- tcg_temp_free(mem_idx);
101
- tcg_temp_free(memop);
102
return true;
103
#else
104
return false;
105
@@ -XXX,XX +XXX,XX @@ static bool trans_hlvx_wu(DisasContext *ctx, arg_hlvx_wu *a)
106
#ifndef CONFIG_USER_ONLY
107
TCGv t0 = tcg_temp_new();
108
TCGv t1 = tcg_temp_new();
109
- TCGv mem_idx = tcg_temp_new();
110
- TCGv memop = tcg_temp_new();
111
+
112
+ check_access(ctx);
113
114
gen_get_gpr(t0, a->rs1);
115
- tcg_gen_movi_tl(mem_idx, ctx->mem_idx);
116
- tcg_gen_movi_tl(memop, MO_TEUL);
117
118
- gen_helper_hyp_x_load(t1, cpu_env, t0, mem_idx, memop);
119
+ gen_helper_hyp_hlvx_wu(t1, cpu_env, t0);
120
gen_set_gpr(a->rd, t1);
121
122
tcg_temp_free(t0);
123
tcg_temp_free(t1);
124
- tcg_temp_free(mem_idx);
125
- tcg_temp_free(memop);
126
return true;
127
#else
128
return false;
129
--
130
2.29.2
131
132
diff view generated by jsdifflib
Deleted patch
1
After claiming the interrupt by reading the claim register we want to
2
clear the register to make sure the interrupt doesn't appear at the next
3
read.
4
1
5
This matches the documentation for the claim register as when an interrupt
6
is claimed by a target the relevant bit of IP is cleared (which we already
7
do): https://docs.opentitan.org/hw/ip/rv_plic/doc/index.html
8
9
This also matches the current hardware.
10
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 68d4575deef2559b7a747f3bda193fcf43af4558.1604629928.git.alistair.francis@wdc.com
14
---
15
hw/intc/ibex_plic.c | 3 +++
16
1 file changed, 3 insertions(+)
17
18
diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/ibex_plic.c
21
+++ b/hw/intc/ibex_plic.c
22
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_plic_read(void *opaque, hwaddr addr,
23
/* Return the current claimed interrupt */
24
ret = s->claim;
25
26
+ /* Clear the claimed interrupt */
27
+ s->claim = 0x00000000;
28
+
29
/* Update the interrupt status after the claim */
30
ibex_plic_update(s);
31
}
32
--
33
2.29.2
34
35
diff view generated by jsdifflib