diff mbox

[1/7] alpha: Implement IMB; add placeholders for other userspace PALcalls.

Message ID bc24851204b87d15ad800dbe59572b5be0b19946.1260403522.git.rth@twiddle.net
State New
Headers show

Commit Message

Richard Henderson Dec. 9, 2009, 11:38 p.m. UTC
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 hw/alpha_palcode.c |   29 +++++++++++++++++++++++++++--
 1 files changed, 27 insertions(+), 2 deletions(-)

Comments

Aurelien Jarno Dec. 13, 2009, 7:28 p.m. UTC | #1
On Wed, Dec 09, 2009 at 03:38:40PM -0800, Richard Henderson wrote:
> 
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>  hw/alpha_palcode.c |   29 +++++++++++++++++++++++++++--
>  1 files changed, 27 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/alpha_palcode.c b/hw/alpha_palcode.c
> index c48a297..44b2ca4 100644
> --- a/hw/alpha_palcode.c
> +++ b/hw/alpha_palcode.c
> @@ -1062,6 +1062,16 @@ void call_pal (CPUState *env, int palcode)
>  
>      qemu_log("%s: palcode %02x\n", __func__, palcode);
>      switch (palcode) {
> +    case 0x80:
> +        /* BPT */
> +        qemu_log("BPT\n");
> +        /* FIXME: Sends SIGTRAP, si_code=TRAP_BRKPT.  */
> +        exit(1);
> +    case 0x81:
> +        /* BUGCHK */
> +        qemu_log("BUGCHK\n");
> +        /* FIXME: Sends SIGTRAP, si_code=SI_FAULT.  */
> +        exit(1);
>      case 0x83:
>          /* CALLSYS */
>          qemu_log("CALLSYS n " TARGET_FMT_ld "\n", env->ir[0]);
> @@ -1076,6 +1086,11 @@ void call_pal (CPUState *env, int palcode)
>              env->ir[IR_V0] = -ret;
>          }
>          break;
> +    case 0x86:
> +        /* IMB */
> +        qemu_log("IMB\n");
> +        tb_flush(env);

Is it really necessary to flush all the TB here? QEMU should already
discard TB that have been modified.

On other architecture this kind of memory barrier instruction is simply
ignored.

> +        break;
>      case 0x9E:
>          /* RDUNIQUE */
>          env->ir[IR_V0] = env->unique;
> @@ -1086,9 +1101,19 @@ void call_pal (CPUState *env, int palcode)
>          env->unique = env->ir[IR_A0];
>          qemu_log("WRUNIQUE: " TARGET_FMT_lx "\n", env->unique);
>          break;
> +    case 0xAA:
> +        /* GENTRAP */
> +        qemu_log("GENTRAP: " TARGET_FMT_lx "\n", env->ir[IR_A0]);
> +        /* FIXME: This is supposed to send a signal:
> +           SIGFPE:
> +             GEN_INTOVF, GEN_INTDIV, GEN_FLTOVF, GEN_FLTDIV,
> +             GEN_FLTUND, GEN_FLTINV, GEN_FLTINE, GEN_ROPRAND
> +           SIGTRAP:
> +             others
> +           with various settings of si_code.  */
> +        exit(1);
>      default:
> -        qemu_log("%s: unhandled palcode %02x\n",
> -                    __func__, palcode);
> +        qemu_log("%s: unhandled palcode %02x\n", __func__, palcode);
>          exit(1);
>      }
>  }
> -- 
> 1.6.5.2
> 
> 
> 
>
Richard Henderson Dec. 13, 2009, 7:54 p.m. UTC | #2
On 12/13/2009 11:28 AM, Aurelien Jarno wrote:
> Is it really necessary to flush all the TB here? QEMU should already
> discard TB that have been modified.

No.  But I meant to look into this more carefully with a view to 
disabling the other checking within QEMU and speed things up a tad.  It 
seems to me that the explicit checking with each memory write ought to 
only be necessary on architectures like x86 that don't architecturally 
require a flush insn to be used.

I can drop this fragment if necessary for patch acceptance, however.


r~
Aurelien Jarno Dec. 13, 2009, 8:47 p.m. UTC | #3
On Sun, Dec 13, 2009 at 11:54:02AM -0800, Richard Henderson wrote:
> On 12/13/2009 11:28 AM, Aurelien Jarno wrote:
> >Is it really necessary to flush all the TB here? QEMU should already
> >discard TB that have been modified.
> 
> No.  But I meant to look into this more carefully with a view to
> disabling the other checking within QEMU and speed things up a tad.
> It seems to me that the explicit checking with each memory write
> ought to only be necessary on architectures like x86 that don't
> architecturally require a flush insn to be used.

This is actually done only on the first write access to a page and not
to each write, so it should not be so costly. It is however something
to investigate, as I agree that removing the checks can add some 
speed-up.

> I can drop this fragment if necessary for patch acceptance, however.
> 

I think it is better to drop it until we have a better view of the whole
thing. You can add a comment saying that an optimisation might be
possible here.
diff mbox

Patch

diff --git a/hw/alpha_palcode.c b/hw/alpha_palcode.c
index c48a297..44b2ca4 100644
--- a/hw/alpha_palcode.c
+++ b/hw/alpha_palcode.c
@@ -1062,6 +1062,16 @@  void call_pal (CPUState *env, int palcode)
 
     qemu_log("%s: palcode %02x\n", __func__, palcode);
     switch (palcode) {
+    case 0x80:
+        /* BPT */
+        qemu_log("BPT\n");
+        /* FIXME: Sends SIGTRAP, si_code=TRAP_BRKPT.  */
+        exit(1);
+    case 0x81:
+        /* BUGCHK */
+        qemu_log("BUGCHK\n");
+        /* FIXME: Sends SIGTRAP, si_code=SI_FAULT.  */
+        exit(1);
     case 0x83:
         /* CALLSYS */
         qemu_log("CALLSYS n " TARGET_FMT_ld "\n", env->ir[0]);
@@ -1076,6 +1086,11 @@  void call_pal (CPUState *env, int palcode)
             env->ir[IR_V0] = -ret;
         }
         break;
+    case 0x86:
+        /* IMB */
+        qemu_log("IMB\n");
+        tb_flush(env);
+        break;
     case 0x9E:
         /* RDUNIQUE */
         env->ir[IR_V0] = env->unique;
@@ -1086,9 +1101,19 @@  void call_pal (CPUState *env, int palcode)
         env->unique = env->ir[IR_A0];
         qemu_log("WRUNIQUE: " TARGET_FMT_lx "\n", env->unique);
         break;
+    case 0xAA:
+        /* GENTRAP */
+        qemu_log("GENTRAP: " TARGET_FMT_lx "\n", env->ir[IR_A0]);
+        /* FIXME: This is supposed to send a signal:
+           SIGFPE:
+             GEN_INTOVF, GEN_INTDIV, GEN_FLTOVF, GEN_FLTDIV,
+             GEN_FLTUND, GEN_FLTINV, GEN_FLTINE, GEN_ROPRAND
+           SIGTRAP:
+             others
+           with various settings of si_code.  */
+        exit(1);
     default:
-        qemu_log("%s: unhandled palcode %02x\n",
-                    __func__, palcode);
+        qemu_log("%s: unhandled palcode %02x\n", __func__, palcode);
         exit(1);
     }
 }