From: Stafford Horne <shorne@gmail.com>
To: QEMU Development <qemu-devel@nongnu.org>
Cc: Linux OpenRISC <linux-openrisc@vger.kernel.org>,
Stafford Horne <shorne@gmail.com>
Subject: [PATCH 1/3] target/openrisc: Allow fpcsr access in user mode
Date: Tue, 2 May 2023 19:57:29 +0100 [thread overview]
Message-ID: <20230502185731.3543420-2-shorne@gmail.com> (raw)
In-Reply-To: <20230502185731.3543420-1-shorne@gmail.com>
As per OpenRISC spec 1.4 FPCSR can be read and written in user mode.
Update mtspr and mfspr helpers to support this by moving the is_user
check into the helper.
There is a logic change here to no longer throw an illegal instruction
exception when executing mtspr/mfspr in user mode. The illegal
instruction exception is not part of the spec, so this should be OK.
Link: https://raw.githubusercontent.com/openrisc/doc/master/openrisc-arch-1.4-rev0.pdf
Signed-off-by: Stafford Horne <shorne@gmail.com>
---
target/openrisc/sys_helper.c | 45 +++++++++++++++++-----
target/openrisc/translate.c | 72 ++++++++++++++++--------------------
2 files changed, 67 insertions(+), 50 deletions(-)
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index ec145960e3..8a0259c710 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -29,17 +29,37 @@
#define TO_SPR(group, number) (((group) << 11) + (number))
+static inline bool is_user(CPUOpenRISCState *env)
+{
+#ifdef CONFIG_USER_ONLY
+ return true;
+#else
+ return (env->sr & SR_SM) == 0;
+#endif
+}
+
void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
{
-#ifndef CONFIG_USER_ONLY
OpenRISCCPU *cpu = env_archcpu(env);
+#ifndef CONFIG_USER_ONLY
CPUState *cs = env_cpu(env);
target_ulong mr;
int idx;
#endif
+ /* Handle user accessible SPRs first. */
switch (spr) {
+ case TO_SPR(0, 20): /* FPCSR */
+ cpu_set_fpcsr(env, rb);
+ return;
+ }
+
+ if (is_user(env)) {
+ raise_exception(cpu, EXCP_ILLEGAL);
+ }
+
#ifndef CONFIG_USER_ONLY
+ switch (spr) {
case TO_SPR(0, 11): /* EVBAR */
env->evbar = rb;
break;
@@ -187,12 +207,8 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
cpu_openrisc_timer_update(cpu);
qemu_mutex_unlock_iothread();
break;
-#endif
-
- case TO_SPR(0, 20): /* FPCSR */
- cpu_set_fpcsr(env, rb);
- break;
}
+#endif
}
target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
@@ -204,10 +220,22 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
OpenRISCCPU *cpu = env_archcpu(env);
CPUState *cs = env_cpu(env);
int idx;
+#else
+ OpenRISCCPU *cpu = env_archcpu(env);
#endif
+ /* Handle user accessible SPRs first. */
switch (spr) {
+ case TO_SPR(0, 20): /* FPCSR */
+ return env->fpcsr;
+ }
+
+ if (is_user(env)) {
+ raise_exception(cpu, EXCP_ILLEGAL);
+ }
+
#ifndef CONFIG_USER_ONLY
+ switch (spr) {
case TO_SPR(0, 0): /* VR */
return env->vr;
@@ -324,11 +352,8 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
cpu_openrisc_count_update(cpu);
qemu_mutex_unlock_iothread();
return cpu_openrisc_count_get(cpu);
-#endif
-
- case TO_SPR(0, 20): /* FPCSR */
- return env->fpcsr;
}
+#endif
/* for rd is passed in, if rd unchanged, just keep it back. */
return rd;
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 76e53c78d4..43ba0cc1ad 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -819,45 +819,12 @@ static bool trans_l_xori(DisasContext *dc, arg_rri *a)
static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a)
{
- check_r0_write(dc, a->d);
-
- if (is_user(dc)) {
- gen_illegal_exception(dc);
- } else {
- TCGv spr = tcg_temp_new();
-
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
- gen_io_start();
- if (dc->delayed_branch) {
- tcg_gen_mov_tl(cpu_pc, jmp_pc);
- tcg_gen_discard_tl(jmp_pc);
- } else {
- tcg_gen_movi_tl(cpu_pc, dc->base.pc_next + 4);
- }
- dc->base.is_jmp = DISAS_EXIT;
- }
+ TCGv spr = tcg_temp_new();
- tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
- gen_helper_mfspr(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->d), spr);
- }
- return true;
-}
-
-static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a)
-{
- if (is_user(dc)) {
- gen_illegal_exception(dc);
- } else {
- TCGv spr;
+ check_r0_write(dc, a->d);
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
- gen_io_start();
- }
- /* For SR, we will need to exit the TB to recognize the new
- * exception state. For NPC, in theory this counts as a branch
- * (although the SPR only exists for use by an ICE). Save all
- * of the cpu state first, allowing it to be overwritten.
- */
+ if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
+ gen_io_start();
if (dc->delayed_branch) {
tcg_gen_mov_tl(cpu_pc, jmp_pc);
tcg_gen_discard_tl(jmp_pc);
@@ -865,11 +832,36 @@ static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a)
tcg_gen_movi_tl(cpu_pc, dc->base.pc_next + 4);
}
dc->base.is_jmp = DISAS_EXIT;
+ }
+
+ tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
+ gen_helper_mfspr(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->d), spr);
+ return true;
+}
+
+static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a)
+{
+ TCGv spr = tcg_temp_new();
- spr = tcg_temp_new();
- tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
- gen_helper_mtspr(cpu_env, spr, cpu_R(dc, a->b));
+ if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
+ gen_io_start();
}
+ /*
+ * For SR, we will need to exit the TB to recognize the new
+ * exception state. For NPC, in theory this counts as a branch
+ * (although the SPR only exists for use by an ICE). Save all
+ * of the cpu state first, allowing it to be overwritten.
+ */
+ if (dc->delayed_branch) {
+ tcg_gen_mov_tl(cpu_pc, jmp_pc);
+ tcg_gen_discard_tl(jmp_pc);
+ } else {
+ tcg_gen_movi_tl(cpu_pc, dc->base.pc_next + 4);
+ }
+ dc->base.is_jmp = DISAS_EXIT;
+
+ tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
+ gen_helper_mtspr(cpu_env, spr, cpu_R(dc, a->b));
return true;
}
--
2.39.1
next prev parent reply other threads:[~2023-05-02 18:58 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-02 18:57 [PATCH 0/3] OpenRISC updates for user space FPU Stafford Horne
2023-05-02 18:57 ` Stafford Horne [this message]
2023-05-03 6:29 ` [PATCH 1/3] target/openrisc: Allow fpcsr access in user mode Stafford Horne
2023-05-02 18:57 ` [PATCH 2/3] target/openrisc: Set PC to cpu state on FPU exception Stafford Horne
2023-05-03 7:36 ` Richard Henderson
2023-05-03 9:12 ` Stafford Horne
2023-05-02 18:57 ` [PATCH 3/3] target/openrisc: Setup FPU for detecting tininess before rounding Stafford Horne
2023-05-03 7:37 ` Richard Henderson
2023-05-03 9:14 ` Stafford Horne
2023-05-03 9:41 ` Richard Henderson
2023-05-03 16:31 ` Stafford Horne
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230502185731.3543420-2-shorne@gmail.com \
--to=shorne@gmail.com \
--cc=linux-openrisc@vger.kernel.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).