qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 05/26] target-alpha: Fix translation of PALmode memory insns.
Date: Mon, 23 May 2011 13:28:25 -0700	[thread overview]
Message-ID: <1306182526-12081-6-git-send-email-rth@twiddle.net> (raw)
In-Reply-To: <1306182526-12081-1-git-send-email-rth@twiddle.net>

All of the "raw" memory accesses should be "phys" instead.  Fix
some confusion about argument ordering of the store routines.
Fix the implementation of store-conditional.

Delete the "alt-mode" helpers.  Because we only implement two
mmu modes, let /a imply user-mode unconditionally.

Leave some combinations of virt access without permission
checks as unimplemented.  There are too many hoops through
which to jump, and these insns will not be needed in the
emulation palcode.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/helper.h    |   26 +++-----
 target-alpha/op_helper.c |  147 +++++++++++-----------------------------------
 target-alpha/translate.c |   75 +++++++-----------------
 3 files changed, 65 insertions(+), 183 deletions(-)

diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index ccf6a2a..f4f693a 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -104,23 +104,15 @@ DEF_HELPER_0(hw_rei, void)
 DEF_HELPER_1(hw_ret, void, i64)
 DEF_HELPER_2(mfpr, i64, int, i64)
 DEF_HELPER_2(mtpr, void, int, i64)
-DEF_HELPER_0(set_alt_mode, void)
-DEF_HELPER_0(restore_mode, void)
-
-DEF_HELPER_1(ld_virt_to_phys, i64, i64)
-DEF_HELPER_1(st_virt_to_phys, i64, i64)
-DEF_HELPER_2(ldl_raw, void, i64, i64)
-DEF_HELPER_2(ldq_raw, void, i64, i64)
-DEF_HELPER_2(ldl_l_raw, void, i64, i64)
-DEF_HELPER_2(ldq_l_raw, void, i64, i64)
-DEF_HELPER_2(ldl_kernel, void, i64, i64)
-DEF_HELPER_2(ldq_kernel, void, i64, i64)
-DEF_HELPER_2(ldl_data, void, i64, i64)
-DEF_HELPER_2(ldq_data, void, i64, i64)
-DEF_HELPER_2(stl_raw, void, i64, i64)
-DEF_HELPER_2(stq_raw, void, i64, i64)
-DEF_HELPER_2(stl_c_raw, i64, i64, i64)
-DEF_HELPER_2(stq_c_raw, i64, i64, i64)
+
+DEF_HELPER_1(ldl_phys, i64, i64)
+DEF_HELPER_1(ldq_phys, i64, i64)
+DEF_HELPER_1(ldl_l_phys, i64, i64)
+DEF_HELPER_1(ldq_l_phys, i64, i64)
+DEF_HELPER_2(stl_phys, void, i64, i64)
+DEF_HELPER_2(stq_phys, void, i64, i64)
+DEF_HELPER_2(stl_c_phys, i64, i64, i64)
+DEF_HELPER_2(stq_c_phys, i64, i64, i64)
 #endif
 
 #include "def-helper.h"
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 4ccb10b..a90c7a6 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1188,150 +1188,71 @@ void helper_mtpr (int iprn, uint64_t val)
 {
     cpu_alpha_mtpr(env, iprn, val, NULL);
 }
-
-void helper_set_alt_mode (void)
-{
-    env->saved_mode = env->ps & 0xC;
-    env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC);
-}
-
-void helper_restore_mode (void)
-{
-    env->ps = (env->ps & ~0xC) | env->saved_mode;
-}
-
 #endif
 
 /*****************************************************************************/
 /* Softmmu support */
 #if !defined (CONFIG_USER_ONLY)
-
-/* XXX: the two following helpers are pure hacks.
- *      Hopefully, we emulate the PALcode, then we should never see
- *      HW_LD / HW_ST instructions.
- */
-uint64_t helper_ld_virt_to_phys (uint64_t virtaddr)
-{
-    uint64_t tlb_addr, physaddr;
-    int index, mmu_idx;
-    void *retaddr;
-
-    mmu_idx = cpu_mmu_index(env);
-    index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
-    tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
-    if ((virtaddr & TARGET_PAGE_MASK) ==
-        (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend;
-    } else {
-        /* the page is not in the TLB : fill it */
-        retaddr = GETPC();
-        tlb_fill(virtaddr, 0, mmu_idx, retaddr);
-        goto redo;
-    }
-    return physaddr;
-}
-
-uint64_t helper_st_virt_to_phys (uint64_t virtaddr)
-{
-    uint64_t tlb_addr, physaddr;
-    int index, mmu_idx;
-    void *retaddr;
-
-    mmu_idx = cpu_mmu_index(env);
-    index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
-    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
-    if ((virtaddr & TARGET_PAGE_MASK) ==
-        (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend;
-    } else {
-        /* the page is not in the TLB : fill it */
-        retaddr = GETPC();
-        tlb_fill(virtaddr, 1, mmu_idx, retaddr);
-        goto redo;
-    }
-    return physaddr;
-}
-
-void helper_ldl_raw(uint64_t t0, uint64_t t1)
+uint64_t helper_ldl_phys(uint64_t p)
 {
-    ldl_raw(t1, t0);
+    return (int32_t)ldl_phys(p);
 }
 
-void helper_ldq_raw(uint64_t t0, uint64_t t1)
+uint64_t helper_ldq_phys(uint64_t p)
 {
-    ldq_raw(t1, t0);
+    return ldq_phys(p);
 }
 
-void helper_ldl_l_raw(uint64_t t0, uint64_t t1)
+uint64_t helper_ldl_l_phys(uint64_t p)
 {
-    env->lock = t1;
-    ldl_raw(t1, t0);
+    env->lock_addr = p;
+    return env->lock_value = (int32_t)ldl_phys(p);
 }
 
-void helper_ldq_l_raw(uint64_t t0, uint64_t t1)
+uint64_t helper_ldq_l_phys(uint64_t p)
 {
-    env->lock = t1;
-    ldl_raw(t1, t0);
+    env->lock_addr = p;
+    return env->lock_value = ldl_phys(p);
 }
 
-void helper_ldl_kernel(uint64_t t0, uint64_t t1)
+void helper_stl_phys(uint64_t p, uint64_t v)
 {
-    ldl_kernel(t1, t0);
+    stl_phys(p, v);
 }
 
-void helper_ldq_kernel(uint64_t t0, uint64_t t1)
+void helper_stq_phys(uint64_t p, uint64_t v)
 {
-    ldq_kernel(t1, t0);
+    stq_phys(p, v);
 }
 
-void helper_ldl_data(uint64_t t0, uint64_t t1)
+uint64_t helper_stl_c_phys(uint64_t p, uint64_t v)
 {
-    ldl_data(t1, t0);
-}
+    uint64_t ret = 0;
 
-void helper_ldq_data(uint64_t t0, uint64_t t1)
-{
-    ldq_data(t1, t0);
-}
-
-void helper_stl_raw(uint64_t t0, uint64_t t1)
-{
-    stl_raw(t1, t0);
-}
-
-void helper_stq_raw(uint64_t t0, uint64_t t1)
-{
-    stq_raw(t1, t0);
-}
-
-uint64_t helper_stl_c_raw(uint64_t t0, uint64_t t1)
-{
-    uint64_t ret;
-
-    if (t1 == env->lock) {
-        stl_raw(t1, t0);
-        ret = 0;
-    } else
-        ret = 1;
-
-    env->lock = 1;
+    if (p == env->lock_addr) {
+        int32_t old = ldl_phys(p);
+        if (old == (int32_t)env->lock_value) {
+            stl_phys(p, v);
+            ret = 1;
+        }
+    }
+    env->lock_addr = -1;
 
     return ret;
 }
 
-uint64_t helper_stq_c_raw(uint64_t t0, uint64_t t1)
+uint64_t helper_stq_c_phys(uint64_t p, uint64_t v)
 {
-    uint64_t ret;
+    uint64_t ret = 0;
 
-    if (t1 == env->lock) {
-        stq_raw(t1, t0);
-        ret = 0;
-    } else
-        ret = 1;
-
-    env->lock = 1;
+    if (p == env->lock_addr) {
+        uint64_t old = ldq_phys(p);
+        if (old == env->lock_value) {
+            stq_phys(p, v);
+            ret = 1;
+        }
+    }
+    env->lock_addr = -1;
 
     return ret;
 }
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index c9fd16f..73c19d9 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -2616,27 +2616,26 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
             switch ((insn >> 12) & 0xF) {
             case 0x0:
                 /* Longword physical access (hw_ldl/p) */
-                gen_helper_ldl_raw(cpu_ir[ra], addr);
+                gen_helper_ldl_phys(cpu_ir[ra], addr);
                 break;
             case 0x1:
                 /* Quadword physical access (hw_ldq/p) */
-                gen_helper_ldq_raw(cpu_ir[ra], addr);
+                gen_helper_ldq_phys(cpu_ir[ra], addr);
                 break;
             case 0x2:
                 /* Longword physical access with lock (hw_ldl_l/p) */
-                gen_helper_ldl_l_raw(cpu_ir[ra], addr);
+                gen_helper_ldl_l_phys(cpu_ir[ra], addr);
                 break;
             case 0x3:
                 /* Quadword physical access with lock (hw_ldq_l/p) */
-                gen_helper_ldq_l_raw(cpu_ir[ra], addr);
+                gen_helper_ldq_l_phys(cpu_ir[ra], addr);
                 break;
             case 0x4:
                 /* Longword virtual PTE fetch (hw_ldl/v) */
-                tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0);
-                break;
+                goto invalid_opc;
             case 0x5:
                 /* Quadword virtual PTE fetch (hw_ldq/v) */
-                tcg_gen_qemu_ld64(cpu_ir[ra], addr, 0);
+                goto invalid_opc;
                 break;
             case 0x6:
                 /* Incpu_ir[ra]id */
@@ -2646,14 +2645,10 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
                 goto invalid_opc;
             case 0x8:
                 /* Longword virtual access (hw_ldl) */
-                gen_helper_st_virt_to_phys(addr, addr);
-                gen_helper_ldl_raw(cpu_ir[ra], addr);
-                break;
+                goto invalid_opc;
             case 0x9:
                 /* Quadword virtual access (hw_ldq) */
-                gen_helper_st_virt_to_phys(addr, addr);
-                gen_helper_ldq_raw(cpu_ir[ra], addr);
-                break;
+                goto invalid_opc;
             case 0xA:
                 /* Longword virtual access with protection check (hw_ldl/w) */
                 tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0);
@@ -2664,33 +2659,19 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
                 break;
             case 0xC:
                 /* Longword virtual access with alt access mode (hw_ldl/a)*/
-                gen_helper_set_alt_mode();
-                gen_helper_st_virt_to_phys(addr, addr);
-                gen_helper_ldl_raw(cpu_ir[ra], addr);
-                gen_helper_restore_mode();
-                break;
+                goto invalid_opc;
             case 0xD:
                 /* Quadword virtual access with alt access mode (hw_ldq/a) */
-                gen_helper_set_alt_mode();
-                gen_helper_st_virt_to_phys(addr, addr);
-                gen_helper_ldq_raw(cpu_ir[ra], addr);
-                gen_helper_restore_mode();
-                break;
+                goto invalid_opc;
             case 0xE:
                 /* Longword virtual access with alternate access mode and
-                 * protection checks (hw_ldl/wa)
-                 */
-                gen_helper_set_alt_mode();
-                gen_helper_ldl_data(cpu_ir[ra], addr);
-                gen_helper_restore_mode();
+                   protection checks (hw_ldl/wa) */
+                tcg_gen_qemu_ld32s(cpu_ir[ra], addr, MMU_USER_IDX);
                 break;
             case 0xF:
                 /* Quadword virtual access with alternate access mode and
-                 * protection checks (hw_ldq/wa)
-                 */
-                gen_helper_set_alt_mode();
-                gen_helper_ldq_data(cpu_ir[ra], addr);
-                gen_helper_restore_mode();
+                   protection checks (hw_ldq/wa) */
+                tcg_gen_qemu_ld64(cpu_ir[ra], addr, MMU_USER_IDX);
                 break;
             }
             tcg_temp_free(addr);
@@ -2940,30 +2921,26 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
             switch ((insn >> 12) & 0xF) {
             case 0x0:
                 /* Longword physical access */
-                gen_helper_stl_raw(val, addr);
+                gen_helper_stl_phys(addr, val);
                 break;
             case 0x1:
                 /* Quadword physical access */
-                gen_helper_stq_raw(val, addr);
+                gen_helper_stq_phys(addr, val);
                 break;
             case 0x2:
                 /* Longword physical access with lock */
-                gen_helper_stl_c_raw(val, val, addr);
+                gen_helper_stl_c_phys(val, addr, val);
                 break;
             case 0x3:
                 /* Quadword physical access with lock */
-                gen_helper_stq_c_raw(val, val, addr);
+                gen_helper_stq_c_phys(val, addr, val);
                 break;
             case 0x4:
                 /* Longword virtual access */
-                gen_helper_st_virt_to_phys(addr, addr);
-                gen_helper_stl_raw(val, addr);
-                break;
+                goto invalid_opc;
             case 0x5:
                 /* Quadword virtual access */
-                gen_helper_st_virt_to_phys(addr, addr);
-                gen_helper_stq_raw(val, addr);
-                break;
+                goto invalid_opc;
             case 0x6:
                 /* Invalid */
                 goto invalid_opc;
@@ -2984,18 +2961,10 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
                 goto invalid_opc;
             case 0xC:
                 /* Longword virtual access with alternate access mode */
-                gen_helper_set_alt_mode();
-                gen_helper_st_virt_to_phys(addr, addr);
-                gen_helper_stl_raw(val, addr);
-                gen_helper_restore_mode();
-                break;
+                goto invalid_opc;
             case 0xD:
                 /* Quadword virtual access with alternate access mode */
-                gen_helper_set_alt_mode();
-                gen_helper_st_virt_to_phys(addr, addr);
-                gen_helper_stl_raw(val, addr);
-                gen_helper_restore_mode();
-                break;
+                goto invalid_opc;
             case 0xE:
                 /* Invalid */
                 goto invalid_opc;
-- 
1.7.4.4

  parent reply	other threads:[~2011-05-23 20:29 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 01/26] target-alpha: Claim ownership Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 02/26] target-alpha: Disassemble EV6 PALcode instructions Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 03/26] target-alpha: Single-step properly across branches Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 04/26] target-alpha: Remove partial support for palcode emulation Richard Henderson
2011-05-23 20:28 ` Richard Henderson [this message]
2011-05-23 20:28 ` [Qemu-devel] [PATCH 06/26] target-alpha: Fix system store_conditional Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 07/26] target-alpha: Cleanup MMU modes Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 08/26] target-alpha: Merge HW_REI and HW_RET implementations Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 09/26] target-alpha: Rationalize internal processor registers Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 10/26] target-alpha: Enable the alpha-softmmu target Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 11/26] target-alpha: Tidy exception constants Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 12/26] target-alpha: Tidy up arithmetic exceptions Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 13/26] target-alpha: Use do_restore_state for " Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 14/26] target-alpha: Add various symbolic constants Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 15/26] target-alpha: Use kernel mmu_idx for pal_mode Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 16/26] target-alpha: Add IPRs to be used by the emulation PALcode Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 17/26] target-alpha: Implement do_interrupt for system mode Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 18/26] target-alpha: Swap shadow registers moving to/from PALmode Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 19/26] target-alpha: All ISA checks to use TB->FLAGS Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 20/26] target-alpha: Disable interrupts properly Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 21/26] target-alpha: Implement more CALL_PAL values inline Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 22/26] target-alpha: Implement cpu_alpha_handle_mmu_fault for system mode Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 23/26] target-alpha: Remap PIO space for 43-bit KSEG for EV6 Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 24/26] target-alpha: Trap for unassigned and unaligned addresses Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 25/26] target-alpha: Use a fixed frequency for the RPCC in system mode Richard Henderson
2011-05-23 20:28 ` [Qemu-devel] [PATCH 26/26] target-alpha: Implement TLB flush primitives Richard Henderson
2011-05-27 19:55 ` [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
2011-06-02 14:56   ` Richard Henderson
2011-06-08 19:10     ` Richard Henderson
2011-06-10 20:32       ` Edgar E. Iglesias

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=1306182526-12081-6-git-send-email-rth@twiddle.net \
    --to=rth@twiddle.net \
    --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).