All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/26] Alpha system emulation, v5
@ 2011-05-23 20:28 Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 01/26] target-alpha: Claim ownership Richard Henderson
                   ` (26 more replies)
  0 siblings, 27 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

Changes from v4 -> v5

  * Claim official ownership of the Alpha port, rather
    than leave it as "unmaintained".

  * Drop all the patches in hw/ for now.  While they're necessary
    to actually make the port work, these are the subset of the whole
    patchset for which I'm confident I'm doing the Right Thing and
    don't really need patch review.

    No mistake, patch review is still welcome but no one has posted
    *anything* substantive for v1->v4.

Please pull.


r~


The following changes since commit dcfd14b3741983c466ad92fa2ae91eeafce3e5d5:

  Delete unused tb_invalidate_page_range (2011-05-22 10:47:28 +0000)

are available in the git repository at:
  git://repo.or.cz/qemu/rth.git axp-next

Richard Henderson (26):
      target-alpha: Claim ownership.
      target-alpha: Disassemble EV6 PALcode instructions.
      target-alpha: Single-step properly across branches.
      target-alpha: Remove partial support for palcode emulation.
      target-alpha: Fix translation of PALmode memory insns.
      target-alpha: Fix system store_conditional
      target-alpha: Cleanup MMU modes.
      target-alpha: Merge HW_REI and HW_RET implementations.
      target-alpha: Rationalize internal processor registers.
      target-alpha: Enable the alpha-softmmu target.
      target-alpha: Tidy exception constants.
      target-alpha: Tidy up arithmetic exceptions.
      target-alpha: Use do_restore_state for arithmetic exceptions.
      target-alpha: Add various symbolic constants.
      target-alpha: Use kernel mmu_idx for pal_mode.
      target-alpha: Add IPRs to be used by the emulation PALcode.
      target-alpha: Implement do_interrupt for system mode.
      target-alpha: Swap shadow registers moving to/from PALmode.
      target-alpha: All ISA checks to use TB->FLAGS.
      target-alpha: Disable interrupts properly.
      target-alpha: Implement more CALL_PAL values inline.
      target-alpha: Implement cpu_alpha_handle_mmu_fault for system mode.
      target-alpha: Remap PIO space for 43-bit KSEG for EV6.
      target-alpha: Trap for unassigned and unaligned addresses.
      target-alpha: Use a fixed frequency for the RPCC in system mode.
      target-alpha: Implement TLB flush primitives.

 MAINTAINERS                       |    4 +-
 Makefile.target                   |    3 +-
 alpha-dis.c                       |    4 -
 configure                         |    1 +
 cpu-exec.c                        |   33 +-
 default-configs/alpha-softmmu.mak |    9 +
 dis-asm.h                         |    3 +
 disas.c                           |    2 +-
 exec-all.h                        |    2 +-
 exec.c                            |   12 +-
 hw/alpha_palcode.c                | 1048 -------------------------------------
 linux-user/main.c                 |   50 +--
 target-alpha/cpu.h                |  375 ++++++--------
 target-alpha/exec.h               |   12 +-
 target-alpha/helper.c             |  589 +++++++++------------
 target-alpha/helper.h             |   32 +-
 target-alpha/machine.c            |   87 +++
 target-alpha/op_helper.c          |  278 +++++------
 target-alpha/translate.c          |  804 ++++++++++++++++------------
 19 files changed, 1179 insertions(+), 2169 deletions(-)
 create mode 100644 default-configs/alpha-softmmu.mak
 delete mode 100644 hw/alpha_palcode.c
 create mode 100644 target-alpha/machine.c

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 01/26] target-alpha: Claim ownership.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
@ 2011-05-23 20:28 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 02/26] target-alpha: Disassemble EV6 PALcode instructions Richard Henderson
                   ` (25 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

I've been maintaining this port for a while now.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 MAINTAINERS |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index e6f853d..35d4496 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -56,8 +56,8 @@ M: Paul Brook <paul@codesourcery.com>
 Guest CPU cores (TCG):
 ----------------------
 Alpha
-M: qemu-devel@nongnu.org
-S: Orphan
+M: Richard Henderson <rth@twiddle.net>
+S: Maintained
 F: target-alpha/
 
 ARM
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 02/26] target-alpha: Disassemble EV6 PALcode instructions.
  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 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 03/26] target-alpha: Single-step properly across branches Richard Henderson
                   ` (24 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

The QEMU emulation PALcode will use EV6 PALcode insns regardless
of the "real" cpu instruction set being emulated.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 alpha-dis.c |    4 ----
 dis-asm.h   |    3 +++
 disas.c     |    2 +-
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/alpha-dis.c b/alpha-dis.c
index 8a2411e..ae331b3 100644
--- a/alpha-dis.c
+++ b/alpha-dis.c
@@ -238,10 +238,6 @@ extern const unsigned alpha_num_operands;
 #define AXP_REG_SP	30
 #define AXP_REG_ZERO	31
 
-#define bfd_mach_alpha_ev4  0x10
-#define bfd_mach_alpha_ev5  0x20
-#define bfd_mach_alpha_ev6  0x30
-
 enum bfd_reloc_code_real {
     BFD_RELOC_23_PCREL_S2,
     BFD_RELOC_ALPHA_HINT
diff --git a/dis-asm.h b/dis-asm.h
index 296537a..5b07d7f 100644
--- a/dis-asm.h
+++ b/dis-asm.h
@@ -184,6 +184,9 @@ enum bfd_architecture
 #define bfd_mach_sh5        0x50
   bfd_arch_alpha,      /* Dec Alpha */
 #define bfd_mach_alpha 1
+#define bfd_mach_alpha_ev4  0x10
+#define bfd_mach_alpha_ev5  0x20
+#define bfd_mach_alpha_ev6  0x30
   bfd_arch_arm,        /* Advanced Risc Machines ARM */
 #define bfd_mach_arm_unknown	0
 #define bfd_mach_arm_2		1
diff --git a/disas.c b/disas.c
index 223606c..d208c52 100644
--- a/disas.c
+++ b/disas.c
@@ -205,7 +205,7 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
     disasm_info.mach = bfd_mach_sh4;
     print_insn = print_insn_sh;
 #elif defined(TARGET_ALPHA)
-    disasm_info.mach = bfd_mach_alpha;
+    disasm_info.mach = bfd_mach_alpha_ev6;
     print_insn = print_insn_alpha;
 #elif defined(TARGET_CRIS)
     if (flags != 32) {
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 03/26] target-alpha: Single-step properly across branches.
  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 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 04/26] target-alpha: Remove partial support for palcode emulation Richard Henderson
                   ` (23 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

We were failing to generate EXC_DEBUG in the EXIT_PC_UPDATED path.
This caused us not to stop at the instruction after a branch, but
on the instruction afterward.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/translate.c |   35 ++++++++++++++++++++---------------
 1 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 456ba51..194a286 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -147,17 +147,21 @@ static void alpha_translate_init(void)
     done_init = 1;
 }
 
-static ExitStatus gen_excp(DisasContext *ctx, int exception, int error_code)
+static void gen_excp_1(int exception, int error_code)
 {
     TCGv_i32 tmp1, tmp2;
 
-    tcg_gen_movi_i64(cpu_pc, ctx->pc);
     tmp1 = tcg_const_i32(exception);
     tmp2 = tcg_const_i32(error_code);
     gen_helper_excp(tmp1, tmp2);
     tcg_temp_free_i32(tmp2);
     tcg_temp_free_i32(tmp1);
+}
 
+static ExitStatus gen_excp(DisasContext *ctx, int exception, int error_code)
+{
+    tcg_gen_movi_i64(cpu_pc, ctx->pc);
+    gen_excp_1(exception, error_code);
     return EXIT_NORETURN;
 }
 
@@ -3211,18 +3215,15 @@ static inline void gen_intermediate_code_internal(CPUState *env,
         ctx.pc += 4;
         ret = translate_one(ctxp, insn);
 
-        if (ret == NO_EXIT) {
-            /* If we reach a page boundary, are single stepping,
-               or exhaust instruction count, stop generation.  */
-            if (env->singlestep_enabled) {
-                gen_excp(&ctx, EXCP_DEBUG, 0);
-                ret = EXIT_PC_UPDATED;
-            } else if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0
-                       || gen_opc_ptr >= gen_opc_end
-                       || num_insns >= max_insns
-                       || singlestep) {
-                ret = EXIT_PC_STALE;
-            }
+        /* If we reach a page boundary, are single stepping,
+           or exhaust instruction count, stop generation.  */
+        if (ret == NO_EXIT
+            && ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0
+                || gen_opc_ptr >= gen_opc_end
+                || num_insns >= max_insns
+                || singlestep
+                || env->singlestep_enabled)) {
+            ret = EXIT_PC_STALE;
         }
     } while (ret == NO_EXIT);
 
@@ -3238,7 +3239,11 @@ static inline void gen_intermediate_code_internal(CPUState *env,
         tcg_gen_movi_i64(cpu_pc, ctx.pc);
         /* FALLTHRU */
     case EXIT_PC_UPDATED:
-        tcg_gen_exit_tb(0);
+        if (env->singlestep_enabled) {
+            gen_excp_1(EXCP_DEBUG, 0);
+        } else {
+            tcg_gen_exit_tb(0);
+        }
         break;
     default:
         abort();
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 04/26] target-alpha: Remove partial support for palcode emulation.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (2 preceding siblings ...)
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 03/26] target-alpha: Single-step properly across branches Richard Henderson
@ 2011-05-23 20:28 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 05/26] target-alpha: Fix translation of PALmode memory insns Richard Henderson
                   ` (22 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

This code does not work, and will be replaced by a bios image.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 Makefile.target          |    2 +-
 hw/alpha_palcode.c       | 1048 ----------------------------------------------
 target-alpha/cpu.h       |   35 --
 target-alpha/helper.c    |    2 +-
 target-alpha/translate.c |    2 -
 5 files changed, 2 insertions(+), 1087 deletions(-)
 delete mode 100644 hw/alpha_palcode.c

diff --git a/Makefile.target b/Makefile.target
index 2e281a4..9f67ae7 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -376,7 +376,7 @@ obj-m68k-y += m68k-semi.o dummy_m68k.o
 
 obj-s390x-y = s390-virtio-bus.o s390-virtio.o
 
-obj-alpha-y = alpha_palcode.o
+obj-alpha-y =
 
 main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
diff --git a/hw/alpha_palcode.c b/hw/alpha_palcode.c
deleted file mode 100644
index 033b542..0000000
--- a/hw/alpha_palcode.c
+++ /dev/null
@@ -1,1048 +0,0 @@
-/*
- *  Alpha emulation - PALcode emulation for qemu.
- *
- *  Copyright (c) 2007 Jocelyn Mayer
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-
-/* Shared handlers */
-static void pal_reset (CPUState *env);
-/* Console handlers */
-static void pal_console_call (CPUState *env, uint32_t palcode);
-/* OpenVMS handlers */
-static void pal_openvms_call (CPUState *env, uint32_t palcode);
-/* UNIX / Linux handlers */
-static void pal_unix_call (CPUState *env, uint32_t palcode);
-
-pal_handler_t pal_handlers[] = {
-    /* Console handler */
-    {
-        .reset = &pal_reset,
-        .call_pal = &pal_console_call,
-    },
-    /* OpenVMS handler */
-    {
-        .reset = &pal_reset,
-        .call_pal = &pal_openvms_call,
-    },
-    /* UNIX / Linux handler */
-    {
-        .reset = &pal_reset,
-        .call_pal = &pal_unix_call,
-    },
-};
-
-#if 0
-/* One must explicitly check that the TB is valid and the FOE bit is reset */
-static void update_itb (void)
-{
-    /* This writes into a temp register, not the actual one */
-    mtpr(TB_TAG);
-    mtpr(TB_CTL);
-    /* This commits the TB update */
-    mtpr(ITB_PTE);
-}
-
-static void update_dtb (void);
-{
-    mtpr(TB_CTL);
-    /* This write into a temp register, not the actual one */
-    mtpr(TB_TAG);
-    /* This commits the TB update */
-    mtpr(DTB_PTE);
-}
-#endif
-
-static void pal_reset (CPUState *env)
-{
-}
-
-static void do_swappal (CPUState *env, uint64_t palid)
-{
-    pal_handler_t *pal_handler;
-
-    switch (palid) {
-    case 0 ... 2:
-        pal_handler = &pal_handlers[palid];
-        env->pal_handler = pal_handler;
-        env->ipr[IPR_PAL_BASE] = -1ULL;
-        (*pal_handler->reset)(env);
-        break;
-    case 3 ... 255:
-        /* Unknown identifier */
-        env->ir[0] = 1;
-        return;
-    default:
-        /* We were given the entry point address */
-        env->pal_handler = NULL;
-        env->ipr[IPR_PAL_BASE] = palid;
-        env->pc = env->ipr[IPR_PAL_BASE];
-        cpu_loop_exit();
-    }
-}
-
-static void pal_console_call (CPUState *env, uint32_t palcode)
-{
-    uint64_t palid;
-
-    if (palcode < 0x00000080) {
-        /* Privileged palcodes */
-        if (!(env->ps >> 3)) {
-            /* TODO: generate privilege exception */
-        }
-    }
-    switch (palcode) {
-    case 0x00000000:
-        /* HALT */
-        /* REQUIRED */
-        break;
-    case 0x00000001:
-        /* CFLUSH */
-        break;
-    case 0x00000002:
-        /* DRAINA */
-        /* REQUIRED */
-        /* Implemented as no-op */
-        break;
-    case 0x00000009:
-        /* CSERVE */
-        /* REQUIRED */
-        break;
-    case 0x0000000A:
-        /* SWPPAL */
-        /* REQUIRED */
-        palid = env->ir[16];
-        do_swappal(env, palid);
-        break;
-    case 0x00000080:
-        /* BPT */
-        /* REQUIRED */
-        break;
-    case 0x00000081:
-        /* BUGCHK */
-        /* REQUIRED */
-        break;
-    case 0x00000086:
-        /* IMB */
-        /* REQUIRED */
-        /* Implemented as no-op */
-        break;
-    case 0x0000009E:
-        /* RDUNIQUE */
-        /* REQUIRED */
-        break;
-    case 0x0000009F:
-        /* WRUNIQUE */
-        /* REQUIRED */
-        break;
-    case 0x000000AA:
-        /* GENTRAP */
-        /* REQUIRED */
-        break;
-    default:
-        break;
-    }
-}
-
-static void pal_openvms_call (CPUState *env, uint32_t palcode)
-{
-    uint64_t palid, val, oldval;
-
-    if (palcode < 0x00000080) {
-        /* Privileged palcodes */
-        if (!(env->ps >> 3)) {
-            /* TODO: generate privilege exception */
-        }
-    }
-    switch (palcode) {
-    case 0x00000000:
-        /* HALT */
-        /* REQUIRED */
-        break;
-    case 0x00000001:
-        /* CFLUSH */
-        break;
-    case 0x00000002:
-        /* DRAINA */
-        /* REQUIRED */
-        /* Implemented as no-op */
-        break;
-    case 0x00000003:
-        /* LDQP */
-        break;
-    case 0x00000004:
-        /* STQP */
-        break;
-    case 0x00000005:
-        /* SWPCTX */
-        break;
-    case 0x00000006:
-        /* MFPR_ASN */
-        if (cpu_alpha_mfpr(env, IPR_ASN, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000007:
-        /* MTPR_ASTEN */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_ASTEN, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000008:
-        /* MTPR_ASTSR */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_ASTSR, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000009:
-        /* CSERVE */
-        /* REQUIRED */
-        break;
-    case 0x0000000A:
-        /* SWPPAL */
-        /* REQUIRED */
-        palid = env->ir[16];
-        do_swappal(env, palid);
-        break;
-    case 0x0000000B:
-        /* MFPR_FEN */
-        if (cpu_alpha_mfpr(env, IPR_FEN, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000000C:
-        /* MTPR_FEN */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_FEN, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000000D:
-        /* MTPR_IPIR */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_IPIR, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000000E:
-        /* MFPR_IPL */
-        if (cpu_alpha_mfpr(env, IPR_IPL, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000000F:
-        /* MTPR_IPL */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_IPL, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000010:
-        /* MFPR_MCES */
-        if (cpu_alpha_mfpr(env, IPR_MCES, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000011:
-        /* MTPR_MCES */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_MCES, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000012:
-        /* MFPR_PCBB */
-        if (cpu_alpha_mfpr(env, IPR_PCBB, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000013:
-        /* MFPR_PRBR */
-        if (cpu_alpha_mfpr(env, IPR_PRBR, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000014:
-        /* MTPR_PRBR */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_PRBR, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000015:
-        /* MFPR_PTBR */
-        if (cpu_alpha_mfpr(env, IPR_PTBR, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000016:
-        /* MFPR_SCBB */
-        if (cpu_alpha_mfpr(env, IPR_SCBB, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000017:
-        /* MTPR_SCBB */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_SCBB, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000018:
-        /* MTPR_SIRR */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_SIRR, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000019:
-        /* MFPR_SISR */
-        if (cpu_alpha_mfpr(env, IPR_SISR, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000001A:
-        /* MFPR_TBCHK */
-        if (cpu_alpha_mfpr(env, IPR_TBCHK, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000001B:
-        /* MTPR_TBIA */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_TBIA, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000001C:
-        /* MTPR_TBIAP */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_TBIAP, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000001D:
-        /* MTPR_TBIS */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_TBIS, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000001E:
-        /* MFPR_ESP */
-        if (cpu_alpha_mfpr(env, IPR_ESP, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000001F:
-        /* MTPR_ESP */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_ESP, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000020:
-        /* MFPR_SSP */
-        if (cpu_alpha_mfpr(env, IPR_SSP, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000021:
-        /* MTPR_SSP */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_SSP, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000022:
-        /* MFPR_USP */
-        if (cpu_alpha_mfpr(env, IPR_USP, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000023:
-        /* MTPR_USP */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_USP, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000024:
-        /* MTPR_TBISD */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_TBISD, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000025:
-        /* MTPR_TBISI */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_TBISI, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000026:
-        /* MFPR_ASTEN */
-        if (cpu_alpha_mfpr(env, IPR_ASTEN, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000027:
-        /* MFPR_ASTSR */
-        if (cpu_alpha_mfpr(env, IPR_ASTSR, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000029:
-        /* MFPR_VPTB */
-        if (cpu_alpha_mfpr(env, IPR_VPTB, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000002A:
-        /* MTPR_VPTB */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_VPTB, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000002B:
-        /* MTPR_PERFMON */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_PERFMON, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000002E:
-        /* MTPR_DATFX */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_DATFX, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000003E:
-        /* WTINT */
-        break;
-    case 0x0000003F:
-        /* MFPR_WHAMI */
-        if (cpu_alpha_mfpr(env, IPR_WHAMI, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000080:
-        /* BPT */
-        /* REQUIRED */
-        break;
-    case 0x00000081:
-        /* BUGCHK */
-        /* REQUIRED */
-        break;
-    case 0x00000082:
-        /* CHME */
-        break;
-    case 0x00000083:
-        /* CHMK */
-        break;
-    case 0x00000084:
-        /* CHMS */
-        break;
-    case 0x00000085:
-        /* CHMU */
-        break;
-    case 0x00000086:
-        /* IMB */
-        /* REQUIRED */
-        /* Implemented as no-op */
-        break;
-    case 0x00000087:
-        /* INSQHIL */
-        break;
-    case 0x00000088:
-        /* INSQTIL */
-        break;
-    case 0x00000089:
-        /* INSQHIQ */
-        break;
-    case 0x0000008A:
-        /* INSQTIQ */
-        break;
-    case 0x0000008B:
-        /* INSQUEL */
-        break;
-    case 0x0000008C:
-        /* INSQUEQ */
-        break;
-    case 0x0000008D:
-        /* INSQUEL/D */
-        break;
-    case 0x0000008E:
-        /* INSQUEQ/D */
-        break;
-    case 0x0000008F:
-        /* PROBER */
-        break;
-    case 0x00000090:
-        /* PROBEW */
-        break;
-    case 0x00000091:
-        /* RD_PS */
-        break;
-    case 0x00000092:
-        /* REI */
-        break;
-    case 0x00000093:
-        /* REMQHIL */
-        break;
-    case 0x00000094:
-        /* REMQTIL */
-        break;
-    case 0x00000095:
-        /* REMQHIQ */
-        break;
-    case 0x00000096:
-        /* REMQTIQ */
-        break;
-    case 0x00000097:
-        /* REMQUEL */
-        break;
-    case 0x00000098:
-        /* REMQUEQ */
-        break;
-    case 0x00000099:
-        /* REMQUEL/D */
-        break;
-    case 0x0000009A:
-        /* REMQUEQ/D */
-        break;
-    case 0x0000009B:
-        /* SWASTEN */
-        break;
-    case 0x0000009C:
-        /* WR_PS_SW */
-        break;
-    case 0x0000009D:
-        /* RSCC */
-        break;
-    case 0x0000009E:
-        /* READ_UNQ */
-        /* REQUIRED */
-        break;
-    case 0x0000009F:
-        /* WRITE_UNQ */
-        /* REQUIRED */
-        break;
-    case 0x000000A0:
-        /* AMOVRR */
-        break;
-    case 0x000000A1:
-        /* AMOVRM */
-        break;
-    case 0x000000A2:
-        /* INSQHILR */
-        break;
-    case 0x000000A3:
-        /* INSQTILR */
-        break;
-    case 0x000000A4:
-        /* INSQHIQR */
-        break;
-    case 0x000000A5:
-        /* INSQTIQR */
-        break;
-    case 0x000000A6:
-        /* REMQHILR */
-        break;
-    case 0x000000A7:
-        /* REMQTILR */
-        break;
-    case 0x000000A8:
-        /* REMQHIQR */
-        break;
-    case 0x000000A9:
-        /* REMQTIQR */
-        break;
-    case 0x000000AA:
-        /* GENTRAP */
-        /* REQUIRED */
-        break;
-    case 0x000000AE:
-        /* CLRFEN */
-        break;
-    default:
-        break;
-    }
-}
-
-static void pal_unix_call (CPUState *env, uint32_t palcode)
-{
-    uint64_t palid, val, oldval;
-
-    if (palcode < 0x00000080) {
-        /* Privileged palcodes */
-        if (!(env->ps >> 3)) {
-            /* TODO: generate privilege exception */
-        }
-    }
-    switch (palcode) {
-    case 0x00000000:
-        /* HALT */
-        /* REQUIRED */
-        break;
-    case 0x00000001:
-        /* CFLUSH */
-        break;
-    case 0x00000002:
-        /* DRAINA */
-        /* REQUIRED */
-        /* Implemented as no-op */
-        break;
-    case 0x00000009:
-        /* CSERVE */
-        /* REQUIRED */
-        break;
-    case 0x0000000A:
-        /* SWPPAL */
-        /* REQUIRED */
-        palid = env->ir[16];
-        do_swappal(env, palid);
-        break;
-    case 0x0000000D:
-        /* WRIPIR */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_IPIR, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000010:
-        /* RDMCES */
-        if (cpu_alpha_mfpr(env, IPR_MCES, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000011:
-        /* WRMCES */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_MCES, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000002B:
-        /* WRFEN */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_PERFMON, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000002D:
-        /* WRVPTPTR */
-        break;
-    case 0x00000030:
-        /* SWPCTX */
-        break;
-    case 0x00000031:
-        /* WRVAL */
-        break;
-    case 0x00000032:
-        /* RDVAL */
-        break;
-    case 0x00000033:
-        /* TBI */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_TBIS, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000034:
-        /* WRENT */
-        break;
-    case 0x00000035:
-        /* SWPIPL */
-        break;
-    case 0x00000036:
-        /* RDPS */
-        break;
-    case 0x00000037:
-        /* WRKGP */
-        break;
-    case 0x00000038:
-        /* WRUSP */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_USP, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x00000039:
-        /* WRPERFMON */
-        val = env->ir[16];
-        if (cpu_alpha_mtpr(env, IPR_PERFMON, val, &oldval) == 1)
-            env->ir[0] = val;
-        break;
-    case 0x0000003A:
-        /* RDUSP */
-        if (cpu_alpha_mfpr(env, IPR_USP, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000003C:
-        /* WHAMI */
-        if (cpu_alpha_mfpr(env, IPR_WHAMI, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x0000003D:
-        /* RETSYS */
-        break;
-    case 0x0000003E:
-        /* WTINT */
-        break;
-    case 0x0000003F:
-        /* RTI */
-        if (cpu_alpha_mfpr(env, IPR_WHAMI, &val) == 0)
-            env->ir[0] = val;
-        break;
-    case 0x00000080:
-        /* BPT */
-        /* REQUIRED */
-        break;
-    case 0x00000081:
-        /* BUGCHK */
-        /* REQUIRED */
-        break;
-    case 0x00000083:
-        /* CALLSYS */
-        break;
-    case 0x00000086:
-        /* IMB */
-        /* REQUIRED */
-        /* Implemented as no-op */
-        break;
-    case 0x00000092:
-        /* URTI */
-        break;
-    case 0x0000009E:
-        /* RDUNIQUE */
-        /* REQUIRED */
-        break;
-    case 0x0000009F:
-        /* WRUNIQUE */
-        /* REQUIRED */
-        break;
-    case 0x000000AA:
-        /* GENTRAP */
-        /* REQUIRED */
-        break;
-    case 0x000000AE:
-        /* CLRFEN */
-        break;
-    default:
-        break;
-    }
-}
-
-void call_pal (CPUState *env)
-{
-    pal_handler_t *pal_handler = env->pal_handler;
-
-    switch (env->exception_index) {
-    case EXCP_RESET:
-        (*pal_handler->reset)(env);
-        break;
-    case EXCP_MCHK:
-        (*pal_handler->machine_check)(env);
-        break;
-    case EXCP_ARITH:
-        (*pal_handler->arithmetic)(env);
-        break;
-    case EXCP_INTERRUPT:
-        (*pal_handler->interrupt)(env);
-        break;
-    case EXCP_DFAULT:
-        (*pal_handler->dfault)(env);
-        break;
-    case EXCP_DTB_MISS_PAL:
-        (*pal_handler->dtb_miss_pal)(env);
-        break;
-    case EXCP_DTB_MISS_NATIVE:
-        (*pal_handler->dtb_miss_native)(env);
-        break;
-    case EXCP_UNALIGN:
-        (*pal_handler->unalign)(env);
-        break;
-    case EXCP_ITB_MISS:
-        (*pal_handler->itb_miss)(env);
-        break;
-    case EXCP_ITB_ACV:
-        (*pal_handler->itb_acv)(env);
-        break;
-    case EXCP_OPCDEC:
-        (*pal_handler->opcdec)(env);
-        break;
-    case EXCP_FEN:
-        (*pal_handler->fen)(env);
-        break;
-    default:
-        if (env->exception_index >= EXCP_CALL_PAL &&
-            env->exception_index < EXCP_CALL_PALP) {
-            /* Unprivileged PAL call */
-            (*pal_handler->call_pal)
-                (env, (env->exception_index - EXCP_CALL_PAL) >> 6);
-        } else if (env->exception_index >= EXCP_CALL_PALP &&
-                   env->exception_index < EXCP_CALL_PALE) {
-            /* Privileged PAL call */
-            (*pal_handler->call_pal)
-                (env, ((env->exception_index - EXCP_CALL_PALP) >> 6) + 0x80);
-        } else {
-            /* Should never happen */
-        }
-        break;
-    }
-    env->ipr[IPR_EXC_ADDR] &= ~1;
-}
-
-void pal_init (CPUState *env)
-{
-    do_swappal(env, 0);
-}
-
-#if 0
-static uint64_t get_ptebase (CPUState *env, uint64_t vaddr)
-{
-    uint64_t virbnd, ptbr;
-
-    if ((env->features & FEATURE_VIRBND)) {
-        cpu_alpha_mfpr(env, IPR_VIRBND, &virbnd);
-        if (vaddr >= virbnd)
-            cpu_alpha_mfpr(env, IPR_SYSPTBR, &ptbr);
-        else
-            cpu_alpha_mfpr(env, IPR_PTBR, &ptbr);
-    } else {
-        cpu_alpha_mfpr(env, IPR_PTBR, &ptbr);
-    }
-
-    return ptbr;
-}
-
-static int get_page_bits (CPUState *env)
-{
-    /* XXX */
-    return 13;
-}
-
-static int get_pte (uint64_t *pfnp, int *zbitsp, int *protp,
-                    uint64_t ptebase, int page_bits, uint64_t level,
-                    int mmu_idx, int rw)
-{
-    uint64_t pteaddr, pte, pfn;
-    uint8_t gh;
-    int ure, uwe, kre, kwe, foE, foR, foW, v, ret, ar, is_user;
-
-    /* XXX: TOFIX */
-    is_user = mmu_idx == MMU_USER_IDX;
-    pteaddr = (ptebase << page_bits) + (8 * level);
-    pte = ldq_raw(pteaddr);
-    /* Decode all interresting PTE fields */
-    pfn = pte >> 32;
-    uwe = (pte >> 13) & 1;
-    kwe = (pte >> 12) & 1;
-    ure = (pte >> 9) & 1;
-    kre = (pte >> 8) & 1;
-    gh = (pte >> 5) & 3;
-    foE = (pte >> 3) & 1;
-    foW = (pte >> 2) & 1;
-    foR = (pte >> 1) & 1;
-    v = pte & 1;
-    ret = 0;
-    if (!v)
-        ret = 0x1;
-    /* Check access rights */
-    ar = 0;
-    if (is_user) {
-        if (ure)
-            ar |= PAGE_READ;
-        if (uwe)
-            ar |= PAGE_WRITE;
-        if (rw == 1 && !uwe)
-            ret |= 0x2;
-        if (rw != 1 && !ure)
-            ret |= 0x2;
-    } else {
-        if (kre)
-            ar |= PAGE_READ;
-        if (kwe)
-            ar |= PAGE_WRITE;
-        if (rw == 1 && !kwe)
-            ret |= 0x2;
-        if (rw != 1 && !kre)
-            ret |= 0x2;
-    }
-    if (rw == 0 && foR)
-        ret |= 0x4;
-    if (rw == 2 && foE)
-        ret |= 0x8;
-    if (rw == 1 && foW)
-        ret |= 0xC;
-    *pfnp = pfn;
-    if (zbitsp != NULL)
-        *zbitsp = page_bits + (3 * gh);
-    if (protp != NULL)
-        *protp = ar;
-
-    return ret;
-}
-
-static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot,
-                           uint64_t ptebase, int page_bits,
-                           uint64_t vaddr, int mmu_idx, int rw)
-{
-    uint64_t pfn, page_mask, lvl_mask, level1, level2, level3;
-    int lvl_bits, ret;
-
-    page_mask = (1ULL << page_bits) - 1ULL;
-    lvl_bits = page_bits - 3;
-    lvl_mask = (1ULL << lvl_bits) - 1ULL;
-    level3 = (vaddr >> page_bits) & lvl_mask;
-    level2 = (vaddr >> (page_bits + lvl_bits)) & lvl_mask;
-    level1 = (vaddr >> (page_bits + (2 * lvl_bits))) & lvl_mask;
-    /* Level 1 PTE */
-    ret = get_pte(&pfn, NULL, NULL, ptebase, page_bits, level1, 0, 0);
-    switch (ret) {
-    case 3:
-        /* Access violation */
-        return 2;
-    case 2:
-        /* translation not valid */
-        return 1;
-    default:
-        /* OK */
-        break;
-    }
-    /* Level 2 PTE */
-    ret = get_pte(&pfn, NULL, NULL, pfn, page_bits, level2, 0, 0);
-    switch (ret) {
-    case 3:
-        /* Access violation */
-        return 2;
-    case 2:
-        /* translation not valid */
-        return 1;
-    default:
-        /* OK */
-        break;
-    }
-    /* Level 3 PTE */
-    ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, mmu_idx, rw);
-    if (ret & 0x1) {
-        /* Translation not valid */
-        ret = 1;
-    } else if (ret & 2) {
-        /* Access violation */
-        ret = 2;
-    } else {
-        switch (ret & 0xC) {
-        case 0:
-            /* OK */
-            ret = 0;
-            break;
-        case 0x4:
-            /* Fault on read */
-            ret = 3;
-            break;
-        case 0x8:
-            /* Fault on execute */
-            ret = 4;
-            break;
-        case 0xC:
-            /* Fault on write */
-            ret = 5;
-            break;
-        }
-    }
-    *paddr = (pfn << page_bits) | (vaddr & page_mask);
-
-    return 0;
-}
-
-static int virtual_to_physical (CPUState *env, uint64_t *physp,
-                                int *zbitsp, int *protp,
-                                uint64_t virtual, int mmu_idx, int rw)
-{
-    uint64_t sva, ptebase;
-    int seg, page_bits, ret;
-
-    sva = ((int64_t)(virtual << (64 - VA_BITS))) >> (64 - VA_BITS);
-    if (sva != virtual)
-        seg = -1;
-    else
-        seg = sva >> (VA_BITS - 2);
-    virtual &= ~(0xFFFFFC0000000000ULL << (VA_BITS - 43));
-    ptebase = get_ptebase(env, virtual);
-    page_bits = get_page_bits(env);
-    ret = 0;
-    switch (seg) {
-    case 0:
-        /* seg1: 3 levels of PTE */
-        ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, mmu_idx, rw);
-        break;
-    case 1:
-        /* seg1: 2 levels of PTE */
-        ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, mmu_idx, rw);
-        break;
-    case 2:
-        /* kernel segment */
-        if (mmu_idx != 0) {
-            ret = 2;
-        } else {
-            *physp = virtual;
-        }
-        break;
-    case 3:
-        /* seg1: TB mapped */
-        ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, mmu_idx, rw);
-        break;
-    default:
-        ret = 1;
-        break;
-    }
-
-    return ret;
-}
-
-/* XXX: code provision */
-int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
-                              int mmu_idx, int is_softmmu)
-{
-    uint64_t physical, page_size, end;
-    int prot, zbits, ret;
-
-    ret = virtual_to_physical(env, &physical, &zbits, &prot,
-                              address, mmu_idx, rw);
-
-    switch (ret) {
-    case 0:
-        /* No fault */
-        page_size = 1ULL << zbits;
-        address &= ~(page_size - 1);
-        /* FIXME: page_size should probably be passed to tlb_set_page,
-           and this loop removed.   */
-        for (end = physical + page_size; physical < end; physical += 0x1000) {
-            tlb_set_page(env, address, physical, prot, mmu_idx,
-                         TARGET_PAGE_SIZE);
-            address += 0x1000;
-        }
-        ret = 0;
-        break;
-#if 0
-    case 1:
-        env->exception_index = EXCP_DFAULT;
-        env->ipr[IPR_EXC_ADDR] = address;
-        ret = 1;
-        break;
-    case 2:
-        env->exception_index = EXCP_ACCESS_VIOLATION;
-        env->ipr[IPR_EXC_ADDR] = address;
-        ret = 1;
-        break;
-    case 3:
-        env->exception_index = EXCP_FAULT_ON_READ;
-        env->ipr[IPR_EXC_ADDR] = address;
-        ret = 1;
-        break;
-    case 4:
-        env->exception_index = EXCP_FAULT_ON_EXECUTE;
-        env->ipr[IPR_EXC_ADDR] = address;
-        ret = 1;
-    case 5:
-        env->exception_index = EXCP_FAULT_ON_WRITE;
-        env->ipr[IPR_EXC_ADDR] = address;
-        ret = 1;
-#endif
-    default:
-        /* Should never happen */
-        env->exception_index = EXCP_MCHK;
-        env->ipr[IPR_EXC_ADDR] = address;
-        ret = 1;
-        break;
-    }
-
-    return ret;
-}
-#endif
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 686fb4a..0daa556 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -319,36 +319,6 @@ enum {
 
 typedef struct CPUAlphaState CPUAlphaState;
 
-typedef struct pal_handler_t pal_handler_t;
-struct pal_handler_t {
-    /* Reset */
-    void (*reset)(CPUAlphaState *env);
-    /* Uncorrectable hardware error */
-    void (*machine_check)(CPUAlphaState *env);
-    /* Arithmetic exception */
-    void (*arithmetic)(CPUAlphaState *env);
-    /* Interrupt / correctable hardware error */
-    void (*interrupt)(CPUAlphaState *env);
-    /* Data fault */
-    void (*dfault)(CPUAlphaState *env);
-    /* DTB miss pal */
-    void (*dtb_miss_pal)(CPUAlphaState *env);
-    /* DTB miss native */
-    void (*dtb_miss_native)(CPUAlphaState *env);
-    /* Unaligned access */
-    void (*unalign)(CPUAlphaState *env);
-    /* ITB miss */
-    void (*itb_miss)(CPUAlphaState *env);
-    /* Instruction stream access violation */
-    void (*itb_acv)(CPUAlphaState *env);
-    /* Reserved or privileged opcode */
-    void (*opcdec)(CPUAlphaState *env);
-    /* Floating point exception */
-    void (*fen)(CPUAlphaState *env);
-    /* Call pal instruction */
-    void (*call_pal)(CPUAlphaState *env, uint32_t palcode);
-};
-
 #define NB_MMU_MODES 4
 
 struct CPUAlphaState {
@@ -393,7 +363,6 @@ struct CPUAlphaState {
     uint32_t features;
     uint32_t amask;
     int implver;
-    pal_handler_t *pal_handler;
 };
 
 #define cpu_init cpu_alpha_init
@@ -506,10 +475,6 @@ uint64_t cpu_alpha_load_fpcr (CPUState *env);
 void cpu_alpha_store_fpcr (CPUState *env, uint64_t val);
 int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
 int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
-#if !defined (CONFIG_USER_ONLY)
-void pal_init (CPUState *env);
-void call_pal (CPUState *env);
-#endif
 
 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 3ba4478..f7cf4ee 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -528,7 +528,7 @@ void do_interrupt (CPUState *env)
         env->pc = env->ipr[IPR_PAL_BASE] + excp;
     } else {
         /* We use emulated PALcode */
-        call_pal(env);
+        abort();
         /* Emulate REI */
         env->pc = env->ipr[IPR_EXC_ADDR] & ~7;
         env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 194a286..c9fd16f 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3335,8 +3335,6 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model)
     env->ps |= 1 << 3;
     cpu_alpha_store_fpcr(env, (FPCR_INVD | FPCR_DZED | FPCR_OVFD
                                | FPCR_UNFD | FPCR_INED | FPCR_DNOD));
-#else
-    pal_init(env);
 #endif
     env->lock_addr = -1;
 
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 05/26] target-alpha: Fix translation of PALmode memory insns.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (3 preceding siblings ...)
  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
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 06/26] target-alpha: Fix system store_conditional Richard Henderson
                   ` (21 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

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

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 06/26] target-alpha: Fix system store_conditional
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (4 preceding siblings ...)
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 05/26] target-alpha: Fix translation of PALmode memory insns Richard Henderson
@ 2011-05-23 20:28 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 07/26] target-alpha: Cleanup MMU modes Richard Henderson
                   ` (20 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

This code contained typos, as it had never been compiled.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/translate.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 73c19d9..851a045 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -326,7 +326,7 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
 #if defined(CONFIG_USER_ONLY)
     addr = cpu_lock_st_addr;
 #else
-    addr = tcg_local_new();
+    addr = tcg_temp_local_new();
 #endif
 
     if (rb != 31) {
@@ -349,7 +349,7 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
 
         lab_fail = gen_new_label();
         lab_done = gen_new_label();
-        tcg_gen_brcond(TCG_COND_NE, addr, cpu_lock_addr, lab_fail);
+        tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail);
 
         val = tcg_temp_new();
         if (quad) {
@@ -357,7 +357,7 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
         } else {
             tcg_gen_qemu_ld32s(val, addr, ctx->mem_idx);
         }
-        tcg_gen_brcond(TCG_COND_NE, val, cpu_lock_value, lab_fail);
+        tcg_gen_brcond_i64(TCG_COND_NE, val, cpu_lock_value, lab_fail);
 
         if (quad) {
             tcg_gen_qemu_st64(cpu_ir[ra], addr, ctx->mem_idx);
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 07/26] target-alpha: Cleanup MMU modes.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (5 preceding siblings ...)
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 06/26] target-alpha: Fix system store_conditional Richard Henderson
@ 2011-05-23 20:28 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 08/26] target-alpha: Merge HW_REI and HW_RET implementations Richard Henderson
                   ` (19 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

Don't bother including executive and supervisor modes.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/cpu.h       |   37 ++++++++++++++++++++++++++++---------
 target-alpha/translate.c |    7 ++++---
 2 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 0daa556..6b9deb3 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -317,9 +317,34 @@ enum {
     IPR_LAST,
 };
 
-typedef struct CPUAlphaState CPUAlphaState;
+/* MMU modes definitions */
+
+/* Alpha has 5 MMU modes: PALcode, kernel, executive, supervisor, and user.
+   The Unix PALcode only exposes the kernel and user modes; presumably
+   executive and supervisor are used by VMS.
+
+   PALcode itself uses physical mode for code and kernel mode for data;
+   there are PALmode instructions that can access data via physical mode
+   or via an os-installed "alternate mode", which is one of the 4 above.
+
+   QEMU does not currently properly distinguish between code/data when
+   looking up addresses.  To avoid having to address this issue, our
+   emulated PALcode will cheat and use the KSEG mapping for its code+data
+   rather than physical addresses.
+
+   Moreover, we're only emulating Unix PALcode, and not attempting VMS.
+
+   All of which allows us to drop all but kernel and user modes.
+   Elide the unused MMU modes to save space.  */
 
-#define NB_MMU_MODES 4
+#define NB_MMU_MODES 2
+
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_KERNEL_IDX   0
+#define MMU_USER_IDX     1
+
+typedef struct CPUAlphaState CPUAlphaState;
 
 struct CPUAlphaState {
     uint64_t ir[31];
@@ -370,15 +395,9 @@ struct CPUAlphaState {
 #define cpu_gen_code cpu_alpha_gen_code
 #define cpu_signal_handler cpu_alpha_signal_handler
 
-/* MMU modes definitions */
-#define MMU_MODE0_SUFFIX _kernel
-#define MMU_MODE1_SUFFIX _executive
-#define MMU_MODE2_SUFFIX _supervisor
-#define MMU_MODE3_SUFFIX _user
-#define MMU_USER_IDX 3
 static inline int cpu_mmu_index (CPUState *env)
 {
-    return (env->ps >> 3) & 3;
+    return (env->ps >> 3) & 1;
 }
 
 #include "cpu-all.h"
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 851a045..2c0b9c2 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1522,8 +1522,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
 #ifndef CONFIG_USER_ONLY
         if (palcode < 0x40) {
             /* Privileged PAL code */
-            if (ctx->mem_idx & 1)
+            if (ctx->mem_idx != MMU_KERNEL_IDX) {
                 goto invalid_opc;
+            }
             ret = gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0);
         }
 #endif
@@ -2651,11 +2652,11 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
                 goto invalid_opc;
             case 0xA:
                 /* Longword virtual access with protection check (hw_ldl/w) */
-                tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0);
+                tcg_gen_qemu_ld32s(cpu_ir[ra], addr, MMU_KERNEL_IDX);
                 break;
             case 0xB:
                 /* Quadword virtual access with protection check (hw_ldq/w) */
-                tcg_gen_qemu_ld64(cpu_ir[ra], addr, 0);
+                tcg_gen_qemu_ld64(cpu_ir[ra], addr, MMU_KERNEL_IDX);
                 break;
             case 0xC:
                 /* Longword virtual access with alt access mode (hw_ldl/a)*/
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 08/26] target-alpha: Merge HW_REI and HW_RET implementations.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (6 preceding siblings ...)
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 07/26] target-alpha: Cleanup MMU modes Richard Henderson
@ 2011-05-23 20:28 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 09/26] target-alpha: Rationalize internal processor registers Richard Henderson
                   ` (18 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/helper.h    |    1 -
 target-alpha/op_helper.c |   10 ----------
 target-alpha/translate.c |   19 ++++++++-----------
 3 files changed, 8 insertions(+), 22 deletions(-)

diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index f4f693a..de86ff2 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -100,7 +100,6 @@ DEF_HELPER_1(ieee_input_cmp, i64, i64)
 DEF_HELPER_1(ieee_input_s, i64, i64)
 
 #if !defined (CONFIG_USER_ONLY)
-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)
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index a90c7a6..ea11cd2 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1156,22 +1156,12 @@ uint64_t helper_cvtqg (uint64_t a)
 
 /* PALcode support special instructions */
 #if !defined (CONFIG_USER_ONLY)
-void helper_hw_rei (void)
-{
-    env->pc = env->ipr[IPR_EXC_ADDR] & ~3;
-    env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
-    env->intr_flag = 0;
-    env->lock_addr = -1;
-    /* XXX: re-enable interrupts and memory mapping */
-}
-
 void helper_hw_ret (uint64_t a)
 {
     env->pc = a & ~3;
     env->ipr[IPR_EXC_ADDR] = a & 1;
     env->intr_flag = 0;
     env->lock_addr = -1;
-    /* XXX: re-enable interrupts and memory mapping */
 }
 
 uint64_t helper_mfpr (int iprn, uint64_t val)
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 2c0b9c2..2559814 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -2876,25 +2876,22 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
         break;
 #endif
     case 0x1E:
-        /* HW_REI (PALcode) */
+        /* HW_RET (PALcode) */
 #if defined (CONFIG_USER_ONLY)
         goto invalid_opc;
 #else
         if (!ctx->pal_mode)
             goto invalid_opc;
         if (rb == 31) {
-            /* "Old" alpha */
-            gen_helper_hw_rei();
-        } else {
-            TCGv tmp;
-
-            if (ra != 31) {
-                tmp = tcg_temp_new();
-                tcg_gen_addi_i64(tmp, cpu_ir[rb], (((int64_t)insn << 51) >> 51));
-            } else
-                tmp = tcg_const_i64(((int64_t)insn << 51) >> 51);
+            /* Pre-EV6 CPUs interpreted this as HW_REI, loading the return
+               address from EXC_ADDR.  This turns out to be useful for our
+               emulation PALcode, so continue to accept it.  */
+            TCGv tmp = tcg_temp_new();
+            tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUState, ipr[IPR_EXC_ADDR]));
             gen_helper_hw_ret(tmp);
             tcg_temp_free(tmp);
+        } else {
+            gen_helper_hw_ret(cpu_ir[rb]);
         }
         ret = EXIT_PC_UPDATED;
         break;
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 09/26] target-alpha: Rationalize internal processor registers.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (7 preceding siblings ...)
  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 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 10/26] target-alpha: Enable the alpha-softmmu target Richard Henderson
                   ` (17 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

Delete all the code that tried to emulate the real IPRs of some
unnamed CPU.  Replace those with just 3 slots that we can use to
communicate trap information between the helper functions that
signal exceptions and the OS trap handler.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/main.c        |    6 +-
 target-alpha/cpu.h       |  145 ++------------------
 target-alpha/helper.c    |  349 +---------------------------------------------
 target-alpha/helper.h    |    2 -
 target-alpha/op_helper.c |   19 +---
 target-alpha/translate.c |   64 +--------
 6 files changed, 23 insertions(+), 562 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 8336639..1c985ab 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2524,9 +2524,9 @@ void cpu_loop (CPUState *env)
             env->lock_addr = -1;
             info.si_signo = TARGET_SIGSEGV;
             info.si_errno = 0;
-            info.si_code = (page_get_flags(env->ipr[IPR_EXC_ADDR]) & PAGE_VALID
+            info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID
                             ? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR);
-            info._sifields._sigfault._addr = env->ipr[IPR_EXC_ADDR];
+            info._sifields._sigfault._addr = env->trap_arg0;
             queue_signal(env, info.si_signo, &info);
             break;
         case EXCP_DTB_MISS_PAL:
@@ -2550,7 +2550,7 @@ void cpu_loop (CPUState *env)
             info.si_signo = TARGET_SIGBUS;
             info.si_errno = 0;
             info.si_code = TARGET_BUS_ADRALN;
-            info._sifields._sigfault._addr = env->ipr[IPR_EXC_ADDR];
+            info._sifields._sigfault._addr = env->trap_arg0;
             queue_signal(env, info.si_signo, &info);
             break;
         case EXCP_OPCDEC:
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 6b9deb3..be7d151 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -192,131 +192,6 @@ enum {
 
 #define SWCR_MASK  (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK | SWCR_STATUS_MASK)
 
-/* Internal processor registers */
-/* XXX: TOFIX: most of those registers are implementation dependant */
-enum {
-#if defined(CONFIG_USER_ONLY)
-    IPR_EXC_ADDR,
-    IPR_EXC_SUM,
-    IPR_EXC_MASK,
-#else
-    /* Ebox IPRs */
-    IPR_CC           = 0xC0,            /* 21264 */
-    IPR_CC_CTL       = 0xC1,            /* 21264 */
-#define IPR_CC_CTL_ENA_SHIFT 32
-#define IPR_CC_CTL_COUNTER_MASK 0xfffffff0UL
-    IPR_VA           = 0xC2,            /* 21264 */
-    IPR_VA_CTL       = 0xC4,            /* 21264 */
-#define IPR_VA_CTL_VA_48_SHIFT 1
-#define IPR_VA_CTL_VPTB_SHIFT 30
-    IPR_VA_FORM      = 0xC3,            /* 21264 */
-    /* Ibox IPRs */
-    IPR_ITB_TAG      = 0x00,            /* 21264 */
-    IPR_ITB_PTE      = 0x01,            /* 21264 */
-    IPR_ITB_IAP      = 0x02,
-    IPR_ITB_IA       = 0x03,            /* 21264 */
-    IPR_ITB_IS       = 0x04,            /* 21264 */
-    IPR_PMPC         = 0x05,
-    IPR_EXC_ADDR     = 0x06,            /* 21264 */
-    IPR_IVA_FORM     = 0x07,            /* 21264 */
-    IPR_CM           = 0x09,            /* 21264 */
-#define IPR_CM_SHIFT 3
-#define IPR_CM_MASK (3ULL << IPR_CM_SHIFT)      /* 21264 */
-    IPR_IER          = 0x0A,            /* 21264 */
-#define IPR_IER_MASK 0x0000007fffffe000ULL
-    IPR_IER_CM       = 0x0B,            /* 21264: = CM | IER */
-    IPR_SIRR         = 0x0C,            /* 21264 */
-#define IPR_SIRR_SHIFT 14
-#define IPR_SIRR_MASK 0x7fff
-    IPR_ISUM         = 0x0D,            /* 21264 */
-    IPR_HW_INT_CLR   = 0x0E,            /* 21264 */
-    IPR_EXC_SUM      = 0x0F,
-    IPR_PAL_BASE     = 0x10,
-    IPR_I_CTL        = 0x11,
-#define IPR_I_CTL_CHIP_ID_SHIFT 24      /* 21264 */
-#define IPR_I_CTL_BIST_FAIL (1 << 23)   /* 21264 */
-#define IPR_I_CTL_IC_EN_SHIFT 2         /* 21264 */
-#define IPR_I_CTL_SDE1_SHIFT 7          /* 21264 */
-#define IPR_I_CTL_HWE_SHIFT 12          /* 21264 */
-#define IPR_I_CTL_VA_48_SHIFT 15        /* 21264 */
-#define IPR_I_CTL_SPE_SHIFT 3           /* 21264 */
-#define IPR_I_CTL_CALL_PAL_R23_SHIFT 20 /* 21264 */
-    IPR_I_STAT       = 0x16,            /* 21264 */
-    IPR_IC_FLUSH     = 0x13,            /* 21264 */
-    IPR_IC_FLUSH_ASM = 0x12,            /* 21264 */
-    IPR_CLR_MAP      = 0x15,
-    IPR_SLEEP        = 0x17,
-    IPR_PCTX         = 0x40,
-    IPR_PCTX_ASN       = 0x01,  /* field */
-#define IPR_PCTX_ASN_SHIFT 39
-    IPR_PCTX_ASTER     = 0x02,  /* field */
-#define IPR_PCTX_ASTER_SHIFT 5
-    IPR_PCTX_ASTRR     = 0x04,  /* field */
-#define IPR_PCTX_ASTRR_SHIFT 9
-    IPR_PCTX_PPCE      = 0x08,  /* field */
-#define IPR_PCTX_PPCE_SHIFT 1
-    IPR_PCTX_FPE       = 0x10,  /* field */
-#define IPR_PCTX_FPE_SHIFT 2
-    IPR_PCTX_ALL       = 0x5f,  /* all fields */
-    IPR_PCTR_CTL     = 0x14,            /* 21264 */
-    /* Mbox IPRs */
-    IPR_DTB_TAG0     = 0x20,            /* 21264 */
-    IPR_DTB_TAG1     = 0xA0,            /* 21264 */
-    IPR_DTB_PTE0     = 0x21,            /* 21264 */
-    IPR_DTB_PTE1     = 0xA1,            /* 21264 */
-    IPR_DTB_ALTMODE  = 0xA6,
-    IPR_DTB_ALTMODE0 = 0x26,            /* 21264 */
-#define IPR_DTB_ALTMODE_MASK 3
-    IPR_DTB_IAP      = 0xA2,
-    IPR_DTB_IA       = 0xA3,            /* 21264 */
-    IPR_DTB_IS0      = 0x24,
-    IPR_DTB_IS1      = 0xA4,
-    IPR_DTB_ASN0     = 0x25,            /* 21264 */
-    IPR_DTB_ASN1     = 0xA5,            /* 21264 */
-#define IPR_DTB_ASN_SHIFT 56
-    IPR_MM_STAT      = 0x27,            /* 21264 */
-    IPR_M_CTL        = 0x28,            /* 21264 */
-#define IPR_M_CTL_SPE_SHIFT 1
-#define IPR_M_CTL_SPE_MASK 7
-    IPR_DC_CTL       = 0x29,            /* 21264 */
-    IPR_DC_STAT      = 0x2A,            /* 21264 */
-    /* Cbox IPRs */
-    IPR_C_DATA       = 0x2B,
-    IPR_C_SHIFT      = 0x2C,
-
-    IPR_ASN,
-    IPR_ASTEN,
-    IPR_ASTSR,
-    IPR_DATFX,
-    IPR_ESP,
-    IPR_FEN,
-    IPR_IPIR,
-    IPR_IPL,
-    IPR_KSP,
-    IPR_MCES,
-    IPR_PERFMON,
-    IPR_PCBB,
-    IPR_PRBR,
-    IPR_PTBR,
-    IPR_SCBB,
-    IPR_SISR,
-    IPR_SSP,
-    IPR_SYSPTBR,
-    IPR_TBCHK,
-    IPR_TBIA,
-    IPR_TBIAP,
-    IPR_TBIS,
-    IPR_TBISD,
-    IPR_TBISI,
-    IPR_USP,
-    IPR_VIRBND,
-    IPR_VPTB,
-    IPR_WHAMI,
-    IPR_ALT_MODE,
-#endif
-    IPR_LAST,
-};
-
 /* MMU modes definitions */
 
 /* Alpha has 5 MMU modes: PALcode, kernel, executive, supervisor, and user.
@@ -350,8 +225,6 @@ struct CPUAlphaState {
     uint64_t ir[31];
     float64 fir[31];
     uint64_t pc;
-    uint64_t ipr[IPR_LAST];
-    uint64_t ps;
     uint64_t unique;
     uint64_t lock_addr;
     uint64_t lock_st_addr;
@@ -366,10 +239,18 @@ struct CPUAlphaState {
     uint8_t fpcr_dnod;
     uint8_t fpcr_undz;
 
-    /* Used for HW_LD / HW_ST */
-    uint8_t saved_mode;
-    /* For RC and RS */
+    /* The Internal Processor Registers.  Some of these we assume always
+       exist for use in user-mode.  */
+    uint8_t ps;
     uint8_t intr_flag;
+    uint8_t pal_mode;
+
+    /* These pass data from the exception logic in the translator and
+       helpers to the OS entry point.  This is used for both system
+       emulation and user-mode.  */
+    uint64_t trap_arg0;
+    uint64_t trap_arg1;
+    uint64_t trap_arg2;
 
 #if TARGET_LONG_BITS > HOST_LONG_BITS
     /* temporary fixed-point registers
@@ -381,8 +262,6 @@ struct CPUAlphaState {
     /* Those resources are used only in Qemu core */
     CPU_COMMON
 
-    uint32_t hflags;
-
     int error_code;
 
     uint32_t features;
@@ -492,8 +371,6 @@ void do_interrupt (CPUState *env);
 
 uint64_t cpu_alpha_load_fpcr (CPUState *env);
 void cpu_alpha_store_fpcr (CPUState *env, uint64_t val);
-int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
-int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
 
 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index f7cf4ee..5c3263b 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -168,8 +168,7 @@ int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
         env->exception_index = EXCP_ITB_MISS;
     else
         env->exception_index = EXCP_DFAULT;
-    env->ipr[IPR_EXC_ADDR] = address;
-
+    env->trap_arg0 = address;
     return 1;
 }
 
@@ -188,352 +187,12 @@ target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                                 int mmu_idx, int is_softmmu)
 {
-    uint32_t opc;
-
-    if (rw == 2) {
-        /* Instruction translation buffer miss */
-        env->exception_index = EXCP_ITB_MISS;
-    } else {
-        if (env->ipr[IPR_EXC_ADDR] & 1)
-            env->exception_index = EXCP_DTB_MISS_PAL;
-        else
-            env->exception_index = EXCP_DTB_MISS_NATIVE;
-        opc = (ldl_code(env->pc) >> 21) << 4;
-        if (rw) {
-            opc |= 0x9;
-        } else {
-            opc |= 0x4;
-        }
-        env->ipr[IPR_MM_STAT] = opc;
-    }
-
-    return 1;
-}
-
-int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp)
-{
-    uint64_t hwpcb;
-    int ret = 0;
-
-    hwpcb = env->ipr[IPR_PCBB];
-    switch (iprn) {
-    case IPR_ASN:
-        if (env->features & FEATURE_ASN)
-            *valp = env->ipr[IPR_ASN];
-        else
-            *valp = 0;
-        break;
-    case IPR_ASTEN:
-        *valp = ((int64_t)(env->ipr[IPR_ASTEN] << 60)) >> 60;
-        break;
-    case IPR_ASTSR:
-        *valp = ((int64_t)(env->ipr[IPR_ASTSR] << 60)) >> 60;
-        break;
-    case IPR_DATFX:
-        /* Write only */
-        ret = -1;
-        break;
-    case IPR_ESP:
-        if (env->features & FEATURE_SPS)
-            *valp = env->ipr[IPR_ESP];
-        else
-            *valp = ldq_raw(hwpcb + 8);
-        break;
-    case IPR_FEN:
-        *valp = ((int64_t)(env->ipr[IPR_FEN] << 63)) >> 63;
-        break;
-    case IPR_IPIR:
-        /* Write-only */
-        ret = -1;
-        break;
-    case IPR_IPL:
-        *valp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59;
-        break;
-    case IPR_KSP:
-        if (!(env->ipr[IPR_EXC_ADDR] & 1)) {
-            ret = -1;
-        } else {
-            if (env->features & FEATURE_SPS)
-                *valp = env->ipr[IPR_KSP];
-            else
-                *valp = ldq_raw(hwpcb + 0);
-        }
-        break;
-    case IPR_MCES:
-        *valp = ((int64_t)(env->ipr[IPR_MCES] << 59)) >> 59;
-        break;
-    case IPR_PERFMON:
-        /* Implementation specific */
-        *valp = 0;
-        break;
-    case IPR_PCBB:
-        *valp = ((int64_t)env->ipr[IPR_PCBB] << 16) >> 16;
-        break;
-    case IPR_PRBR:
-        *valp = env->ipr[IPR_PRBR];
-        break;
-    case IPR_PTBR:
-        *valp = env->ipr[IPR_PTBR];
-        break;
-    case IPR_SCBB:
-        *valp = (int64_t)((int32_t)env->ipr[IPR_SCBB]);
-        break;
-    case IPR_SIRR:
-        /* Write-only */
-        ret = -1;
-        break;
-    case IPR_SISR:
-        *valp = (int64_t)((int16_t)env->ipr[IPR_SISR]);
-    case IPR_SSP:
-        if (env->features & FEATURE_SPS)
-            *valp = env->ipr[IPR_SSP];
-        else
-            *valp = ldq_raw(hwpcb + 16);
-        break;
-    case IPR_SYSPTBR:
-        if (env->features & FEATURE_VIRBND)
-            *valp = env->ipr[IPR_SYSPTBR];
-        else
-            ret = -1;
-        break;
-    case IPR_TBCHK:
-        if ((env->features & FEATURE_TBCHK)) {
-            /* XXX: TODO */
-            *valp = 0;
-            ret = -1;
-        } else {
-            ret = -1;
-        }
-        break;
-    case IPR_TBIA:
-        /* Write-only */
-        ret = -1;
-        break;
-    case IPR_TBIAP:
-        /* Write-only */
-        ret = -1;
-        break;
-    case IPR_TBIS:
-        /* Write-only */
-        ret = -1;
-        break;
-    case IPR_TBISD:
-        /* Write-only */
-        ret = -1;
-        break;
-    case IPR_TBISI:
-        /* Write-only */
-        ret = -1;
-        break;
-    case IPR_USP:
-        if (env->features & FEATURE_SPS)
-            *valp = env->ipr[IPR_USP];
-        else
-            *valp = ldq_raw(hwpcb + 24);
-        break;
-    case IPR_VIRBND:
-        if (env->features & FEATURE_VIRBND)
-            *valp = env->ipr[IPR_VIRBND];
-        else
-            ret = -1;
-        break;
-    case IPR_VPTB:
-        *valp = env->ipr[IPR_VPTB];
-        break;
-    case IPR_WHAMI:
-        *valp = env->ipr[IPR_WHAMI];
-        break;
-    default:
-        /* Invalid */
-        ret = -1;
-        break;
-    }
-
-    return ret;
-}
-
-int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp)
-{
-    uint64_t hwpcb, tmp64;
-    uint8_t tmp8;
-    int ret = 0;
-
-    hwpcb = env->ipr[IPR_PCBB];
-    switch (iprn) {
-    case IPR_ASN:
-        /* Read-only */
-        ret = -1;
-        break;
-    case IPR_ASTEN:
-        tmp8 = ((int8_t)(env->ipr[IPR_ASTEN] << 4)) >> 4;
-        *oldvalp = tmp8;
-        tmp8 &= val & 0xF;
-        tmp8 |= (val >> 4) & 0xF;
-        env->ipr[IPR_ASTEN] &= ~0xF;
-        env->ipr[IPR_ASTEN] |= tmp8;
-        ret = 1;
-        break;
-    case IPR_ASTSR:
-        tmp8 = ((int8_t)(env->ipr[IPR_ASTSR] << 4)) >> 4;
-        *oldvalp = tmp8;
-        tmp8 &= val & 0xF;
-        tmp8 |= (val >> 4) & 0xF;
-        env->ipr[IPR_ASTSR] &= ~0xF;
-        env->ipr[IPR_ASTSR] |= tmp8;
-        ret = 1;
-    case IPR_DATFX:
-        env->ipr[IPR_DATFX] &= ~0x1;
-        env->ipr[IPR_DATFX] |= val & 1;
-        tmp64 = ldq_raw(hwpcb + 56);
-        tmp64 &= ~0x8000000000000000ULL;
-        tmp64 |= (val & 1) << 63;
-        stq_raw(hwpcb + 56, tmp64);
-        break;
-    case IPR_ESP:
-        if (env->features & FEATURE_SPS)
-            env->ipr[IPR_ESP] = val;
-        else
-            stq_raw(hwpcb + 8, val);
-        break;
-    case IPR_FEN:
-        env->ipr[IPR_FEN] = val & 1;
-        tmp64 = ldq_raw(hwpcb + 56);
-        tmp64 &= ~1;
-        tmp64 |= val & 1;
-        stq_raw(hwpcb + 56, tmp64);
-        break;
-    case IPR_IPIR:
-        /* XXX: TODO: Send IRQ to CPU #ir[16] */
-        break;
-    case IPR_IPL:
-        *oldvalp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59;
-        env->ipr[IPR_IPL] &= ~0x1F;
-        env->ipr[IPR_IPL] |= val & 0x1F;
-        /* XXX: may issue an interrupt or ASR _now_ */
-        ret = 1;
-        break;
-    case IPR_KSP:
-        if (!(env->ipr[IPR_EXC_ADDR] & 1)) {
-            ret = -1;
-        } else {
-            if (env->features & FEATURE_SPS)
-                env->ipr[IPR_KSP] = val;
-            else
-                stq_raw(hwpcb + 0, val);
-        }
-        break;
-    case IPR_MCES:
-        env->ipr[IPR_MCES] &= ~((val & 0x7) | 0x18);
-        env->ipr[IPR_MCES] |= val & 0x18;
-        break;
-    case IPR_PERFMON:
-        /* Implementation specific */
-        *oldvalp = 0;
-        ret = 1;
-        break;
-    case IPR_PCBB:
-        /* Read-only */
-        ret = -1;
-        break;
-    case IPR_PRBR:
-        env->ipr[IPR_PRBR] = val;
-        break;
-    case IPR_PTBR:
-        /* Read-only */
-        ret = -1;
-        break;
-    case IPR_SCBB:
-        env->ipr[IPR_SCBB] = (uint32_t)val;
-        break;
-    case IPR_SIRR:
-        if (val & 0xF) {
-            env->ipr[IPR_SISR] |= 1 << (val & 0xF);
-            /* XXX: request a software interrupt _now_ */
-        }
-        break;
-    case IPR_SISR:
-        /* Read-only */
-        ret = -1;
-        break;
-    case IPR_SSP:
-        if (env->features & FEATURE_SPS)
-            env->ipr[IPR_SSP] = val;
-        else
-            stq_raw(hwpcb + 16, val);
-        break;
-    case IPR_SYSPTBR:
-        if (env->features & FEATURE_VIRBND)
-            env->ipr[IPR_SYSPTBR] = val;
-        else
-            ret = -1;
-        break;
-    case IPR_TBCHK:
-        /* Read-only */
-        ret = -1;
-        break;
-    case IPR_TBIA:
-        tlb_flush(env, 1);
-        break;
-    case IPR_TBIAP:
-        tlb_flush(env, 1);
-        break;
-    case IPR_TBIS:
-        tlb_flush_page(env, val);
-        break;
-    case IPR_TBISD:
-        tlb_flush_page(env, val);
-        break;
-    case IPR_TBISI:
-        tlb_flush_page(env, val);
-        break;
-    case IPR_USP:
-        if (env->features & FEATURE_SPS)
-            env->ipr[IPR_USP] = val;
-        else
-            stq_raw(hwpcb + 24, val);
-        break;
-    case IPR_VIRBND:
-        if (env->features & FEATURE_VIRBND)
-            env->ipr[IPR_VIRBND] = val;
-        else
-            ret = -1;
-        break;
-    case IPR_VPTB:
-        env->ipr[IPR_VPTB] = val;
-        break;
-    case IPR_WHAMI:
-        /* Read-only */
-        ret = -1;
-        break;
-    default:
-        /* Invalid */
-        ret = -1;
-        break;
-    }
-
-    return ret;
+    return 0;
 }
 
 void do_interrupt (CPUState *env)
 {
-    int excp;
-
-    env->ipr[IPR_EXC_ADDR] = env->pc | 1;
-    excp = env->exception_index;
-    env->exception_index = -1;
-    env->error_code = 0;
-    /* XXX: disable interrupts and memory mapping */
-    if (env->ipr[IPR_PAL_BASE] != -1ULL) {
-        /* We use native PALcode */
-        env->pc = env->ipr[IPR_PAL_BASE] + excp;
-    } else {
-        /* We use emulated PALcode */
-        abort();
-        /* Emulate REI */
-        env->pc = env->ipr[IPR_EXC_ADDR] & ~7;
-        env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
-        /* XXX: re-enable interrupts and memory mapping */
-    }
+    abort();
 }
 #endif
 
@@ -548,7 +207,7 @@ void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
     };
     int i;
 
-    cpu_fprintf(f, "     PC  " TARGET_FMT_lx "      PS  " TARGET_FMT_lx "\n",
+    cpu_fprintf(f, "     PC  " TARGET_FMT_lx "      PS  %02x\n",
                 env->pc, env->ps);
     for (i = 0; i < 31; i++) {
         cpu_fprintf(f, "IR%02d %s " TARGET_FMT_lx " ", i,
diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index de86ff2..9ffc372 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -101,8 +101,6 @@ DEF_HELPER_1(ieee_input_s, i64, i64)
 
 #if !defined (CONFIG_USER_ONLY)
 DEF_HELPER_1(hw_ret, void, i64)
-DEF_HELPER_2(mfpr, i64, int, i64)
-DEF_HELPER_2(mtpr, void, int, i64)
 
 DEF_HELPER_1(ldl_phys, i64, i64)
 DEF_HELPER_1(ldq_phys, i64, i64)
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index ea11cd2..73e5805 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -373,7 +373,7 @@ void helper_fp_exc_raise(uint32_t exc, uint32_t regno)
     if (exc) {
         uint32_t hw_exc = 0;
 
-        env->ipr[IPR_EXC_MASK] |= 1ull << regno;
+        env->trap_arg1 = 1ull << regno;
 
         if (exc & float_flag_invalid) {
             hw_exc |= EXC_M_INV;
@@ -1159,25 +1159,10 @@ uint64_t helper_cvtqg (uint64_t a)
 void helper_hw_ret (uint64_t a)
 {
     env->pc = a & ~3;
-    env->ipr[IPR_EXC_ADDR] = a & 1;
+    env->pal_mode = a & 1;
     env->intr_flag = 0;
     env->lock_addr = -1;
 }
-
-uint64_t helper_mfpr (int iprn, uint64_t val)
-{
-    uint64_t tmp;
-
-    if (cpu_alpha_mfpr(env, iprn, &tmp) == 0)
-        val = tmp;
-
-    return val;
-}
-
-void helper_mtpr (int iprn, uint64_t val)
-{
-    cpu_alpha_mtpr(env, iprn, val, NULL);
-}
 #endif
 
 /*****************************************************************************/
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 2559814..fe0ae96 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -2576,18 +2576,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
         break;
     case 0x19:
         /* HW_MFPR (PALcode) */
-#if defined (CONFIG_USER_ONLY)
         goto invalid_opc;
-#else
-        if (!ctx->pal_mode)
-            goto invalid_opc;
-        if (ra != 31) {
-            TCGv tmp = tcg_const_i32(insn & 0xFF);
-            gen_helper_mfpr(cpu_ir[ra], tmp, cpu_ir[ra]);
-            tcg_temp_free(tmp);
-        }
-        break;
-#endif
     case 0x1A:
         /* JMP, JSR, RET, JSR_COROUTINE.  These only differ by the branch
            prediction stack action, which of course we don't implement.  */
@@ -2856,25 +2845,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
         break;
     case 0x1D:
         /* HW_MTPR (PALcode) */
-#if defined (CONFIG_USER_ONLY)
         goto invalid_opc;
-#else
-        if (!ctx->pal_mode)
-            goto invalid_opc;
-        else {
-            TCGv tmp1 = tcg_const_i32(insn & 0xFF);
-            if (ra != 31)
-                gen_helper_mtpr(tmp1, cpu_ir[ra]);
-            else {
-                TCGv tmp2 = tcg_const_i64(0);
-                gen_helper_mtpr(tmp1, tmp2);
-                tcg_temp_free(tmp2);
-            }
-            tcg_temp_free(tmp1);
-            ret = EXIT_PC_STALE;
-        }
-        break;
-#endif
     case 0x1E:
         /* HW_RET (PALcode) */
 #if defined (CONFIG_USER_ONLY)
@@ -2887,7 +2858,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
                address from EXC_ADDR.  This turns out to be useful for our
                emulation PALcode, so continue to accept it.  */
             TCGv tmp = tcg_temp_new();
-            tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUState, ipr[IPR_EXC_ADDR]));
+            /* FIXME: Get exc_addr.  */
             gen_helper_hw_ret(tmp);
             tcg_temp_free(tmp);
         } else {
@@ -3131,7 +3102,7 @@ static inline void gen_intermediate_code_internal(CPUState *env,
     ctx.mem_idx = 0;
 #else
     ctx.mem_idx = ((env->ps >> 3) & 3);
-    ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1;
+    ctx.pal_mode = env->pal_mode;
 #endif
 
     /* ??? Every TB begins with unset rounding mode, to be initialized on
@@ -3297,42 +3268,13 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model)
     env->implver = implver;
     env->amask = amask;
 
-    env->ps = 0x1F00;
 #if defined (CONFIG_USER_ONLY)
-    env->ps |= 1 << 3;
+    env->ps = 1 << 3;
     cpu_alpha_store_fpcr(env, (FPCR_INVD | FPCR_DZED | FPCR_OVFD
                                | FPCR_UNFD | FPCR_INED | FPCR_DNOD));
 #endif
     env->lock_addr = -1;
 
-    /* Initialize IPR */
-#if defined (CONFIG_USER_ONLY)
-    env->ipr[IPR_EXC_ADDR] = 0;
-    env->ipr[IPR_EXC_SUM] = 0;
-    env->ipr[IPR_EXC_MASK] = 0;
-#else
-    {
-        // uint64_t hwpcb;
-        // hwpcb = env->ipr[IPR_PCBB];
-        env->ipr[IPR_ASN] = 0;
-        env->ipr[IPR_ASTEN] = 0;
-        env->ipr[IPR_ASTSR] = 0;
-        env->ipr[IPR_DATFX] = 0;
-        /* XXX: fix this */
-        //    env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8);
-        //    env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0);
-        //    env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16);
-        //    env->ipr[IPR_USP] = ldq_raw(hwpcb + 24);
-        env->ipr[IPR_FEN] = 0;
-        env->ipr[IPR_IPL] = 31;
-        env->ipr[IPR_MCES] = 0;
-        env->ipr[IPR_PERFMON] = 0; /* Implementation specific */
-        //    env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32);
-        env->ipr[IPR_SISR] = 0;
-        env->ipr[IPR_VIRBND] = -1ULL;
-    }
-#endif
-
     qemu_init_vcpu(env);
     return env;
 }
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 10/26] target-alpha: Enable the alpha-softmmu target.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (8 preceding siblings ...)
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 09/26] target-alpha: Rationalize internal processor registers Richard Henderson
@ 2011-05-23 20:28 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 11/26] target-alpha: Tidy exception constants Richard Henderson
                   ` (16 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

With all of the pre-existing code that would not compile gone,
this is the earliest point at which the target can be enabled.

There is no machine defined yet, so this will crash on startup.
Enable the target anyway, to make sure that further compilation
problems do not creep back in.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 Makefile.target                   |    3 +-
 configure                         |    1 +
 default-configs/alpha-softmmu.mak |    9 ++++
 target-alpha/machine.c            |   74 +++++++++++++++++++++++++++++++++++++
 4 files changed, 86 insertions(+), 1 deletions(-)
 create mode 100644 default-configs/alpha-softmmu.mak
 create mode 100644 target-alpha/machine.c

diff --git a/Makefile.target b/Makefile.target
index 9f67ae7..0803f0b 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -376,7 +376,8 @@ obj-m68k-y += m68k-semi.o dummy_m68k.o
 
 obj-s390x-y = s390-virtio-bus.o s390-virtio.o
 
-obj-alpha-y =
+obj-alpha-y = i8259.o mc146818rtc.o
+obj-alpha-y += vga.o cirrus_vga.o
 
 main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
diff --git a/configure b/configure
index d7dba5d..f42760c 100755
--- a/configure
+++ b/configure
@@ -831,6 +831,7 @@ if [ "$softmmu" = "yes" ] ; then
     default_target_list="\
 i386-softmmu \
 x86_64-softmmu \
+alpha-softmmu \
 arm-softmmu \
 cris-softmmu \
 lm32-softmmu \
diff --git a/default-configs/alpha-softmmu.mak b/default-configs/alpha-softmmu.mak
new file mode 100644
index 0000000..abadcff
--- /dev/null
+++ b/default-configs/alpha-softmmu.mak
@@ -0,0 +1,9 @@
+# Default configuration for alpha-softmmu
+
+include pci.mak
+CONFIG_SERIAL=y
+CONFIG_I8254=y
+CONFIG_VGA_PCI=y
+CONFIG_IDE_CORE=y
+CONFIG_IDE_QDEV=y
+CONFIG_VMWARE_VGA=y
diff --git a/target-alpha/machine.c b/target-alpha/machine.c
new file mode 100644
index 0000000..ed9bf65
--- /dev/null
+++ b/target-alpha/machine.c
@@ -0,0 +1,74 @@
+#include "hw/hw.h"
+#include "hw/boards.h"
+
+static int get_fpcr(QEMUFile *f, void *opaque, size_t size)
+{
+    CPUAlphaState *env = opaque;
+    cpu_alpha_store_fpcr(env, qemu_get_be64(f));
+    return 0;
+}
+
+static void put_fpcr(QEMUFile *f, void *opaque, size_t size)
+{
+    CPUAlphaState *env = opaque;
+    qemu_put_be64(f, cpu_alpha_load_fpcr(env));
+}
+
+static const VMStateInfo vmstate_fpcr = {
+    .name = "fpcr",
+    .get = get_fpcr,
+    .put = put_fpcr,
+};
+
+static VMStateField vmstate_cpu_fields[] = {
+    VMSTATE_UINTTL_ARRAY(ir, CPUState, 31),
+    VMSTATE_UINTTL_ARRAY(fir, CPUState, 31),
+    /* Save the architecture value of the fpcr, not the internally
+       expanded version.  Since this architecture value does not
+       exist in memory to be stored, this requires a but of hoop
+       jumping.  We want OFFSET=0 so that we effectively pass ENV
+       to the helper functions, and we need to fill in the name by
+       hand since there's no field of that name.  */
+    {
+        .name = "fpcr",
+        .version_id = 0,
+        .size = sizeof(uint64_t),
+        .info = &vmstate_fpcr,
+        .flags = VMS_SINGLE,
+        .offset = 0
+    },
+    VMSTATE_UINTTL(pc, CPUState),
+    VMSTATE_UINTTL(unique, CPUState),
+    VMSTATE_UINTTL(lock_addr, CPUState),
+    VMSTATE_UINTTL(lock_value, CPUState),
+    /* Note that lock_st_addr is not saved; it is a temporary
+       used during the execution of the st[lq]_c insns.  */
+
+    VMSTATE_UINT8(ps, CPUState),
+    VMSTATE_UINT8(intr_flag, CPUState),
+    VMSTATE_UINT8(pal_mode, CPUState),
+
+    VMSTATE_UINTTL(trap_arg0, CPUState),
+    VMSTATE_UINTTL(trap_arg1, CPUState),
+    VMSTATE_UINTTL(trap_arg2, CPUState),
+
+    VMSTATE_END_OF_LIST()
+};
+
+static const VMStateDescription vmstate_cpu = {
+    .name = "cpu",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = vmstate_cpu_fields,
+};
+
+void cpu_save(QEMUFile *f, void *opaque)
+{
+    vmstate_save_state(f, &vmstate_cpu, opaque);
+}
+
+int cpu_load(QEMUFile *f, void *opaque, int version_id)
+{
+    return vmstate_load_state(f, &vmstate_cpu, opaque, version_id);
+}
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 11/26] target-alpha: Tidy exception constants.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (9 preceding siblings ...)
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 10/26] target-alpha: Enable the alpha-softmmu target Richard Henderson
@ 2011-05-23 20:28 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 12/26] target-alpha: Tidy up arithmetic exceptions Richard Henderson
                   ` (15 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

There's no need to attempt to match EXCP_* values with PALcode entry
point offsets.  Instead, compress all the values to make for more
efficient switch statements within QEMU.

We will be doing TLB fill within QEMU proper, not within the PALcode,
so all of the ITB/DTB miss, double fault, and access exceptions can
be compressed to EXCP_MMFAULT.

Compress all of the EXCP_CALL_PAL exceptions into one.
Use env->error_code to store the specific entry point.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/main.c        |   44 ++++++++++++++------------------------------
 target-alpha/cpu.h       |   34 ++++++++++++++--------------------
 target-alpha/helper.c    |    5 +----
 target-alpha/translate.c |    4 ++--
 4 files changed, 31 insertions(+), 56 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 1c985ab..1b17261 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2508,19 +2508,13 @@ void cpu_loop (CPUState *env)
             fprintf(stderr, "Machine check exception. Exit\n");
             exit(1);
             break;
-        case EXCP_ARITH:
-            env->lock_addr = -1;
-            info.si_signo = TARGET_SIGFPE;
-            info.si_errno = 0;
-            info.si_code = TARGET_FPE_FLTINV;
-            info._sifields._sigfault._addr = env->pc;
-            queue_signal(env, info.si_signo, &info);
-            break;
-        case EXCP_HW_INTERRUPT:
+        case EXCP_SMP_INTERRUPT:
+        case EXCP_CLK_INTERRUPT:
+        case EXCP_DEV_INTERRUPT:
             fprintf(stderr, "External interrupt. Exit\n");
             exit(1);
             break;
-        case EXCP_DFAULT:
+        case EXCP_MMFAULT:
             env->lock_addr = -1;
             info.si_signo = TARGET_SIGSEGV;
             info.si_errno = 0;
@@ -2529,22 +2523,6 @@ void cpu_loop (CPUState *env)
             info._sifields._sigfault._addr = env->trap_arg0;
             queue_signal(env, info.si_signo, &info);
             break;
-        case EXCP_DTB_MISS_PAL:
-            fprintf(stderr, "MMU data TLB miss in PALcode\n");
-            exit(1);
-            break;
-        case EXCP_ITB_MISS:
-            fprintf(stderr, "MMU instruction TLB miss\n");
-            exit(1);
-            break;
-        case EXCP_ITB_ACV:
-            fprintf(stderr, "MMU instruction access violation\n");
-            exit(1);
-            break;
-        case EXCP_DTB_MISS_NATIVE:
-            fprintf(stderr, "MMU data TLB miss\n");
-            exit(1);
-            break;
         case EXCP_UNALIGN:
             env->lock_addr = -1;
             info.si_signo = TARGET_SIGBUS;
@@ -2562,12 +2540,20 @@ void cpu_loop (CPUState *env)
             info._sifields._sigfault._addr = env->pc;
             queue_signal(env, info.si_signo, &info);
             break;
+        case EXCP_ARITH:
+            env->lock_addr = -1;
+            info.si_signo = TARGET_SIGFPE;
+            info.si_errno = 0;
+            info.si_code = TARGET_FPE_FLTINV;
+            info._sifields._sigfault._addr = env->pc;
+            queue_signal(env, info.si_signo, &info);
+            break;
         case EXCP_FEN:
             /* No-op.  Linux simply re-enables the FPU.  */
             break;
-        case EXCP_CALL_PAL ... (EXCP_CALL_PALP - 1):
+        case EXCP_CALL_PAL:
             env->lock_addr = -1;
-            switch ((trapnr >> 6) | 0x80) {
+            switch (env->error_code) {
             case 0x80:
                 /* BPT */
                 info.si_signo = TARGET_SIGTRAP;
@@ -2658,8 +2644,6 @@ void cpu_loop (CPUState *env)
                 goto do_sigill;
             }
             break;
-        case EXCP_CALL_PALP ... (EXCP_CALL_PALE - 1):
-            goto do_sigill;
         case EXCP_DEBUG:
             info.si_signo = gdb_handlesig (env, TARGET_SIGTRAP);
             if (info.si_signo) {
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index be7d151..01e3741 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -289,26 +289,20 @@ enum {
 };
 
 enum {
-    EXCP_RESET            = 0x0000,
-    EXCP_MCHK             = 0x0020,
-    EXCP_ARITH            = 0x0060,
-    EXCP_HW_INTERRUPT     = 0x00E0,
-    EXCP_DFAULT           = 0x01E0,
-    EXCP_DTB_MISS_PAL     = 0x09E0,
-    EXCP_ITB_MISS         = 0x03E0,
-    EXCP_ITB_ACV          = 0x07E0,
-    EXCP_DTB_MISS_NATIVE  = 0x08E0,
-    EXCP_UNALIGN          = 0x11E0,
-    EXCP_OPCDEC           = 0x13E0,
-    EXCP_FEN              = 0x17E0,
-    EXCP_CALL_PAL         = 0x2000,
-    EXCP_CALL_PALP        = 0x3000,
-    EXCP_CALL_PALE        = 0x4000,
-    /* Pseudo exception for console */
-    EXCP_CONSOLE_DISPATCH = 0x4001,
-    EXCP_CONSOLE_FIXUP    = 0x4002,
-    EXCP_STL_C            = 0x4003,
-    EXCP_STQ_C            = 0x4004,
+    EXCP_RESET,
+    EXCP_MCHK,
+    EXCP_SMP_INTERRUPT,
+    EXCP_CLK_INTERRUPT,
+    EXCP_DEV_INTERRUPT,
+    EXCP_MMFAULT,
+    EXCP_UNALIGN,
+    EXCP_OPCDEC,
+    EXCP_ARITH,
+    EXCP_FEN,
+    EXCP_CALL_PAL,
+    /* For Usermode emulation.  */
+    EXCP_STL_C,
+    EXCP_STQ_C,
 };
 
 /* Arithmetic exception */
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 5c3263b..c5479fd 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -164,10 +164,7 @@ void cpu_alpha_store_fpcr (CPUState *env, uint64_t val)
 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                                 int mmu_idx, int is_softmmu)
 {
-    if (rw == 2)
-        env->exception_index = EXCP_ITB_MISS;
-    else
-        env->exception_index = EXCP_DFAULT;
+    env->exception_index = EXCP_MMFAULT;
     env->trap_arg0 = address;
     return 1;
 }
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index fe0ae96..5f40d34 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1516,7 +1516,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
 #endif
         if (palcode >= 0x80 && palcode < 0xC0) {
             /* Unprivileged PAL call */
-            ret = gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x3F) << 6), 0);
+            ret = gen_excp(ctx, EXCP_CALL_PAL, palcode & 0xBF);
             break;
         }
 #ifndef CONFIG_USER_ONLY
@@ -1525,7 +1525,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
             if (ctx->mem_idx != MMU_KERNEL_IDX) {
                 goto invalid_opc;
             }
-            ret = gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0);
+            ret = gen_excp(ctx, EXCP_CALL_PAL, palcode & 0x3F);
         }
 #endif
         /* Invalid PAL call */
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 12/26] target-alpha: Tidy up arithmetic exceptions.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (10 preceding siblings ...)
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 11/26] target-alpha: Tidy exception constants Richard Henderson
@ 2011-05-23 20:28 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 13/26] target-alpha: Use do_restore_state for " Richard Henderson
                   ` (14 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

Introduce and use arith_excp, filling in the trap_arg[01] IPRs.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/op_helper.c |   34 +++++++++++++++++++++-------------
 1 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 73e5805..672940e 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -32,6 +32,15 @@ void QEMU_NORETURN helper_excp (int excp, int error)
     cpu_loop_exit();
 }
 
+static void QEMU_NORETURN arith_excp(int exc, uint64_t mask)
+{
+    env->exception_index = EXCP_ARITH;
+    env->error_code = 0;
+    env->trap_arg0 = exc;
+    env->trap_arg1 = mask;
+    cpu_loop_exit();
+}
+
 uint64_t helper_load_pcc (void)
 {
     /* ??? This isn't a timer for which we have any rate info.  */
@@ -53,7 +62,7 @@ uint64_t helper_addqv (uint64_t op1, uint64_t op2)
     uint64_t tmp = op1;
     op1 += op2;
     if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) {
-        helper_excp(EXCP_ARITH, EXC_M_IOV);
+        arith_excp(EXC_M_IOV, 0);
     }
     return op1;
 }
@@ -63,7 +72,7 @@ uint64_t helper_addlv (uint64_t op1, uint64_t op2)
     uint64_t tmp = op1;
     op1 = (uint32_t)(op1 + op2);
     if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) {
-        helper_excp(EXCP_ARITH, EXC_M_IOV);
+        arith_excp(EXC_M_IOV, 0);
     }
     return op1;
 }
@@ -73,7 +82,7 @@ uint64_t helper_subqv (uint64_t op1, uint64_t op2)
     uint64_t res;
     res = op1 - op2;
     if (unlikely((op1 ^ op2) & (res ^ op1) & (1ULL << 63))) {
-        helper_excp(EXCP_ARITH, EXC_M_IOV);
+        arith_excp(EXC_M_IOV, 0);
     }
     return res;
 }
@@ -83,7 +92,7 @@ uint64_t helper_sublv (uint64_t op1, uint64_t op2)
     uint32_t res;
     res = op1 - op2;
     if (unlikely((op1 ^ op2) & (res ^ op1) & (1UL << 31))) {
-        helper_excp(EXCP_ARITH, EXC_M_IOV);
+        arith_excp(EXC_M_IOV, 0);
     }
     return res;
 }
@@ -93,7 +102,7 @@ uint64_t helper_mullv (uint64_t op1, uint64_t op2)
     int64_t res = (int64_t)op1 * (int64_t)op2;
 
     if (unlikely((int32_t)res != res)) {
-        helper_excp(EXCP_ARITH, EXC_M_IOV);
+        arith_excp(EXC_M_IOV, 0);
     }
     return (int64_t)((int32_t)res);
 }
@@ -105,7 +114,7 @@ uint64_t helper_mulqv (uint64_t op1, uint64_t op2)
     muls64(&tl, &th, op1, op2);
     /* If th != 0 && th != -1, then we had an overflow */
     if (unlikely((th + 1) > 1)) {
-        helper_excp(EXCP_ARITH, EXC_M_IOV);
+        arith_excp(EXC_M_IOV, 0);
     }
     return tl;
 }
@@ -373,8 +382,6 @@ void helper_fp_exc_raise(uint32_t exc, uint32_t regno)
     if (exc) {
         uint32_t hw_exc = 0;
 
-        env->trap_arg1 = 1ull << regno;
-
         if (exc & float_flag_invalid) {
             hw_exc |= EXC_M_INV;
         }
@@ -390,7 +397,8 @@ void helper_fp_exc_raise(uint32_t exc, uint32_t regno)
         if (exc & float_flag_inexact) {
             hw_exc |= EXC_M_INE;
         }
-        helper_excp(EXCP_ARITH, hw_exc);
+
+        arith_excp(hw_exc, 1ull << regno);
     }
 }
 
@@ -420,7 +428,7 @@ uint64_t helper_ieee_input(uint64_t val)
             if (env->fpcr_dnz) {
                 val &= 1ull << 63;
             } else {
-                helper_excp(EXCP_ARITH, EXC_M_UNF);
+                arith_excp(EXC_M_UNF, 0);
             }
         }
     } else if (exp == 0x7ff) {
@@ -428,7 +436,7 @@ uint64_t helper_ieee_input(uint64_t val)
         /* ??? I'm not sure these exception bit flags are correct.  I do
            know that the Linux kernel, at least, doesn't rely on them and
            just emulates the insn to figure out what exception to use.  */
-        helper_excp(EXCP_ARITH, frac ? EXC_M_INV : EXC_M_FOV);
+        arith_excp(frac ? EXC_M_INV : EXC_M_FOV, 0);
     }
     return val;
 }
@@ -445,12 +453,12 @@ uint64_t helper_ieee_input_cmp(uint64_t val)
             if (env->fpcr_dnz) {
                 val &= 1ull << 63;
             } else {
-                helper_excp(EXCP_ARITH, EXC_M_UNF);
+                arith_excp(EXC_M_UNF, 0);
             }
         }
     } else if (exp == 0x7ff && frac) {
         /* NaN.  */
-        helper_excp(EXCP_ARITH, EXC_M_INV);
+        arith_excp(EXC_M_INV, 0);
     }
     return val;
 }
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 13/26] target-alpha: Use do_restore_state for arithmetic exceptions.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (11 preceding siblings ...)
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 12/26] target-alpha: Tidy up arithmetic exceptions Richard Henderson
@ 2011-05-23 20:28 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 14/26] target-alpha: Add various symbolic constants Richard Henderson
                   ` (13 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

This gets the PC right after an arithmetic exception.  Also tidies
the code in the TLB fault handlers to use common code.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/op_helper.c |   49 ++++++++++++++++++++++++++++-----------------
 1 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 672940e..fc5020a 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -25,20 +25,42 @@
 
 /*****************************************************************************/
 /* Exceptions processing helpers */
-void QEMU_NORETURN helper_excp (int excp, int error)
+
+/* This should only be called from translate, via gen_excp.
+   We expect that ENV->PC has already been updated.  */
+void QEMU_NORETURN helper_excp(int excp, int error)
+{
+    env->exception_index = excp;
+    env->error_code = error;
+    cpu_loop_exit();
+}
+
+static void do_restore_state(void *retaddr)
+{
+    unsigned long pc = (unsigned long)retaddr;
+
+    if (pc) {
+        TranslationBlock *tb = tb_find_pc(pc);
+        if (tb) {
+            cpu_restore_state(tb, env, pc);
+        }
+    }
+}
+
+/* This may be called from any of the helpers to set up EXCEPTION_INDEX.  */
+static void QEMU_NORETURN dynamic_excp(int excp, int error)
 {
     env->exception_index = excp;
     env->error_code = error;
+    do_restore_state(GETPC());
     cpu_loop_exit();
 }
 
 static void QEMU_NORETURN arith_excp(int exc, uint64_t mask)
 {
-    env->exception_index = EXCP_ARITH;
-    env->error_code = 0;
     env->trap_arg0 = exc;
     env->trap_arg1 = mask;
-    cpu_loop_exit();
+    dynamic_excp(EXCP_ARITH, 0);
 }
 
 uint64_t helper_load_pcc (void)
@@ -521,7 +543,7 @@ static inline float32 f_to_float32(uint64_t a)
 
     if (unlikely(!exp && mant_sig)) {
         /* Reserved operands / Dirty zero */
-        helper_excp(EXCP_OPCDEC, 0);
+        dynamic_excp(EXCP_OPCDEC, 0);
     }
 
     if (exp < 3) {
@@ -651,7 +673,7 @@ static inline float64 g_to_float64(uint64_t a)
 
     if (!exp && mant_sig) {
         /* Reserved operands / Dirty zero */
-        helper_excp(EXCP_OPCDEC, 0);
+        dynamic_excp(EXCP_OPCDEC, 0);
     }
 
     if (exp < 3) {
@@ -1260,9 +1282,7 @@ uint64_t helper_stq_c_phys(uint64_t p, uint64_t v)
 /* XXX: fix it to restore all registers */
 void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
-    TranslationBlock *tb;
     CPUState *saved_env;
-    unsigned long pc;
     int ret;
 
     /* XXX: hack to restore env in all cases, even if not called from
@@ -1270,17 +1290,8 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
     saved_env = env;
     env = cpu_single_env;
     ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
-    if (!likely(ret == 0)) {
-        if (likely(retaddr)) {
-            /* now we have a real cpu fault */
-            pc = (unsigned long)retaddr;
-            tb = tb_find_pc(pc);
-            if (likely(tb)) {
-                /* the PC is inside the translated code. It means that we have
-                   a virtual CPU fault */
-                cpu_restore_state(tb, env, pc);
-            }
-        }
+    if (unlikely(ret != 0)) {
+        do_restore_state(retaddr);
         /* Exception index and error code are already set */
         cpu_loop_exit();
     }
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 14/26] target-alpha: Add various symbolic constants.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (12 preceding siblings ...)
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 13/26] target-alpha: Use do_restore_state for " Richard Henderson
@ 2011-05-23 20:28 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 15/26] target-alpha: Use kernel mmu_idx for pal_mode Richard Henderson
                   ` (12 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

The EXC_M_* constants were being set for the EV6, not as set for
the Unix kernel entry point.

Use PS_USER_MODE instead of hard-coding access to the PS register.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/cpu.h       |   56 +++++++++++++++++++++++++++++++++++----------
 target-alpha/translate.c |    2 +-
 2 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 01e3741..4407b32 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -274,11 +274,6 @@ struct CPUAlphaState {
 #define cpu_gen_code cpu_alpha_gen_code
 #define cpu_signal_handler cpu_alpha_signal_handler
 
-static inline int cpu_mmu_index (CPUState *env)
-{
-    return (env->ps >> 3) & 1;
-}
-
 #include "cpu-all.h"
 
 enum {
@@ -305,14 +300,49 @@ enum {
     EXCP_STQ_C,
 };
 
-/* Arithmetic exception */
-#define EXC_M_IOV       (1<<16)         /* Integer Overflow */
-#define EXC_M_INE       (1<<15)         /* Inexact result */
-#define EXC_M_UNF       (1<<14)         /* Underflow */
-#define EXC_M_FOV       (1<<13)         /* Overflow */
-#define EXC_M_DZE       (1<<12)         /* Division by zero */
-#define EXC_M_INV       (1<<11)         /* Invalid operation */
-#define EXC_M_SWC       (1<<10)         /* Software completion */
+/* Hardware interrupt (entInt) constants.  */
+enum {
+    INT_K_IP,
+    INT_K_CLK,
+    INT_K_MCHK,
+    INT_K_DEV,
+    INT_K_PERF,
+};
+
+/* Memory management (entMM) constants.  */
+enum {
+    MM_K_TNV,
+    MM_K_ACV,
+    MM_K_FOR,
+    MM_K_FOE,
+    MM_K_FOW
+};
+
+/* Arithmetic exception (entArith) constants.  */
+enum {
+    EXC_M_SWC = 1,      /* Software completion */
+    EXC_M_INV = 2,      /* Invalid operation */
+    EXC_M_DZE = 4,      /* Division by zero */
+    EXC_M_FOV = 8,      /* Overflow */
+    EXC_M_UNF = 16,     /* Underflow */
+    EXC_M_INE = 32,     /* Inexact result */
+    EXC_M_IOV = 64      /* Integer Overflow */
+};
+
+/* Processor status constants.  */
+enum {
+    /* Low 3 bits are interrupt mask level.  */
+    PS_INT_MASK = 7,
+
+    /* Bits 4 and 5 are the mmu mode.  The VMS PALcode uses all 4 modes;
+       The Unix PALcode only uses bit 4.  */
+    PS_USER_MODE = 8
+};
+
+static inline int cpu_mmu_index(CPUState *env)
+{
+    return (env->ps & PS_USER_MODE) != 0;
+}
 
 enum {
     IR_V0   = 0,
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 5f40d34..2f3c637 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3269,7 +3269,7 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model)
     env->amask = amask;
 
 #if defined (CONFIG_USER_ONLY)
-    env->ps = 1 << 3;
+    env->ps = PS_USER_MODE;
     cpu_alpha_store_fpcr(env, (FPCR_INVD | FPCR_DZED | FPCR_OVFD
                                | FPCR_UNFD | FPCR_INED | FPCR_DNOD));
 #endif
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 15/26] target-alpha: Use kernel mmu_idx for pal_mode.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (13 preceding siblings ...)
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 14/26] target-alpha: Add various symbolic constants Richard Henderson
@ 2011-05-23 20:28 ` 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
                   ` (11 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/cpu.h       |    8 +++++++-
 target-alpha/translate.c |    6 ++----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 4407b32..a59b39a 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -341,7 +341,13 @@ enum {
 
 static inline int cpu_mmu_index(CPUState *env)
 {
-    return (env->ps & PS_USER_MODE) != 0;
+    if (env->pal_mode) {
+        return MMU_KERNEL_IDX;
+    } else if (env->ps & PS_USER_MODE) {
+        return MMU_USER_IDX;
+    } else {
+        return MMU_KERNEL_IDX;
+    }
 }
 
 enum {
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 2f3c637..a937356 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3098,10 +3098,8 @@ static inline void gen_intermediate_code_internal(CPUState *env,
     ctx.env = env;
     ctx.pc = pc_start;
     ctx.amask = env->amask;
-#if defined (CONFIG_USER_ONLY)
-    ctx.mem_idx = 0;
-#else
-    ctx.mem_idx = ((env->ps >> 3) & 3);
+    ctx.mem_idx = cpu_mmu_index(env);
+#if !defined (CONFIG_USER_ONLY)
     ctx.pal_mode = env->pal_mode;
 #endif
 
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 16/26] target-alpha: Add IPRs to be used by the emulation PALcode.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (14 preceding siblings ...)
  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 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 17/26] target-alpha: Implement do_interrupt for system mode Richard Henderson
                   ` (10 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

These aren't actually used yet, but we can at least access
them via the HW_MFPR and HW_MTPR instructions.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/cpu.h       |   15 +++++++
 target-alpha/machine.c   |   13 ++++++
 target-alpha/translate.c |   96 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 124 insertions(+), 0 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index a59b39a..d1ef04d 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -244,6 +244,9 @@ struct CPUAlphaState {
     uint8_t ps;
     uint8_t intr_flag;
     uint8_t pal_mode;
+    uint8_t fen;
+
+    uint32_t pcc_ofs;
 
     /* These pass data from the exception logic in the translator and
        helpers to the OS entry point.  This is used for both system
@@ -252,6 +255,18 @@ struct CPUAlphaState {
     uint64_t trap_arg1;
     uint64_t trap_arg2;
 
+#if !defined(CONFIG_USER_ONLY)
+    /* The internal data required by our emulation of the Unix PALcode.  */
+    uint64_t exc_addr;
+    uint64_t palbr;
+    uint64_t ptbr;
+    uint64_t vptptr;
+    uint64_t sysval;
+    uint64_t usp;
+    uint64_t shadow[8];
+    uint64_t scratch[24];
+#endif
+
 #if TARGET_LONG_BITS > HOST_LONG_BITS
     /* temporary fixed-point registers
      * used to emulate 64 bits target on 32 bits hosts
diff --git a/target-alpha/machine.c b/target-alpha/machine.c
index ed9bf65..76d70d9 100644
--- a/target-alpha/machine.c
+++ b/target-alpha/machine.c
@@ -47,11 +47,24 @@ static VMStateField vmstate_cpu_fields[] = {
     VMSTATE_UINT8(ps, CPUState),
     VMSTATE_UINT8(intr_flag, CPUState),
     VMSTATE_UINT8(pal_mode, CPUState),
+    VMSTATE_UINT8(fen, CPUState),
+
+    VMSTATE_UINT32(pcc_ofs, CPUState),
 
     VMSTATE_UINTTL(trap_arg0, CPUState),
     VMSTATE_UINTTL(trap_arg1, CPUState),
     VMSTATE_UINTTL(trap_arg2, CPUState),
 
+    VMSTATE_UINTTL(exc_addr, CPUState),
+    VMSTATE_UINTTL(palbr, CPUState),
+    VMSTATE_UINTTL(ptbr, CPUState),
+    VMSTATE_UINTTL(vptptr, CPUState),
+    VMSTATE_UINTTL(sysval, CPUState),
+    VMSTATE_UINTTL(usp, CPUState),
+
+    VMSTATE_UINTTL_ARRAY(shadow, CPUState, 8),
+    VMSTATE_UINTTL_ARRAY(scratch, CPUState, 24),
+
     VMSTATE_END_OF_LIST()
 };
 
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index a937356..3802428 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1468,6 +1468,89 @@ static void gen_rx(int ra, int set)
     tcg_temp_free_i32(tmp);
 }
 
+#ifndef CONFIG_USER_ONLY
+
+#define PR_BYTE         0x100000
+#define PR_LONG         0x200000
+
+static int cpu_pr_data(int pr)
+{
+    switch (pr) {
+    case  0: return offsetof(CPUAlphaState, ps) | PR_BYTE;
+    case  1: return offsetof(CPUAlphaState, fen) | PR_BYTE;
+    case  2: return offsetof(CPUAlphaState, pcc_ofs) | PR_LONG;
+    case  3: return offsetof(CPUAlphaState, trap_arg0);
+    case  4: return offsetof(CPUAlphaState, trap_arg1);
+    case  5: return offsetof(CPUAlphaState, trap_arg2);
+    case  6: return offsetof(CPUAlphaState, exc_addr);
+    case  7: return offsetof(CPUAlphaState, palbr);
+    case  8: return offsetof(CPUAlphaState, ptbr);
+    case  9: return offsetof(CPUAlphaState, vptptr);
+    case 10: return offsetof(CPUAlphaState, unique);
+    case 11: return offsetof(CPUAlphaState, sysval);
+    case 12: return offsetof(CPUAlphaState, usp);
+
+    case 32 ... 39:
+        return offsetof(CPUAlphaState, shadow[pr - 32]);
+    case 40 ... 63:
+        return offsetof(CPUAlphaState, scratch[pr - 40]);
+    }
+    return 0;
+}
+
+static void gen_mfpr(int ra, int regno)
+{
+    int data = cpu_pr_data(regno);
+
+    /* In our emulated PALcode, these processor registers have no
+       side effects from reading.  */
+    if (ra == 31) {
+        return;
+    }
+
+    /* The basic registers are data only, and unknown registers
+       are read-zero, write-ignore.  */
+    if (data == 0) {
+        tcg_gen_movi_i64(cpu_ir[ra], 0);
+    } else if (data & PR_BYTE) {
+        tcg_gen_ld8u_i64(cpu_ir[ra], cpu_env, data & ~PR_BYTE);
+    } else if (data & PR_LONG) {
+        tcg_gen_ld32s_i64(cpu_ir[ra], cpu_env, data & ~PR_LONG);
+    } else {
+        tcg_gen_ld_i64(cpu_ir[ra], cpu_env, data);
+    }
+}
+
+static void gen_mtpr(int rb, int regno)
+{
+    TCGv tmp;
+    int data;
+
+    if (rb == 31) {
+        tmp = tcg_const_i64(0);
+    } else {
+        tmp = cpu_ir[rb];
+    }
+
+    /* The basic registers are data only, and unknown registers
+       are read-zero, write-ignore.  */
+    data = cpu_pr_data(regno);
+    if (data != 0) {
+        if (data & PR_BYTE) {
+            tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE);
+        } else if (data & PR_LONG) {
+            tcg_gen_st32_i64(tmp, cpu_env, data & ~PR_LONG);
+        } else {
+            tcg_gen_st_i64(tmp, cpu_env, data);
+        }
+    }
+
+    if (rb == 31) {
+        tcg_temp_free(tmp);
+    }
+}
+#endif /* !USER_ONLY*/
+
 static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
 {
     uint32_t palcode;
@@ -2576,6 +2659,12 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
         break;
     case 0x19:
         /* HW_MFPR (PALcode) */
+#ifndef CONFIG_USER_ONLY
+        if (ctx->pal_mode) {
+            gen_mfpr(ra, insn & 0xffff);
+            break;
+        }
+#endif
         goto invalid_opc;
     case 0x1A:
         /* JMP, JSR, RET, JSR_COROUTINE.  These only differ by the branch
@@ -2845,6 +2934,12 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
         break;
     case 0x1D:
         /* HW_MTPR (PALcode) */
+#ifndef CONFIG_USER_ONLY
+        if (ctx->pal_mode) {
+            gen_mtpr(ra, insn & 0xffff);
+            break;
+        }
+#endif
         goto invalid_opc;
     case 0x1E:
         /* HW_RET (PALcode) */
@@ -3272,6 +3367,7 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model)
                                | FPCR_UNFD | FPCR_INED | FPCR_DNOD));
 #endif
     env->lock_addr = -1;
+    env->fen = 1;
 
     qemu_init_vcpu(env);
     return env;
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 17/26] target-alpha: Implement do_interrupt for system mode.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (15 preceding siblings ...)
  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 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 18/26] target-alpha: Swap shadow registers moving to/from PALmode Richard Henderson
                   ` (9 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/helper.c |  121 +++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 111 insertions(+), 10 deletions(-)

diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index c5479fd..a49f632 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -160,7 +160,6 @@ void cpu_alpha_store_fpcr (CPUState *env, uint64_t val)
 }
 
 #if defined(CONFIG_USER_ONLY)
-
 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                                 int mmu_idx, int is_softmmu)
 {
@@ -168,14 +167,7 @@ int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
     env->trap_arg0 = address;
     return 1;
 }
-
-void do_interrupt (CPUState *env)
-{
-    env->exception_index = -1;
-}
-
 #else
-
 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
 {
     return -1;
@@ -186,12 +178,121 @@ int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
 {
     return 0;
 }
+#endif /* USER_ONLY */
 
 void do_interrupt (CPUState *env)
 {
-    abort();
+    int i = env->exception_index;
+
+    if (qemu_loglevel_mask(CPU_LOG_INT)) {
+        static int count;
+        const char *name = "<unknown>";
+
+        switch (i) {
+        case EXCP_RESET:
+            name = "reset";
+            break;
+        case EXCP_MCHK:
+            name = "mchk";
+            break;
+        case EXCP_SMP_INTERRUPT:
+            name = "smp_interrupt";
+            break;
+        case EXCP_CLK_INTERRUPT:
+            name = "clk_interrupt";
+            break;
+        case EXCP_DEV_INTERRUPT:
+            name = "dev_interrupt";
+            break;
+        case EXCP_MMFAULT:
+            name = "mmfault";
+            break;
+        case EXCP_UNALIGN:
+            name = "unalign";
+            break;
+        case EXCP_OPCDEC:
+            name = "opcdec";
+            break;
+        case EXCP_ARITH:
+            name = "arith";
+            break;
+        case EXCP_FEN:
+            name = "fen";
+            break;
+        case EXCP_CALL_PAL:
+            name = "call_pal";
+            break;
+        case EXCP_STL_C:
+            name = "stl_c";
+            break;
+        case EXCP_STQ_C:
+            name = "stq_c";
+            break;
+        }
+        qemu_log("INT %6d: %s(%#x) pc=%016" PRIx64 " sp=%016" PRIx64 "\n",
+                 ++count, name, env->error_code, env->pc, env->ir[IR_SP]);
+    }
+
+    env->exception_index = -1;
+
+#if !defined(CONFIG_USER_ONLY)
+    switch (i) {
+    case EXCP_RESET:
+        i = 0x0000;
+        break;
+    case EXCP_MCHK:
+        i = 0x0080;
+        break;
+    case EXCP_SMP_INTERRUPT:
+        i = 0x0100;
+        break;
+    case EXCP_CLK_INTERRUPT:
+        i = 0x0180;
+        break;
+    case EXCP_DEV_INTERRUPT:
+        i = 0x0200;
+        break;
+    case EXCP_MMFAULT:
+        i = 0x0280;
+        break;
+    case EXCP_UNALIGN:
+        i = 0x0300;
+        break;
+    case EXCP_OPCDEC:
+        i = 0x0380;
+        break;
+    case EXCP_ARITH:
+        i = 0x0400;
+        break;
+    case EXCP_FEN:
+        i = 0x0480;
+        break;
+    case EXCP_CALL_PAL:
+        i = env->error_code;
+        /* There are 64 entry points for both privilaged and unprivlaged,
+           with bit 0x80 indicating unprivlaged.  Each entry point gets
+           64 bytes to do its job.  */
+        if (i & 0x80) {
+            i = 0x2000 + (i - 0x80) * 64;
+        } else {
+            i = 0x1000 + i * 64;
+        }
+        break;
+    default:
+        cpu_abort(env, "Unhandled CPU exception");
+    }
+
+    /* Remember where the exception happened.  Emulate real hardware in
+       that the low bit of the PC indicates PALmode.  */
+    env->exc_addr = env->pc | env->pal_mode;
+
+    /* Continue execution at the PALcode entry point.  */
+    env->pc = env->palbr + i;
+
+    /* Switch to PALmode.  */
+    env->pal_mode = 1;
+#endif /* !USER_ONLY */
 }
-#endif
 
 void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                      int flags)
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 18/26] target-alpha: Swap shadow registers moving to/from PALmode.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (16 preceding siblings ...)
  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 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 19/26] target-alpha: All ISA checks to use TB->FLAGS Richard Henderson
                   ` (8 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/cpu.h       |    1 +
 target-alpha/helper.c    |   37 ++++++++++++++++++++++++++++++++++++-
 target-alpha/op_helper.c |    5 ++++-
 3 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index d1ef04d..c1546f8 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -416,6 +416,7 @@ void do_interrupt (CPUState *env);
 
 uint64_t cpu_alpha_load_fpcr (CPUState *env);
 void cpu_alpha_store_fpcr (CPUState *env, uint64_t val);
+extern void swap_shadow_regs(CPUState *env);
 
 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index a49f632..4f706f2 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -168,6 +168,38 @@ int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
     return 1;
 }
 #else
+void swap_shadow_regs(CPUState *env)
+{
+    uint64_t i0, i1, i2, i3, i4, i5, i6, i7;
+
+    i0 = env->ir[8];
+    i1 = env->ir[9];
+    i2 = env->ir[10];
+    i3 = env->ir[11];
+    i4 = env->ir[12];
+    i5 = env->ir[13];
+    i6 = env->ir[14];
+    i7 = env->ir[25];
+
+    env->ir[8]  = env->shadow[0];
+    env->ir[9]  = env->shadow[1];
+    env->ir[10] = env->shadow[2];
+    env->ir[11] = env->shadow[3];
+    env->ir[12] = env->shadow[4];
+    env->ir[13] = env->shadow[5];
+    env->ir[14] = env->shadow[6];
+    env->ir[25] = env->shadow[7];
+
+    env->shadow[0] = i0;
+    env->shadow[1] = i1;
+    env->shadow[2] = i2;
+    env->shadow[3] = i3;
+    env->shadow[4] = i4;
+    env->shadow[5] = i5;
+    env->shadow[6] = i6;
+    env->shadow[7] = i7;
+}
+
 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
 {
     return -1;
@@ -290,7 +322,10 @@ void do_interrupt (CPUState *env)
     env->pc = env->palbr + i;
 
     /* Switch to PALmode.  */
-    env->pal_mode = 1;
+    if (!env->pal_mode) {
+        env->pal_mode = 1;
+        swap_shadow_regs(env);
+    }
 #endif /* !USER_ONLY */
 }
 
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index fc5020a..03b5091 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1189,9 +1189,12 @@ uint64_t helper_cvtqg (uint64_t a)
 void helper_hw_ret (uint64_t a)
 {
     env->pc = a & ~3;
-    env->pal_mode = a & 1;
     env->intr_flag = 0;
     env->lock_addr = -1;
+    if ((a & 1) == 0) {
+        env->pal_mode = 0;
+        swap_shadow_regs(env);
+    }
 }
 #endif
 
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 19/26] target-alpha: All ISA checks to use TB->FLAGS.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (17 preceding siblings ...)
  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 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 20/26] target-alpha: Disable interrupts properly Richard Henderson
                   ` (7 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

We had two different methods in use, both of which referenced ENV,
and neither of which indicated to the generic code when different
compilation modes are not compatible.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/cpu.h       |   32 ++++-
 target-alpha/translate.c |  378 ++++++++++++++++++++++++----------------------
 2 files changed, 229 insertions(+), 181 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index c1546f8..f5d90c7 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -418,12 +418,40 @@ uint64_t cpu_alpha_load_fpcr (CPUState *env);
 void cpu_alpha_store_fpcr (CPUState *env, uint64_t val);
 extern void swap_shadow_regs(CPUState *env);
 
+/* Bits in TB->FLAGS that control how translation is processed.  */
+enum {
+    TB_FLAGS_PAL_MODE = 1,
+    TB_FLAGS_FEN = 2,
+    TB_FLAGS_USER_MODE = 8,
+
+    TB_FLAGS_AMASK_SHIFT = 4,
+    TB_FLAGS_AMASK_BWX = AMASK_BWX << TB_FLAGS_AMASK_SHIFT,
+    TB_FLAGS_AMASK_FIX = AMASK_FIX << TB_FLAGS_AMASK_SHIFT,
+    TB_FLAGS_AMASK_CIX = AMASK_CIX << TB_FLAGS_AMASK_SHIFT,
+    TB_FLAGS_AMASK_MVI = AMASK_MVI << TB_FLAGS_AMASK_SHIFT,
+    TB_FLAGS_AMASK_TRAP = AMASK_TRAP << TB_FLAGS_AMASK_SHIFT,
+    TB_FLAGS_AMASK_PREFETCH = AMASK_PREFETCH << TB_FLAGS_AMASK_SHIFT,
+};
+
 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
-                                        target_ulong *cs_base, int *flags)
+                                        target_ulong *cs_base, int *pflags)
 {
+    int flags = 0;
+
     *pc = env->pc;
     *cs_base = 0;
-    *flags = env->ps;
+
+    if (env->pal_mode) {
+        flags = TB_FLAGS_PAL_MODE;
+    } else {
+        flags = env->ps & PS_USER_MODE;
+    }
+    if (env->fen) {
+        flags |= TB_FLAGS_FEN;
+    }
+    flags |= env->amask << TB_FLAGS_AMASK_SHIFT;
+
+    *pflags = flags;
 }
 
 #if defined(CONFIG_USER_ONLY)
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 3802428..a6c6bca 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -47,10 +47,6 @@ struct DisasContext {
     CPUAlphaState *env;
     uint64_t pc;
     int mem_idx;
-#if !defined (CONFIG_USER_ONLY)
-    int pal_mode;
-#endif
-    uint32_t amask;
 
     /* Current rounding mode for this TB.  */
     int tb_rm;
@@ -1654,20 +1650,22 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
         break;
     case 0x0A:
         /* LDBU */
-        if (!(ctx->amask & AMASK_BWX))
-            goto invalid_opc;
-        gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
-        break;
+        if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
+            gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
+            break;
+        }
+        goto invalid_opc;
     case 0x0B:
         /* LDQ_U */
         gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
         break;
     case 0x0C:
         /* LDWU */
-        if (!(ctx->amask & AMASK_BWX))
-            goto invalid_opc;
-        gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
-        break;
+        if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
+            gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
+            break;
+        }
+        goto invalid_opc;
     case 0x0D:
         /* STW */
         gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0);
@@ -2071,20 +2069,12 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
         case 0x61:
             /* AMASK */
             if (likely(rc != 31)) {
-                if (islit)
-                    tcg_gen_movi_i64(cpu_ir[rc], lit);
-                else
-                    tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
-                switch (ctx->env->implver) {
-                case IMPLVER_2106x:
-                    /* EV4, EV45, LCA, LCA45 & EV5 */
-                    break;
-                case IMPLVER_21164:
-                case IMPLVER_21264:
-                case IMPLVER_21364:
-                    tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[rc],
-                                     ~(uint64_t)ctx->amask);
-                    break;
+                uint64_t amask = ctx->tb->flags >> TB_FLAGS_AMASK_SHIFT;
+
+                if (islit) {
+                    tcg_gen_movi_i64(cpu_ir[rc], lit & ~amask);
+                } else {
+                    tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[rb], ~amask);
                 }
             }
             break;
@@ -2298,8 +2288,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
         switch (fpfn) { /* fn11 & 0x3F */
         case 0x04:
             /* ITOFS */
-            if (!(ctx->amask & AMASK_FIX))
+            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
                 goto invalid_opc;
+            }
             if (likely(rc != 31)) {
                 if (ra != 31) {
                     TCGv_i32 tmp = tcg_temp_new_i32();
@@ -2312,20 +2303,23 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
             break;
         case 0x0A:
             /* SQRTF */
-            if (!(ctx->amask & AMASK_FIX))
-                goto invalid_opc;
-            gen_fsqrtf(rb, rc);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
+                gen_fsqrtf(rb, rc);
+                break;
+            }
+            goto invalid_opc;
         case 0x0B:
             /* SQRTS */
-            if (!(ctx->amask & AMASK_FIX))
-                goto invalid_opc;
-            gen_fsqrts(ctx, rb, rc, fn11);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
+                gen_fsqrts(ctx, rb, rc, fn11);
+                break;
+            }
+            goto invalid_opc;
         case 0x14:
             /* ITOFF */
-            if (!(ctx->amask & AMASK_FIX))
+            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
                 goto invalid_opc;
+            }
             if (likely(rc != 31)) {
                 if (ra != 31) {
                     TCGv_i32 tmp = tcg_temp_new_i32();
@@ -2338,8 +2332,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
             break;
         case 0x24:
             /* ITOFT */
-            if (!(ctx->amask & AMASK_FIX))
+            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
                 goto invalid_opc;
+            }
             if (likely(rc != 31)) {
                 if (ra != 31)
                     tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]);
@@ -2349,16 +2344,18 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
             break;
         case 0x2A:
             /* SQRTG */
-            if (!(ctx->amask & AMASK_FIX))
-                goto invalid_opc;
-            gen_fsqrtg(rb, rc);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
+                gen_fsqrtg(rb, rc);
+                break;
+            }
+            goto invalid_opc;
         case 0x02B:
             /* SQRTT */
-            if (!(ctx->amask & AMASK_FIX))
-                goto invalid_opc;
-            gen_fsqrtt(ctx, rb, rc, fn11);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
+                gen_fsqrtt(ctx, rb, rc, fn11);
+                break;
+            }
+            goto invalid_opc;
         default:
             goto invalid_opc;
         }
@@ -2660,7 +2657,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
     case 0x19:
         /* HW_MFPR (PALcode) */
 #ifndef CONFIG_USER_ONLY
-        if (ctx->pal_mode) {
+        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
             gen_mfpr(ra, insn & 0xffff);
             break;
         }
@@ -2681,13 +2678,15 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
         break;
     case 0x1B:
         /* HW_LD (PALcode) */
-#if defined (CONFIG_USER_ONLY)
-        goto invalid_opc;
-#else
-        if (!ctx->pal_mode)
-            goto invalid_opc;
-        if (ra != 31) {
-            TCGv addr = tcg_temp_new();
+#ifndef CONFIG_USER_ONLY
+        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
+            TCGv addr;
+
+            if (ra == 31) {
+                break;
+            }
+
+            addr = tcg_temp_new();
             if (rb != 31)
                 tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
             else
@@ -2754,15 +2753,17 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
                 break;
             }
             tcg_temp_free(addr);
+            break;
         }
-        break;
 #endif
+        goto invalid_opc;
     case 0x1C:
         switch (fn7) {
         case 0x00:
             /* SEXTB */
-            if (!(ctx->amask & AMASK_BWX))
+            if ((ctx->tb->flags & TB_FLAGS_AMASK_BWX) == 0) {
                 goto invalid_opc;
+            }
             if (likely(rc != 31)) {
                 if (islit)
                     tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit));
@@ -2772,138 +2773,164 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
             break;
         case 0x01:
             /* SEXTW */
-            if (!(ctx->amask & AMASK_BWX))
-                goto invalid_opc;
-            if (likely(rc != 31)) {
-                if (islit)
-                    tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit));
-                else
-                    tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]);
+            if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
+                if (likely(rc != 31)) {
+                    if (islit) {
+                        tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit));
+                    } else {
+                        tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]);
+                    }
+                }
+                break;
             }
-            break;
+            goto invalid_opc;
         case 0x30:
             /* CTPOP */
-            if (!(ctx->amask & AMASK_CIX))
-                goto invalid_opc;
-            if (likely(rc != 31)) {
-                if (islit)
-                    tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit));
-                else
-                    gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]);
+            if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {
+                if (likely(rc != 31)) {
+                    if (islit) {
+                        tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit));
+                    } else {
+                        gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]);
+                    }
+                }
+                break;
             }
-            break;
+            goto invalid_opc;
         case 0x31:
             /* PERR */
-            if (!(ctx->amask & AMASK_MVI))
-                goto invalid_opc;
-            gen_perr(ra, rb, rc, islit, lit);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
+                gen_perr(ra, rb, rc, islit, lit);
+                break;
+            }
+            goto invalid_opc;
         case 0x32:
             /* CTLZ */
-            if (!(ctx->amask & AMASK_CIX))
-                goto invalid_opc;
-            if (likely(rc != 31)) {
-                if (islit)
-                    tcg_gen_movi_i64(cpu_ir[rc], clz64(lit));
-                else
-                    gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]);
+            if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {
+                if (likely(rc != 31)) {
+                    if (islit) {
+                        tcg_gen_movi_i64(cpu_ir[rc], clz64(lit));
+                    } else {
+                        gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]);
+                    }
+                }
+                break;
             }
-            break;
+            goto invalid_opc;
         case 0x33:
             /* CTTZ */
-            if (!(ctx->amask & AMASK_CIX))
-                goto invalid_opc;
-            if (likely(rc != 31)) {
-                if (islit)
-                    tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit));
-                else
-                    gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]);
+            if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {
+                if (likely(rc != 31)) {
+                    if (islit) {
+                        tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit));
+                    } else {
+                        gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]);
+                    }
+                }
+                break;
             }
-            break;
+            goto invalid_opc;
         case 0x34:
             /* UNPKBW */
-            if (!(ctx->amask & AMASK_MVI))
-                goto invalid_opc;
-            if (real_islit || ra != 31)
-                goto invalid_opc;
-            gen_unpkbw (rb, rc);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
+                if (real_islit || ra != 31) {
+                    goto invalid_opc;
+                }
+                gen_unpkbw(rb, rc);
+                break;
+            }
+            goto invalid_opc;
         case 0x35:
             /* UNPKBL */
-            if (!(ctx->amask & AMASK_MVI))
-                goto invalid_opc;
-            if (real_islit || ra != 31)
-                goto invalid_opc;
-            gen_unpkbl (rb, rc);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
+                if (real_islit || ra != 31) {
+                    goto invalid_opc;
+                }
+                gen_unpkbl(rb, rc);
+                break;
+            }
+            goto invalid_opc;
         case 0x36:
             /* PKWB */
-            if (!(ctx->amask & AMASK_MVI))
-                goto invalid_opc;
-            if (real_islit || ra != 31)
-                goto invalid_opc;
-            gen_pkwb (rb, rc);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
+                if (real_islit || ra != 31) {
+                    goto invalid_opc;
+                }
+                gen_pkwb(rb, rc);
+                break;
+            }
+            goto invalid_opc;
         case 0x37:
             /* PKLB */
-            if (!(ctx->amask & AMASK_MVI))
-                goto invalid_opc;
-            if (real_islit || ra != 31)
-                goto invalid_opc;
-            gen_pklb (rb, rc);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
+                if (real_islit || ra != 31) {
+                    goto invalid_opc;
+                }
+                gen_pklb(rb, rc);
+                break;
+            }
+            goto invalid_opc;
         case 0x38:
             /* MINSB8 */
-            if (!(ctx->amask & AMASK_MVI))
-                goto invalid_opc;
-            gen_minsb8 (ra, rb, rc, islit, lit);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
+                gen_minsb8(ra, rb, rc, islit, lit);
+                break;
+            }
+            goto invalid_opc;
         case 0x39:
             /* MINSW4 */
-            if (!(ctx->amask & AMASK_MVI))
-                goto invalid_opc;
-            gen_minsw4 (ra, rb, rc, islit, lit);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
+                gen_minsw4(ra, rb, rc, islit, lit);
+                break;
+            }
+            goto invalid_opc;
         case 0x3A:
             /* MINUB8 */
-            if (!(ctx->amask & AMASK_MVI))
-                goto invalid_opc;
-            gen_minub8 (ra, rb, rc, islit, lit);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
+                gen_minub8(ra, rb, rc, islit, lit);
+                break;
+            }
+            goto invalid_opc;
         case 0x3B:
             /* MINUW4 */
-            if (!(ctx->amask & AMASK_MVI))
-                goto invalid_opc;
-            gen_minuw4 (ra, rb, rc, islit, lit);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
+                gen_minuw4(ra, rb, rc, islit, lit);
+                break;
+            }
+            goto invalid_opc;
         case 0x3C:
             /* MAXUB8 */
-            if (!(ctx->amask & AMASK_MVI))
-                goto invalid_opc;
-            gen_maxub8 (ra, rb, rc, islit, lit);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
+                gen_maxub8(ra, rb, rc, islit, lit);
+                break;
+            }
+            goto invalid_opc;
         case 0x3D:
             /* MAXUW4 */
-            if (!(ctx->amask & AMASK_MVI))
-                goto invalid_opc;
-            gen_maxuw4 (ra, rb, rc, islit, lit);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
+                gen_maxuw4(ra, rb, rc, islit, lit);
+                break;
+            }
+            goto invalid_opc;
         case 0x3E:
             /* MAXSB8 */
-            if (!(ctx->amask & AMASK_MVI))
-                goto invalid_opc;
-            gen_maxsb8 (ra, rb, rc, islit, lit);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
+                gen_maxsb8(ra, rb, rc, islit, lit);
+                break;
+            }
+            goto invalid_opc;
         case 0x3F:
             /* MAXSW4 */
-            if (!(ctx->amask & AMASK_MVI))
-                goto invalid_opc;
-            gen_maxsw4 (ra, rb, rc, islit, lit);
-            break;
+            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
+                gen_maxsw4(ra, rb, rc, islit, lit);
+                break;
+            }
+            goto invalid_opc;
         case 0x70:
             /* FTOIT */
-            if (!(ctx->amask & AMASK_FIX))
+            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
                 goto invalid_opc;
+            }
             if (likely(rc != 31)) {
                 if (ra != 31)
                     tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]);
@@ -2913,8 +2940,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
             break;
         case 0x78:
             /* FTOIS */
-            if (!(ctx->amask & AMASK_FIX))
+            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
                 goto invalid_opc;
+            }
             if (rc != 31) {
                 TCGv_i32 tmp1 = tcg_temp_new_i32();
                 if (ra != 31)
@@ -2935,41 +2963,36 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
     case 0x1D:
         /* HW_MTPR (PALcode) */
 #ifndef CONFIG_USER_ONLY
-        if (ctx->pal_mode) {
-            gen_mtpr(ra, insn & 0xffff);
+        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
+            gen_mtpr(rb, insn & 0xffff);
             break;
         }
 #endif
         goto invalid_opc;
     case 0x1E:
         /* HW_RET (PALcode) */
-#if defined (CONFIG_USER_ONLY)
-        goto invalid_opc;
-#else
-        if (!ctx->pal_mode)
-            goto invalid_opc;
-        if (rb == 31) {
-            /* Pre-EV6 CPUs interpreted this as HW_REI, loading the return
-               address from EXC_ADDR.  This turns out to be useful for our
-               emulation PALcode, so continue to accept it.  */
-            TCGv tmp = tcg_temp_new();
-            /* FIXME: Get exc_addr.  */
-            gen_helper_hw_ret(tmp);
-            tcg_temp_free(tmp);
-        } else {
-            gen_helper_hw_ret(cpu_ir[rb]);
+#ifndef CONFIG_USER_ONLY
+        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
+            if (rb == 31) {
+                /* Pre-EV6 CPUs interpreted this as HW_REI, loading the return
+                   address from EXC_ADDR.  This turns out to be useful for our
+                   emulation PALcode, so continue to accept it.  */
+                TCGv tmp = tcg_temp_new();
+                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUState, exc_addr));
+                gen_helper_hw_ret(tmp);
+                tcg_temp_free(tmp);
+            } else {
+                gen_helper_hw_ret(cpu_ir[rb]);
+            }
+            ret = EXIT_PC_UPDATED;
+            break;
         }
-        ret = EXIT_PC_UPDATED;
-        break;
 #endif
+        goto invalid_opc;
     case 0x1F:
         /* HW_ST (PALcode) */
-#if defined (CONFIG_USER_ONLY)
-        goto invalid_opc;
-#else
-        if (!ctx->pal_mode)
-            goto invalid_opc;
-        else {
+#ifndef CONFIG_USER_ONLY
+        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
             TCGv addr, val;
             addr = tcg_temp_new();
             if (rb != 31)
@@ -3039,9 +3062,10 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
             if (ra == 31)
                 tcg_temp_free(val);
             tcg_temp_free(addr);
+            break;
         }
-        break;
 #endif
+        goto invalid_opc;
     case 0x20:
         /* LDF */
         gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);
@@ -3192,11 +3216,7 @@ static inline void gen_intermediate_code_internal(CPUState *env,
     ctx.tb = tb;
     ctx.env = env;
     ctx.pc = pc_start;
-    ctx.amask = env->amask;
     ctx.mem_idx = cpu_mmu_index(env);
-#if !defined (CONFIG_USER_ONLY)
-    ctx.pal_mode = env->pal_mode;
-#endif
 
     /* ??? Every TB begins with unset rounding mode, to be initialized on
        the first fp insn of the TB.  Alternately we could define a proper
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 20/26] target-alpha: Disable interrupts properly.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (18 preceding siblings ...)
  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 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 21/26] target-alpha: Implement more CALL_PAL values inline Richard Henderson
                   ` (6 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

Interrupts are disabled in PALmode, and when the PS IL is high enough.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 cpu-exec.c          |   33 ++++++++++++++++++++++++++++++---
 target-alpha/cpu.h  |    5 +++++
 target-alpha/exec.h |   12 +++++++++++-
 3 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 16a223e..6d03bc4 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -525,9 +525,36 @@ int cpu_exec(CPUState *env1)
                         next_tb = 0;
                     }
 #elif defined(TARGET_ALPHA)
-                    if (interrupt_request & CPU_INTERRUPT_HARD) {
-                        do_interrupt(env);
-                        next_tb = 0;
+                    {
+                        int idx = -1;
+                        /* ??? This hard-codes the OSF/1 interrupt levels.  */
+		        switch (env->pal_mode ? 7 : env->ps & PS_INT_MASK) {
+                        case 0 ... 3:
+                            if (interrupt_request & CPU_INTERRUPT_HARD) {
+                                idx = EXCP_DEV_INTERRUPT;
+                            }
+                            /* FALLTHRU */
+                        case 4:
+                            if (interrupt_request & CPU_INTERRUPT_TIMER) {
+                                idx = EXCP_CLK_INTERRUPT;
+                            }
+                            /* FALLTHRU */
+                        case 5:
+                            if (interrupt_request & CPU_INTERRUPT_SMP) {
+                                idx = EXCP_SMP_INTERRUPT;
+                            }
+                            /* FALLTHRU */
+                        case 6:
+                            if (interrupt_request & CPU_INTERRUPT_MCHK) {
+                                idx = EXCP_MCHK;
+                            }
+                        }
+                        if (idx >= 0) {
+                            env->exception_index = idx;
+                            env->error_code = 0;
+                            do_interrupt(env);
+                            next_tb = 0;
+                        }
                     }
 #elif defined(TARGET_CRIS)
                     if (interrupt_request & CPU_INTERRUPT_HARD
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index f5d90c7..a1f92ab 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -315,6 +315,11 @@ enum {
     EXCP_STQ_C,
 };
 
+/* Alpha-specific interrupt pending bits.  */
+#define CPU_INTERRUPT_TIMER	CPU_INTERRUPT_TGT_EXT_0
+#define CPU_INTERRUPT_SMP	CPU_INTERRUPT_TGT_EXT_1
+#define CPU_INTERRUPT_MCHK	CPU_INTERRUPT_TGT_EXT_2
+
 /* Hardware interrupt (entInt) constants.  */
 enum {
     INT_K_IP,
diff --git a/target-alpha/exec.h b/target-alpha/exec.h
index 6ae96d1..7a325e7 100644
--- a/target-alpha/exec.h
+++ b/target-alpha/exec.h
@@ -39,7 +39,17 @@ register struct CPUAlphaState *env asm(AREG0);
 
 static inline int cpu_has_work(CPUState *env)
 {
-    return (env->interrupt_request & CPU_INTERRUPT_HARD);
+    /* Here we are checking to see if the CPU should wake up from HALT.
+       We will have gotten into this state only for WTINT from PALmode.  */
+    /* ??? I'm not sure how the IPL state works with WTINT to keep a CPU
+       asleep even if (some) interrupts have been asserted.  For now, 
+       assume that if a CPU really wants to stay asleep, it will mask
+       interrupts at the chipset level, which will prevent these bits
+       from being set in the first place.  */
+    return env->interrupt_request & (CPU_INTERRUPT_HARD
+                                     | CPU_INTERRUPT_TIMER
+                                     | CPU_INTERRUPT_SMP
+                                     | CPU_INTERRUPT_MCHK);
 }
 
 static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 21/26] target-alpha: Implement more CALL_PAL values inline.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (19 preceding siblings ...)
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 20/26] target-alpha: Disable interrupts properly Richard Henderson
@ 2011-05-23 20:28 ` 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
                   ` (5 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

In particular, SWPIPL is used quite a lot by the Linux kernel.
Doing this inline makes it significantly easier to step through
without the debugger getting confused by the mode switch.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/translate.c |  140 +++++++++++++++++++++++++++++++++++-----------
 1 files changed, 108 insertions(+), 32 deletions(-)

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index a6c6bca..e664d62 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -85,8 +85,10 @@ static TCGv cpu_pc;
 static TCGv cpu_lock_addr;
 static TCGv cpu_lock_st_addr;
 static TCGv cpu_lock_value;
-#ifdef CONFIG_USER_ONLY
-static TCGv cpu_uniq;
+static TCGv cpu_unique;
+#ifndef CONFIG_USER_ONLY
+static TCGv cpu_sysval;
+static TCGv cpu_usp;
 #endif
 
 /* register names */
@@ -131,9 +133,13 @@ static void alpha_translate_init(void)
 					    offsetof(CPUState, lock_value),
 					    "lock_value");
 
-#ifdef CONFIG_USER_ONLY
-    cpu_uniq = tcg_global_mem_new_i64(TCG_AREG0,
-                                      offsetof(CPUState, unique), "uniq");
+    cpu_unique = tcg_global_mem_new_i64(TCG_AREG0,
+                                        offsetof(CPUState, unique), "unique");
+#ifndef CONFIG_USER_ONLY
+    cpu_sysval = tcg_global_mem_new_i64(TCG_AREG0,
+                                        offsetof(CPUState, sysval), "sysval");
+    cpu_usp = tcg_global_mem_new_i64(TCG_AREG0,
+                                     offsetof(CPUState, usp), "usp");
 #endif
 
     /* register helpers */
@@ -1464,6 +1470,101 @@ static void gen_rx(int ra, int set)
     tcg_temp_free_i32(tmp);
 }
 
+static ExitStatus gen_call_pal(DisasContext *ctx, int palcode)
+{
+    /* We're emulating OSF/1 PALcode.  Many of these are trivial access
+       to internal cpu registers.  */
+
+    /* Unprivileged PAL call */
+    if (palcode >= 0x80 && palcode < 0xC0) {
+        switch (palcode) {
+        case 0x86:
+            /* IMB */
+            /* No-op inside QEMU.  */
+            break;
+        case 0x9E:
+            /* RDUNIQUE */
+            tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_unique);
+            break;
+        case 0x9F:
+            /* WRUNIQUE */
+            tcg_gen_mov_i64(cpu_unique, cpu_ir[IR_A0]);
+            break;
+        default:
+            return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0xbf);
+        }
+        return NO_EXIT;
+    }
+
+#ifndef CONFIG_USER_ONLY
+    /* Privileged PAL code */
+    if (palcode < 0x40 && (ctx->tb->flags & TB_FLAGS_USER_MODE) == 0) {
+        switch (palcode) {
+        case 0x01:
+            /* CFLUSH */
+            /* No-op inside QEMU.  */
+            break;
+        case 0x02:
+            /* DRAINA */
+            /* No-op inside QEMU.  */
+            break;
+        case 0x2D:
+            /* WRVPTPTR */
+            tcg_gen_st_i64(cpu_ir[IR_A0], cpu_env, offsetof(CPUState, vptptr));
+            break;
+        case 0x31:
+            /* WRVAL */
+            tcg_gen_mov_i64(cpu_sysval, cpu_ir[IR_A0]);
+            break;
+        case 0x32:
+            /* RDVAL */
+            tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_sysval);
+            break;
+
+        case 0x35: {
+            /* SWPIPL */
+            TCGv tmp;
+
+            /* Note that we already know we're in kernel mode, so we know
+               that PS only contains the 3 IPL bits.  */
+            tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUState, ps));
+
+            /* But make sure and store only the 3 IPL bits from the user.  */
+            tmp = tcg_temp_new();
+            tcg_gen_andi_i64(tmp, cpu_ir[IR_A0], PS_INT_MASK);
+            tcg_gen_st8_i64(tmp, cpu_env, offsetof(CPUState, ps));
+            tcg_temp_free(tmp);
+            break;
+        }
+
+        case 0x36:
+            /* RDPS */
+            tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUState, ps));
+            break;
+        case 0x38:
+            /* WRUSP */
+            tcg_gen_mov_i64(cpu_usp, cpu_ir[IR_A0]);
+            break;
+        case 0x3A:
+            /* RDUSP */
+            tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_usp);
+            break;
+        case 0x3C:
+            /* WHAMI */
+            tcg_gen_ld32s_i64(cpu_ir[IR_V0], cpu_env,
+                              offsetof(CPUState, cpu_index));
+            break;
+
+        default:
+            return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0x3f);
+        }
+        return NO_EXIT;
+    }
+#endif
+
+    return gen_invalid(ctx);
+}
+
 #ifndef CONFIG_USER_ONLY
 
 #define PR_BYTE         0x100000
@@ -1582,33 +1683,8 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
     switch (opc) {
     case 0x00:
         /* CALL_PAL */
-#ifdef CONFIG_USER_ONLY
-        if (palcode == 0x9E) {
-            /* RDUNIQUE */
-            tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_uniq);
-            break;
-        } else if (palcode == 0x9F) {
-            /* WRUNIQUE */
-            tcg_gen_mov_i64(cpu_uniq, cpu_ir[IR_A0]);
-            break;
-        }
-#endif
-        if (palcode >= 0x80 && palcode < 0xC0) {
-            /* Unprivileged PAL call */
-            ret = gen_excp(ctx, EXCP_CALL_PAL, palcode & 0xBF);
-            break;
-        }
-#ifndef CONFIG_USER_ONLY
-        if (palcode < 0x40) {
-            /* Privileged PAL code */
-            if (ctx->mem_idx != MMU_KERNEL_IDX) {
-                goto invalid_opc;
-            }
-            ret = gen_excp(ctx, EXCP_CALL_PAL, palcode & 0x3F);
-        }
-#endif
-        /* Invalid PAL call */
-        goto invalid_opc;
+        ret = gen_call_pal(ctx, palcode);
+        break;
     case 0x01:
         /* OPC01 */
         goto invalid_opc;
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 22/26] target-alpha: Implement cpu_alpha_handle_mmu_fault for system mode.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (20 preceding siblings ...)
  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 ` 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
                   ` (4 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

Reads the page table how PALcode would, except that the virtual
page table base register is not used.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/cpu.h    |   13 +++++
 target-alpha/helper.c |  129 +++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 138 insertions(+), 4 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index a1f92ab..030ed17 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -320,6 +320,19 @@ enum {
 #define CPU_INTERRUPT_SMP	CPU_INTERRUPT_TGT_EXT_1
 #define CPU_INTERRUPT_MCHK	CPU_INTERRUPT_TGT_EXT_2
 
+/* OSF/1 Page table bits.  */
+enum {
+    PTE_VALID = 0x0001,
+    PTE_FOR   = 0x0002,  /* used for page protection (fault on read) */
+    PTE_FOW   = 0x0004,  /* used for page protection (fault on write) */
+    PTE_FOE   = 0x0008,  /* used for page protection (fault on exec) */
+    PTE_ASM   = 0x0010,
+    PTE_KRE   = 0x0100,
+    PTE_URE   = 0x0200,
+    PTE_KWE   = 0x1000,
+    PTE_UWE   = 0x2000
+};
+
 /* Hardware interrupt (entInt) constants.  */
 enum {
     INT_K_IP,
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 4f706f2..96b407b 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -200,14 +200,135 @@ void swap_shadow_regs(CPUState *env)
     env->shadow[7] = i7;
 }
 
-target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
+/* Returns the OSF/1 entMM failure indication, or -1 on success.  */
+static int get_physical_address(CPUState *env, target_ulong addr,
+                                int prot_need, int mmu_idx,
+                                target_ulong *pphys, int *pprot)
 {
-    return -1;
+    target_long saddr = addr;
+    target_ulong phys = 0;
+    target_ulong L1pte, L2pte, L3pte;
+    target_ulong pt, index;
+    int prot = 0;
+    int ret = MM_K_ACV;
+
+    /* Ensure that the virtual address is properly sign-extended from
+       the last implemented virtual address bit.  */
+    if (saddr >> TARGET_VIRT_ADDR_SPACE_BITS != saddr >> 63) {
+        goto exit;
+    }
+
+    /* Translate the superpage.  */
+    /* ??? When we do more than emulate Unix PALcode, we'll need to
+       determine which superpage is actually active.  */
+    if (saddr < 0 && (saddr >> (TARGET_VIRT_ADDR_SPACE_BITS - 2) & 3) == 2) {
+        /* User-space cannot access kseg addresses.  */
+        if (mmu_idx != MMU_KERNEL_IDX) {
+            goto exit;
+        }
+
+        phys = saddr & ((1ull << 40) - 1);
+        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+        ret = -1;
+        goto exit;
+    }
+
+    /* Interpret the page table exactly like PALcode does.  */
+
+    pt = env->ptbr;
+
+    /* L1 page table read.  */
+    index = (addr >> (TARGET_PAGE_BITS + 20)) & 0x3ff;
+    L1pte = ldq_phys(pt + index*8);
+
+    if (unlikely((L1pte & PTE_VALID) == 0)) {
+        ret = MM_K_TNV;
+        goto exit;
+    }
+    if (unlikely((L1pte & PTE_KRE) == 0)) {
+        goto exit;
+    }
+    pt = L1pte >> 32 << TARGET_PAGE_BITS;
+
+    /* L2 page table read.  */
+    index = (addr >> (TARGET_PAGE_BITS + 10)) & 0x3ff;
+    L2pte = ldq_phys(pt + index*8);
+
+    if (unlikely((L2pte & PTE_VALID) == 0)) {
+        ret = MM_K_TNV;
+        goto exit;
+    }
+    if (unlikely((L2pte & PTE_KRE) == 0)) {
+        goto exit;
+    }
+    pt = L2pte >> 32 << TARGET_PAGE_BITS;
+
+    /* L3 page table read.  */
+    index = (addr >> TARGET_PAGE_BITS) & 0x3ff;
+    L3pte = ldq_phys(pt + index*8);
+
+    phys = L3pte >> 32 << TARGET_PAGE_BITS;
+    if (unlikely((L3pte & PTE_VALID) == 0)) {
+        ret = MM_K_TNV;
+        goto exit;
+    }
+
+#if PAGE_READ != 1 || PAGE_WRITE != 2 || PAGE_EXEC != 4
+# error page bits out of date
+#endif
+
+    /* Check access violations.  */
+    if (L3pte & (PTE_KRE << mmu_idx)) {
+        prot |= PAGE_READ | PAGE_EXEC;
+    }
+    if (L3pte & (PTE_KWE << mmu_idx)) {
+        prot |= PAGE_WRITE;
+    }
+    if (unlikely((prot & prot_need) == 0 && prot_need)) {
+        goto exit;
+    }
+
+    /* Check fault-on-operation violations.  */
+    prot &= ~(L3pte >> 1);
+    ret = -1;
+    if (unlikely((prot & prot_need) == 0)) {
+        ret = (prot_need & PAGE_EXEC ? MM_K_FOE :
+               prot_need & PAGE_WRITE ? MM_K_FOW :
+               prot_need & PAGE_READ ? MM_K_FOR : -1);
+    }
+
+ exit:
+    *pphys = phys;
+    *pprot = prot;
+    return ret;
 }
 
-int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                                int mmu_idx, int is_softmmu)
+target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+{
+    target_ulong phys;
+    int prot, fail;
+
+    fail = get_physical_address(env, addr, 0, 0, &phys, &prot);
+    return (fail >= 0 ? -1 : phys);
+}
+
+int cpu_alpha_handle_mmu_fault(CPUState *env, target_ulong addr, int rw,
+                               int mmu_idx, int is_softmmu)
 {
+    target_ulong phys;
+    int prot, fail;
+
+    fail = get_physical_address(env, addr, 1 << rw, mmu_idx, &phys, &prot);
+    if (unlikely(fail >= 0)) {
+        env->exception_index = EXCP_MMFAULT;
+        env->trap_arg0 = addr;
+        env->trap_arg1 = fail;
+        env->trap_arg2 = (rw == 2 ? -1 : rw);
+        return 1;
+    }
+
+    tlb_set_page(env, addr & TARGET_PAGE_MASK, phys & TARGET_PAGE_MASK,
+                 prot, mmu_idx, TARGET_PAGE_SIZE);
     return 0;
 }
 #endif /* USER_ONLY */
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 23/26] target-alpha: Remap PIO space for 43-bit KSEG for EV6.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (21 preceding siblings ...)
  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 ` Richard Henderson
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 24/26] target-alpha: Trap for unassigned and unaligned addresses Richard Henderson
                   ` (3 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/helper.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 96b407b..bd3af38 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -220,14 +220,18 @@ static int get_physical_address(CPUState *env, target_ulong addr,
 
     /* Translate the superpage.  */
     /* ??? When we do more than emulate Unix PALcode, we'll need to
-       determine which superpage is actually active.  */
-    if (saddr < 0 && (saddr >> (TARGET_VIRT_ADDR_SPACE_BITS - 2) & 3) == 2) {
-        /* User-space cannot access kseg addresses.  */
+       determine which KSEG is actually active.  */
+    if (saddr < 0 && ((saddr >> 41) & 3) == 2) {
+        /* User-space cannot access KSEG addresses.  */
         if (mmu_idx != MMU_KERNEL_IDX) {
             goto exit;
         }
 
+        /* For the benefit of the Typhoon chipset, move bit 40 to bit 43.
+           We would not do this if the 48-bit KSEG is enabled.  */
         phys = saddr & ((1ull << 40) - 1);
+        phys |= (saddr & (1ull << 40)) << 3;
+
         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
         ret = -1;
         goto exit;
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 24/26] target-alpha: Trap for unassigned and unaligned addresses.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (22 preceding siblings ...)
  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 ` 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
                   ` (2 subsequent siblings)
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 exec-all.h               |    2 +-
 exec.c                   |   12 ++++++------
 target-alpha/cpu.h       |    6 +++++-
 target-alpha/op_helper.c |   26 ++++++++++++++++++++++++++
 4 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/exec-all.h b/exec-all.h
index cf3a704..15ec440 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -321,7 +321,7 @@ static inline tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong add
     }
     pd = env1->tlb_table[mmu_idx][page_index].addr_code & ~TARGET_PAGE_MASK;
     if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
-#if defined(TARGET_SPARC) || defined(TARGET_MIPS)
+#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SPARC)
         do_unassigned_access(addr, 0, 1, 0, 4);
 #else
         cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);
diff --git a/exec.c b/exec.c
index a6df2d6..f1c3c0f 100644
--- a/exec.c
+++ b/exec.c
@@ -3173,7 +3173,7 @@ static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
     do_unassigned_access(addr, 0, 0, 0, 1);
 #endif
     return 0;
@@ -3184,7 +3184,7 @@ static uint32_t unassigned_mem_readw(void *opaque, target_phys_addr_t addr)
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
     do_unassigned_access(addr, 0, 0, 0, 2);
 #endif
     return 0;
@@ -3195,7 +3195,7 @@ static uint32_t unassigned_mem_readl(void *opaque, target_phys_addr_t addr)
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
     do_unassigned_access(addr, 0, 0, 0, 4);
 #endif
     return 0;
@@ -3206,7 +3206,7 @@ static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
     do_unassigned_access(addr, 1, 0, 0, 1);
 #endif
 }
@@ -3216,7 +3216,7 @@ static void unassigned_mem_writew(void *opaque, target_phys_addr_t addr, uint32_
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
     do_unassigned_access(addr, 1, 0, 0, 2);
 #endif
 }
@@ -3226,7 +3226,7 @@ static void unassigned_mem_writel(void *opaque, target_phys_addr_t addr, uint32_
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
     do_unassigned_access(addr, 1, 0, 0, 4);
 #endif
 }
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 030ed17..e98b325 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -434,7 +434,11 @@ void do_interrupt (CPUState *env);
 
 uint64_t cpu_alpha_load_fpcr (CPUState *env);
 void cpu_alpha_store_fpcr (CPUState *env, uint64_t val);
-extern void swap_shadow_regs(CPUState *env);
+#ifndef CONFIG_USER_ONLY
+void swap_shadow_regs(CPUState *env);
+extern QEMU_NORETURN void do_unassigned_access(target_phys_addr_t addr,
+                                               int, int, int, int);
+#endif
 
 /* Bits in TB->FLAGS that control how translation is processed.  */
 enum {
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 03b5091..91ef90a 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1265,7 +1265,33 @@ uint64_t helper_stq_c_phys(uint64_t p, uint64_t v)
     return ret;
 }
 
+static void QEMU_NORETURN do_unaligned_access(target_ulong addr, int is_write,
+                                              int is_user, void *retaddr)
+{
+    uint64_t pc;
+    uint32_t insn;
+
+    do_restore_state(retaddr);
+
+    pc = env->pc;
+    insn = ldl_code(pc);
+
+    env->trap_arg0 = addr;
+    env->trap_arg1 = insn >> 26;                /* opcode */
+    env->trap_arg2 = (insn >> 21) & 31;         /* dest regno */
+    helper_excp(EXCP_UNALIGN, 0);
+}
+
+void QEMU_NORETURN do_unassigned_access(target_phys_addr_t addr, int is_write,
+                                        int is_exec, int unused, int size)
+{
+    env->trap_arg0 = addr;
+    env->trap_arg1 = is_write;
+    dynamic_excp(EXCP_MCHK, 0);
+}
+
 #define MMUSUFFIX _mmu
+#define ALIGNED_ONLY
 
 #define SHIFT 0
 #include "softmmu_template.h"
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 25/26] target-alpha: Use a fixed frequency for the RPCC in system mode.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (23 preceding siblings ...)
  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 ` 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
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

Also include the PCC_OFS in the return value.  For user mode we
can pretend the PCC_OFS value is always zero.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/op_helper.c |   11 ++++++++++-
 1 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 91ef90a..36b8289 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -65,8 +65,17 @@ static void QEMU_NORETURN arith_excp(int exc, uint64_t mask)
 
 uint64_t helper_load_pcc (void)
 {
-    /* ??? This isn't a timer for which we have any rate info.  */
+#ifndef CONFIG_USER_ONLY
+    /* In system mode we have access to a decent high-resolution clock.
+       In order to make OS-level time accounting work with the RPCC,
+       present it with a well-timed clock fixed at 250MHz.  */
+    return (((uint64_t)env->pcc_ofs << 32)
+            | (uint32_t)(qemu_get_clock_ns(vm_clock) >> 2));
+#else
+    /* In user-mode, vm_clock doesn't exist.  Just pass through the host cpu
+       clock ticks.  Also, don't bother taking PCC_OFS into account.  */
     return (uint32_t)cpu_get_real_ticks();
+#endif
 }
 
 uint64_t helper_load_fpcr (void)
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 26/26] target-alpha: Implement TLB flush primitives.
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (24 preceding siblings ...)
  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 ` Richard Henderson
  2011-05-27 19:55 ` [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
  26 siblings, 0 replies; 31+ messages in thread
From: Richard Henderson @ 2011-05-23 20:28 UTC (permalink / raw)
  To: qemu-devel

Expose these via MTPR, more or less like the real HW does.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-alpha/helper.h    |    3 +++
 target-alpha/op_helper.c |   11 ++++++++++-
 target-alpha/translate.c |   32 +++++++++++++++++++++-----------
 3 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index 9ffc372..2dec57e 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -110,6 +110,9 @@ 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)
+
+DEF_HELPER_FLAGS_0(tbia, TCG_CALL_CONST, void)
+DEF_HELPER_FLAGS_1(tbis, TCG_CALL_CONST, void, i64)
 #endif
 
 #include "def-helper.h"
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 36b8289..d332719 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1205,6 +1205,16 @@ void helper_hw_ret (uint64_t a)
         swap_shadow_regs(env);
     }
 }
+
+void helper_tbia(void)
+{
+    tlb_flush(env, 1);
+}
+
+void helper_tbis(uint64_t p)
+{
+    tlb_flush_page(env, p);
+}
 #endif
 
 /*****************************************************************************/
@@ -1335,5 +1345,4 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
     }
     env = saved_env;
 }
-
 #endif
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index e664d62..ad6c2ca 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1621,7 +1621,6 @@ static void gen_mfpr(int ra, int regno)
 static void gen_mtpr(int rb, int regno)
 {
     TCGv tmp;
-    int data;
 
     if (rb == 31) {
         tmp = tcg_const_i64(0);
@@ -1629,16 +1628,27 @@ static void gen_mtpr(int rb, int regno)
         tmp = cpu_ir[rb];
     }
 
-    /* The basic registers are data only, and unknown registers
-       are read-zero, write-ignore.  */
-    data = cpu_pr_data(regno);
-    if (data != 0) {
-        if (data & PR_BYTE) {
-            tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE);
-        } else if (data & PR_LONG) {
-            tcg_gen_st32_i64(tmp, cpu_env, data & ~PR_LONG);
-        } else {
-            tcg_gen_st_i64(tmp, cpu_env, data);
+    /* These two register numbers perform a TLB cache flush.  Thankfully we
+       can only do this inside PALmode, which means that the current basic
+       block cannot be affected by the change in mappings.  */
+    if (regno == 255) {
+        /* TBIA */
+        gen_helper_tbia();
+    } else if (regno == 254) {
+        /* TBIS */
+        gen_helper_tbis(tmp);
+    } else {
+        /* The basic registers are data only, and unknown registers
+           are read-zero, write-ignore.  */
+        int data = cpu_pr_data(regno);
+        if (data != 0) {
+            if (data & PR_BYTE) {
+                tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE);
+            } else if (data & PR_LONG) {
+                tcg_gen_st32_i64(tmp, cpu_env, data & ~PR_LONG);
+            } else {
+                tcg_gen_st_i64(tmp, cpu_env, data);
+            }
         }
     }
 
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PULL 00/26] Alpha system emulation, v5
  2011-05-23 20:28 [Qemu-devel] [PULL 00/26] Alpha system emulation, v5 Richard Henderson
                   ` (25 preceding siblings ...)
  2011-05-23 20:28 ` [Qemu-devel] [PATCH 26/26] target-alpha: Implement TLB flush primitives Richard Henderson
@ 2011-05-27 19:55 ` Richard Henderson
  2011-06-02 14:56   ` Richard Henderson
  26 siblings, 1 reply; 31+ messages in thread
From: Richard Henderson @ 2011-05-27 19:55 UTC (permalink / raw)
  To: qemu-devel

Ping?


r~

On 05/23/2011 01:28 PM, Richard Henderson wrote:
> Changes from v4 -> v5
> 
>   * Claim official ownership of the Alpha port, rather
>     than leave it as "unmaintained".
> 
>   * Drop all the patches in hw/ for now.  While they're necessary
>     to actually make the port work, these are the subset of the whole
>     patchset for which I'm confident I'm doing the Right Thing and
>     don't really need patch review.
> 
>     No mistake, patch review is still welcome but no one has posted
>     *anything* substantive for v1->v4.
> 
> Please pull.
> 
> 
> r~
> 
> 
> The following changes since commit dcfd14b3741983c466ad92fa2ae91eeafce3e5d5:
> 
>   Delete unused tb_invalidate_page_range (2011-05-22 10:47:28 +0000)
> 
> are available in the git repository at:
>   git://repo.or.cz/qemu/rth.git axp-next
> 
> Richard Henderson (26):
>       target-alpha: Claim ownership.
>       target-alpha: Disassemble EV6 PALcode instructions.
>       target-alpha: Single-step properly across branches.
>       target-alpha: Remove partial support for palcode emulation.
>       target-alpha: Fix translation of PALmode memory insns.
>       target-alpha: Fix system store_conditional
>       target-alpha: Cleanup MMU modes.
>       target-alpha: Merge HW_REI and HW_RET implementations.
>       target-alpha: Rationalize internal processor registers.
>       target-alpha: Enable the alpha-softmmu target.
>       target-alpha: Tidy exception constants.
>       target-alpha: Tidy up arithmetic exceptions.
>       target-alpha: Use do_restore_state for arithmetic exceptions.
>       target-alpha: Add various symbolic constants.
>       target-alpha: Use kernel mmu_idx for pal_mode.
>       target-alpha: Add IPRs to be used by the emulation PALcode.
>       target-alpha: Implement do_interrupt for system mode.
>       target-alpha: Swap shadow registers moving to/from PALmode.
>       target-alpha: All ISA checks to use TB->FLAGS.
>       target-alpha: Disable interrupts properly.
>       target-alpha: Implement more CALL_PAL values inline.
>       target-alpha: Implement cpu_alpha_handle_mmu_fault for system mode.
>       target-alpha: Remap PIO space for 43-bit KSEG for EV6.
>       target-alpha: Trap for unassigned and unaligned addresses.
>       target-alpha: Use a fixed frequency for the RPCC in system mode.
>       target-alpha: Implement TLB flush primitives.
> 
>  MAINTAINERS                       |    4 +-
>  Makefile.target                   |    3 +-
>  alpha-dis.c                       |    4 -
>  configure                         |    1 +
>  cpu-exec.c                        |   33 +-
>  default-configs/alpha-softmmu.mak |    9 +
>  dis-asm.h                         |    3 +
>  disas.c                           |    2 +-
>  exec-all.h                        |    2 +-
>  exec.c                            |   12 +-
>  hw/alpha_palcode.c                | 1048 -------------------------------------
>  linux-user/main.c                 |   50 +--
>  target-alpha/cpu.h                |  375 ++++++--------
>  target-alpha/exec.h               |   12 +-
>  target-alpha/helper.c             |  589 +++++++++------------
>  target-alpha/helper.h             |   32 +-
>  target-alpha/machine.c            |   87 +++
>  target-alpha/op_helper.c          |  278 +++++------
>  target-alpha/translate.c          |  804 ++++++++++++++++------------
>  19 files changed, 1179 insertions(+), 2169 deletions(-)
>  create mode 100644 default-configs/alpha-softmmu.mak
>  delete mode 100644 hw/alpha_palcode.c
>  create mode 100644 target-alpha/machine.c

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PULL 00/26] Alpha system emulation, v5
  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
  0 siblings, 1 reply; 31+ messages in thread
From: Richard Henderson @ 2011-06-02 14:56 UTC (permalink / raw)
  To: qemu-devel

Ping^2.

r~

On 05/27/2011 12:55 PM, Richard Henderson wrote:
> Ping?
> 
> 
> r~
> 
> On 05/23/2011 01:28 PM, Richard Henderson wrote:
>> Changes from v4 -> v5
>>
>>   * Claim official ownership of the Alpha port, rather
>>     than leave it as "unmaintained".
>>
>>   * Drop all the patches in hw/ for now.  While they're necessary
>>     to actually make the port work, these are the subset of the whole
>>     patchset for which I'm confident I'm doing the Right Thing and
>>     don't really need patch review.
>>
>>     No mistake, patch review is still welcome but no one has posted
>>     *anything* substantive for v1->v4.
>>
>> Please pull.
>>
>>
>> r~
>>
>>
>> The following changes since commit dcfd14b3741983c466ad92fa2ae91eeafce3e5d5:
>>
>>   Delete unused tb_invalidate_page_range (2011-05-22 10:47:28 +0000)
>>
>> are available in the git repository at:
>>   git://repo.or.cz/qemu/rth.git axp-next
>>
>> Richard Henderson (26):
>>       target-alpha: Claim ownership.
>>       target-alpha: Disassemble EV6 PALcode instructions.
>>       target-alpha: Single-step properly across branches.
>>       target-alpha: Remove partial support for palcode emulation.
>>       target-alpha: Fix translation of PALmode memory insns.
>>       target-alpha: Fix system store_conditional
>>       target-alpha: Cleanup MMU modes.
>>       target-alpha: Merge HW_REI and HW_RET implementations.
>>       target-alpha: Rationalize internal processor registers.
>>       target-alpha: Enable the alpha-softmmu target.
>>       target-alpha: Tidy exception constants.
>>       target-alpha: Tidy up arithmetic exceptions.
>>       target-alpha: Use do_restore_state for arithmetic exceptions.
>>       target-alpha: Add various symbolic constants.
>>       target-alpha: Use kernel mmu_idx for pal_mode.
>>       target-alpha: Add IPRs to be used by the emulation PALcode.
>>       target-alpha: Implement do_interrupt for system mode.
>>       target-alpha: Swap shadow registers moving to/from PALmode.
>>       target-alpha: All ISA checks to use TB->FLAGS.
>>       target-alpha: Disable interrupts properly.
>>       target-alpha: Implement more CALL_PAL values inline.
>>       target-alpha: Implement cpu_alpha_handle_mmu_fault for system mode.
>>       target-alpha: Remap PIO space for 43-bit KSEG for EV6.
>>       target-alpha: Trap for unassigned and unaligned addresses.
>>       target-alpha: Use a fixed frequency for the RPCC in system mode.
>>       target-alpha: Implement TLB flush primitives.
>>
>>  MAINTAINERS                       |    4 +-
>>  Makefile.target                   |    3 +-
>>  alpha-dis.c                       |    4 -
>>  configure                         |    1 +
>>  cpu-exec.c                        |   33 +-
>>  default-configs/alpha-softmmu.mak |    9 +
>>  dis-asm.h                         |    3 +
>>  disas.c                           |    2 +-
>>  exec-all.h                        |    2 +-
>>  exec.c                            |   12 +-
>>  hw/alpha_palcode.c                | 1048 -------------------------------------
>>  linux-user/main.c                 |   50 +--
>>  target-alpha/cpu.h                |  375 ++++++--------
>>  target-alpha/exec.h               |   12 +-
>>  target-alpha/helper.c             |  589 +++++++++------------
>>  target-alpha/helper.h             |   32 +-
>>  target-alpha/machine.c            |   87 +++
>>  target-alpha/op_helper.c          |  278 +++++------
>>  target-alpha/translate.c          |  804 ++++++++++++++++------------
>>  19 files changed, 1179 insertions(+), 2169 deletions(-)
>>  create mode 100644 default-configs/alpha-softmmu.mak
>>  delete mode 100644 hw/alpha_palcode.c
>>  create mode 100644 target-alpha/machine.c
> 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PULL 00/26] Alpha system emulation, v5
  2011-06-02 14:56   ` Richard Henderson
@ 2011-06-08 19:10     ` Richard Henderson
  2011-06-10 20:32       ` Edgar E. Iglesias
  0 siblings, 1 reply; 31+ messages in thread
From: Richard Henderson @ 2011-06-08 19:10 UTC (permalink / raw)
  To: qemu-devel

Ping^3.  Anyone?  Bueller?  Bueller?

r~

On 06/02/2011 07:56 AM, Richard Henderson wrote:
> Ping^2.
> 
> r~
> 
> On 05/27/2011 12:55 PM, Richard Henderson wrote:
>> Ping?
>>
>>
>> r~
>>
>> On 05/23/2011 01:28 PM, Richard Henderson wrote:
>>> Changes from v4 -> v5
>>>
>>>   * Claim official ownership of the Alpha port, rather
>>>     than leave it as "unmaintained".
>>>
>>>   * Drop all the patches in hw/ for now.  While they're necessary
>>>     to actually make the port work, these are the subset of the whole
>>>     patchset for which I'm confident I'm doing the Right Thing and
>>>     don't really need patch review.
>>>
>>>     No mistake, patch review is still welcome but no one has posted
>>>     *anything* substantive for v1->v4.
>>>
>>> Please pull.
>>>
>>>
>>> r~
>>>
>>>
>>> The following changes since commit dcfd14b3741983c466ad92fa2ae91eeafce3e5d5:
>>>
>>>   Delete unused tb_invalidate_page_range (2011-05-22 10:47:28 +0000)
>>>
>>> are available in the git repository at:
>>>   git://repo.or.cz/qemu/rth.git axp-next
>>>
>>> Richard Henderson (26):
>>>       target-alpha: Claim ownership.
>>>       target-alpha: Disassemble EV6 PALcode instructions.
>>>       target-alpha: Single-step properly across branches.
>>>       target-alpha: Remove partial support for palcode emulation.
>>>       target-alpha: Fix translation of PALmode memory insns.
>>>       target-alpha: Fix system store_conditional
>>>       target-alpha: Cleanup MMU modes.
>>>       target-alpha: Merge HW_REI and HW_RET implementations.
>>>       target-alpha: Rationalize internal processor registers.
>>>       target-alpha: Enable the alpha-softmmu target.
>>>       target-alpha: Tidy exception constants.
>>>       target-alpha: Tidy up arithmetic exceptions.
>>>       target-alpha: Use do_restore_state for arithmetic exceptions.
>>>       target-alpha: Add various symbolic constants.
>>>       target-alpha: Use kernel mmu_idx for pal_mode.
>>>       target-alpha: Add IPRs to be used by the emulation PALcode.
>>>       target-alpha: Implement do_interrupt for system mode.
>>>       target-alpha: Swap shadow registers moving to/from PALmode.
>>>       target-alpha: All ISA checks to use TB->FLAGS.
>>>       target-alpha: Disable interrupts properly.
>>>       target-alpha: Implement more CALL_PAL values inline.
>>>       target-alpha: Implement cpu_alpha_handle_mmu_fault for system mode.
>>>       target-alpha: Remap PIO space for 43-bit KSEG for EV6.
>>>       target-alpha: Trap for unassigned and unaligned addresses.
>>>       target-alpha: Use a fixed frequency for the RPCC in system mode.
>>>       target-alpha: Implement TLB flush primitives.
>>>
>>>  MAINTAINERS                       |    4 +-
>>>  Makefile.target                   |    3 +-
>>>  alpha-dis.c                       |    4 -
>>>  configure                         |    1 +
>>>  cpu-exec.c                        |   33 +-
>>>  default-configs/alpha-softmmu.mak |    9 +
>>>  dis-asm.h                         |    3 +
>>>  disas.c                           |    2 +-
>>>  exec-all.h                        |    2 +-
>>>  exec.c                            |   12 +-
>>>  hw/alpha_palcode.c                | 1048 -------------------------------------
>>>  linux-user/main.c                 |   50 +--
>>>  target-alpha/cpu.h                |  375 ++++++--------
>>>  target-alpha/exec.h               |   12 +-
>>>  target-alpha/helper.c             |  589 +++++++++------------
>>>  target-alpha/helper.h             |   32 +-
>>>  target-alpha/machine.c            |   87 +++
>>>  target-alpha/op_helper.c          |  278 +++++------
>>>  target-alpha/translate.c          |  804 ++++++++++++++++------------
>>>  19 files changed, 1179 insertions(+), 2169 deletions(-)
>>>  create mode 100644 default-configs/alpha-softmmu.mak
>>>  delete mode 100644 hw/alpha_palcode.c
>>>  create mode 100644 target-alpha/machine.c
>>
> 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PULL 00/26] Alpha system emulation, v5
  2011-06-08 19:10     ` Richard Henderson
@ 2011-06-10 20:32       ` Edgar E. Iglesias
  0 siblings, 0 replies; 31+ messages in thread
From: Edgar E. Iglesias @ 2011-06-10 20:32 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

On Wed, Jun 08, 2011 at 12:10:39PM -0700, Richard Henderson wrote:
> Ping^3.  Anyone?  Bueller?  Bueller?
> 
> r~
> 
> On 06/02/2011 07:56 AM, Richard Henderson wrote:
> > Ping^2.
> > 
> > r~
> > 
> > On 05/27/2011 12:55 PM, Richard Henderson wrote:
> >> Ping?
> >>
> >>
> >> r~
> >>
> >> On 05/23/2011 01:28 PM, Richard Henderson wrote:
> >>> Changes from v4 -> v5
> >>>
> >>>   * Claim official ownership of the Alpha port, rather
> >>>     than leave it as "unmaintained".
> >>>
> >>>   * Drop all the patches in hw/ for now.  While they're necessary
> >>>     to actually make the port work, these are the subset of the whole
> >>>     patchset for which I'm confident I'm doing the Right Thing and
> >>>     don't really need patch review.
> >>>
> >>>     No mistake, patch review is still welcome but no one has posted
> >>>     *anything* substantive for v1->v4.
> >>>
> >>> Please pull.
> >>>


Thanks, I've pulled your changes.

Cheers

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2011-06-10 20:32 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [Qemu-devel] [PATCH 05/26] target-alpha: Fix translation of PALmode memory insns Richard Henderson
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

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.