All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, proljc@gmail.com
Subject: [Qemu-devel] [PATCH 17/17] target-openrisc: Implement lwa, swa
Date: Wed,  2 Sep 2015 17:17:43 -0700	[thread overview]
Message-ID: <1441239463-18981-18-git-send-email-rth@twiddle.net> (raw)
In-Reply-To: <1441239463-18981-1-git-send-email-rth@twiddle.net>

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/main.c                  | 45 ++++++++++++++++++++++++
 target-openrisc/cpu.c              |  1 +
 target-openrisc/cpu.h              |  9 +++++
 target-openrisc/interrupt.c        |  1 +
 target-openrisc/interrupt_helper.c |  1 +
 target-openrisc/mmu.c              |  1 +
 target-openrisc/translate.c        | 70 ++++++++++++++++++++++++++++++++++++++
 7 files changed, 128 insertions(+)

diff --git a/linux-user/main.c b/linux-user/main.c
index 2c9658e..77b301c 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2644,6 +2644,48 @@ error:
 #endif
 
 #ifdef TARGET_OPENRISC
+static void do_store_exclusive(CPUOpenRISCState *env)
+{
+    target_ulong addr, val, tmp;
+    target_siginfo_t info;
+    int ret = 0;
+
+    addr = env->lock_addr;
+    tmp = env->lock_st_addr;
+    env->lock_addr = -1;
+    env->lock_st_addr = 0;
+
+    start_exclusive();
+    mmap_lock();
+
+    if (addr == tmp) {
+        if (get_user_u32(val, addr)) {
+            goto do_sigsegv;
+        }
+        if (val == env->lock_value) {
+            if (put_user_u32(env->lock_st_value, addr)) {
+                goto do_sigsegv;
+            }
+            ret = 1;
+        }
+    }
+    env->sr_f = ret;
+    env->pc += 4;
+
+    mmap_unlock();
+    end_exclusive();
+    return;
+
+ do_sigsegv:
+    mmap_unlock();
+    end_exclusive();
+
+    info.si_signo = TARGET_SIGSEGV;
+    info.si_errno = 0;
+    info.si_code = TARGET_SEGV_MAPERR;
+    info._sifields._sigfault._addr = addr;
+    queue_signal(env, TARGET_SIGSEGV, &info);
+}
 
 void cpu_loop(CPUOpenRISCState *env)
 {
@@ -2713,6 +2755,9 @@ void cpu_loop(CPUOpenRISCState *env)
         case EXCP_NR:
             qemu_log("\nNR\n");
             break;
+	case EXCP_SWA:
+            do_store_exclusive(env);
+            break;
         default:
             qemu_log("\nqemu: unhandled CPU exception %#x - aborting\n",
                      trapnr);
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index d97f3c0..56ceba4 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -52,6 +52,7 @@ static void openrisc_cpu_reset(CPUState *s)
 
     cpu->env.pc = 0x100;
     cpu->env.sr = SR_FO | SR_SM;
+    cpu->env.lock_addr = -1;
     s->exception_index = -1;
 
     cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP;
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 5ddf477..e3afe26 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -171,6 +171,8 @@ enum {
     EXCP_FPE      = 0xd,
     EXCP_TRAP     = 0xe,
     EXCP_NR,
+    /* For usermode emulation.  */
+    EXCP_SWA,
 };
 
 /* Supervisor register */
@@ -297,6 +299,13 @@ typedef struct CPUOpenRISCState {
     uint32_t fpcsr;           /* Float register */
     float_status fp_status;
 
+    target_ulong lock_addr;
+    target_ulong lock_value;
+#ifdef CONFIG_USER_ONLY
+    target_ulong lock_st_addr;
+    target_ulong lock_st_value;
+#endif
+
     uint32_t flags;           /* cpu_flags, we only use it for exception
                                  in solt so far.  */
 
diff --git a/target-openrisc/interrupt.c b/target-openrisc/interrupt.c
index 2d89acb..428314f 100644
--- a/target-openrisc/interrupt.c
+++ b/target-openrisc/interrupt.c
@@ -53,6 +53,7 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
     env->sr &= ~SR_TEE;
     env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
     env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;
+    env->lock_addr = -1;
 
     if (cs->exception_index > 0 && cs->exception_index < EXCP_NR) {
         env->pc = (cs->exception_index << 8);
diff --git a/target-openrisc/interrupt_helper.c b/target-openrisc/interrupt_helper.c
index 8695fe7..70e64a3 100644
--- a/target-openrisc/interrupt_helper.c
+++ b/target-openrisc/interrupt_helper.c
@@ -32,6 +32,7 @@ void HELPER(rfe)(CPUOpenRISCState *env)
     cpu->env.pc = cpu->env.epcr;
     cpu->env.npc = cpu->env.epcr;
     cpu_set_sr(&cpu->env, cpu->env.esr);
+    cpu->env.lock_addr = -1;
 
 #ifndef CONFIG_USER_ONLY
     if (cpu->env.sr & SR_DME) {
diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c
index 750a936..a656232 100644
--- a/target-openrisc/mmu.c
+++ b/target-openrisc/mmu.c
@@ -172,6 +172,7 @@ static void cpu_openrisc_raise_mmu_exception(OpenRISCCPU *cpu,
 
     cs->exception_index = exception;
     cpu->env.eear = address;
+    cpu->env.lock_addr = -1;
 }
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 569f4ab..80d2b84 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -57,6 +57,8 @@ static TCGv cpu_ppc;
 static TCGv cpu_sr_f;           /* bf/bnf, F flag taken */
 static TCGv cpu_sr_cy;          /* carry (unsigned overflow) */
 static TCGv cpu_sr_ov;          /* signed overflow */
+static TCGv cpu_lock_addr;
+static TCGv cpu_lock_value;
 static TCGv_i32 fpcsr;
 static TCGv_i64 cpu_mac;        /* MACHI:MACLO */
 static TCGv_i32 env_flags;
@@ -92,6 +94,12 @@ void openrisc_translate_init(void)
                                  offsetof(CPUOpenRISCState, sr_cy), "sr_cy");
     cpu_sr_ov = tcg_global_mem_new(TCG_AREG0,
                                  offsetof(CPUOpenRISCState, sr_ov), "sr_ov");
+    cpu_lock_addr = tcg_global_mem_new(TCG_AREG0,
+                                       offsetof(CPUOpenRISCState, lock_addr),
+                                       "lock_addr");
+    cpu_lock_value = tcg_global_mem_new(TCG_AREG0,
+                                        offsetof(CPUOpenRISCState, lock_value),
+                                        "lock_value");
     fpcsr = tcg_global_mem_new_i32(TCG_AREG0,
                                    offsetof(CPUOpenRISCState, fpcsr),
                                    "fpcsr");
@@ -467,6 +475,58 @@ static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb)
     gen_ove_cy(dc);
 }
 
+static void gen_lwa(DisasContext *dc, TCGv rd, TCGv ra, int32_t ofs)
+{
+    TCGv ea = tcg_temp_new();
+
+    tcg_gen_addi_tl(ea, ra, ofs);
+    tcg_gen_qemu_ld_tl(rd, ea, dc->mem_idx, MO_TEUL);
+    tcg_gen_mov_tl(cpu_lock_addr, ea);
+    tcg_gen_mov_tl(cpu_lock_value, rd);
+    tcg_temp_free(ea);
+}
+
+static void gen_swa(DisasContext *dc, TCGv rb, TCGv ra, int32_t ofs)
+{
+#ifdef CONFIG_USER_ONLY
+    TCGv ea = tcg_temp_new();
+    tcg_gen_addi_tl(ea, ra, ofs);
+    tcg_gen_st_tl(ea, cpu_env, offsetof(CPUOpenRISCState, lock_st_addr));
+    tcg_temp_free(ea);
+
+    tcg_gen_st32_tl(rb, cpu_env, offsetof(CPUOpenRISCState, lock_st_value));
+
+    tcg_gen_movi_tl(cpu_pc, dc->pc);
+    gen_exception(dc, EXCP_SWA);
+    dc->is_jmp = DISAS_UPDATE;
+#else
+    TCGv ea, val;
+    TCGLabel *lab_fail, *lab_done;
+
+    ea = tcg_temp_new();
+    tcg_gen_addi_tl(ea, ra, ofs);
+
+    lab_fail = gen_new_label();
+    lab_done = gen_new_label();
+    tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_lock_addr, lab_fail);
+    tcg_temp_free(ea);
+
+    val = tcg_temp_new();
+    tcg_gen_qemu_ld_tl(val, cpu_lock_addr, dc->mem_idx, MO_TEUL);
+    tcg_gen_brcond_tl(TCG_COND_NE, val, cpu_lock_value, lab_fail);
+
+    tcg_gen_qemu_st_tl(rb, cpu_lock_addr, dc->mem_idx, MO_TEUL);
+    tcg_gen_movi_tl(cpu_sr_f, 1);
+    tcg_gen_br(lab_done);
+
+    gen_set_label(lab_fail);
+    tcg_gen_movi_tl(cpu_sr_f, 0);
+
+    gen_set_label(lab_done);
+    tcg_gen_movi_tl(cpu_lock_addr, -1);
+#endif
+}
+
 static void dec_calc(DisasContext *dc, uint32_t insn)
 {
     uint32_t op0, op1, op2;
@@ -721,6 +781,11 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         }
         break;
 
+    case 0x1b: /* l.lwa */
+        LOG_DIS("l.lwa r%d, r%d, %d\n", rd, ra, I16);
+        gen_lwa(dc, cpu_R[rd], cpu_R[ra], I16);
+        break;
+
     case 0x1c:    /* l.cust1 */
         LOG_DIS("l.cust1\n");
         break;
@@ -847,6 +912,11 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         }
         break;
 
+    case 0x33: /* l.swa */
+        LOG_DIS("l.swa r%d, r%d, %d\n", ra, rb, I5_11);
+        gen_swa(dc, cpu_R[rb], cpu_R[ra], I5_11);
+        break;
+
     case 0x34:    /* l.sd */
         LOG_DIS("l.sd r%d, r%d, %d\n", ra, rb, I5_11);
         check_ob64s(dc);
-- 
2.4.3

  parent reply	other threads:[~2015-09-03  0:18 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
2015-09-03  0:17 ` [Qemu-devel] [PATCH 01/17] target-openrisc: Always enable OPENRISC_DISAS Richard Henderson
2015-09-03 14:15   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 02/17] target-openrisc: Streamline arithmetic and OVE Richard Henderson
2015-09-03 14:16   ` Bastian Koppelmann
2015-09-03 14:44     ` Richard Henderson
2015-09-04 13:12       ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 03/17] target-openrisc: Invert the decoding in dec_calc Richard Henderson
2015-09-03 14:48   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 04/17] target-openrisc: Keep SR_F in a separate variable Richard Henderson
2015-09-03 15:09   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 05/17] target-openrisc: Use movcond where appropriate Richard Henderson
2015-09-03 16:04   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 06/17] target-openrisc: Put SR[OVE] in TB flags Richard Henderson
2015-09-04 13:05   ` Bastian Koppelmann
2015-09-04 14:29     ` Richard Henderson
2015-09-03  0:17 ` [Qemu-devel] [PATCH 07/17] target-openrisc: Keep SR_CY and SR_OV in a separate variables Richard Henderson
2015-09-04 13:33   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 08/17] target-openrisc: Set flags on helpers Richard Henderson
2015-09-04 13:58   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 09/17] target-openrisc: Implement ff1 and fl1 for 64-bit Richard Henderson
2015-09-04 13:59   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 10/17] target-openrisc: Represent MACHI:MACLO as a single unit Richard Henderson
2015-09-04 15:04   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 11/17] target-openrisc: Rationalize immediate extraction Richard Henderson
2015-09-04 15:24   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 12/17] target-openrisc: Enable m[tf]spr from user mode Richard Henderson
2015-09-05 21:35   ` Bastian Koppelmann
2015-09-06 20:36     ` Richard Henderson
2015-09-13  8:34       ` Bastian Koppelmann
2015-09-14 17:11         ` Richard Henderson
2015-09-15  7:22           ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 13/17] target-openrisc: Enable trap, csync, msync, psync for " Richard Henderson
2015-09-06  9:30   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 14/17] target-openrisc: Implement muld, muldu, macu, msbu Richard Henderson
2015-09-06 11:38   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 15/17] target-openrisc: Fix madd Richard Henderson
2015-09-13  8:21   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 16/17] target-openrisc: Write back result before FPE exception Richard Henderson
2015-09-15 13:02   ` Bastian Koppelmann
2015-09-03  0:17 ` Richard Henderson [this message]
2015-09-15 13:04   ` [Qemu-devel] [PATCH 17/17] target-openrisc: Implement lwa, swa Bastian Koppelmann

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=1441239463-18981-18-git-send-email-rth@twiddle.net \
    --to=rth@twiddle.net \
    --cc=peter.maydell@linaro.org \
    --cc=proljc@gmail.com \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.