All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] RFC: cleanups: CPU_MEM_INDEX
@ 2007-10-09 19:33 J. Mayer
  2007-10-10  0:12 ` Thiemo Seufer
  0 siblings, 1 reply; 9+ messages in thread
From: J. Mayer @ 2007-10-09 19:33 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 520 bytes --]

Here's a proposal to add a int cpu_mem_index (CPUState *env) function in
targets cpu.h header.
The idea of this patch is:
- avoid many #ifdef TARGET_xxx in exec-all.h and  softmmu_header.h then
make the code more readable
- avoid multiple implementation of the same code (3, in that particular
case) this to avoid potential conflicts if the definition has to be
updated for any reason (ie support for new memory access modes,
emulation optimisation...)

Please comment.

-- 
J. Mayer <l_indien@magic.fr>
Never organized

[-- Attachment #2: cpu_mem_index.diff --]
[-- Type: text/x-patch, Size: 10388 bytes --]

Index: cpu-exec.c
===================================================================
RCS file: /sources/qemu/qemu/cpu-exec.c,v
retrieving revision 1.119
diff -u -d -d -p -r1.119 cpu-exec.c
--- cpu-exec.c	8 Oct 2007 13:16:13 -0000	1.119
+++ cpu-exec.c	9 Oct 2007 10:36:07 -0000
@@ -885,7 +885,7 @@ static inline int handle_cpu_signal(unsi
 
     /* see if it is an MMU fault */
     ret = cpu_x86_handle_mmu_fault(env, address, is_write,
-                                   ((env->hflags & HF_CPL_MASK) == 3), 0);
+                                   cpu_mem_index(env), 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1007,7 +1009,8 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, msr_pr, 0);
+    ret = cpu_ppc_handle_mmu_fault(env, address, is_write,
+                                   cpu_mem_index(env), 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1191,7 +1197,8 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_alpha_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_alpha_handle_mmu_fault(env, address, is_write,
+                                     cpu_mem_index(env), 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
Index: exec-all.h
===================================================================
RCS file: /sources/qemu/qemu/exec-all.h,v
retrieving revision 1.67
diff -u -d -d -p -r1.67 exec-all.h
--- exec-all.h	8 Oct 2007 13:16:14 -0000	1.67
+++ exec-all.h	9 Oct 2007 10:36:07 -0000
@@ -601,27 +606,7 @@ static inline target_ulong get_phys_addr
     int is_user, index, pd;
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-#if defined(TARGET_I386)
-    is_user = ((env->hflags & HF_CPL_MASK) == 3);
-#elif defined (TARGET_PPC)
-    is_user = msr_pr;
-#elif defined (TARGET_MIPS)
-    is_user = ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
-#elif defined (TARGET_SPARC)
-    is_user = (env->psrs == 0);
-#elif defined (TARGET_ARM)
-    is_user = ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR);
-#elif defined (TARGET_SH4)
-    is_user = ((env->sr & SR_MD) == 0);
-#elif defined (TARGET_ALPHA)
-    is_user = ((env->ps >> 3) & 3);
-#elif defined (TARGET_M68K)
-    is_user = ((env->sr & SR_S) == 0);
-#elif defined (TARGET_CRIS)
-    is_user = (0);
-#else
-#error unimplemented CPU
-#endif
+    is_user = cpu_mem_index(env);
     if (__builtin_expect(env->tlb_table[is_user][index].addr_code !=
                          (addr & TARGET_PAGE_MASK), 0)) {
         ldub_code(addr);
Index: softmmu_header.h
===================================================================
RCS file: /sources/qemu/qemu/softmmu_header.h,v
retrieving revision 1.17
diff -u -d -d -p -r1.17 softmmu_header.h
--- softmmu_header.h	8 Oct 2007 13:16:14 -0000	1.17
+++ softmmu_header.h	9 Oct 2007 10:36:07 -0000
@@ -51,54 +51,12 @@
 
 #elif ACCESS_TYPE == 2
 
-#ifdef TARGET_I386
-#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
-#elif defined (TARGET_PPC)
-#define CPU_MEM_INDEX (msr_pr)
-#elif defined (TARGET_MIPS)
-#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
-#elif defined (TARGET_SPARC)
-#define CPU_MEM_INDEX ((env->psrs) == 0)
-#elif defined (TARGET_ARM)
-#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
-#elif defined (TARGET_SH4)
-#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
-#elif defined (TARGET_ALPHA)
-#define CPU_MEM_INDEX ((env->ps >> 3) & 3)
-#elif defined (TARGET_M68K)
-#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)
-#elif defined (TARGET_CRIS)
-/* CRIS FIXME: I guess we want to validate supervisor mode acceses here.  */
-#define CPU_MEM_INDEX (0)
-#else
-#error unsupported CPU
-#endif
+#define CPU_MEM_INDEX (cpu_mem_index(env))
 #define MMUSUFFIX _mmu
 
 #elif ACCESS_TYPE == 3
 
-#ifdef TARGET_I386
-#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
-#elif defined (TARGET_PPC)
-#define CPU_MEM_INDEX (msr_pr)
-#elif defined (TARGET_MIPS)
-#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
-#elif defined (TARGET_SPARC)
-#define CPU_MEM_INDEX ((env->psrs) == 0)
-#elif defined (TARGET_ARM)
-#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
-#elif defined (TARGET_SH4)
-#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
-#elif defined (TARGET_ALPHA)
-#define CPU_MEM_INDEX ((env->ps >> 3) & 3)
-#elif defined (TARGET_M68K)
-#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)
-#elif defined (TARGET_CRIS)
-/* CRIS FIXME: I guess we want to validate supervisor mode acceses here.  */
-#define CPU_MEM_INDEX (0)
-#else
-#error unsupported CPU
-#endif
+#define CPU_MEM_INDEX (cpu_mem_index(env))
 #define MMUSUFFIX _cmmu
 
 #else
Index: target-alpha/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-alpha/cpu.h,v
retrieving revision 1.8
diff -u -d -d -p -r1.8 cpu.h
--- target-alpha/cpu.h	27 Sep 2007 16:44:31 -0000	1.8
+++ target-alpha/cpu.h	9 Oct 2007 10:36:07 -0000
@@ -302,6 +302,11 @@ struct CPUAlphaState {
 #define cpu_gen_code cpu_alpha_gen_code
 #define cpu_signal_handler cpu_alpha_signal_handler
 
+static inline int cpu_mem_index (CPUState *env)
+{
+    return (env->ps >> 3) & 3;
+}
+
 #include "cpu-all.h"
 
 enum {
Index: target-arm/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-arm/cpu.h,v
retrieving revision 1.34
diff -u -d -d -p -r1.34 cpu.h
--- target-arm/cpu.h	27 Sep 2007 16:44:31 -0000	1.34
+++ target-arm/cpu.h	9 Oct 2007 10:36:07 -0000
@@ -300,6 +300,11 @@ void cpu_arm_set_cp_io(CPUARMState *env,
 #define cpu_gen_code cpu_arm_gen_code
 #define cpu_signal_handler cpu_arm_signal_handler
 
+static inline int cpu_mem_index (CPUState *env)
+{
+    return (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR;
+}
+
 #include "cpu-all.h"
 
 #endif
Index: target-cris/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-cris/cpu.h,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 cpu.h
--- target-cris/cpu.h	8 Oct 2007 13:04:02 -0000	1.1
+++ target-cris/cpu.h	9 Oct 2007 10:36:07 -0000
@@ -229,6 +229,12 @@ void register_cris_insns (CPUCRISState *
 #define cpu_gen_code cpu_cris_gen_code
 #define cpu_signal_handler cpu_cris_signal_handler
 
+/* CRIS FIXME: I guess we want to validate supervisor mode acceses here.  */
+static inline int cpu_mem_index (CPUState *env)
+{
+    return 0;
+}
+
 #include "cpu-all.h"
 
 /* Register aliases.  */
Index: target-i386/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-i386/cpu.h,v
retrieving revision 1.50
diff -u -d -d -p -r1.50 cpu.h
--- target-i386/cpu.h	27 Sep 2007 16:44:31 -0000	1.50
+++ target-i386/cpu.h	9 Oct 2007 10:36:07 -0000
@@ -688,6 +688,11 @@ static inline int cpu_get_time_fast(void
 #define cpu_gen_code cpu_x86_gen_code
 #define cpu_signal_handler cpu_x86_signal_handler
 
+static inline int cpu_mem_index (CPUState *env)
+{
+    return (env->hflags & HF_CPL_MASK) == 3;
+}
+
 #include "cpu-all.h"
 
 #include "svm.h"
Index: target-m68k/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-m68k/cpu.h,v
retrieving revision 1.13
diff -u -d -d -p -r1.13 cpu.h
--- target-m68k/cpu.h	17 Sep 2007 08:09:53 -0000	1.13
+++ target-m68k/cpu.h	9 Oct 2007 10:36:07 -0000
@@ -223,6 +223,11 @@ void register_m68k_insns (CPUM68KState *
 #define cpu_gen_code cpu_m68k_gen_code
 #define cpu_signal_handler cpu_m68k_signal_handler
 
+static inline int cpu_mem_index (CPUState *env)
+{
+    return (env->sr & SR_S) == 0;
+}
+
 #include "cpu-all.h"
 
 #endif
Index: target-mips/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-mips/cpu.h,v
retrieving revision 1.47
diff -u -d -d -p -r1.47 cpu.h
--- target-mips/cpu.h	27 Sep 2007 16:44:31 -0000	1.47
+++ target-mips/cpu.h	9 Oct 2007 10:36:07 -0000
@@ -483,6 +483,11 @@ int cpu_mips_register (CPUMIPSState *env
 #define cpu_gen_code cpu_mips_gen_code
 #define cpu_signal_handler cpu_mips_signal_handler
 
+static inline int cpu_mem_index (CPUState *env)
+{
+    return (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM;
+}
+
 #include "cpu-all.h"
 
 /* Memory access type :
Index: target-ppc/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/cpu.h,v
retrieving revision 1.78
diff -u -d -d -p -r1.78 cpu.h
--- target-ppc/cpu.h	8 Oct 2007 02:58:07 -0000	1.78
+++ target-ppc/cpu.h	9 Oct 2007 10:36:07 -0000
@@ -698,6 +696,16 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, i
 #define cpu_gen_code cpu_ppc_gen_code
 #define cpu_signal_handler cpu_ppc_signal_handler
 
+static inline int cpu_mem_index (CPUState *env)
+{
+#if defined(TARGET_PPC64H)
+    if (msr_pr == 0 && msr_hv == 1)
+        return 2;
+    else
+#endif
+        return msr_pr;
+}
+
 #include "cpu-all.h"
 
 /*****************************************************************************/
Index: target-sh4/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/cpu.h,v
retrieving revision 1.10
diff -u -d -d -p -r1.10 cpu.h
--- target-sh4/cpu.h	16 Sep 2007 21:08:05 -0000	1.10
+++ target-sh4/cpu.h	9 Oct 2007 10:36:07 -0000
@@ -134,6 +134,11 @@ int cpu_sh4_signal_handler(int host_sign
 #define cpu_gen_code cpu_sh4_gen_code
 #define cpu_signal_handler cpu_sh4_signal_handler
 
+static inline int cpu_mem_index (CPUState *env)
+{
+    return (env->sr & SR_MD) == 0;
+}
+
 #include "cpu-all.h"
 
 /* Memory access type */
Index: target-sparc/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/cpu.h,v
retrieving revision 1.52
diff -u -d -d -p -r1.52 cpu.h
--- target-sparc/cpu.h	27 Sep 2007 16:44:32 -0000	1.52
+++ target-sparc/cpu.h	9 Oct 2007 10:36:07 -0000
@@ -316,6 +316,11 @@ void cpu_check_irqs(CPUSPARCState *env);
 #define cpu_gen_code cpu_sparc_gen_code
 #define cpu_signal_handler cpu_sparc_signal_handler
 
+static inline int cpu_mem_index (CPUState *env)
+{
+    return env->psrs == 0;
+}
+
 #include "cpu-all.h"
 
 #endif

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

* Re: [Qemu-devel] RFC: cleanups: CPU_MEM_INDEX
  2007-10-09 19:33 [Qemu-devel] RFC: cleanups: CPU_MEM_INDEX J. Mayer
@ 2007-10-10  0:12 ` Thiemo Seufer
  2007-10-10  5:06   ` J. Mayer
  0 siblings, 1 reply; 9+ messages in thread
From: Thiemo Seufer @ 2007-10-10  0:12 UTC (permalink / raw)
  To: J. Mayer; +Cc: qemu-devel

J. Mayer wrote:
> Here's a proposal to add a int cpu_mem_index (CPUState *env) function in
> targets cpu.h header.
> The idea of this patch is:
> - avoid many #ifdef TARGET_xxx in exec-all.h and  softmmu_header.h then
> make the code more readable
> - avoid multiple implementation of the same code (3, in that particular
> case) this to avoid potential conflicts if the definition has to be
> updated for any reason (ie support for new memory access modes,
> emulation optimisation...)
> 
> Please comment.
> 
> -- 
> J. Mayer <l_indien@magic.fr>
> Never organized

> Index: cpu-exec.c
> ===================================================================
> RCS file: /sources/qemu/qemu/cpu-exec.c,v
> retrieving revision 1.119
> diff -u -d -d -p -r1.119 cpu-exec.c
> --- cpu-exec.c	8 Oct 2007 13:16:13 -0000	1.119
> +++ cpu-exec.c	9 Oct 2007 10:36:07 -0000
> @@ -885,7 +885,7 @@ static inline int handle_cpu_signal(unsi
>  
>      /* see if it is an MMU fault */
>      ret = cpu_x86_handle_mmu_fault(env, address, is_write,
> -                                   ((env->hflags & HF_CPL_MASK) == 3), 0);
> +                                   cpu_mem_index(env), 0);
>      if (ret < 0)
>          return 0; /* not an MMU fault */
>      if (ret == 0)
> @@ -1007,7 +1009,8 @@ static inline int handle_cpu_signal(unsi
>      }
>  
>      /* see if it is an MMU fault */
> -    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, msr_pr, 0);
> +    ret = cpu_ppc_handle_mmu_fault(env, address, is_write,
> +                                   cpu_mem_index(env), 0);
>      if (ret < 0)
>          return 0; /* not an MMU fault */
>      if (ret == 0)
> @@ -1191,7 +1197,8 @@ static inline int handle_cpu_signal(unsi
>      }
>  
>      /* see if it is an MMU fault */
> -    ret = cpu_alpha_handle_mmu_fault(env, address, is_write, 1, 0);
> +    ret = cpu_alpha_handle_mmu_fault(env, address, is_write,
> +                                     cpu_mem_index(env), 0);

I have the feeling some architectures are missing here. :-)

>      if (ret < 0)
>          return 0; /* not an MMU fault */
>      if (ret == 0)
> Index: exec-all.h
> ===================================================================
> RCS file: /sources/qemu/qemu/exec-all.h,v
> retrieving revision 1.67
> diff -u -d -d -p -r1.67 exec-all.h
> --- exec-all.h	8 Oct 2007 13:16:14 -0000	1.67
> +++ exec-all.h	9 Oct 2007 10:36:07 -0000
> @@ -601,27 +606,7 @@ static inline target_ulong get_phys_addr
>      int is_user, index, pd;
>  
>      index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
> -#if defined(TARGET_I386)
> -    is_user = ((env->hflags & HF_CPL_MASK) == 3);
> -#elif defined (TARGET_PPC)
> -    is_user = msr_pr;
> -#elif defined (TARGET_MIPS)
> -    is_user = ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
> -#elif defined (TARGET_SPARC)
> -    is_user = (env->psrs == 0);
> -#elif defined (TARGET_ARM)
> -    is_user = ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR);
> -#elif defined (TARGET_SH4)
> -    is_user = ((env->sr & SR_MD) == 0);
> -#elif defined (TARGET_ALPHA)
> -    is_user = ((env->ps >> 3) & 3);
> -#elif defined (TARGET_M68K)
> -    is_user = ((env->sr & SR_S) == 0);
> -#elif defined (TARGET_CRIS)
> -    is_user = (0);
> -#else
> -#error unimplemented CPU
> -#endif
> +    is_user = cpu_mem_index(env);
>      if (__builtin_expect(env->tlb_table[is_user][index].addr_code !=
>                           (addr & TARGET_PAGE_MASK), 0)) {

I presume cpu_mem_index is supposed to do more than checking for
usermode. In that case, is_user should get renamed, and the
cpu_mem_index implementation of some (most?) CPUs should have a
FIXME comment as reminder to implement the missing MMU modes.

Other than that it looks good to me (and reminds me to check what the
supervisor mode on MIPS actually does now :-).


Thiemo

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

* Re: [Qemu-devel] RFC: cleanups: CPU_MEM_INDEX
  2007-10-10  0:12 ` Thiemo Seufer
@ 2007-10-10  5:06   ` J. Mayer
  2007-10-11 12:09     ` J. Mayer
  0 siblings, 1 reply; 9+ messages in thread
From: J. Mayer @ 2007-10-10  5:06 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 7499 bytes --]

On Wed, 2007-10-10 at 01:12 +0100, Thiemo Seufer wrote:
> J. Mayer wrote:
> > Here's a proposal to add a int cpu_mem_index (CPUState *env) function in
> > targets cpu.h header.
> > The idea of this patch is:
> > - avoid many #ifdef TARGET_xxx in exec-all.h and  softmmu_header.h then
> > make the code more readable
> > - avoid multiple implementation of the same code (3, in that particular
> > case) this to avoid potential conflicts if the definition has to be
> > updated for any reason (ie support for new memory access modes,
> > emulation optimisation...)
> > 
> > Please comment.
> > 
> > -- 
> > J. Mayer <l_indien@magic.fr>
> > Never organized
> 
> > Index: cpu-exec.c
> > ===================================================================
> > RCS file: /sources/qemu/qemu/cpu-exec.c,v
> > retrieving revision 1.119
> > diff -u -d -d -p -r1.119 cpu-exec.c
> > --- cpu-exec.c	8 Oct 2007 13:16:13 -0000	1.119
> > +++ cpu-exec.c	9 Oct 2007 10:36:07 -0000
> > @@ -885,7 +885,7 @@ static inline int handle_cpu_signal(unsi
> >  
> >      /* see if it is an MMU fault */
> >      ret = cpu_x86_handle_mmu_fault(env, address, is_write,
> > -                                   ((env->hflags & HF_CPL_MASK) == 3), 0);
> > +                                   cpu_mem_index(env), 0);
> >      if (ret < 0)
> >          return 0; /* not an MMU fault */
> >      if (ret == 0)
> > @@ -1007,7 +1009,8 @@ static inline int handle_cpu_signal(unsi
> >      }
> >  
> >      /* see if it is an MMU fault */
> > -    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, msr_pr, 0);
> > +    ret = cpu_ppc_handle_mmu_fault(env, address, is_write,
> > +                                   cpu_mem_index(env), 0);
> >      if (ret < 0)
> >          return 0; /* not an MMU fault */
> >      if (ret == 0)
> > @@ -1191,7 +1197,8 @@ static inline int handle_cpu_signal(unsi
> >      }
> >  
> >      /* see if it is an MMU fault */
> > -    ret = cpu_alpha_handle_mmu_fault(env, address, is_write, 1, 0);
> > +    ret = cpu_alpha_handle_mmu_fault(env, address, is_write,
> > +                                     cpu_mem_index(env), 0);
> 
> I have the feeling some architectures are missing here. :-)

Right, but as this code is used only with !CONFIG_SOFTMMU, I wonder if
we really want to give the cpu_mem_index to the called function, as the
CPU emulation code may not maintain it properly in that case. Then, I
choosed not to change the current behavior: when the index was given to
cpu_handle_mmu_fault (or when I think it's safe), I still does it. When
it was hardcoded to 1, I did let it hardcoded.

> >      if (ret < 0)
> >          return 0; /* not an MMU fault */
> >      if (ret == 0)
> > Index: exec-all.h
> > ===================================================================
> > RCS file: /sources/qemu/qemu/exec-all.h,v
> > retrieving revision 1.67
> > diff -u -d -d -p -r1.67 exec-all.h
> > --- exec-all.h	8 Oct 2007 13:16:14 -0000	1.67
> > +++ exec-all.h	9 Oct 2007 10:36:07 -0000
> > @@ -601,27 +606,7 @@ static inline target_ulong get_phys_addr
> >      int is_user, index, pd;
> >  
> >      index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
> > -#if defined(TARGET_I386)
> > -    is_user = ((env->hflags & HF_CPL_MASK) == 3);
> > -#elif defined (TARGET_PPC)
> > -    is_user = msr_pr;
> > -#elif defined (TARGET_MIPS)
> > -    is_user = ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
> > -#elif defined (TARGET_SPARC)
> > -    is_user = (env->psrs == 0);
> > -#elif defined (TARGET_ARM)
> > -    is_user = ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR);
> > -#elif defined (TARGET_SH4)
> > -    is_user = ((env->sr & SR_MD) == 0);
> > -#elif defined (TARGET_ALPHA)
> > -    is_user = ((env->ps >> 3) & 3);
> > -#elif defined (TARGET_M68K)
> > -    is_user = ((env->sr & SR_S) == 0);
> > -#elif defined (TARGET_CRIS)
> > -    is_user = (0);
> > -#else
> > -#error unimplemented CPU
> > -#endif
> > +    is_user = cpu_mem_index(env);
> >      if (__builtin_expect(env->tlb_table[is_user][index].addr_code !=
> >                           (addr & TARGET_PAGE_MASK), 0)) {
> 
> I presume cpu_mem_index is supposed to do more than checking for
> usermode. In that case, is_user should get renamed, and the
> cpu_mem_index implementation of some (most?) CPUs should have a
> FIXME comment as reminder to implement the missing MMU modes.

You're right, calling this variable is_user is only valid because this
code supposes it knows what cpu_mem_index means. For targets with more
than 2 modes of execution, this is not correct.
My first idea was to try not to change the code too much. After thinking
more about the problem, it appears to me that:
1/ in the softmmu routines, we should do no assumption about the
signification of the memory index
2/ then, softmmu routines should use an index and all exported
interfaces (ie tlb_fill and handle_mmu_fault) should take an index
instead of is_user as an argument.
3/ to maintain compatibility with the existing code, I choosed to add a
is_user variable inside most handle_mmu_fault implementation,
initialized with the value of the given index, which is then given to
the target mmu translation routines.
4/ to ease implementation of targets with more than 2 execution modes, I
choosed to define a per-target NB_MMU_MODES in each target_xxx/cpu.h
(instead of the hack for PowerPC 64 and Alpha that did pre-exist) and
add a local definition of the meaning of each mmu_index index. Then, for
PowerPC, I choosed to use the same convention than I do in translate.c,
which seems more logical to me, then: 0 => user, 1 => supervisor, 2 =>
hypervisor.
5/ to avoid confusion between the memory index used in the translation
context, which may contain more than the access mode information, and
the one used by the softmmu routines, I choosed to name the one used in
softmmu 'mmu_idx' (the one in target_xxx/translate.c is called mem_idx).
6/ I choosed to add a constant MMU_USER_IDX which is used in the
user-mode handle_cpu_signal routine, then addressing your first remark.

This patch solves a problem I had no solution to until today: how to add
new mmu modes (ie hypervisor for PowerPC 64, supervisor and executive
for Alpha) for some specific targets.

The result is a much more invasive patch but the is supposed (!) to;
1/ do not change the behavior of the current targets implementations
2/ be less hardcoded, more flexible and extensible for any specific
targets requirements.
As this new version of the patch could deadly break the softmmu mode and
I got no way to properly check all targets, I would greatly appreciate
that some do some tests for arm, cris, m68k, mips, sh4 and sparc
targets.

For now, I did a few tests, running Linux (debian hdd installation) for
PowerPC on PPC 603 & 750 in 32 bits and 64 bits mode emulation on x86
and amd64 and a few OSes using the i386-softmmu emulation (Linux Gentoo,
solaris 10 installation CDROM, ...), with success; then I guess I did
not deadly broke everything !
The good point is that PowerPC runs, considering it is the only target
for which I did change the mmu_idx semantics...

> Other than that it looks good to me (and reminds me to check what the
> supervisor mode on MIPS actually does now :-).

This updated patch gives the opportunity to define a per-target semantic
of the mmu_idx... Time to check what it means in actual CPU
implementation !!!! ;-)

Thanks in advance for any comments or improvment suggestions....

-- 
J. Mayer <l_indien@magic.fr>
Never organized

[-- Attachment #2: cpu_mmu_index.diff --]
[-- Type: text/x-patch, Size: 78954 bytes --]

Index: cpu-defs.h
===================================================================
RCS file: /sources/qemu/qemu/cpu-defs.h,v
retrieving revision 1.24
diff -u -d -d -p -r1.24 cpu-defs.h
--- cpu-defs.h	19 Sep 2007 05:46:03 -0000	1.24
+++ cpu-defs.h	10 Oct 2007 03:29:03 -0000
@@ -112,15 +112,6 @@ typedef struct CPUTLBEntry {
     target_phys_addr_t addend;
 } CPUTLBEntry;
 
-/* Alpha has 4 different running levels */
-#if defined(TARGET_ALPHA)
-#define NB_MMU_MODES 4
-#elif defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
-#define NB_MMU_MODES 3
-#else
-#define NB_MMU_MODES 2
-#endif
-
 #define CPU_COMMON                                                      \
     struct TranslationBlock *current_tb; /* currently executing TB  */  \
     /* soft mmu support */                                              \
Index: cpu-exec.c
===================================================================
RCS file: /sources/qemu/qemu/cpu-exec.c,v
retrieving revision 1.119
diff -u -d -d -p -r1.119 cpu-exec.c
--- cpu-exec.c	8 Oct 2007 13:16:13 -0000	1.119
+++ cpu-exec.c	10 Oct 2007 03:29:04 -0000
@@ -884,8 +884,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_x86_handle_mmu_fault(env, address, is_write,
-                                   ((env->hflags & HF_CPL_MASK) == 3), 0);
+    ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -934,7 +933,7 @@ static inline int handle_cpu_signal(unsi
         return 1;
     }
     /* see if it is an MMU fault */
-    ret = cpu_arm_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -970,7 +970,7 @@ static inline int handle_cpu_signal(unsi
         return 1;
     }
     /* see if it is an MMU fault */
-    ret = cpu_sparc_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1007,7 +1008,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, msr_pr, 0);
+    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1056,7 +1057,7 @@ static inline int handle_cpu_signal(unsi
         return 1;
     }
     /* see if it is an MMU fault */
-    ret = cpu_m68k_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1096,7 +1098,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_mips_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1146,7 +1149,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_sh4_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1191,7 +1195,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_alpha_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1235,7 +1239,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_cris_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
Index: exec-all.h
===================================================================
RCS file: /sources/qemu/qemu/exec-all.h,v
retrieving revision 1.67
diff -u -d -d -p -r1.67 exec-all.h
--- exec-all.h	8 Oct 2007 13:16:14 -0000	1.67
+++ exec-all.h	10 Oct 2007 03:29:04 -0000
@@ -117,14 +122,14 @@ void tlb_flush_page(CPUState *env, targe
 void tlb_flush(CPUState *env, int flush_global);
 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
                       target_phys_addr_t paddr, int prot,
-                      int is_user, int is_softmmu);
+                      int mmu_idx, int is_softmmu);
 static inline int tlb_set_page(CPUState *env, target_ulong vaddr,
                                target_phys_addr_t paddr, int prot,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     if (prot & PAGE_READ)
         prot |= PAGE_EXEC;
-    return tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+    return tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
 }
 
 #define CODE_GEN_MAX_SIZE        65536
@@ -562,10 +567,10 @@ extern int tb_invalidated_flag;
 
 #if !defined(CONFIG_USER_ONLY)
 
-void tlb_fill(target_ulong addr, int is_write, int is_user,
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
               void *retaddr);
 
-#define ACCESS_TYPE 3
+#define ACCESS_TYPE (NB_MMU_MODES + 1)
 #define MEMSUFFIX _code
 #define env cpu_single_env
 
@@ -598,35 +603,15 @@ static inline target_ulong get_phys_addr
    is the offset relative to phys_ram_base */
 static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
 {
-    int is_user, index, pd;
+    int mmu_idx, index, pd;
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-#if defined(TARGET_I386)
-    is_user = ((env->hflags & HF_CPL_MASK) == 3);
-#elif defined (TARGET_PPC)
-    is_user = msr_pr;
-#elif defined (TARGET_MIPS)
-    is_user = ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
-#elif defined (TARGET_SPARC)
-    is_user = (env->psrs == 0);
-#elif defined (TARGET_ARM)
-    is_user = ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR);
-#elif defined (TARGET_SH4)
-    is_user = ((env->sr & SR_MD) == 0);
-#elif defined (TARGET_ALPHA)
-    is_user = ((env->ps >> 3) & 3);
-#elif defined (TARGET_M68K)
-    is_user = ((env->sr & SR_S) == 0);
-#elif defined (TARGET_CRIS)
-    is_user = (0);
-#else
-#error unimplemented CPU
-#endif
-    if (__builtin_expect(env->tlb_table[is_user][index].addr_code !=
+    mmu_idx = cpu_mmu_index(env);
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].addr_code !=
                          (addr & TARGET_PAGE_MASK), 0)) {
         ldub_code(addr);
     }
-    pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK;
+    pd = env->tlb_table[mmu_idx][index].addr_code & ~TARGET_PAGE_MASK;
     if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
 #ifdef TARGET_SPARC
         do_unassigned_access(addr, 0, 1, 0);
@@ -634,7 +619,7 @@ static inline target_ulong get_phys_addr
         cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);
 #endif
     }
-    return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base;
+    return addr + env->tlb_table[mmu_idx][index].addend - (unsigned long)phys_ram_base;
 }
 #endif
 
Index: exec.c
===================================================================
RCS file: /sources/qemu/qemu/exec.c,v
retrieving revision 1.108
diff -u -d -d -p -r1.108 exec.c
--- exec.c	8 Oct 2007 13:16:14 -0000	1.108
+++ exec.c	10 Oct 2007 03:29:04 -0000
@@ -1608,7 +1608,7 @@ static inline void tlb_set_dirty(CPUStat
    conflicting with the host address space). */
 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
                       target_phys_addr_t paddr, int prot,
-                      int is_user, int is_softmmu)
+                      int mmu_idx, int is_softmmu)
 {
     PhysPageDesc *p;
     unsigned long pd;
@@ -1626,8 +1626,8 @@ int tlb_set_page_exec(CPUState *env, tar
         pd = p->phys_offset;
     }
 #if defined(DEBUG_TLB)
-    printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x u=%d smmu=%d pd=0x%08lx\n",
-           vaddr, (int)paddr, prot, is_user, is_softmmu, pd);
+    printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x idx=%d smmu=%d pd=0x%08lx\n",
+           vaddr, (int)paddr, prot, mmu_idx, is_softmmu, pd);
 #endif
 
     ret = 0;
@@ -1664,7 +1664,7 @@ int tlb_set_page_exec(CPUState *env, tar
 
         index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
         addend -= vaddr;
-        te = &env->tlb_table[is_user][index];
+        te = &env->tlb_table[mmu_idx][index];
         te->addend = addend;
         if (prot & PAGE_READ) {
             te->addr_read = address;
@@ -1790,7 +1790,7 @@ void tlb_flush_page(CPUState *env, targe
 
 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
                       target_phys_addr_t paddr, int prot,
-                      int is_user, int is_softmmu)
+                      int mmu_idx, int is_softmmu)
 {
     return 0;
 }
Index: softmmu_exec.h
===================================================================
RCS file: /sources/qemu/qemu/softmmu_exec.h,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 softmmu_exec.h
--- softmmu_exec.h	30 Oct 2005 18:16:26 -0000	1.1
+++ softmmu_exec.h	10 Oct 2007 03:29:04 -0000
@@ -1,10 +1,16 @@
 /* Common softmmu definitions and inline routines.  */
 
-#define ldul_user ldl_user
-#define ldul_kernel ldl_kernel
+/* XXX: find something cleaner.
+ * Furthermore, this is false for 64 bits targets
+ */
+#define ldul_user       ldl_user
+#define ldul_kernel     ldl_kernel
+#define ldul_hypv       ldl_hypv
+#define ldul_executive  ldl_executive
+#define ldul_supervisor ldl_supervisor
 
 #define ACCESS_TYPE 0
-#define MEMSUFFIX _kernel
+#define MEMSUFFIX MMU_MODE0_SUFFIX
 #define DATA_SIZE 1
 #include "softmmu_header.h"
 
@@ -20,7 +26,7 @@
 #undef MEMSUFFIX
 
 #define ACCESS_TYPE 1
-#define MEMSUFFIX _user
+#define MEMSUFFIX MMU_MODE1_SUFFIX
 #define DATA_SIZE 1
 #include "softmmu_header.h"
 
@@ -35,8 +41,50 @@
 #undef ACCESS_TYPE
 #undef MEMSUFFIX
 
-/* these access are slower, they must be as rare as possible */
+#if (NB_MMU_MODES >= 3)
+
 #define ACCESS_TYPE 2
+#define MEMSUFFIX MMU_MODE2_SUFFIX
+#define DATA_SIZE 1
+#include "softmmu_header.h"
+
+#define DATA_SIZE 2
+#include "softmmu_header.h"
+
+#define DATA_SIZE 4
+#include "softmmu_header.h"
+
+#define DATA_SIZE 8
+#include "softmmu_header.h"
+#undef ACCESS_TYPE
+#undef MEMSUFFIX
+
+#if (NB_MMU_MODES >= 4)
+
+#define ACCESS_TYPE 3
+#define MEMSUFFIX MMU_MODE3_SUFFIX
+#define DATA_SIZE 1
+#include "softmmu_header.h"
+
+#define DATA_SIZE 2
+#include "softmmu_header.h"
+
+#define DATA_SIZE 4
+#include "softmmu_header.h"
+
+#define DATA_SIZE 8
+#include "softmmu_header.h"
+#undef ACCESS_TYPE
+#undef MEMSUFFIX
+
+#if (NB_MMU_MODES > 4)
+#error "NB_MMU_MODES > 4 is not supported for now"
+#endif /* (NB_MMU_MODES > 4) */
+#endif /* (NB_MMU_MODES == 4) */
+#endif /* (NB_MMU_MODES >= 3) */
+
+/* these access are slower, they must be as rare as possible */
+#define ACCESS_TYPE (NB_MMU_MODES)
 #define MEMSUFFIX _data
 #define DATA_SIZE 1
 #include "softmmu_header.h"
Index: softmmu_header.h
===================================================================
RCS file: /sources/qemu/qemu/softmmu_header.h,v
retrieving revision 1.17
diff -u -d -d -p -r1.17 softmmu_header.h
--- softmmu_header.h	8 Oct 2007 13:16:14 -0000	1.17
+++ softmmu_header.h	10 Oct 2007 03:29:04 -0000
@@ -39,66 +39,19 @@
 #error unsupported data size
 #endif
 
-#if ACCESS_TYPE == 0
-
-#define CPU_MEM_INDEX 0
-#define MMUSUFFIX _mmu
-
-#elif ACCESS_TYPE == 1
+#if ACCESS_TYPE < (NB_MMU_MODES)
 
-#define CPU_MEM_INDEX 1
+#define CPU_MMU_INDEX ACCESS_TYPE
 #define MMUSUFFIX _mmu
 
-#elif ACCESS_TYPE == 2
+#elif ACCESS_TYPE == (NB_MMU_MODES)
 
-#ifdef TARGET_I386
-#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
-#elif defined (TARGET_PPC)
-#define CPU_MEM_INDEX (msr_pr)
-#elif defined (TARGET_MIPS)
-#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
-#elif defined (TARGET_SPARC)
-#define CPU_MEM_INDEX ((env->psrs) == 0)
-#elif defined (TARGET_ARM)
-#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
-#elif defined (TARGET_SH4)
-#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
-#elif defined (TARGET_ALPHA)
-#define CPU_MEM_INDEX ((env->ps >> 3) & 3)
-#elif defined (TARGET_M68K)
-#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)
-#elif defined (TARGET_CRIS)
-/* CRIS FIXME: I guess we want to validate supervisor mode acceses here.  */
-#define CPU_MEM_INDEX (0)
-#else
-#error unsupported CPU
-#endif
+#define CPU_MMU_INDEX (cpu_mmu_index(env))
 #define MMUSUFFIX _mmu
 
-#elif ACCESS_TYPE == 3
+#elif ACCESS_TYPE == (NB_MMU_MODES + 1)
 
-#ifdef TARGET_I386
-#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
-#elif defined (TARGET_PPC)
-#define CPU_MEM_INDEX (msr_pr)
-#elif defined (TARGET_MIPS)
-#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
-#elif defined (TARGET_SPARC)
-#define CPU_MEM_INDEX ((env->psrs) == 0)
-#elif defined (TARGET_ARM)
-#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
-#elif defined (TARGET_SH4)
-#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
-#elif defined (TARGET_ALPHA)
-#define CPU_MEM_INDEX ((env->ps >> 3) & 3)
-#elif defined (TARGET_M68K)
-#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)
-#elif defined (TARGET_CRIS)
-/* CRIS FIXME: I guess we want to validate supervisor mode acceses here.  */
-#define CPU_MEM_INDEX (0)
-#else
-#error unsupported CPU
-#endif
+#define CPU_MMU_INDEX (cpu_mmu_index(env))
 #define MMUSUFFIX _cmmu
 
 #else
@@ -111,15 +64,15 @@
 #define RES_TYPE int
 #endif
 
-#if ACCESS_TYPE == 3
+#if ACCESS_TYPE == (NB_MMU_MODES + 1)
 #define ADDR_READ addr_code
 #else
 #define ADDR_READ addr_read
 #endif
 
 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                         int is_user);
-void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int is_user);
+                                                         int mmu_idx);
+void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int mmu_idx);
 
 #if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
     (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU)
@@ -161,8 +114,8 @@ static inline RES_TYPE glue(glue(ld, USU
                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
-                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
-                  "i" (CPU_MEM_INDEX),
+                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
+                  "i" (CPU_MMU_INDEX),
                   "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
                   : "%eax", "%ecx", "%edx", "memory", "cc");
     return res;
@@ -208,8 +161,8 @@ static inline int glue(glue(lds, SUFFIX)
                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
-                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
-                  "i" (CPU_MEM_INDEX),
+                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
+                  "i" (CPU_MMU_INDEX),
                   "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
                   : "%eax", "%ecx", "%edx", "memory", "cc");
     return res;
@@ -260,8 +213,8 @@ static inline void glue(glue(st, SUFFIX)
                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
-                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_write)),
-                  "i" (CPU_MEM_INDEX),
+                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)),
+                  "i" (CPU_MMU_INDEX),
                   "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
                   : "%eax", "%ecx", "%edx", "memory", "cc");
 }
@@ -276,16 +229,16 @@ static inline RES_TYPE glue(glue(ld, USU
     RES_TYPE res;
     target_ulong addr;
     unsigned long physaddr;
-    int is_user;
+    int mmu_idx;
 
     addr = ptr;
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    is_user = CPU_MEM_INDEX;
-    if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
+    mmu_idx = CPU_MMU_INDEX;
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].ADDR_READ !=
                          (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
-        res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
+        res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
     } else {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
     }
     return res;
@@ -297,23 +250,23 @@ static inline int glue(glue(lds, SUFFIX)
     int res, index;
     target_ulong addr;
     unsigned long physaddr;
-    int is_user;
+    int mmu_idx;
 
     addr = ptr;
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    is_user = CPU_MEM_INDEX;
-    if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
+    mmu_idx = CPU_MMU_INDEX;
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].ADDR_READ !=
                          (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
-        res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
+        res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
     } else {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
     }
     return res;
 }
 #endif
 
-#if ACCESS_TYPE != 3
+#if ACCESS_TYPE != (NB_MMU_MODES + 1)
 
 /* generic store macro */
 
@@ -322,25 +275,25 @@ static inline void glue(glue(st, SUFFIX)
     int index;
     target_ulong addr;
     unsigned long physaddr;
-    int is_user;
+    int mmu_idx;
 
     addr = ptr;
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    is_user = CPU_MEM_INDEX;
-    if (__builtin_expect(env->tlb_table[is_user][index].addr_write !=
+    mmu_idx = CPU_MMU_INDEX;
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].addr_write !=
                          (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
-        glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user);
+        glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx);
     } else {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
     }
 }
 
-#endif /* ACCESS_TYPE != 3 */
+#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
 
 #endif /* !asm */
 
-#if ACCESS_TYPE != 3
+#if ACCESS_TYPE != (NB_MMU_MODES + 1)
 
 #if DATA_SIZE == 8
 static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
@@ -386,7 +339,7 @@ static inline void glue(stfl, MEMSUFFIX)
 }
 #endif /* DATA_SIZE == 4 */
 
-#endif /* ACCESS_TYPE != 3 */
+#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
 
 #undef RES_TYPE
 #undef DATA_TYPE
@@ -394,6 +347,6 @@ static inline void glue(stfl, MEMSUFFIX)
 #undef SUFFIX
 #undef USUFFIX
 #undef DATA_SIZE
-#undef CPU_MEM_INDEX
+#undef CPU_MMU_INDEX
 #undef MMUSUFFIX
 #undef ADDR_READ
Index: softmmu_template.h
===================================================================
RCS file: /sources/qemu/qemu/softmmu_template.h,v
retrieving revision 1.18
diff -u -d -d -p -r1.18 softmmu_template.h
--- softmmu_template.h	17 Sep 2007 08:09:45 -0000	1.18
+++ softmmu_template.h	10 Oct 2007 03:29:04 -0000
@@ -48,7 +48,7 @@
 #endif
 
 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                        int is_user,
+                                                        int mmu_idx,
                                                         void *retaddr);
 static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
                                               target_ulong tlb_addr)
@@ -76,7 +76,7 @@ static inline DATA_TYPE glue(io_read, SU
 
 /* handle all cases except unaligned access which span two pages */
 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                         int is_user)
+                                                         int mmu_idx)
 {
     DATA_TYPE res;
     int index;
@@ -88,9 +88,9 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF
     /* XXX: could done more in memory macro in a non portable way */
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
+    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -101,16 +101,16 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF
         do_unaligned_access:
             retaddr = GETPC();
 #ifdef ALIGNED_ONLY
-            do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
+            do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
 #endif
             res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
-                                                         is_user, retaddr);
+                                                         mmu_idx, retaddr);
         } else {
             /* unaligned/aligned access in the same page */
 #ifdef ALIGNED_ONLY
             if ((addr & (DATA_SIZE - 1)) != 0) {
                 retaddr = GETPC();
-                do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
+                do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
             }
 #endif
             res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr);
@@ -120,9 +120,9 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF
         retaddr = GETPC();
 #ifdef ALIGNED_ONLY
         if ((addr & (DATA_SIZE - 1)) != 0)
-            do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
+            do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
 #endif
-        tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
+        tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
         goto redo;
     }
     return res;
@@ -130,7 +130,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF
 
 /* handle all unaligned cases */
 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                        int is_user,
+                                                        int mmu_idx,
                                                         void *retaddr)
 {
     DATA_TYPE res, res1, res2;
@@ -140,9 +140,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFF
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
+    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -154,9 +154,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFF
             addr1 = addr & ~(DATA_SIZE - 1);
             addr2 = addr1 + DATA_SIZE;
             res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1,
-                                                          is_user, retaddr);
+                                                          mmu_idx, retaddr);
             res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2,
-                                                          is_user, retaddr);
+                                                          mmu_idx, retaddr);
             shift = (addr & (DATA_SIZE - 1)) * 8;
 #ifdef TARGET_WORDS_BIGENDIAN
             res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
@@ -170,7 +170,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFF
         }
     } else {
         /* the page is not in the TLB : fill it */
-        tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
+        tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
         goto redo;
     }
     return res;
@@ -180,7 +180,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFF
 
 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                    DATA_TYPE val,
-                                                   int is_user,
+                                                   int mmu_idx,
                                                    void *retaddr);
 
 static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
@@ -211,7 +211,7 @@ static inline void glue(io_write, SUFFIX
 
 void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                     DATA_TYPE val,
-                                                    int is_user)
+                                                    int mmu_idx)
 {
     target_phys_addr_t physaddr;
     target_ulong tlb_addr;
@@ -220,9 +220,9 @@ void REGPARM(2) glue(glue(__st, SUFFIX),
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].addr_write;
+    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -233,16 +233,16 @@ void REGPARM(2) glue(glue(__st, SUFFIX),
         do_unaligned_access:
             retaddr = GETPC();
 #ifdef ALIGNED_ONLY
-            do_unaligned_access(addr, 1, is_user, retaddr);
+            do_unaligned_access(addr, 1, mmu_idx, retaddr);
 #endif
             glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
-                                                   is_user, retaddr);
+                                                   mmu_idx, retaddr);
         } else {
             /* aligned/unaligned access in the same page */
 #ifdef ALIGNED_ONLY
             if ((addr & (DATA_SIZE - 1)) != 0) {
                 retaddr = GETPC();
-                do_unaligned_access(addr, 1, is_user, retaddr);
+                do_unaligned_access(addr, 1, mmu_idx, retaddr);
             }
 #endif
             glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val);
@@ -252,9 +252,9 @@ void REGPARM(2) glue(glue(__st, SUFFIX),
         retaddr = GETPC();
 #ifdef ALIGNED_ONLY
         if ((addr & (DATA_SIZE - 1)) != 0)
-            do_unaligned_access(addr, 1, is_user, retaddr);
+            do_unaligned_access(addr, 1, mmu_idx, retaddr);
 #endif
-        tlb_fill(addr, 1, is_user, retaddr);
+        tlb_fill(addr, 1, mmu_idx, retaddr);
         goto redo;
     }
 }
@@ -262,7 +262,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX),
 /* handles all unaligned cases */
 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                    DATA_TYPE val,
-                                                   int is_user,
+                                                   int mmu_idx,
                                                    void *retaddr)
 {
     target_phys_addr_t physaddr;
@@ -271,9 +271,9 @@ static void glue(glue(slow_st, SUFFIX), 
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].addr_write;
+    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -285,10 +285,10 @@ static void glue(glue(slow_st, SUFFIX), 
             for(i = 0;i < DATA_SIZE; i++) {
 #ifdef TARGET_WORDS_BIGENDIAN
                 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
-                                          is_user, retaddr);
+                                          mmu_idx, retaddr);
 #else
                 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8),
-                                          is_user, retaddr);
+                                          mmu_idx, retaddr);
 #endif
             }
         } else {
@@ -297,7 +297,7 @@ static void glue(glue(slow_st, SUFFIX), 
         }
     } else {
         /* the page is not in the TLB : fill it */
-        tlb_fill(addr, 1, is_user, retaddr);
+        tlb_fill(addr, 1, mmu_idx, retaddr);
         goto redo;
     }
 }
Index: hw/alpha_palcode.c
===================================================================
RCS file: /sources/qemu/qemu/hw/alpha_palcode.c,v
retrieving revision 1.3
diff -u -d -d -p -r1.3 alpha_palcode.c
--- hw/alpha_palcode.c	17 Sep 2007 08:09:46 -0000	1.3
+++ hw/alpha_palcode.c	10 Oct 2007 03:29:05 -0000
@@ -811,12 +811,14 @@ static int get_page_bits (CPUState *env)
 
 static int get_pte (uint64_t *pfnp, int *zbitsp, int *protp,
                     uint64_t ptebase, int page_bits, uint64_t level,
-                    int is_user, int rw)
+                    int mmu_idx, int rw)
 {
     uint64_t pteaddr, pte, pfn;
     uint8_t gh;
-    int ure, uwe, kre, kwe, foE, foR, foW, v, ret, ar;
+    int ure, uwe, kre, kwe, foE, foR, foW, v, ret, ar, is_user;
 
+    /* XXX: TOFIX */
+    is_user = mmu_idx != 0 ? 1 : 0;
     pteaddr = (ptebase << page_bits) + (8 * level);
     pte = ldq_raw(pteaddr);
     /* Decode all interresting PTE fields */
@@ -871,7 +873,7 @@ static int get_pte (uint64_t *pfnp, int 
 
 static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot,
                            uint64_t ptebase, int page_bits,
-                           uint64_t vaddr, int is_user, int rw)
+                           uint64_t vaddr, int mmu_idx, int rw)
 {
     uint64_t pfn, page_mask, lvl_mask, level1, level2, level3;
     int lvl_bits, ret;
@@ -909,7 +911,7 @@ static int paddr_from_pte (uint64_t *pad
         break;
     }
     /* Level 3 PTE */
-    ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, is_user, rw);
+    ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, mmu_idx, rw);
     if (ret & 0x1) {
         /* Translation not valid */
         ret = 1;
@@ -943,7 +945,7 @@ static int paddr_from_pte (uint64_t *pad
 
 static int virtual_to_physical (CPUState *env, uint64_t *physp,
                                 int *zbitsp, int *protp,
-                                uint64_t virtual, int is_user, int rw)
+                                uint64_t virtual, int mmu_idx, int rw)
 {
     uint64_t sva, ptebase;
     int seg, page_bits, ret;
@@ -961,16 +963,16 @@ static int virtual_to_physical (CPUState
     case 0:
         /* seg1: 3 levels of PTE */
         ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, is_user, rw);
+                             virtual, mmu_idx, rw);
         break;
     case 1:
         /* seg1: 2 levels of PTE */
         ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, is_user, rw);
+                             virtual, mmu_idx, rw);
         break;
     case 2:
         /* kernel segment */
-        if (is_user) {
+        if (mmu_idx != 0) {
             ret = 2;
         } else {
             *physp = virtual;
@@ -979,7 +981,7 @@ static int virtual_to_physical (CPUState
     case 3:
         /* seg1: TB mapped */
         ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, is_user, rw);
+                             virtual, mmu_idx, rw);
         break;
     default:
         ret = 1;
@@ -991,7 +993,7 @@ static int virtual_to_physical (CPUState
 
 /* XXX: code provision */
 int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     uint64_t physical, page_size, end;
     int prot, zbits, ret;
@@ -1000,7 +1002,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *
         ret = 2;
     } else {
         ret = virtual_to_physical(env, &physical, &zbits, &prot,
-                                  address, is_user, rw);
+                                  address, mmu_idx, rw);
     }
     switch (ret) {
     case 0:
@@ -1009,7 +1011,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *
         address &= ~(page_size - 1);
         for (end = physical + page_size; physical < end; physical += 0x1000) {
             ret = tlb_set_page(env, address, physical, prot,
-                               is_user, is_softmmu);
+                               mmu_idx, is_softmmu);
             address += 0x1000;
         }
         break;
Index: target-alpha/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-alpha/cpu.h,v
retrieving revision 1.8
diff -u -d -d -p -r1.8 cpu.h
--- target-alpha/cpu.h	27 Sep 2007 16:44:31 -0000	1.8
+++ target-alpha/cpu.h	10 Oct 2007 03:29:07 -0000
@@ -256,6 +256,8 @@ struct pal_handler_t {
     void (*call_pal)(CPUAlphaState *env, uint32_t palcode);
 };
 
+#define NB_MMU_MODES 4
+
 struct CPUAlphaState {
     uint64_t ir[31];
     float64  fir[31];
@@ -302,6 +304,17 @@ 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;
+}
+
 #include "cpu-all.h"
 
 enum {
Index: target-alpha/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-alpha/exec.h,v
retrieving revision 1.3
diff -u -d -d -p -r1.3 exec.h
--- target-alpha/exec.h	16 Sep 2007 21:08:01 -0000	1.3
+++ target-alpha/exec.h	10 Oct 2007 03:29:07 -0000
@@ -73,7 +73,7 @@ static inline void regs_to_env(void)
 }
 
 int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
-                                int is_user, int is_softmmu);
+                                int mmu_idx, int is_softmmu);
 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);
 
Index: target-alpha/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-alpha/helper.c,v
retrieving revision 1.4
diff -u -d -d -p -r1.4 helper.c
--- target-alpha/helper.c	17 Sep 2007 08:09:51 -0000	1.4
+++ target-alpha/helper.c	10 Oct 2007 03:29:07 -0000
@@ -28,7 +28,7 @@
 #if defined(CONFIG_USER_ONLY)
 
 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                                int is_user, int is_softmmu)
+                                int mmu_idx, int is_softmmu)
 {
     if (rw == 2)
         env->exception_index = EXCP_ITB_MISS;
@@ -57,7 +57,7 @@ target_phys_addr_t cpu_get_phys_page_deb
 }
 
 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                                int is_user, int is_softmmu)
+                                int mmu_idx, int is_softmmu)
 {
     uint32_t opc;
 
Index: target-alpha/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-alpha/op_helper.c,v
retrieving revision 1.2
diff -u -d -d -p -r1.2 op_helper.c
--- target-alpha/op_helper.c	16 Sep 2007 21:08:01 -0000	1.2
+++ target-alpha/op_helper.c	10 Oct 2007 03:29:07 -0000
@@ -1164,20 +1164,20 @@ void helper_mtpr (int iprn)
 void helper_ld_phys_to_virt (void)
 {
     uint64_t tlb_addr, physaddr;
-    int index, is_user;
+    int index, mmu_idx;
     void *retaddr;
 
-    is_user = (env->ps >> 3) & 3;
+    mmu_idx = cpu_mmu_index(env);
     index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].addr_read;
+    tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
     if ((T0 & TARGET_PAGE_MASK) ==
         (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = T0 + env->tlb_table[is_user][index].addend;
+        physaddr = T0 + env->tlb_table[mmu_idx][index].addend;
     } else {
         /* the page is not in the TLB : fill it */
         retaddr = GETPC();
-        tlb_fill(T0, 0, is_user, retaddr);
+        tlb_fill(T0, 0, mmu_idx, retaddr);
         goto redo;
     }
     T0 = physaddr;
@@ -1186,20 +1186,20 @@ void helper_ld_phys_to_virt (void)
 void helper_st_phys_to_virt (void)
 {
     uint64_t tlb_addr, physaddr;
-    int index, is_user;
+    int index, mmu_idx;
     void *retaddr;
 
-    is_user = (env->ps >> 3) & 3;
+    mmu_idx = cpu_mmu_index(env);
     index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].addr_write;
+    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
     if ((T0 & TARGET_PAGE_MASK) ==
         (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = T0 + env->tlb_table[is_user][index].addend;
+        physaddr = T0 + env->tlb_table[mmu_idx][index].addend;
     } else {
         /* the page is not in the TLB : fill it */
         retaddr = GETPC();
-        tlb_fill(T0, 1, is_user, retaddr);
+        tlb_fill(T0, 1, mmu_idx, retaddr);
         goto redo;
     }
     T0 = physaddr;
@@ -1223,7 +1223,7 @@ void helper_st_phys_to_virt (void)
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -1234,7 +1234,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    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 */
Index: target-arm/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-arm/cpu.h,v
retrieving revision 1.34
diff -u -d -d -p -r1.34 cpu.h
--- target-arm/cpu.h	27 Sep 2007 16:44:31 -0000	1.34
+++ target-arm/cpu.h	10 Oct 2007 03:29:07 -0000
@@ -43,6 +43,8 @@ typedef void ARMWriteCPFunc(void *opaque
 typedef uint32_t ARMReadCPFunc(void *opaque, int cp_info,
                                int dstreg, int operand);
 
+#define NB_MMU_MODES 2
+
 /* We currently assume float and double are IEEE single and double
    precision respectively.
    Doing runtime conversions is tricky because VFP registers may contain
@@ -299,6 +301,15 @@ void cpu_arm_set_cp_io(CPUARMState *env,
 #define cpu_exec cpu_arm_exec
 #define cpu_gen_code cpu_arm_gen_code
 #define cpu_signal_handler cpu_arm_signal_handler
+
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR ? 1 : 0;
+}
 
 #include "cpu-all.h"
 
Index: target-arm/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-arm/exec.h,v
retrieving revision 1.13
diff -u -d -d -p -r1.13 exec.h
--- target-arm/exec.h	16 Sep 2007 21:08:01 -0000	1.13
+++ target-arm/exec.h	10 Oct 2007 03:29:07 -0000
@@ -46,7 +46,7 @@ static inline void regs_to_env(void)
 }
 
 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu);
+                              int mmu_idx, int is_softmmu);
 
 static inline int cpu_halted(CPUState *env) {
     if (!env->halted)
Index: target-arm/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-arm/helper.c,v
retrieving revision 1.21
diff -u -d -d -p -r1.21 helper.c
--- target-arm/helper.c	16 Sep 2007 21:08:01 -0000	1.21
+++ target-arm/helper.c	10 Oct 2007 03:29:07 -0000
@@ -169,7 +169,7 @@ void do_interrupt (CPUState *env)
 }
 
 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     if (rw == 2) {
         env->exception_index = EXCP_PREFETCH_ABORT;
@@ -547,18 +547,19 @@ do_fault:
 }
 
 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
-                              int access_type, int is_user, int is_softmmu)
+                              int access_type, int mmu_idx, int is_softmmu)
 {
     uint32_t phys_addr;
     int prot;
-    int ret;
+    int ret, is_user;
 
+    is_user = mmu_idx;
     ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot);
     if (ret == 0) {
         /* Map a single [sub]page.  */
         phys_addr &= ~(uint32_t)0x3ff;
         address &= ~(uint32_t)0x3ff;
-        return tlb_set_page (env, address, phys_addr, prot, is_user,
+        return tlb_set_page (env, address, phys_addr, prot, mmu_idx,
                              is_softmmu);
     }
 
Index: target-arm/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-arm/op_helper.c,v
retrieving revision 1.6
diff -u -d -d -p -r1.6 op_helper.c
--- target-arm/op_helper.c	16 Sep 2007 21:08:02 -0000	1.6
+++ target-arm/op_helper.c	10 Oct 2007 03:29:07 -0000
@@ -196,7 +196,7 @@ void do_vfp_get_fpscr(void)
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -207,7 +207,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_arm_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (__builtin_expect(ret, 0)) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-cris/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-cris/cpu.h,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 cpu.h
--- target-cris/cpu.h	8 Oct 2007 13:04:02 -0000	1.1
+++ target-cris/cpu.h	10 Oct 2007 03:29:07 -0000
@@ -74,6 +74,8 @@
 /* Internal flags for the implementation.  */
 #define F_DELAYSLOT 1
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUCRISState {
 	uint32_t debug1;
 	uint32_t debug2;
@@ -229,6 +231,16 @@ void register_cris_insns (CPUCRISState *
 #define cpu_gen_code cpu_cris_gen_code
 #define cpu_signal_handler cpu_cris_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+/* CRIS FIXME: I guess we want to validate supervisor mode acceses here.  */
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return 0;
+}
+
 #include "cpu-all.h"
 
 /* Register aliases.  */
Index: target-cris/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-cris/exec.h,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 exec.h
--- target-cris/exec.h	8 Oct 2007 13:04:02 -0000	1.1
+++ target-cris/exec.h	10 Oct 2007 03:29:07 -0000
@@ -45,8 +45,8 @@ static inline void regs_to_env(void)
 }
 
 int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu);
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr);
+                              int mmu_idx, int is_softmmu);
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr);
 
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
Index: target-cris/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-cris/helper.c,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 helper.c
--- target-cris/helper.c	8 Oct 2007 13:04:02 -0000	1.1
+++ target-cris/helper.c	10 Oct 2007 03:29:07 -0000
@@ -35,7 +35,7 @@ void do_interrupt (CPUState *env)
 }
 
 int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-                             int is_user, int is_softmmu)
+                             int mmu_idx, int is_softmmu)
 {
     env->exception_index = 0xaa;
     env->debug1 = address;
@@ -52,7 +52,7 @@ target_phys_addr_t cpu_get_phys_page_deb
 #else /* !CONFIG_USER_ONLY */
 
 int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
 	struct cris_mmu_result_t res;
 	int prot, miss;
@@ -61,7 +61,7 @@ int cpu_cris_handle_mmu_fault (CPUState 
 	address &= TARGET_PAGE_MASK;
 	prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 //	printf ("%s pc=%x %x w=%d smmu=%d\n", __func__, env->pc, address, rw, is_softmmu);
-	miss = cris_mmu_translate(&res, env, address, rw, is_user);
+	miss = cris_mmu_translate(&res, env, address, rw, mmu_idx);
 	if (miss)
 	{
 		/* handle the miss.  */
@@ -73,7 +73,7 @@ int cpu_cris_handle_mmu_fault (CPUState 
 		phy = res.phy;
 	}
 //	printf ("a=%x phy=%x\n", address, phy);
-	return tlb_set_page(env, address, phy, prot, is_user, is_softmmu);
+	return tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu);
 }
 
 
Index: target-cris/mmu.c
===================================================================
RCS file: /sources/qemu/qemu/target-cris/mmu.c,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 mmu.c
--- target-cris/mmu.c	8 Oct 2007 13:11:58 -0000	1.1
+++ target-cris/mmu.c	10 Oct 2007 03:29:07 -0000
@@ -111,11 +111,12 @@ static int cris_mmu_translate_page(struc
 
 int cris_mmu_translate(struct cris_mmu_result_t *res,
 		       CPUState *env, uint32_t vaddr,
-		       int rw, int is_user)
+		       int rw, int mmu_idx)
 {
 	uint32_t phy = vaddr;
 	int seg;
 	int miss = 0;
+   int is_user = mmu_idx;
 
 	if (!cris_mmu_enabled(env->sregs[SFR_RW_GC_CFG])) {
 		res->phy = vaddr;
Index: target-cris/mmu.h
===================================================================
RCS file: /sources/qemu/qemu/target-cris/mmu.h,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 mmu.h
--- target-cris/mmu.h	8 Oct 2007 13:11:58 -0000	1.1
+++ target-cris/mmu.h	10 Oct 2007 03:29:07 -0000
@@ -17,4 +17,4 @@ struct cris_mmu_result_t
 
 int cris_mmu_translate(struct cris_mmu_result_t *res,
 		       CPUState *env, uint32_t vaddr,
-		       int rw, int is_user);
+		       int rw, int mmu_idx);
Index: target-cris/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-cris/op_helper.c,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 op_helper.c
--- target-cris/op_helper.c	8 Oct 2007 13:04:02 -0000	1.1
+++ target-cris/op_helper.c	10 Oct 2007 03:29:07 -0000
@@ -41,7 +41,7 @@
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -52,7 +52,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (__builtin_expect(ret, 0)) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-i386/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-i386/cpu.h,v
retrieving revision 1.50
diff -u -d -d -p -r1.50 cpu.h
--- target-i386/cpu.h	27 Sep 2007 16:44:31 -0000	1.50
+++ target-i386/cpu.h	10 Oct 2007 03:29:07 -0000
@@ -432,6 +432,8 @@ typedef union {
 #define CPU_NB_REGS 8
 #endif
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUX86State {
 #if TARGET_LONG_BITS > HOST_LONG_BITS
     /* temporaries if we cannot store them in host registers */
@@ -688,6 +690,15 @@ static inline int cpu_get_time_fast(void
 #define cpu_gen_code cpu_x86_gen_code
 #define cpu_signal_handler cpu_x86_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
+}
+
 #include "cpu-all.h"
 
 #include "svm.h"
Index: target-i386/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-i386/exec.h,v
retrieving revision 1.37
diff -u -d -d -p -r1.37 exec.h
--- target-i386/exec.h	23 Sep 2007 15:28:04 -0000	1.37
+++ target-i386/exec.h	10 Oct 2007 03:29:07 -0000
@@ -163,8 +163,8 @@ void cpu_x86_update_cr3(CPUX86State *env
 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
 void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr);
 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
-                             int is_write, int is_user, int is_softmmu);
-void tlb_fill(target_ulong addr, int is_write, int is_user,
+                             int is_write, int mmu_idx, int is_softmmu);
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
               void *retaddr);
 void __hidden cpu_lock(void);
 void __hidden cpu_unlock(void);
Index: target-i386/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-i386/helper.c,v
retrieving revision 1.89
diff -u -d -d -p -r1.89 helper.c
--- target-i386/helper.c	27 Sep 2007 01:52:00 -0000	1.89
+++ target-i386/helper.c	10 Oct 2007 03:29:08 -0000
@@ -3885,7 +3885,7 @@ void update_fp_status(void)
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     int ret;
@@ -3897,7 +3897,7 @@ void tlb_fill(target_ulong addr, int is_
     saved_env = env;
     env = cpu_single_env;
 
-    ret = cpu_x86_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (ret) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-i386/helper2.c
===================================================================
RCS file: /sources/qemu/qemu/target-i386/helper2.c,v
retrieving revision 1.52
diff -u -d -d -p -r1.52 helper2.c
--- target-i386/helper2.c	23 Sep 2007 15:28:04 -0000	1.52
+++ target-i386/helper2.c	10 Oct 2007 03:29:08 -0000
@@ -571,7 +571,7 @@ void cpu_x86_flush_tlb(CPUX86State *env,
 #if defined(CONFIG_USER_ONLY)
 
 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
-                             int is_write, int is_user, int is_softmmu)
+                             int is_write, int mmu_idx, int is_softmmu)
 {
     /* user mode only emulation */
     is_write &= 1;
@@ -598,14 +598,15 @@ target_phys_addr_t cpu_get_phys_page_deb
    2  = soft MMU activation required for this block
 */
 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
-                             int is_write1, int is_user, int is_softmmu)
+                             int is_write1, int mmu_idx, int is_softmmu)
 {
     uint64_t ptep, pte;
     uint32_t pdpe_addr, pde_addr, pte_addr;
-    int error_code, is_dirty, prot, page_size, ret, is_write;
+    int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
     unsigned long paddr, page_offset;
     target_ulong vaddr, virt_addr;
 
+    is_user = mmu_idx;
 #if defined(DEBUG_MMU)
     printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
            addr, is_write1, is_user, env->eip);
@@ -862,7 +863,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State
     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
     vaddr = virt_addr + page_offset;
 
-    ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+    ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
     return ret;
  do_fault_protect:
     error_code = PG_ERROR_P_MASK;
Index: target-m68k/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-m68k/cpu.h,v
retrieving revision 1.13
diff -u -d -d -p -r1.13 cpu.h
--- target-m68k/cpu.h	17 Sep 2007 08:09:53 -0000	1.13
+++ target-m68k/cpu.h	10 Oct 2007 03:29:08 -0000
@@ -53,6 +53,8 @@
 #define EXCP_RTE            0x100
 #define EXCP_HALT_INSN      0x101
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUM68KState {
     uint32_t dregs[8];
     uint32_t aregs[8];
@@ -223,6 +225,15 @@ void register_m68k_insns (CPUM68KState *
 #define cpu_gen_code cpu_m68k_gen_code
 #define cpu_signal_handler cpu_m68k_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return (env->sr & SR_S) == 0 ? 1 : 0;
+}
+
 #include "cpu-all.h"
 
 #endif
Index: target-m68k/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-m68k/exec.h,v
retrieving revision 1.4
diff -u -d -d -p -r1.4 exec.h
--- target-m68k/exec.h	16 Sep 2007 21:08:03 -0000	1.4
+++ target-m68k/exec.h	10 Oct 2007 03:29:08 -0000
@@ -38,7 +38,7 @@ static inline void regs_to_env(void)
 }
 
 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu);
+                              int mmu_idx, int is_softmmu);
 
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
Index: target-m68k/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-m68k/helper.c,v
retrieving revision 1.7
diff -u -d -d -p -r1.7 helper.c
--- target-m68k/helper.c	16 Sep 2007 21:08:03 -0000	1.7
+++ target-m68k/helper.c	10 Oct 2007 03:29:08 -0000
@@ -301,7 +301,7 @@ target_phys_addr_t cpu_get_phys_page_deb
 #if defined(CONFIG_USER_ONLY)
 
 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     env->exception_index = EXCP_ACCESS;
     env->mmu.ar = address;
@@ -311,13 +311,13 @@ int cpu_m68k_handle_mmu_fault (CPUState 
 #else
 
 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     int prot;
 
     address &= TARGET_PAGE_MASK;
     prot = PAGE_READ | PAGE_WRITE;
-    return tlb_set_page(env, address, address, prot, is_user, is_softmmu);
+    return tlb_set_page(env, address, address, prot, mmu_idx, is_softmmu);
 }
 
 /* Notify CPU of a pending interrupt.  Prioritization and vectoring should
Index: target-m68k/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-m68k/op_helper.c,v
retrieving revision 1.6
diff -u -d -d -p -r1.6 op_helper.c
--- target-m68k/op_helper.c	16 Sep 2007 21:08:03 -0000	1.6
+++ target-m68k/op_helper.c	10 Oct 2007 03:29:08 -0000
@@ -49,7 +49,7 @@ extern int semihosting_enabled;
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -60,7 +60,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (__builtin_expect(ret, 0)) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-mips/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-mips/cpu.h,v
retrieving revision 1.47
diff -u -d -d -p -r1.47 cpu.h
--- target-mips/cpu.h	27 Sep 2007 16:44:31 -0000	1.47
+++ target-mips/cpu.h	10 Oct 2007 03:29:08 -0000
@@ -107,6 +107,8 @@ struct CPUMIPSFPUContext {
 #define FP_UNIMPLEMENTED  32
 };
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUMIPSMVPContext CPUMIPSMVPContext;
 struct CPUMIPSMVPContext {
     int32_t CP0_MVPControl;
@@ -482,6 +484,15 @@ int cpu_mips_register (CPUMIPSState *env
 #define cpu_exec cpu_mips_exec
 #define cpu_gen_code cpu_mips_gen_code
 #define cpu_signal_handler cpu_mips_signal_handler
+
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM ? 1 : 0;
+}
 
 #include "cpu-all.h"
 
Index: target-mips/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-mips/exec.h,v
retrieving revision 1.38
diff -u -d -d -p -r1.38 exec.h
--- target-mips/exec.h	9 Oct 2007 03:39:58 -0000	1.38
+++ target-mips/exec.h	10 Oct 2007 03:29:08 -0000
@@ -105,7 +105,7 @@ void do_pmon (int function);
 void dump_sc (void);
 
 int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu);
+                               int mmu_idx, int is_softmmu);
 void do_interrupt (CPUState *env);
 void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra);
 
Index: target-mips/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/helper.c,v
retrieving revision 1.53
diff -u -d -d -p -r1.53 helper.c
--- target-mips/helper.c	30 Sep 2007 01:58:33 -0000	1.53
+++ target-mips/helper.c	10 Oct 2007 03:29:08 -0000
@@ -232,14 +232,15 @@ void cpu_mips_init_mmu (CPUState *env)
 #endif /* !defined(CONFIG_USER_ONLY) */
 
 int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     target_ulong physical;
     int prot;
     int exception = 0, error_code = 0;
-    int access_type;
+    int access_type, is_user;
     int ret = 0;
 
+    is_user = mmu_idx;
     if (logfile) {
 #if 0
         cpu_dump_state(env, logfile, fprintf, 0);
@@ -268,7 +269,7 @@ int cpu_mips_handle_mmu_fault (CPUState 
     if (ret == TLBRET_MATCH) {
        ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
                           physical & TARGET_PAGE_MASK, prot,
-                          is_user, is_softmmu);
+                          mmu_idx, is_softmmu);
     } else if (ret < 0) {
     do_fault:
         switch (ret) {
Index: target-mips/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/op_helper.c,v
retrieving revision 1.65
diff -u -d -d -p -r1.65 op_helper.c
--- target-mips/op_helper.c	9 Oct 2007 03:39:58 -0000	1.65
+++ target-mips/op_helper.c	10 Oct 2007 03:29:08 -0000
@@ -563,7 +563,7 @@ static void do_unaligned_access (target_
     do_raise_exception ((is_write == 1) ? EXCP_AdES : EXCP_AdEL);
 }
 
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -574,7 +574,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_mips_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (ret) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-ppc/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/cpu.h,v
retrieving revision 1.78
diff -u -d -d -p -r1.78 cpu.h
--- target-ppc/cpu.h	8 Oct 2007 02:58:07 -0000	1.78
+++ target-ppc/cpu.h	10 Oct 2007 03:29:08 -0000
@@ -434,6 +432,12 @@ enum {
     POWERPC_FLAG_PMM  = 0x00000400,
 };
 
+#if defined(TARGET_PPC64H)
+#define NB_MMU_MODES 3
+#else
+#define NB_MMU_MODES 2
+#endif
+
 /*****************************************************************************/
 /* The whole PowerPC CPU context */
 struct CPUPPCState {
@@ -697,6 +701,26 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, i
 #define cpu_exec cpu_ppc_exec
 #define cpu_gen_code cpu_ppc_gen_code
 #define cpu_signal_handler cpu_ppc_signal_handler
+
+/* MMU modes definitions */
+#if defined(TARGET_PPC64H)
+#define MMU_MODE0_SUFFIX _user
+#define MMU_MODE1_SUFFIX _kernel
+#define MMU_MODE2_SUFFIX _hypv
+#else
+#define MMU_MODE0_SUFFIX _user
+#define MMU_MODE1_SUFFIX _kernel
+#endif
+#define MMU_USER_IDX 0
+static inline int cpu_mmu_index (CPUState *env)
+{
+#if defined(TARGET_PPC64H)
+    if (msr_pr == 0 && msr_hv == 1)
+        return 2;
+    else
+#endif
+        return 1 - msr_pr;
+}
 
 #include "cpu-all.h"
 
Index: target-ppc/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/exec.h,v
retrieving revision 1.28
diff -u -d -d -p -r1.28 exec.h
--- target-ppc/exec.h	7 Oct 2007 18:19:25 -0000	1.28
+++ target-ppc/exec.h	10 Oct 2007 03:29:08 -0000
@@ -112,7 +114,7 @@ static always_inline void regs_to_env (v
 }
 
 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu);
+                              int mmu_idx, int is_softmmu);
 
 static always_inline int cpu_halted (CPUState *env)
 {
Index: target-ppc/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/helper.c,v
retrieving revision 1.75
diff -u -d -d -p -r1.75 helper.c
--- target-ppc/helper.c	8 Oct 2007 02:58:07 -0000	1.75
+++ target-ppc/helper.c	10 Oct 2007 03:29:08 -0000
@@ -39,7 +40,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     int exception, error_code;
 
@@ -1349,7 +1543,7 @@ target_phys_addr_t cpu_get_phys_page_deb
 
 /* Perform address translation */
 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     mmu_ctx_t ctx;
     int access_type;
@@ -1370,7 +1564,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *
     if (ret == 0) {
         ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
                            ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
-                           is_user, is_softmmu);
+                           mmu_idx, is_softmmu);
     } else if (ret < 0) {
 #if defined (DEBUG_MMU)
         if (loglevel != 0)
Index: target-ppc/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/op_helper.c,v
retrieving revision 1.49
diff -u -d -d -p -r1.49 op_helper.c
--- target-ppc/op_helper.c	7 Oct 2007 17:13:43 -0000	1.49
+++ target-ppc/op_helper.c	10 Oct 2007 03:29:08 -0000
@@ -2307,7 +2315,7 @@ DO_SPE_OP1(fsctuf);
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -2318,7 +2326,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (unlikely(ret != 0)) {
         if (likely(retaddr)) {
             /* now we have a real cpu fault */
Index: target-sh4/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/cpu.h,v
retrieving revision 1.10
diff -u -d -d -p -r1.10 cpu.h
--- target-sh4/cpu.h	16 Sep 2007 21:08:05 -0000	1.10
+++ target-sh4/cpu.h	10 Oct 2007 03:29:09 -0000
@@ -77,6 +77,8 @@ typedef struct tlb_t {
 #define UTLB_SIZE 64
 #define ITLB_SIZE 4
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUSH4State {
     uint32_t flags;		/* general execution flags */
     uint32_t gregs[24];		/* general registers */
@@ -134,6 +136,15 @@ int cpu_sh4_signal_handler(int host_sign
 #define cpu_gen_code cpu_sh4_gen_code
 #define cpu_signal_handler cpu_sh4_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return (env->sr & SR_MD) == 0 ? 1 : 0;
+}
+
 #include "cpu-all.h"
 
 /* Memory access type */
Index: target-sh4/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/exec.h,v
retrieving revision 1.5
diff -u -d -d -p -r1.5 exec.h
--- target-sh4/exec.h	16 Sep 2007 21:08:05 -0000	1.5
+++ target-sh4/exec.h	10 Oct 2007 03:29:09 -0000
@@ -63,7 +63,7 @@ static inline void env_to_regs(void)
 }
 
 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-			     int is_user, int is_softmmu);
+			     int mmu_idx, int is_softmmu);
 
 int find_itlb_entry(CPUState * env, target_ulong address,
 		    int use_asid, int update);
Index: target-sh4/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/helper.c,v
retrieving revision 1.4
diff -u -d -d -p -r1.4 helper.c
--- target-sh4/helper.c	16 Sep 2007 21:08:05 -0000	1.4
+++ target-sh4/helper.c	10 Oct 2007 03:29:09 -0000
@@ -36,7 +36,7 @@ void do_interrupt (CPUState *env)
 }
 
 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-			     int is_user, int is_softmmu)
+			     int mmu_idx, int is_softmmu)
 {
     env->tea = address;
     switch (rw) {
@@ -372,11 +372,12 @@ int get_physical_address(CPUState * env,
 }
 
 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-			     int is_user, int is_softmmu)
+			     int mmu_idx, int is_softmmu)
 {
     target_ulong physical, page_offset, page_size;
-    int prot, ret, access_type;
+    int prot, ret, access_type, is_user;
 
+    is_user = mmu_idx;
     /* XXXXX */
 #if 0
     fprintf(stderr, "%s pc %08x ad %08x rw %d is_user %d smmu %d\n",
@@ -426,7 +427,7 @@ int cpu_sh4_handle_mmu_fault(CPUState * 
     address = (address & TARGET_PAGE_MASK) + page_offset;
     physical = (physical & TARGET_PAGE_MASK) + page_offset;
 
-    return tlb_set_page(env, address, physical, prot, is_user, is_softmmu);
+    return tlb_set_page(env, address, physical, prot, mmu_idx, is_softmmu);
 }
 
 target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
Index: target-sh4/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/op_helper.c,v
retrieving revision 1.4
diff -u -d -d -p -r1.4 op_helper.c
--- target-sh4/op_helper.c	16 Sep 2007 21:08:05 -0000	1.4
+++ target-sh4/op_helper.c	10 Oct 2007 03:29:09 -0000
@@ -42,7 +42,7 @@ void do_raise_exception(void)
 #define SHIFT 3
 #include "softmmu_template.h"
 
-void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -53,7 +53,7 @@ void tlb_fill(target_ulong addr, int is_
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (ret) {
 	if (retaddr) {
 	    /* now we have a real cpu fault */
Index: target-sparc/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/cpu.h,v
retrieving revision 1.52
diff -u -d -d -p -r1.52 cpu.h
--- target-sparc/cpu.h	27 Sep 2007 16:44:32 -0000	1.52
+++ target-sparc/cpu.h	10 Oct 2007 03:29:09 -0000
@@ -166,6 +166,8 @@
 
 typedef struct sparc_def_t sparc_def_t;
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUSPARCState {
     target_ulong gregs[8]; /* general registers */
     target_ulong *regwptr; /* pointer to current register window */
@@ -315,6 +317,15 @@ void cpu_check_irqs(CPUSPARCState *env);
 #define cpu_exec cpu_sparc_exec
 #define cpu_gen_code cpu_sparc_gen_code
 #define cpu_signal_handler cpu_sparc_signal_handler
+
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return env->psrs == 0 ? 1 : 0;
+}
 
 #include "cpu-all.h"
 
Index: target-sparc/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/exec.h,v
retrieving revision 1.21
diff -u -d -d -p -r1.21 exec.h
--- target-sparc/exec.h	30 Sep 2007 19:38:11 -0000	1.21
+++ target-sparc/exec.h	10 Oct 2007 03:29:09 -0000
@@ -115,7 +115,7 @@ static inline void regs_to_env(void)
 }
 
 int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu);
+                               int mmu_idx, int is_softmmu);
 
 static inline int cpu_halted(CPUState *env) {
     if (!env->halted)
Index: target-sparc/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/helper.c,v
retrieving revision 1.27
diff -u -d -d -p -r1.27 helper.c
--- target-sparc/helper.c	24 Sep 2007 19:44:09 -0000	1.27
+++ target-sparc/helper.c	10 Oct 2007 03:29:09 -0000
@@ -49,7 +49,7 @@ void cpu_unlock(void)
 #if defined(CONFIG_USER_ONLY)
 
 int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     if (rw & 2)
         env->exception_index = TT_TFAULT;
@@ -100,15 +100,16 @@ static const int perm_table[2][8] = {
 
 int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
                           int *access_index, target_ulong address, int rw,
-                          int is_user)
+                          int mmu_idx)
 {
     int access_perms = 0;
     target_phys_addr_t pde_ptr;
     uint32_t pde;
     target_ulong virt_addr;
-    int error_code = 0, is_dirty;
+    int error_code = 0, is_dirty, is_user;
     unsigned long page_offset;
 
+    is_user = mmu_idx;
     virt_addr = address & TARGET_PAGE_MASK;
 
     if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
@@ -216,13 +217,13 @@ int get_physical_address (CPUState *env,
 
 /* Perform address translation */
 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     target_phys_addr_t paddr;
     target_ulong vaddr;
     int error_code = 0, prot, ret = 0, access_index;
 
-    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
+    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, mmu_idx);
     if (error_code == 0) {
         vaddr = address & TARGET_PAGE_MASK;
         paddr &= TARGET_PAGE_MASK;
@@ -230,7 +231,7 @@ int cpu_sparc_handle_mmu_fault (CPUState
         printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
                TARGET_FMT_lx "\n", address, paddr, vaddr);
 #endif
-        ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
         return ret;
     }
 
@@ -246,7 +247,7 @@ int cpu_sparc_handle_mmu_fault (CPUState
         // switching to normal mode.
         vaddr = address & TARGET_PAGE_MASK;
         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
-        ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
         return ret;
     } else {
         if (rw & 2)
@@ -484,8 +485,10 @@ static int get_physical_address_code(CPU
 
 int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
                           int *access_index, target_ulong address, int rw,
-                          int is_user)
+                          int mmu_idx)
 {
+    int is_user = mmu_idx;
+
     if (rw == 2)
         return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
     else
@@ -494,20 +497,20 @@ int get_physical_address(CPUState *env, 
 
 /* Perform address translation */
 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     target_ulong virt_addr, vaddr;
     target_phys_addr_t paddr;
     int error_code = 0, prot, ret = 0, access_index;
 
-    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
+    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, mmu_idx);
     if (error_code == 0) {
         virt_addr = address & TARGET_PAGE_MASK;
         vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
 #ifdef DEBUG_MMU
         printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64 "\n", address, paddr, vaddr);
 #endif
-        ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
         return ret;
     }
     // XXX
Index: target-sparc/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.41
diff -u -d -d -p -r1.41 op_helper.c
--- target-sparc/op_helper.c	1 Oct 2007 17:07:58 -0000	1.41
+++ target-sparc/op_helper.c	10 Oct 2007 03:29:10 -0000
@@ -1522,7 +1522,7 @@ static void do_unaligned_access(target_u
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     int ret;
@@ -1534,7 +1534,7 @@ void tlb_fill(target_ulong addr, int is_
     saved_env = env;
     env = cpu_single_env;
 
-    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (ret) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-sparc/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/translate.c,v
retrieving revision 1.73
diff -u -d -d -p -r1.73 translate.c
--- target-sparc/translate.c	3 Oct 2007 17:46:29 -0000	1.73
+++ target-sparc/translate.c	10 Oct 2007 03:29:10 -0000
@@ -3687,8 +3687,8 @@ target_phys_addr_t cpu_get_phys_page_deb
 #else
 extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
                                  int *access_index, target_ulong address, int rw,
-                                 int is_user);
+                                 int mmu_idx);
 
 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
 {
 

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

* Re: [Qemu-devel] RFC: cleanups: CPU_MEM_INDEX
  2007-10-10  5:06   ` J. Mayer
@ 2007-10-11 12:09     ` J. Mayer
  2007-10-11 17:46       ` Thiemo Seufer
  2007-10-12  7:01       ` J. Mayer
  0 siblings, 2 replies; 9+ messages in thread
From: J. Mayer @ 2007-10-11 12:09 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 5004 bytes --]

On Wed, 2007-10-10 at 07:06 +0200, J. Mayer wrote:
> On Wed, 2007-10-10 at 01:12 +0100, Thiemo Seufer wrote:
> > J. Mayer wrote:
> > > Here's a proposal to add a int cpu_mem_index (CPUState *env) function in
> > > targets cpu.h header.
> > > The idea of this patch is:
> > > - avoid many #ifdef TARGET_xxx in exec-all.h and  softmmu_header.h then
> > > make the code more readable
> > > - avoid multiple implementation of the same code (3, in that particular
> > > case) this to avoid potential conflicts if the definition has to be
> > > updated for any reason (ie support for new memory access modes,
> > > emulation optimisation...)
> > > 
> > > Please comment.
> > > 
> > > -- 
> > > J. Mayer <l_indien@magic.fr>
> > > Never organized
> > 

[...]

Here's an updated version of the patch. My comments about it stay valid,
with two additions:
1/ when is user is needed to maintain compatibility with existing code,
I now define it as:
int is_user = mmu_idx == MMU_USER_IDX;
instead of just is_user = mmu_idx.
This definition will then remain correct even if the definition of the
MMU modes are later changed for a specific target
2/ I now precompute the mmu_idx on PowerPC platform as it can never
change inside a single TB. This may save a few instructions for every
memory access. I guess the same optimisation can be made for the other
targets, but not knowing exactly when it would have to be recomputed,
for most targets, I prefer not to do this optimisation myself.

> > 
> > I presume cpu_mem_index is supposed to do more than checking for
> > usermode. In that case, is_user should get renamed, and the
> > cpu_mem_index implementation of some (most?) CPUs should have a
> > FIXME comment as reminder to implement the missing MMU modes.
> 
> You're right, calling this variable is_user is only valid because this
> code supposes it knows what cpu_mem_index means. For targets with more
> than 2 modes of execution, this is not correct.
> My first idea was to try not to change the code too much. After thinking
> more about the problem, it appears to me that:
> 1/ in the softmmu routines, we should do no assumption about the
> signification of the memory index
> 2/ then, softmmu routines should use an index and all exported
> interfaces (ie tlb_fill and handle_mmu_fault) should take an index
> instead of is_user as an argument.
> 3/ to maintain compatibility with the existing code, I choosed to add a
> is_user variable inside most handle_mmu_fault implementation,
> initialized with the value of the given index, which is then given to
> the target mmu translation routines.
> 4/ to ease implementation of targets with more than 2 execution modes, I
> choosed to define a per-target NB_MMU_MODES in each target_xxx/cpu.h
> (instead of the hack for PowerPC 64 and Alpha that did pre-exist) and
> add a local definition of the meaning of each mmu_index index. Then, for
> PowerPC, I choosed to use the same convention than I do in translate.c,
> which seems more logical to me, then: 0 => user, 1 => supervisor, 2 =>
> hypervisor.
> 5/ to avoid confusion between the memory index used in the translation
> context, which may contain more than the access mode information, and
> the one used by the softmmu routines, I choosed to name the one used in
> softmmu 'mmu_idx' (the one in target_xxx/translate.c is called mem_idx).
> 6/ I choosed to add a constant MMU_USER_IDX which is used in the
> user-mode handle_cpu_signal routine, then addressing your first remark.
> 
> This patch solves a problem I had no solution to until today: how to add
> new mmu modes (ie hypervisor for PowerPC 64, supervisor and executive
> for Alpha) for some specific targets.
> 
> The result is a much more invasive patch but the is supposed (!) to;
> 1/ do not change the behavior of the current targets implementations
> 2/ be less hardcoded, more flexible and extensible for any specific
> targets requirements.
> As this new version of the patch could deadly break the softmmu mode and
> I got no way to properly check all targets, I would greatly appreciate
> that some do some tests for arm, cris, m68k, mips, sh4 and sparc
> targets.
> 
> For now, I did a few tests, running Linux (debian hdd installation) for
> PowerPC on PPC 603 & 750 in 32 bits and 64 bits mode emulation on x86
> and amd64 and a few OSes using the i386-softmmu emulation (Linux Gentoo,
> solaris 10 installation CDROM, ...), with success; then I guess I did
> not deadly broke everything !
> The good point is that PowerPC runs, considering it is the only target
> for which I did change the mmu_idx semantics...
> 
> > Other than that it looks good to me (and reminds me to check what the
> > supervisor mode on MIPS actually does now :-).
> 
> This updated patch gives the opportunity to define a per-target semantic
> of the mmu_idx... Time to check what it means in actual CPU
> implementation !!!! ;-)
> 
> Thanks in advance for any comments or improvment suggestions....
> 
-- 
J. Mayer <l_indien@magic.fr>
Never organized

[-- Attachment #2: cpu_mmu_index.diff --]
[-- Type: text/x-patch, Size: 80917 bytes --]

? pc-bios/ppc_rom.bin.k
Index: cpu-defs.h
===================================================================
RCS file: /sources/qemu/qemu/cpu-defs.h,v
retrieving revision 1.24
diff -u -d -d -p -r1.24 cpu-defs.h
--- cpu-defs.h	19 Sep 2007 05:46:03 -0000	1.24
+++ cpu-defs.h	11 Oct 2007 11:00:06 -0000
@@ -112,15 +112,6 @@ typedef struct CPUTLBEntry {
     target_phys_addr_t addend;
 } CPUTLBEntry;
 
-/* Alpha has 4 different running levels */
-#if defined(TARGET_ALPHA)
-#define NB_MMU_MODES 4
-#elif defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
-#define NB_MMU_MODES 3
-#else
-#define NB_MMU_MODES 2
-#endif
-
 #define CPU_COMMON                                                      \
     struct TranslationBlock *current_tb; /* currently executing TB  */  \
     /* soft mmu support */                                              \
Index: cpu-exec.c
===================================================================
RCS file: /sources/qemu/qemu/cpu-exec.c,v
retrieving revision 1.119
diff -u -d -d -p -r1.119 cpu-exec.c
--- cpu-exec.c	8 Oct 2007 13:16:13 -0000	1.119
+++ cpu-exec.c	11 Oct 2007 11:00:06 -0000
@@ -884,8 +884,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_x86_handle_mmu_fault(env, address, is_write,
-                                   ((env->hflags & HF_CPL_MASK) == 3), 0);
+    ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -934,7 +933,7 @@ static inline int handle_cpu_signal(unsi
         return 1;
     }
     /* see if it is an MMU fault */
-    ret = cpu_arm_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -970,7 +969,7 @@ static inline int handle_cpu_signal(unsi
         return 1;
     }
     /* see if it is an MMU fault */
-    ret = cpu_sparc_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1007,7 +1006,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, msr_pr, 0);
+    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1056,7 +1055,7 @@ static inline int handle_cpu_signal(unsi
         return 1;
     }
     /* see if it is an MMU fault */
-    ret = cpu_m68k_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1096,7 +1095,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_mips_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1146,7 +1145,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_sh4_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1191,7 +1190,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_alpha_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1235,7 +1234,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_cris_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
Index: exec-all.h
===================================================================
RCS file: /sources/qemu/qemu/exec-all.h,v
retrieving revision 1.67
diff -u -d -d -p -r1.67 exec-all.h
--- exec-all.h	8 Oct 2007 13:16:14 -0000	1.67
+++ exec-all.h	11 Oct 2007 11:00:06 -0000
@@ -117,14 +117,14 @@ void tlb_flush_page(CPUState *env, targe
 void tlb_flush(CPUState *env, int flush_global);
 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
                       target_phys_addr_t paddr, int prot,
-                      int is_user, int is_softmmu);
+                      int mmu_idx, int is_softmmu);
 static inline int tlb_set_page(CPUState *env, target_ulong vaddr,
                                target_phys_addr_t paddr, int prot,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     if (prot & PAGE_READ)
         prot |= PAGE_EXEC;
-    return tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+    return tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
 }
 
 #define CODE_GEN_MAX_SIZE        65536
@@ -562,10 +562,10 @@ extern int tb_invalidated_flag;
 
 #if !defined(CONFIG_USER_ONLY)
 
-void tlb_fill(target_ulong addr, int is_write, int is_user,
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
               void *retaddr);
 
-#define ACCESS_TYPE 3
+#define ACCESS_TYPE (NB_MMU_MODES + 1)
 #define MEMSUFFIX _code
 #define env cpu_single_env
 
@@ -598,35 +598,15 @@ static inline target_ulong get_phys_addr
    is the offset relative to phys_ram_base */
 static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
 {
-    int is_user, index, pd;
+    int mmu_idx, index, pd;
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-#if defined(TARGET_I386)
-    is_user = ((env->hflags & HF_CPL_MASK) == 3);
-#elif defined (TARGET_PPC)
-    is_user = msr_pr;
-#elif defined (TARGET_MIPS)
-    is_user = ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
-#elif defined (TARGET_SPARC)
-    is_user = (env->psrs == 0);
-#elif defined (TARGET_ARM)
-    is_user = ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR);
-#elif defined (TARGET_SH4)
-    is_user = ((env->sr & SR_MD) == 0);
-#elif defined (TARGET_ALPHA)
-    is_user = ((env->ps >> 3) & 3);
-#elif defined (TARGET_M68K)
-    is_user = ((env->sr & SR_S) == 0);
-#elif defined (TARGET_CRIS)
-    is_user = (0);
-#else
-#error unimplemented CPU
-#endif
-    if (__builtin_expect(env->tlb_table[is_user][index].addr_code !=
+    mmu_idx = cpu_mmu_index(env);
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].addr_code !=
                          (addr & TARGET_PAGE_MASK), 0)) {
         ldub_code(addr);
     }
-    pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK;
+    pd = env->tlb_table[mmu_idx][index].addr_code & ~TARGET_PAGE_MASK;
     if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
 #ifdef TARGET_SPARC
         do_unassigned_access(addr, 0, 1, 0);
@@ -634,7 +614,7 @@ static inline target_ulong get_phys_addr
         cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);
 #endif
     }
-    return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base;
+    return addr + env->tlb_table[mmu_idx][index].addend - (unsigned long)phys_ram_base;
 }
 #endif
 
Index: exec.c
===================================================================
RCS file: /sources/qemu/qemu/exec.c,v
retrieving revision 1.108
diff -u -d -d -p -r1.108 exec.c
--- exec.c	8 Oct 2007 13:16:14 -0000	1.108
+++ exec.c	11 Oct 2007 11:00:06 -0000
@@ -1608,7 +1608,7 @@ static inline void tlb_set_dirty(CPUStat
    conflicting with the host address space). */
 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
                       target_phys_addr_t paddr, int prot,
-                      int is_user, int is_softmmu)
+                      int mmu_idx, int is_softmmu)
 {
     PhysPageDesc *p;
     unsigned long pd;
@@ -1626,8 +1626,8 @@ int tlb_set_page_exec(CPUState *env, tar
         pd = p->phys_offset;
     }
 #if defined(DEBUG_TLB)
-    printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x u=%d smmu=%d pd=0x%08lx\n",
-           vaddr, (int)paddr, prot, is_user, is_softmmu, pd);
+    printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x idx=%d smmu=%d pd=0x%08lx\n",
+           vaddr, (int)paddr, prot, mmu_idx, is_softmmu, pd);
 #endif
 
     ret = 0;
@@ -1664,7 +1664,7 @@ int tlb_set_page_exec(CPUState *env, tar
 
         index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
         addend -= vaddr;
-        te = &env->tlb_table[is_user][index];
+        te = &env->tlb_table[mmu_idx][index];
         te->addend = addend;
         if (prot & PAGE_READ) {
             te->addr_read = address;
@@ -1790,7 +1790,7 @@ void tlb_flush_page(CPUState *env, targe
 
 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
                       target_phys_addr_t paddr, int prot,
-                      int is_user, int is_softmmu)
+                      int mmu_idx, int is_softmmu)
 {
     return 0;
 }
Index: softmmu_exec.h
===================================================================
RCS file: /sources/qemu/qemu/softmmu_exec.h,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 softmmu_exec.h
--- softmmu_exec.h	30 Oct 2005 18:16:26 -0000	1.1
+++ softmmu_exec.h	11 Oct 2007 11:00:06 -0000
@@ -1,10 +1,16 @@
 /* Common softmmu definitions and inline routines.  */
 
-#define ldul_user ldl_user
-#define ldul_kernel ldl_kernel
+/* XXX: find something cleaner.
+ * Furthermore, this is false for 64 bits targets
+ */
+#define ldul_user       ldl_user
+#define ldul_kernel     ldl_kernel
+#define ldul_hypv       ldl_hypv
+#define ldul_executive  ldl_executive
+#define ldul_supervisor ldl_supervisor
 
 #define ACCESS_TYPE 0
-#define MEMSUFFIX _kernel
+#define MEMSUFFIX MMU_MODE0_SUFFIX
 #define DATA_SIZE 1
 #include "softmmu_header.h"
 
@@ -20,7 +26,7 @@
 #undef MEMSUFFIX
 
 #define ACCESS_TYPE 1
-#define MEMSUFFIX _user
+#define MEMSUFFIX MMU_MODE1_SUFFIX
 #define DATA_SIZE 1
 #include "softmmu_header.h"
 
@@ -35,8 +41,50 @@
 #undef ACCESS_TYPE
 #undef MEMSUFFIX
 
-/* these access are slower, they must be as rare as possible */
+#if (NB_MMU_MODES >= 3)
+
 #define ACCESS_TYPE 2
+#define MEMSUFFIX MMU_MODE2_SUFFIX
+#define DATA_SIZE 1
+#include "softmmu_header.h"
+
+#define DATA_SIZE 2
+#include "softmmu_header.h"
+
+#define DATA_SIZE 4
+#include "softmmu_header.h"
+
+#define DATA_SIZE 8
+#include "softmmu_header.h"
+#undef ACCESS_TYPE
+#undef MEMSUFFIX
+
+#if (NB_MMU_MODES >= 4)
+
+#define ACCESS_TYPE 3
+#define MEMSUFFIX MMU_MODE3_SUFFIX
+#define DATA_SIZE 1
+#include "softmmu_header.h"
+
+#define DATA_SIZE 2
+#include "softmmu_header.h"
+
+#define DATA_SIZE 4
+#include "softmmu_header.h"
+
+#define DATA_SIZE 8
+#include "softmmu_header.h"
+#undef ACCESS_TYPE
+#undef MEMSUFFIX
+
+#if (NB_MMU_MODES > 4)
+#error "NB_MMU_MODES > 4 is not supported for now"
+#endif /* (NB_MMU_MODES > 4) */
+#endif /* (NB_MMU_MODES == 4) */
+#endif /* (NB_MMU_MODES >= 3) */
+
+/* these access are slower, they must be as rare as possible */
+#define ACCESS_TYPE (NB_MMU_MODES)
 #define MEMSUFFIX _data
 #define DATA_SIZE 1
 #include "softmmu_header.h"
Index: softmmu_header.h
===================================================================
RCS file: /sources/qemu/qemu/softmmu_header.h,v
retrieving revision 1.17
diff -u -d -d -p -r1.17 softmmu_header.h
--- softmmu_header.h	8 Oct 2007 13:16:14 -0000	1.17
+++ softmmu_header.h	11 Oct 2007 11:00:06 -0000
@@ -39,66 +39,19 @@
 #error unsupported data size
 #endif
 
-#if ACCESS_TYPE == 0
-
-#define CPU_MEM_INDEX 0
-#define MMUSUFFIX _mmu
-
-#elif ACCESS_TYPE == 1
+#if ACCESS_TYPE < (NB_MMU_MODES)
 
-#define CPU_MEM_INDEX 1
+#define CPU_MMU_INDEX ACCESS_TYPE
 #define MMUSUFFIX _mmu
 
-#elif ACCESS_TYPE == 2
+#elif ACCESS_TYPE == (NB_MMU_MODES)
 
-#ifdef TARGET_I386
-#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
-#elif defined (TARGET_PPC)
-#define CPU_MEM_INDEX (msr_pr)
-#elif defined (TARGET_MIPS)
-#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
-#elif defined (TARGET_SPARC)
-#define CPU_MEM_INDEX ((env->psrs) == 0)
-#elif defined (TARGET_ARM)
-#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
-#elif defined (TARGET_SH4)
-#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
-#elif defined (TARGET_ALPHA)
-#define CPU_MEM_INDEX ((env->ps >> 3) & 3)
-#elif defined (TARGET_M68K)
-#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)
-#elif defined (TARGET_CRIS)
-/* CRIS FIXME: I guess we want to validate supervisor mode acceses here.  */
-#define CPU_MEM_INDEX (0)
-#else
-#error unsupported CPU
-#endif
+#define CPU_MMU_INDEX (cpu_mmu_index(env))
 #define MMUSUFFIX _mmu
 
-#elif ACCESS_TYPE == 3
+#elif ACCESS_TYPE == (NB_MMU_MODES + 1)
 
-#ifdef TARGET_I386
-#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
-#elif defined (TARGET_PPC)
-#define CPU_MEM_INDEX (msr_pr)
-#elif defined (TARGET_MIPS)
-#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
-#elif defined (TARGET_SPARC)
-#define CPU_MEM_INDEX ((env->psrs) == 0)
-#elif defined (TARGET_ARM)
-#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
-#elif defined (TARGET_SH4)
-#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
-#elif defined (TARGET_ALPHA)
-#define CPU_MEM_INDEX ((env->ps >> 3) & 3)
-#elif defined (TARGET_M68K)
-#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)
-#elif defined (TARGET_CRIS)
-/* CRIS FIXME: I guess we want to validate supervisor mode acceses here.  */
-#define CPU_MEM_INDEX (0)
-#else
-#error unsupported CPU
-#endif
+#define CPU_MMU_INDEX (cpu_mmu_index(env))
 #define MMUSUFFIX _cmmu
 
 #else
@@ -111,15 +64,15 @@
 #define RES_TYPE int
 #endif
 
-#if ACCESS_TYPE == 3
+#if ACCESS_TYPE == (NB_MMU_MODES + 1)
 #define ADDR_READ addr_code
 #else
 #define ADDR_READ addr_read
 #endif
 
 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                         int is_user);
-void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int is_user);
+                                                         int mmu_idx);
+void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int mmu_idx);
 
 #if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
     (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU)
@@ -161,8 +114,8 @@ static inline RES_TYPE glue(glue(ld, USU
                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
-                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
-                  "i" (CPU_MEM_INDEX),
+                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
+                  "i" (CPU_MMU_INDEX),
                   "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
                   : "%eax", "%ecx", "%edx", "memory", "cc");
     return res;
@@ -208,8 +161,8 @@ static inline int glue(glue(lds, SUFFIX)
                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
-                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
-                  "i" (CPU_MEM_INDEX),
+                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
+                  "i" (CPU_MMU_INDEX),
                   "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
                   : "%eax", "%ecx", "%edx", "memory", "cc");
     return res;
@@ -260,8 +213,8 @@ static inline void glue(glue(st, SUFFIX)
                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
-                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_write)),
-                  "i" (CPU_MEM_INDEX),
+                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)),
+                  "i" (CPU_MMU_INDEX),
                   "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
                   : "%eax", "%ecx", "%edx", "memory", "cc");
 }
@@ -276,16 +229,16 @@ static inline RES_TYPE glue(glue(ld, USU
     RES_TYPE res;
     target_ulong addr;
     unsigned long physaddr;
-    int is_user;
+    int mmu_idx;
 
     addr = ptr;
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    is_user = CPU_MEM_INDEX;
-    if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
+    mmu_idx = CPU_MMU_INDEX;
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].ADDR_READ !=
                          (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
-        res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
+        res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
     } else {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
     }
     return res;
@@ -297,23 +250,23 @@ static inline int glue(glue(lds, SUFFIX)
     int res, index;
     target_ulong addr;
     unsigned long physaddr;
-    int is_user;
+    int mmu_idx;
 
     addr = ptr;
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    is_user = CPU_MEM_INDEX;
-    if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
+    mmu_idx = CPU_MMU_INDEX;
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].ADDR_READ !=
                          (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
-        res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
+        res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
     } else {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
     }
     return res;
 }
 #endif
 
-#if ACCESS_TYPE != 3
+#if ACCESS_TYPE != (NB_MMU_MODES + 1)
 
 /* generic store macro */
 
@@ -322,25 +275,25 @@ static inline void glue(glue(st, SUFFIX)
     int index;
     target_ulong addr;
     unsigned long physaddr;
-    int is_user;
+    int mmu_idx;
 
     addr = ptr;
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    is_user = CPU_MEM_INDEX;
-    if (__builtin_expect(env->tlb_table[is_user][index].addr_write !=
+    mmu_idx = CPU_MMU_INDEX;
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].addr_write !=
                          (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
-        glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user);
+        glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx);
     } else {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
     }
 }
 
-#endif /* ACCESS_TYPE != 3 */
+#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
 
 #endif /* !asm */
 
-#if ACCESS_TYPE != 3
+#if ACCESS_TYPE != (NB_MMU_MODES + 1)
 
 #if DATA_SIZE == 8
 static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
@@ -386,7 +339,7 @@ static inline void glue(stfl, MEMSUFFIX)
 }
 #endif /* DATA_SIZE == 4 */
 
-#endif /* ACCESS_TYPE != 3 */
+#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
 
 #undef RES_TYPE
 #undef DATA_TYPE
@@ -394,6 +347,6 @@ static inline void glue(stfl, MEMSUFFIX)
 #undef SUFFIX
 #undef USUFFIX
 #undef DATA_SIZE
-#undef CPU_MEM_INDEX
+#undef CPU_MMU_INDEX
 #undef MMUSUFFIX
 #undef ADDR_READ
Index: softmmu_template.h
===================================================================
RCS file: /sources/qemu/qemu/softmmu_template.h,v
retrieving revision 1.18
diff -u -d -d -p -r1.18 softmmu_template.h
--- softmmu_template.h	17 Sep 2007 08:09:45 -0000	1.18
+++ softmmu_template.h	11 Oct 2007 11:00:06 -0000
@@ -48,7 +48,7 @@
 #endif
 
 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                        int is_user,
+                                                        int mmu_idx,
                                                         void *retaddr);
 static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
                                               target_ulong tlb_addr)
@@ -76,7 +76,7 @@ static inline DATA_TYPE glue(io_read, SU
 
 /* handle all cases except unaligned access which span two pages */
 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                         int is_user)
+                                                         int mmu_idx)
 {
     DATA_TYPE res;
     int index;
@@ -88,9 +88,9 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF
     /* XXX: could done more in memory macro in a non portable way */
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
+    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -101,16 +101,16 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF
         do_unaligned_access:
             retaddr = GETPC();
 #ifdef ALIGNED_ONLY
-            do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
+            do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
 #endif
             res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
-                                                         is_user, retaddr);
+                                                         mmu_idx, retaddr);
         } else {
             /* unaligned/aligned access in the same page */
 #ifdef ALIGNED_ONLY
             if ((addr & (DATA_SIZE - 1)) != 0) {
                 retaddr = GETPC();
-                do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
+                do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
             }
 #endif
             res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr);
@@ -120,9 +120,9 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF
         retaddr = GETPC();
 #ifdef ALIGNED_ONLY
         if ((addr & (DATA_SIZE - 1)) != 0)
-            do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
+            do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
 #endif
-        tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
+        tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
         goto redo;
     }
     return res;
@@ -130,7 +130,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF
 
 /* handle all unaligned cases */
 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                        int is_user,
+                                                        int mmu_idx,
                                                         void *retaddr)
 {
     DATA_TYPE res, res1, res2;
@@ -140,9 +140,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFF
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
+    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -154,9 +154,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFF
             addr1 = addr & ~(DATA_SIZE - 1);
             addr2 = addr1 + DATA_SIZE;
             res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1,
-                                                          is_user, retaddr);
+                                                          mmu_idx, retaddr);
             res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2,
-                                                          is_user, retaddr);
+                                                          mmu_idx, retaddr);
             shift = (addr & (DATA_SIZE - 1)) * 8;
 #ifdef TARGET_WORDS_BIGENDIAN
             res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
@@ -170,7 +170,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFF
         }
     } else {
         /* the page is not in the TLB : fill it */
-        tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
+        tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
         goto redo;
     }
     return res;
@@ -180,7 +180,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFF
 
 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                    DATA_TYPE val,
-                                                   int is_user,
+                                                   int mmu_idx,
                                                    void *retaddr);
 
 static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
@@ -211,7 +211,7 @@ static inline void glue(io_write, SUFFIX
 
 void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                     DATA_TYPE val,
-                                                    int is_user)
+                                                    int mmu_idx)
 {
     target_phys_addr_t physaddr;
     target_ulong tlb_addr;
@@ -220,9 +220,9 @@ void REGPARM(2) glue(glue(__st, SUFFIX),
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].addr_write;
+    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -233,16 +233,16 @@ void REGPARM(2) glue(glue(__st, SUFFIX),
         do_unaligned_access:
             retaddr = GETPC();
 #ifdef ALIGNED_ONLY
-            do_unaligned_access(addr, 1, is_user, retaddr);
+            do_unaligned_access(addr, 1, mmu_idx, retaddr);
 #endif
             glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
-                                                   is_user, retaddr);
+                                                   mmu_idx, retaddr);
         } else {
             /* aligned/unaligned access in the same page */
 #ifdef ALIGNED_ONLY
             if ((addr & (DATA_SIZE - 1)) != 0) {
                 retaddr = GETPC();
-                do_unaligned_access(addr, 1, is_user, retaddr);
+                do_unaligned_access(addr, 1, mmu_idx, retaddr);
             }
 #endif
             glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val);
@@ -252,9 +252,9 @@ void REGPARM(2) glue(glue(__st, SUFFIX),
         retaddr = GETPC();
 #ifdef ALIGNED_ONLY
         if ((addr & (DATA_SIZE - 1)) != 0)
-            do_unaligned_access(addr, 1, is_user, retaddr);
+            do_unaligned_access(addr, 1, mmu_idx, retaddr);
 #endif
-        tlb_fill(addr, 1, is_user, retaddr);
+        tlb_fill(addr, 1, mmu_idx, retaddr);
         goto redo;
     }
 }
@@ -262,7 +262,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX),
 /* handles all unaligned cases */
 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                    DATA_TYPE val,
-                                                   int is_user,
+                                                   int mmu_idx,
                                                    void *retaddr)
 {
     target_phys_addr_t physaddr;
@@ -271,9 +271,9 @@ static void glue(glue(slow_st, SUFFIX), 
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].addr_write;
+    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -285,10 +285,10 @@ static void glue(glue(slow_st, SUFFIX), 
             for(i = 0;i < DATA_SIZE; i++) {
 #ifdef TARGET_WORDS_BIGENDIAN
                 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
-                                          is_user, retaddr);
+                                          mmu_idx, retaddr);
 #else
                 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8),
-                                          is_user, retaddr);
+                                          mmu_idx, retaddr);
 #endif
             }
         } else {
@@ -297,7 +297,7 @@ static void glue(glue(slow_st, SUFFIX), 
         }
     } else {
         /* the page is not in the TLB : fill it */
-        tlb_fill(addr, 1, is_user, retaddr);
+        tlb_fill(addr, 1, mmu_idx, retaddr);
         goto redo;
     }
 }
Index: hw/alpha_palcode.c
===================================================================
RCS file: /sources/qemu/qemu/hw/alpha_palcode.c,v
retrieving revision 1.3
diff -u -d -d -p -r1.3 alpha_palcode.c
--- hw/alpha_palcode.c	17 Sep 2007 08:09:46 -0000	1.3
+++ hw/alpha_palcode.c	11 Oct 2007 11:00:07 -0000
@@ -811,12 +811,14 @@ static int get_page_bits (CPUState *env)
 
 static int get_pte (uint64_t *pfnp, int *zbitsp, int *protp,
                     uint64_t ptebase, int page_bits, uint64_t level,
-                    int is_user, int rw)
+                    int mmu_idx, int rw)
 {
     uint64_t pteaddr, pte, pfn;
     uint8_t gh;
-    int ure, uwe, kre, kwe, foE, foR, foW, v, ret, ar;
+    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 */
@@ -871,7 +873,7 @@ static int get_pte (uint64_t *pfnp, int 
 
 static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot,
                            uint64_t ptebase, int page_bits,
-                           uint64_t vaddr, int is_user, int rw)
+                           uint64_t vaddr, int mmu_idx, int rw)
 {
     uint64_t pfn, page_mask, lvl_mask, level1, level2, level3;
     int lvl_bits, ret;
@@ -909,7 +911,7 @@ static int paddr_from_pte (uint64_t *pad
         break;
     }
     /* Level 3 PTE */
-    ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, is_user, rw);
+    ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, mmu_idx, rw);
     if (ret & 0x1) {
         /* Translation not valid */
         ret = 1;
@@ -943,7 +945,7 @@ static int paddr_from_pte (uint64_t *pad
 
 static int virtual_to_physical (CPUState *env, uint64_t *physp,
                                 int *zbitsp, int *protp,
-                                uint64_t virtual, int is_user, int rw)
+                                uint64_t virtual, int mmu_idx, int rw)
 {
     uint64_t sva, ptebase;
     int seg, page_bits, ret;
@@ -961,16 +963,16 @@ static int virtual_to_physical (CPUState
     case 0:
         /* seg1: 3 levels of PTE */
         ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, is_user, rw);
+                             virtual, mmu_idx, rw);
         break;
     case 1:
         /* seg1: 2 levels of PTE */
         ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, is_user, rw);
+                             virtual, mmu_idx, rw);
         break;
     case 2:
         /* kernel segment */
-        if (is_user) {
+        if (mmu_idx != 0) {
             ret = 2;
         } else {
             *physp = virtual;
@@ -979,7 +981,7 @@ static int virtual_to_physical (CPUState
     case 3:
         /* seg1: TB mapped */
         ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, is_user, rw);
+                             virtual, mmu_idx, rw);
         break;
     default:
         ret = 1;
@@ -991,7 +993,7 @@ static int virtual_to_physical (CPUState
 
 /* XXX: code provision */
 int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     uint64_t physical, page_size, end;
     int prot, zbits, ret;
@@ -1000,7 +1002,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *
         ret = 2;
     } else {
         ret = virtual_to_physical(env, &physical, &zbits, &prot,
-                                  address, is_user, rw);
+                                  address, mmu_idx, rw);
     }
     switch (ret) {
     case 0:
@@ -1009,7 +1011,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *
         address &= ~(page_size - 1);
         for (end = physical + page_size; physical < end; physical += 0x1000) {
             ret = tlb_set_page(env, address, physical, prot,
-                               is_user, is_softmmu);
+                               mmu_idx, is_softmmu);
             address += 0x1000;
         }
         break;
Index: target-alpha/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-alpha/cpu.h,v
retrieving revision 1.8
diff -u -d -d -p -r1.8 cpu.h
--- target-alpha/cpu.h	27 Sep 2007 16:44:31 -0000	1.8
+++ target-alpha/cpu.h	11 Oct 2007 11:00:07 -0000
@@ -256,6 +256,8 @@ struct pal_handler_t {
     void (*call_pal)(CPUAlphaState *env, uint32_t palcode);
 };
 
+#define NB_MMU_MODES 4
+
 struct CPUAlphaState {
     uint64_t ir[31];
     float64  fir[31];
@@ -302,6 +304,17 @@ 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;
+}
+
 #include "cpu-all.h"
 
 enum {
Index: target-alpha/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-alpha/exec.h,v
retrieving revision 1.3
diff -u -d -d -p -r1.3 exec.h
--- target-alpha/exec.h	16 Sep 2007 21:08:01 -0000	1.3
+++ target-alpha/exec.h	11 Oct 2007 11:00:07 -0000
@@ -73,7 +73,7 @@ static inline void regs_to_env(void)
 }
 
 int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
-                                int is_user, int is_softmmu);
+                                int mmu_idx, int is_softmmu);
 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);
 
Index: target-alpha/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-alpha/helper.c,v
retrieving revision 1.4
diff -u -d -d -p -r1.4 helper.c
--- target-alpha/helper.c	17 Sep 2007 08:09:51 -0000	1.4
+++ target-alpha/helper.c	11 Oct 2007 11:00:07 -0000
@@ -28,7 +28,7 @@
 #if defined(CONFIG_USER_ONLY)
 
 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                                int is_user, int is_softmmu)
+                                int mmu_idx, int is_softmmu)
 {
     if (rw == 2)
         env->exception_index = EXCP_ITB_MISS;
@@ -57,7 +57,7 @@ target_phys_addr_t cpu_get_phys_page_deb
 }
 
 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                                int is_user, int is_softmmu)
+                                int mmu_idx, int is_softmmu)
 {
     uint32_t opc;
 
Index: target-alpha/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-alpha/op_helper.c,v
retrieving revision 1.2
diff -u -d -d -p -r1.2 op_helper.c
--- target-alpha/op_helper.c	16 Sep 2007 21:08:01 -0000	1.2
+++ target-alpha/op_helper.c	11 Oct 2007 11:00:07 -0000
@@ -1164,20 +1164,20 @@ void helper_mtpr (int iprn)
 void helper_ld_phys_to_virt (void)
 {
     uint64_t tlb_addr, physaddr;
-    int index, is_user;
+    int index, mmu_idx;
     void *retaddr;
 
-    is_user = (env->ps >> 3) & 3;
+    mmu_idx = cpu_mmu_index(env);
     index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].addr_read;
+    tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
     if ((T0 & TARGET_PAGE_MASK) ==
         (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = T0 + env->tlb_table[is_user][index].addend;
+        physaddr = T0 + env->tlb_table[mmu_idx][index].addend;
     } else {
         /* the page is not in the TLB : fill it */
         retaddr = GETPC();
-        tlb_fill(T0, 0, is_user, retaddr);
+        tlb_fill(T0, 0, mmu_idx, retaddr);
         goto redo;
     }
     T0 = physaddr;
@@ -1186,20 +1186,20 @@ void helper_ld_phys_to_virt (void)
 void helper_st_phys_to_virt (void)
 {
     uint64_t tlb_addr, physaddr;
-    int index, is_user;
+    int index, mmu_idx;
     void *retaddr;
 
-    is_user = (env->ps >> 3) & 3;
+    mmu_idx = cpu_mmu_index(env);
     index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].addr_write;
+    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
     if ((T0 & TARGET_PAGE_MASK) ==
         (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = T0 + env->tlb_table[is_user][index].addend;
+        physaddr = T0 + env->tlb_table[mmu_idx][index].addend;
     } else {
         /* the page is not in the TLB : fill it */
         retaddr = GETPC();
-        tlb_fill(T0, 1, is_user, retaddr);
+        tlb_fill(T0, 1, mmu_idx, retaddr);
         goto redo;
     }
     T0 = physaddr;
@@ -1223,7 +1223,7 @@ void helper_st_phys_to_virt (void)
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -1234,7 +1234,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    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 */
Index: target-arm/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-arm/cpu.h,v
retrieving revision 1.34
diff -u -d -d -p -r1.34 cpu.h
--- target-arm/cpu.h	27 Sep 2007 16:44:31 -0000	1.34
+++ target-arm/cpu.h	11 Oct 2007 11:00:07 -0000
@@ -43,6 +43,8 @@ typedef void ARMWriteCPFunc(void *opaque
 typedef uint32_t ARMReadCPFunc(void *opaque, int cp_info,
                                int dstreg, int operand);
 
+#define NB_MMU_MODES 2
+
 /* We currently assume float and double are IEEE single and double
    precision respectively.
    Doing runtime conversions is tricky because VFP registers may contain
@@ -300,6 +302,15 @@ void cpu_arm_set_cp_io(CPUARMState *env,
 #define cpu_gen_code cpu_arm_gen_code
 #define cpu_signal_handler cpu_arm_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR ? 1 : 0;
+}
+
 #include "cpu-all.h"
 
 #endif
Index: target-arm/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-arm/exec.h,v
retrieving revision 1.13
diff -u -d -d -p -r1.13 exec.h
--- target-arm/exec.h	16 Sep 2007 21:08:01 -0000	1.13
+++ target-arm/exec.h	11 Oct 2007 11:00:07 -0000
@@ -46,7 +46,7 @@ static inline void regs_to_env(void)
 }
 
 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu);
+                              int mmu_idx, int is_softmmu);
 
 static inline int cpu_halted(CPUState *env) {
     if (!env->halted)
Index: target-arm/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-arm/helper.c,v
retrieving revision 1.21
diff -u -d -d -p -r1.21 helper.c
--- target-arm/helper.c	16 Sep 2007 21:08:01 -0000	1.21
+++ target-arm/helper.c	11 Oct 2007 11:00:07 -0000
@@ -169,7 +169,7 @@ void do_interrupt (CPUState *env)
 }
 
 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     if (rw == 2) {
         env->exception_index = EXCP_PREFETCH_ABORT;
@@ -547,18 +547,19 @@ do_fault:
 }
 
 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
-                              int access_type, int is_user, int is_softmmu)
+                              int access_type, int mmu_idx, int is_softmmu)
 {
     uint32_t phys_addr;
     int prot;
-    int ret;
+    int ret, is_user;
 
+    is_user = mmu_idx == MMU_USER_IDX;
     ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot);
     if (ret == 0) {
         /* Map a single [sub]page.  */
         phys_addr &= ~(uint32_t)0x3ff;
         address &= ~(uint32_t)0x3ff;
-        return tlb_set_page (env, address, phys_addr, prot, is_user,
+        return tlb_set_page (env, address, phys_addr, prot, mmu_idx,
                              is_softmmu);
     }
 
Index: target-arm/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-arm/op_helper.c,v
retrieving revision 1.6
diff -u -d -d -p -r1.6 op_helper.c
--- target-arm/op_helper.c	16 Sep 2007 21:08:02 -0000	1.6
+++ target-arm/op_helper.c	11 Oct 2007 11:00:07 -0000
@@ -196,7 +196,7 @@ void do_vfp_get_fpscr(void)
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -207,7 +207,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_arm_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (__builtin_expect(ret, 0)) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-cris/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-cris/cpu.h,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 cpu.h
--- target-cris/cpu.h	8 Oct 2007 13:04:02 -0000	1.1
+++ target-cris/cpu.h	11 Oct 2007 11:00:07 -0000
@@ -74,6 +74,8 @@
 /* Internal flags for the implementation.  */
 #define F_DELAYSLOT 1
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUCRISState {
 	uint32_t debug1;
 	uint32_t debug2;
@@ -229,6 +231,16 @@ void register_cris_insns (CPUCRISState *
 #define cpu_gen_code cpu_cris_gen_code
 #define cpu_signal_handler cpu_cris_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+/* CRIS FIXME: I guess we want to validate supervisor mode acceses here.  */
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return 0;
+}
+
 #include "cpu-all.h"
 
 /* Register aliases.  */
Index: target-cris/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-cris/exec.h,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 exec.h
--- target-cris/exec.h	8 Oct 2007 13:04:02 -0000	1.1
+++ target-cris/exec.h	11 Oct 2007 11:00:07 -0000
@@ -45,8 +45,8 @@ static inline void regs_to_env(void)
 }
 
 int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu);
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr);
+                              int mmu_idx, int is_softmmu);
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr);
 
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
Index: target-cris/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-cris/helper.c,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 helper.c
--- target-cris/helper.c	8 Oct 2007 13:04:02 -0000	1.1
+++ target-cris/helper.c	11 Oct 2007 11:00:07 -0000
@@ -35,7 +35,7 @@ void do_interrupt (CPUState *env)
 }
 
 int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-                             int is_user, int is_softmmu)
+                             int mmu_idx, int is_softmmu)
 {
     env->exception_index = 0xaa;
     env->debug1 = address;
@@ -52,7 +52,7 @@ target_phys_addr_t cpu_get_phys_page_deb
 #else /* !CONFIG_USER_ONLY */
 
 int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
 	struct cris_mmu_result_t res;
 	int prot, miss;
@@ -61,7 +61,7 @@ int cpu_cris_handle_mmu_fault (CPUState 
 	address &= TARGET_PAGE_MASK;
 	prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 //	printf ("%s pc=%x %x w=%d smmu=%d\n", __func__, env->pc, address, rw, is_softmmu);
-	miss = cris_mmu_translate(&res, env, address, rw, is_user);
+	miss = cris_mmu_translate(&res, env, address, rw, mmu_idx);
 	if (miss)
 	{
 		/* handle the miss.  */
@@ -73,7 +73,7 @@ int cpu_cris_handle_mmu_fault (CPUState 
 		phy = res.phy;
 	}
 //	printf ("a=%x phy=%x\n", address, phy);
-	return tlb_set_page(env, address, phy, prot, is_user, is_softmmu);
+	return tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu);
 }
 
 
Index: target-cris/mmu.c
===================================================================
RCS file: /sources/qemu/qemu/target-cris/mmu.c,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 mmu.c
--- target-cris/mmu.c	8 Oct 2007 13:11:58 -0000	1.1
+++ target-cris/mmu.c	11 Oct 2007 11:00:07 -0000
@@ -111,11 +111,12 @@ static int cris_mmu_translate_page(struc
 
 int cris_mmu_translate(struct cris_mmu_result_t *res,
 		       CPUState *env, uint32_t vaddr,
-		       int rw, int is_user)
+		       int rw, int mmu_idx)
 {
 	uint32_t phy = vaddr;
 	int seg;
 	int miss = 0;
+        int is_user = mmu_idx == MMU_USER_IDX;
 
 	if (!cris_mmu_enabled(env->sregs[SFR_RW_GC_CFG])) {
 		res->phy = vaddr;
Index: target-cris/mmu.h
===================================================================
RCS file: /sources/qemu/qemu/target-cris/mmu.h,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 mmu.h
--- target-cris/mmu.h	8 Oct 2007 13:11:58 -0000	1.1
+++ target-cris/mmu.h	11 Oct 2007 11:00:07 -0000
@@ -17,4 +17,4 @@ struct cris_mmu_result_t
 
 int cris_mmu_translate(struct cris_mmu_result_t *res,
 		       CPUState *env, uint32_t vaddr,
-		       int rw, int is_user);
+		       int rw, int mmu_idx);
Index: target-cris/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-cris/op_helper.c,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 op_helper.c
--- target-cris/op_helper.c	8 Oct 2007 13:04:02 -0000	1.1
+++ target-cris/op_helper.c	11 Oct 2007 11:00:07 -0000
@@ -41,7 +41,7 @@
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -52,7 +52,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (__builtin_expect(ret, 0)) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-i386/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-i386/cpu.h,v
retrieving revision 1.50
diff -u -d -d -p -r1.50 cpu.h
--- target-i386/cpu.h	27 Sep 2007 16:44:31 -0000	1.50
+++ target-i386/cpu.h	11 Oct 2007 11:00:07 -0000
@@ -432,6 +432,8 @@ typedef union {
 #define CPU_NB_REGS 8
 #endif
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUX86State {
 #if TARGET_LONG_BITS > HOST_LONG_BITS
     /* temporaries if we cannot store them in host registers */
@@ -688,6 +690,15 @@ static inline int cpu_get_time_fast(void
 #define cpu_gen_code cpu_x86_gen_code
 #define cpu_signal_handler cpu_x86_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
+}
+
 #include "cpu-all.h"
 
 #include "svm.h"
Index: target-i386/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-i386/exec.h,v
retrieving revision 1.37
diff -u -d -d -p -r1.37 exec.h
--- target-i386/exec.h	23 Sep 2007 15:28:04 -0000	1.37
+++ target-i386/exec.h	11 Oct 2007 11:00:07 -0000
@@ -163,8 +163,8 @@ void cpu_x86_update_cr3(CPUX86State *env
 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
 void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr);
 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
-                             int is_write, int is_user, int is_softmmu);
-void tlb_fill(target_ulong addr, int is_write, int is_user,
+                             int is_write, int mmu_idx, int is_softmmu);
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
               void *retaddr);
 void __hidden cpu_lock(void);
 void __hidden cpu_unlock(void);
Index: target-i386/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-i386/helper.c,v
retrieving revision 1.89
diff -u -d -d -p -r1.89 helper.c
--- target-i386/helper.c	27 Sep 2007 01:52:00 -0000	1.89
+++ target-i386/helper.c	11 Oct 2007 11:00:08 -0000
@@ -3885,7 +3885,7 @@ void update_fp_status(void)
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     int ret;
@@ -3897,7 +3897,7 @@ void tlb_fill(target_ulong addr, int is_
     saved_env = env;
     env = cpu_single_env;
 
-    ret = cpu_x86_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (ret) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-i386/helper2.c
===================================================================
RCS file: /sources/qemu/qemu/target-i386/helper2.c,v
retrieving revision 1.52
diff -u -d -d -p -r1.52 helper2.c
--- target-i386/helper2.c	23 Sep 2007 15:28:04 -0000	1.52
+++ target-i386/helper2.c	11 Oct 2007 11:00:08 -0000
@@ -571,7 +571,7 @@ void cpu_x86_flush_tlb(CPUX86State *env,
 #if defined(CONFIG_USER_ONLY)
 
 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
-                             int is_write, int is_user, int is_softmmu)
+                             int is_write, int mmu_idx, int is_softmmu)
 {
     /* user mode only emulation */
     is_write &= 1;
@@ -598,14 +598,15 @@ target_phys_addr_t cpu_get_phys_page_deb
    2  = soft MMU activation required for this block
 */
 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
-                             int is_write1, int is_user, int is_softmmu)
+                             int is_write1, int mmu_idx, int is_softmmu)
 {
     uint64_t ptep, pte;
     uint32_t pdpe_addr, pde_addr, pte_addr;
-    int error_code, is_dirty, prot, page_size, ret, is_write;
+    int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
     unsigned long paddr, page_offset;
     target_ulong vaddr, virt_addr;
 
+    is_user = mmu_idx == MMU_USER_IDX;
 #if defined(DEBUG_MMU)
     printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
            addr, is_write1, is_user, env->eip);
@@ -862,7 +863,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State
     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
     vaddr = virt_addr + page_offset;
 
-    ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+    ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
     return ret;
  do_fault_protect:
     error_code = PG_ERROR_P_MASK;
Index: target-m68k/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-m68k/cpu.h,v
retrieving revision 1.13
diff -u -d -d -p -r1.13 cpu.h
--- target-m68k/cpu.h	17 Sep 2007 08:09:53 -0000	1.13
+++ target-m68k/cpu.h	11 Oct 2007 11:00:08 -0000
@@ -53,6 +53,8 @@
 #define EXCP_RTE            0x100
 #define EXCP_HALT_INSN      0x101
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUM68KState {
     uint32_t dregs[8];
     uint32_t aregs[8];
@@ -223,6 +225,15 @@ void register_m68k_insns (CPUM68KState *
 #define cpu_gen_code cpu_m68k_gen_code
 #define cpu_signal_handler cpu_m68k_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return (env->sr & SR_S) == 0 ? 1 : 0;
+}
+
 #include "cpu-all.h"
 
 #endif
Index: target-m68k/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-m68k/exec.h,v
retrieving revision 1.4
diff -u -d -d -p -r1.4 exec.h
--- target-m68k/exec.h	16 Sep 2007 21:08:03 -0000	1.4
+++ target-m68k/exec.h	11 Oct 2007 11:00:08 -0000
@@ -38,7 +38,7 @@ static inline void regs_to_env(void)
 }
 
 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu);
+                              int mmu_idx, int is_softmmu);
 
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
Index: target-m68k/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-m68k/helper.c,v
retrieving revision 1.7
diff -u -d -d -p -r1.7 helper.c
--- target-m68k/helper.c	16 Sep 2007 21:08:03 -0000	1.7
+++ target-m68k/helper.c	11 Oct 2007 11:00:08 -0000
@@ -301,7 +301,7 @@ target_phys_addr_t cpu_get_phys_page_deb
 #if defined(CONFIG_USER_ONLY)
 
 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     env->exception_index = EXCP_ACCESS;
     env->mmu.ar = address;
@@ -311,13 +311,13 @@ int cpu_m68k_handle_mmu_fault (CPUState 
 #else
 
 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     int prot;
 
     address &= TARGET_PAGE_MASK;
     prot = PAGE_READ | PAGE_WRITE;
-    return tlb_set_page(env, address, address, prot, is_user, is_softmmu);
+    return tlb_set_page(env, address, address, prot, mmu_idx, is_softmmu);
 }
 
 /* Notify CPU of a pending interrupt.  Prioritization and vectoring should
Index: target-m68k/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-m68k/op_helper.c,v
retrieving revision 1.6
diff -u -d -d -p -r1.6 op_helper.c
--- target-m68k/op_helper.c	16 Sep 2007 21:08:03 -0000	1.6
+++ target-m68k/op_helper.c	11 Oct 2007 11:00:08 -0000
@@ -49,7 +49,7 @@ extern int semihosting_enabled;
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -60,7 +60,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (__builtin_expect(ret, 0)) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-mips/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-mips/cpu.h,v
retrieving revision 1.47
diff -u -d -d -p -r1.47 cpu.h
--- target-mips/cpu.h	27 Sep 2007 16:44:31 -0000	1.47
+++ target-mips/cpu.h	11 Oct 2007 11:00:08 -0000
@@ -107,6 +107,8 @@ struct CPUMIPSFPUContext {
 #define FP_UNIMPLEMENTED  32
 };
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUMIPSMVPContext CPUMIPSMVPContext;
 struct CPUMIPSMVPContext {
     int32_t CP0_MVPControl;
@@ -483,6 +485,15 @@ int cpu_mips_register (CPUMIPSState *env
 #define cpu_gen_code cpu_mips_gen_code
 #define cpu_signal_handler cpu_mips_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM ? 1 : 0;
+}
+
 #include "cpu-all.h"
 
 /* Memory access type :
Index: target-mips/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-mips/exec.h,v
retrieving revision 1.38
diff -u -d -d -p -r1.38 exec.h
--- target-mips/exec.h	9 Oct 2007 03:39:58 -0000	1.38
+++ target-mips/exec.h	11 Oct 2007 11:00:08 -0000
@@ -105,7 +105,7 @@ void do_pmon (int function);
 void dump_sc (void);
 
 int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu);
+                               int mmu_idx, int is_softmmu);
 void do_interrupt (CPUState *env);
 void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra);
 
Index: target-mips/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/helper.c,v
retrieving revision 1.53
diff -u -d -d -p -r1.53 helper.c
--- target-mips/helper.c	30 Sep 2007 01:58:33 -0000	1.53
+++ target-mips/helper.c	11 Oct 2007 11:00:08 -0000
@@ -232,7 +232,7 @@ void cpu_mips_init_mmu (CPUState *env)
 #endif /* !defined(CONFIG_USER_ONLY) */
 
 int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     target_ulong physical;
     int prot;
@@ -244,8 +244,8 @@ int cpu_mips_handle_mmu_fault (CPUState 
 #if 0
         cpu_dump_state(env, logfile, fprintf, 0);
 #endif
-        fprintf(logfile, "%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d is_user %d smmu %d\n",
-                __func__, env->PC[env->current_tc], address, rw, is_user, is_softmmu);
+        fprintf(logfile, "%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d smmu %d\n",
+                __func__, env->PC[env->current_tc], address, rw, mmu_idx, is_softmmu);
     }
 
     rw &= 1;
@@ -268,7 +268,7 @@ int cpu_mips_handle_mmu_fault (CPUState 
     if (ret == TLBRET_MATCH) {
        ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
                           physical & TARGET_PAGE_MASK, prot,
-                          is_user, is_softmmu);
+                          mmu_idx, is_softmmu);
     } else if (ret < 0) {
     do_fault:
         switch (ret) {
Index: target-mips/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/op_helper.c,v
retrieving revision 1.65
diff -u -d -d -p -r1.65 op_helper.c
--- target-mips/op_helper.c	9 Oct 2007 03:39:58 -0000	1.65
+++ target-mips/op_helper.c	11 Oct 2007 11:00:08 -0000
@@ -563,7 +563,7 @@ static void do_unaligned_access (target_
     do_raise_exception ((is_write == 1) ? EXCP_AdES : EXCP_AdEL);
 }
 
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -574,7 +574,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_mips_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (ret) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-ppc/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/cpu.h,v
retrieving revision 1.78
diff -u -d -d -p -r1.78 cpu.h
--- target-ppc/cpu.h	8 Oct 2007 02:58:07 -0000	1.78
+++ target-ppc/cpu.h	11 Oct 2007 11:00:08 -0000
@@ -434,6 +434,12 @@ enum {
     POWERPC_FLAG_PMM  = 0x00000400,
 };
 
+#if defined(TARGET_PPC64H)
+#define NB_MMU_MODES 3
+#else
+#define NB_MMU_MODES 2
+#endif
+
 /*****************************************************************************/
 /* The whole PowerPC CPU context */
 struct CPUPPCState {
@@ -575,6 +581,7 @@ struct CPUPPCState {
     jmp_buf jmp_env;
     int user_mode_only; /* user mode only simulation */
     target_ulong hflags; /* hflags is a MSR & HFLAGS_MASK */
+    int mmu_idx;         /* precomputed MMU index to speed up mem accesses */
 
     /* Power management */
     int power_mode;
@@ -698,6 +705,18 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, i
 #define cpu_gen_code cpu_ppc_gen_code
 #define cpu_signal_handler cpu_ppc_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _user
+#define MMU_MODE1_SUFFIX _kernel
+#if defined(TARGET_PPC64H)
+#define MMU_MODE2_SUFFIX _hypv
+#endif
+#define MMU_USER_IDX 0
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return env->mmu_idx;
+}
+
 #include "cpu-all.h"
 
 /*****************************************************************************/
Index: target-ppc/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/exec.h,v
retrieving revision 1.28
diff -u -d -d -p -r1.28 exec.h
--- target-ppc/exec.h	7 Oct 2007 18:19:25 -0000	1.28
+++ target-ppc/exec.h	11 Oct 2007 11:00:08 -0000
@@ -112,7 +112,7 @@ static always_inline void regs_to_env (v
 }
 
 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu);
+                              int mmu_idx, int is_softmmu);
 
 static always_inline int cpu_halted (CPUState *env)
 {
Index: target-ppc/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/helper.c,v
retrieving revision 1.75
diff -u -d -d -p -r1.75 helper.c
--- target-ppc/helper.c	8 Oct 2007 02:58:07 -0000	1.75
+++ target-ppc/helper.c	11 Oct 2007 11:00:08 -0000
@@ -39,7 +39,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     int exception, error_code;
 
@@ -1349,7 +1349,7 @@ target_phys_addr_t cpu_get_phys_page_deb
 
 /* Perform address translation */
 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     mmu_ctx_t ctx;
     int access_type;
@@ -1370,7 +1370,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *
     if (ret == 0) {
         ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
                            ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
-                           is_user, is_softmmu);
+                           mmu_idx, is_softmmu);
     } else if (ret < 0) {
 #if defined (DEBUG_MMU)
         if (loglevel != 0)
@@ -2083,7 +2083,12 @@ void do_compute_hflags (CPUPPCState *env
     env->hflags |= msr_cm << MSR_CM;
     env->hflags |= (uint64_t)msr_sf << MSR_SF;
     env->hflags |= (uint64_t)msr_hv << MSR_HV;
+    /* Precompute MMU index */
+    if (msr_pr == 0 && msr_hv == 1)
+        env->mmu_idx = 2;
+    else
 #endif
+        env->mmu_idx = 1 - msr_pr;
 }
 
 /*****************************************************************************/
Index: target-ppc/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/op_helper.c,v
retrieving revision 1.49
diff -u -d -d -p -r1.49 op_helper.c
--- target-ppc/op_helper.c	7 Oct 2007 17:13:43 -0000	1.49
+++ target-ppc/op_helper.c	11 Oct 2007 11:00:09 -0000
@@ -2307,7 +2307,7 @@ DO_SPE_OP1(fsctuf);
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -2318,7 +2318,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (unlikely(ret != 0)) {
         if (likely(retaddr)) {
             /* now we have a real cpu fault */
Index: target-ppc/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/translate.c,v
retrieving revision 1.92
diff -u -d -d -p -r1.92 translate.c
--- target-ppc/translate.c	7 Oct 2007 23:10:08 -0000	1.92
+++ target-ppc/translate.c	11 Oct 2007 11:00:09 -0000
@@ -6693,15 +6693,8 @@ static always_inline int gen_intermediat
     ctx.tb = tb;
     ctx.exception = POWERPC_EXCP_NONE;
     ctx.spr_cb = env->spr_cb;
-#if defined(CONFIG_USER_ONLY)
-    supervisor = 0;
-#else
-#if defined(TARGET_PPC64H)
-    if (msr_pr == 0 && msr_hv == 1)
-        supervisor = 2;
-    else
-#endif
-        supervisor = 1 - msr_pr;
+    supervisor = env->mmu_idx;
+#if !defined(CONFIG_USER_ONLY)
     ctx.supervisor = supervisor;
 #endif
 #if defined(TARGET_PPC64)
Index: target-sh4/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/cpu.h,v
retrieving revision 1.10
diff -u -d -d -p -r1.10 cpu.h
--- target-sh4/cpu.h	16 Sep 2007 21:08:05 -0000	1.10
+++ target-sh4/cpu.h	11 Oct 2007 11:00:09 -0000
@@ -77,6 +77,8 @@ typedef struct tlb_t {
 #define UTLB_SIZE 64
 #define ITLB_SIZE 4
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUSH4State {
     uint32_t flags;		/* general execution flags */
     uint32_t gregs[24];		/* general registers */
@@ -134,6 +136,15 @@ int cpu_sh4_signal_handler(int host_sign
 #define cpu_gen_code cpu_sh4_gen_code
 #define cpu_signal_handler cpu_sh4_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return (env->sr & SR_MD) == 0 ? 1 : 0;
+}
+
 #include "cpu-all.h"
 
 /* Memory access type */
Index: target-sh4/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/exec.h,v
retrieving revision 1.5
diff -u -d -d -p -r1.5 exec.h
--- target-sh4/exec.h	16 Sep 2007 21:08:05 -0000	1.5
+++ target-sh4/exec.h	11 Oct 2007 11:00:09 -0000
@@ -63,7 +63,7 @@ static inline void env_to_regs(void)
 }
 
 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-			     int is_user, int is_softmmu);
+			     int mmu_idx, int is_softmmu);
 
 int find_itlb_entry(CPUState * env, target_ulong address,
 		    int use_asid, int update);
Index: target-sh4/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/helper.c,v
retrieving revision 1.4
diff -u -d -d -p -r1.4 helper.c
--- target-sh4/helper.c	16 Sep 2007 21:08:05 -0000	1.4
+++ target-sh4/helper.c	11 Oct 2007 11:00:09 -0000
@@ -36,7 +36,7 @@ void do_interrupt (CPUState *env)
 }
 
 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-			     int is_user, int is_softmmu)
+			     int mmu_idx, int is_softmmu)
 {
     env->tea = address;
     switch (rw) {
@@ -372,15 +372,15 @@ int get_physical_address(CPUState * env,
 }
 
 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-			     int is_user, int is_softmmu)
+			     int mmu_idx, int is_softmmu)
 {
     target_ulong physical, page_offset, page_size;
     int prot, ret, access_type;
 
     /* XXXXX */
 #if 0
-    fprintf(stderr, "%s pc %08x ad %08x rw %d is_user %d smmu %d\n",
-	    __func__, env->pc, address, rw, is_user, is_softmmu);
+    fprintf(stderr, "%s pc %08x ad %08x rw %d mmu_idx %d smmu %d\n",
+	    __func__, env->pc, address, rw, mmu_idx, is_softmmu);
 #endif
 
     access_type = ACCESS_INT;
@@ -426,7 +426,7 @@ int cpu_sh4_handle_mmu_fault(CPUState * 
     address = (address & TARGET_PAGE_MASK) + page_offset;
     physical = (physical & TARGET_PAGE_MASK) + page_offset;
 
-    return tlb_set_page(env, address, physical, prot, is_user, is_softmmu);
+    return tlb_set_page(env, address, physical, prot, mmu_idx, is_softmmu);
 }
 
 target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
Index: target-sh4/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/op_helper.c,v
retrieving revision 1.4
diff -u -d -d -p -r1.4 op_helper.c
--- target-sh4/op_helper.c	16 Sep 2007 21:08:05 -0000	1.4
+++ target-sh4/op_helper.c	11 Oct 2007 11:00:09 -0000
@@ -42,7 +42,7 @@ void do_raise_exception(void)
 #define SHIFT 3
 #include "softmmu_template.h"
 
-void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -53,7 +53,7 @@ void tlb_fill(target_ulong addr, int is_
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (ret) {
 	if (retaddr) {
 	    /* now we have a real cpu fault */
Index: target-sparc/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/cpu.h,v
retrieving revision 1.52
diff -u -d -d -p -r1.52 cpu.h
--- target-sparc/cpu.h	27 Sep 2007 16:44:32 -0000	1.52
+++ target-sparc/cpu.h	11 Oct 2007 11:00:09 -0000
@@ -166,6 +166,8 @@
 
 typedef struct sparc_def_t sparc_def_t;
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUSPARCState {
     target_ulong gregs[8]; /* general registers */
     target_ulong *regwptr; /* pointer to current register window */
@@ -316,6 +318,15 @@ void cpu_check_irqs(CPUSPARCState *env);
 #define cpu_gen_code cpu_sparc_gen_code
 #define cpu_signal_handler cpu_sparc_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return env->psrs == 0 ? 1 : 0;
+}
+
 #include "cpu-all.h"
 
 #endif
Index: target-sparc/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/exec.h,v
retrieving revision 1.21
diff -u -d -d -p -r1.21 exec.h
--- target-sparc/exec.h	30 Sep 2007 19:38:11 -0000	1.21
+++ target-sparc/exec.h	11 Oct 2007 11:00:09 -0000
@@ -115,7 +115,7 @@ static inline void regs_to_env(void)
 }
 
 int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu);
+                               int mmu_idx, int is_softmmu);
 
 static inline int cpu_halted(CPUState *env) {
     if (!env->halted)
Index: target-sparc/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/helper.c,v
retrieving revision 1.27
diff -u -d -d -p -r1.27 helper.c
--- target-sparc/helper.c	24 Sep 2007 19:44:09 -0000	1.27
+++ target-sparc/helper.c	11 Oct 2007 11:00:09 -0000
@@ -49,7 +49,7 @@ void cpu_unlock(void)
 #if defined(CONFIG_USER_ONLY)
 
 int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     if (rw & 2)
         env->exception_index = TT_TFAULT;
@@ -100,15 +100,16 @@ static const int perm_table[2][8] = {
 
 int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
                           int *access_index, target_ulong address, int rw,
-                          int is_user)
+                          int mmu_idx)
 {
     int access_perms = 0;
     target_phys_addr_t pde_ptr;
     uint32_t pde;
     target_ulong virt_addr;
-    int error_code = 0, is_dirty;
+    int error_code = 0, is_dirty, is_user;
     unsigned long page_offset;
 
+    is_user = mmu_idx == MMU_USER_IDX;
     virt_addr = address & TARGET_PAGE_MASK;
 
     if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
@@ -216,13 +217,13 @@ int get_physical_address (CPUState *env,
 
 /* Perform address translation */
 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     target_phys_addr_t paddr;
     target_ulong vaddr;
     int error_code = 0, prot, ret = 0, access_index;
 
-    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
+    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, mmu_idx);
     if (error_code == 0) {
         vaddr = address & TARGET_PAGE_MASK;
         paddr &= TARGET_PAGE_MASK;
@@ -230,7 +231,7 @@ int cpu_sparc_handle_mmu_fault (CPUState
         printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
                TARGET_FMT_lx "\n", address, paddr, vaddr);
 #endif
-        ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
         return ret;
     }
 
@@ -246,7 +247,7 @@ int cpu_sparc_handle_mmu_fault (CPUState
         // switching to normal mode.
         vaddr = address & TARGET_PAGE_MASK;
         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
-        ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
         return ret;
     } else {
         if (rw & 2)
@@ -484,8 +485,10 @@ static int get_physical_address_code(CPU
 
 int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
                           int *access_index, target_ulong address, int rw,
-                          int is_user)
+                          int mmu_idx)
 {
+    int is_user = mmu_idx == MMU_USER_IDX;
+
     if (rw == 2)
         return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
     else
@@ -494,20 +497,20 @@ int get_physical_address(CPUState *env, 
 
 /* Perform address translation */
 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     target_ulong virt_addr, vaddr;
     target_phys_addr_t paddr;
     int error_code = 0, prot, ret = 0, access_index;
 
-    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
+    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, mmu_idx);
     if (error_code == 0) {
         virt_addr = address & TARGET_PAGE_MASK;
         vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
 #ifdef DEBUG_MMU
         printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64 "\n", address, paddr, vaddr);
 #endif
-        ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
         return ret;
     }
     // XXX
Index: target-sparc/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.41
diff -u -d -d -p -r1.41 op_helper.c
--- target-sparc/op_helper.c	1 Oct 2007 17:07:58 -0000	1.41
+++ target-sparc/op_helper.c	11 Oct 2007 11:00:09 -0000
@@ -1522,7 +1522,7 @@ static void do_unaligned_access(target_u
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     int ret;
@@ -1534,7 +1534,7 @@ void tlb_fill(target_ulong addr, int is_
     saved_env = env;
     env = cpu_single_env;
 
-    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (ret) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-sparc/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/translate.c,v
retrieving revision 1.74
diff -u -d -d -p -r1.74 translate.c
--- target-sparc/translate.c	10 Oct 2007 19:11:54 -0000	1.74
+++ target-sparc/translate.c	11 Oct 2007 11:00:09 -0000
@@ -3689,7 +3689,7 @@ target_phys_addr_t cpu_get_phys_page_deb
 #else
 extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
                                  int *access_index, target_ulong address, int rw,
-                                 int is_user);
+                                 int mmu_idx);
 
 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
 {

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

* Re: [Qemu-devel] RFC: cleanups: CPU_MEM_INDEX
  2007-10-11 12:09     ` J. Mayer
@ 2007-10-11 17:46       ` Thiemo Seufer
  2007-10-11 22:27         ` J. Mayer
  2007-10-12  7:01       ` J. Mayer
  1 sibling, 1 reply; 9+ messages in thread
From: Thiemo Seufer @ 2007-10-11 17:46 UTC (permalink / raw)
  To: J. Mayer; +Cc: qemu-devel

J. Mayer wrote:
> On Wed, 2007-10-10 at 07:06 +0200, J. Mayer wrote:
> > On Wed, 2007-10-10 at 01:12 +0100, Thiemo Seufer wrote:
> > > J. Mayer wrote:
> > > > Here's a proposal to add a int cpu_mem_index (CPUState *env) function in
> > > > targets cpu.h header.
> > > > The idea of this patch is:
> > > > - avoid many #ifdef TARGET_xxx in exec-all.h and  softmmu_header.h then
> > > > make the code more readable
> > > > - avoid multiple implementation of the same code (3, in that particular
> > > > case) this to avoid potential conflicts if the definition has to be
> > > > updated for any reason (ie support for new memory access modes,
> > > > emulation optimisation...)
> > > > 
> > > > Please comment.
> > > > 
> > > > -- 
> > > > J. Mayer <l_indien@magic.fr>
> > > > Never organized
> > > 
> 
> [...]
> 
> Here's an updated version of the patch. My comments about it stay valid,
> with two additions:
> 1/ when is user is needed to maintain compatibility with existing code,
> I now define it as:
> int is_user = mmu_idx == MMU_USER_IDX;
> instead of just is_user = mmu_idx.
> This definition will then remain correct even if the definition of the
> MMU modes are later changed for a specific target
> 2/ I now precompute the mmu_idx on PowerPC platform as it can never
> change inside a single TB. This may save a few instructions for every
> memory access. I guess the same optimisation can be made for the other
> targets, but not knowing exactly when it would have to be recomputed,
> for most targets, I prefer not to do this optimisation myself.

I like this version. Tested with x86 and mips, on Linux/ppc host.


Thiemo

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

* Re: [Qemu-devel] RFC: cleanups: CPU_MEM_INDEX
  2007-10-11 17:46       ` Thiemo Seufer
@ 2007-10-11 22:27         ` J. Mayer
  0 siblings, 0 replies; 9+ messages in thread
From: J. Mayer @ 2007-10-11 22:27 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: qemu-devel

On Thu, 2007-10-11 at 18:46 +0100, Thiemo Seufer wrote:
> J. Mayer wrote:
> > On Wed, 2007-10-10 at 07:06 +0200, J. Mayer wrote:
> > > On Wed, 2007-10-10 at 01:12 +0100, Thiemo Seufer wrote:
> > > > J. Mayer wrote:
> > > > > Here's a proposal to add a int cpu_mem_index (CPUState *env) function in
> > > > > targets cpu.h header.
> > > > > The idea of this patch is:
> > > > > - avoid many #ifdef TARGET_xxx in exec-all.h and  softmmu_header.h then
> > > > > make the code more readable
> > > > > - avoid multiple implementation of the same code (3, in that particular
> > > > > case) this to avoid potential conflicts if the definition has to be
> > > > > updated for any reason (ie support for new memory access modes,
> > > > > emulation optimisation...)
> > > > > 
> > > > > Please comment.
> > > > > 
> > > > > -- 
> > > > > J. Mayer <l_indien@magic.fr>
> > > > > Never organized
> > > > 
> > 
> > [...]
> > 
> > Here's an updated version of the patch. My comments about it stay valid,
> > with two additions:
> > 1/ when is user is needed to maintain compatibility with existing code,
> > I now define it as:
> > int is_user = mmu_idx == MMU_USER_IDX;
> > instead of just is_user = mmu_idx.
> > This definition will then remain correct even if the definition of the
> > MMU modes are later changed for a specific target
> > 2/ I now precompute the mmu_idx on PowerPC platform as it can never
> > change inside a single TB. This may save a few instructions for every
> > memory access. I guess the same optimisation can be made for the other
> > targets, but not knowing exactly when it would have to be recomputed,
> > for most targets, I prefer not to do this optimisation myself.
> 
> I like this version. Tested with x86 and mips, on Linux/ppc host.

Thanks for testing.
I guess it's safe... but I'd like to get more reports or comments about
it before applying this !

-- 
J. Mayer <l_indien@magic.fr>
Never organized

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

* Re: [Qemu-devel] RFC: cleanups: CPU_MEM_INDEX
  2007-10-11 12:09     ` J. Mayer
  2007-10-11 17:46       ` Thiemo Seufer
@ 2007-10-12  7:01       ` J. Mayer
  2007-10-13 21:14         ` J. Mayer
  1 sibling, 1 reply; 9+ messages in thread
From: J. Mayer @ 2007-10-12  7:01 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 5768 bytes --]

On Thu, 2007-10-11 at 14:09 +0200, J. Mayer wrote:
> On Wed, 2007-10-10 at 07:06 +0200, J. Mayer wrote:
> > On Wed, 2007-10-10 at 01:12 +0100, Thiemo Seufer wrote:
> > > J. Mayer wrote:
> > > > Here's a proposal to add a int cpu_mem_index (CPUState *env) function in
> > > > targets cpu.h header.
> > > > The idea of this patch is:
> > > > - avoid many #ifdef TARGET_xxx in exec-all.h and  softmmu_header.h then
> > > > make the code more readable
> > > > - avoid multiple implementation of the same code (3, in that particular
> > > > case) this to avoid potential conflicts if the definition has to be
> > > > updated for any reason (ie support for new memory access modes,
> > > > emulation optimisation...)
> > > > 
> > > > Please comment.
> > > > 
> > > > -- 
> > > > J. Mayer <l_indien@magic.fr>
> > > > Never organized
> > > 
> 
> [...]
> 
> Here's an updated version of the patch. My comments about it stay valid,
> with two additions:
> 1/ when is user is needed to maintain compatibility with existing code,
> I now define it as:
> int is_user = mmu_idx == MMU_USER_IDX;
> instead of just is_user = mmu_idx.
> This definition will then remain correct even if the definition of the
> MMU modes are later changed for a specific target
> 2/ I now precompute the mmu_idx on PowerPC platform as it can never
> change inside a single TB. This may save a few instructions for every
> memory access. I guess the same optimisation can be made for the other
> targets, but not knowing exactly when it would have to be recomputed,
> for most targets, I prefer not to do this optimisation myself.

Here's another update, taking care of the commit I just made (which
changes some of the target-xxx/cpu.h files).
It also fixes an issue in softmmu_header; this was missing:

 #if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__)
&& \
-    (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU)
+    (ACCESS_TYPE < NB_MMU_MODES) && defined(ASM_SOFTMMU)
 
 #define CPU_TLB_ENTRY_BITS 4
 
As this affects only the i386 target which is defined with 2 MMU modes,
the miss had no run-time consequence but was still a bug.
 
> > > I presume cpu_mem_index is supposed to do more than checking for
> > > usermode. In that case, is_user should get renamed, and the
> > > cpu_mem_index implementation of some (most?) CPUs should have a
> > > FIXME comment as reminder to implement the missing MMU modes.
> > 
> > You're right, calling this variable is_user is only valid because this
> > code supposes it knows what cpu_mem_index means. For targets with more
> > than 2 modes of execution, this is not correct.
> > My first idea was to try not to change the code too much. After thinking
> > more about the problem, it appears to me that:
> > 1/ in the softmmu routines, we should do no assumption about the
> > signification of the memory index
> > 2/ then, softmmu routines should use an index and all exported
> > interfaces (ie tlb_fill and handle_mmu_fault) should take an index
> > instead of is_user as an argument.
> > 3/ to maintain compatibility with the existing code, I choosed to add a
> > is_user variable inside most handle_mmu_fault implementation,
> > initialized with the value of the given index, which is then given to
> > the target mmu translation routines.
> > 4/ to ease implementation of targets with more than 2 execution modes, I
> > choosed to define a per-target NB_MMU_MODES in each target_xxx/cpu.h
> > (instead of the hack for PowerPC 64 and Alpha that did pre-exist) and
> > add a local definition of the meaning of each mmu_index index. Then, for
> > PowerPC, I choosed to use the same convention than I do in translate.c,
> > which seems more logical to me, then: 0 => user, 1 => supervisor, 2 =>
> > hypervisor.
> > 5/ to avoid confusion between the memory index used in the translation
> > context, which may contain more than the access mode information, and
> > the one used by the softmmu routines, I choosed to name the one used in
> > softmmu 'mmu_idx' (the one in target_xxx/translate.c is called mem_idx).
> > 6/ I choosed to add a constant MMU_USER_IDX which is used in the
> > user-mode handle_cpu_signal routine, then addressing your first remark.
> > 
> > This patch solves a problem I had no solution to until today: how to add
> > new mmu modes (ie hypervisor for PowerPC 64, supervisor and executive
> > for Alpha) for some specific targets.
> > 
> > The result is a much more invasive patch but the is supposed (!) to;
> > 1/ do not change the behavior of the current targets implementations
> > 2/ be less hardcoded, more flexible and extensible for any specific
> > targets requirements.
> > As this new version of the patch could deadly break the softmmu mode and
> > I got no way to properly check all targets, I would greatly appreciate
> > that some do some tests for arm, cris, m68k, mips, sh4 and sparc
> > targets.
> > 
> > For now, I did a few tests, running Linux (debian hdd installation) for
> > PowerPC on PPC 603 & 750 in 32 bits and 64 bits mode emulation on x86
> > and amd64 and a few OSes using the i386-softmmu emulation (Linux Gentoo,
> > solaris 10 installation CDROM, ...), with success; then I guess I did
> > not deadly broke everything !
> > The good point is that PowerPC runs, considering it is the only target
> > for which I did change the mmu_idx semantics...
> > 
> > > Other than that it looks good to me (and reminds me to check what the
> > > supervisor mode on MIPS actually does now :-).
> > 
> > This updated patch gives the opportunity to define a per-target semantic
> > of the mmu_idx... Time to check what it means in actual CPU
> > implementation !!!! ;-)
> > 
> > Thanks in advance for any comments or improvment suggestions....
> > 
-- 
J. Mayer <l_indien@magic.fr>
Never organized

[-- Attachment #2: cpu_mmu_index.diff --]
[-- Type: text/x-patch, Size: 83395 bytes --]

Index: cpu-defs.h
===================================================================
RCS file: /sources/qemu/qemu/cpu-defs.h,v
retrieving revision 1.24
diff -u -d -d -p -r1.24 cpu-defs.h
--- cpu-defs.h	19 Sep 2007 05:46:03 -0000	1.24
+++ cpu-defs.h	12 Oct 2007 06:55:26 -0000
@@ -112,15 +112,6 @@ typedef struct CPUTLBEntry {
     target_phys_addr_t addend;
 } CPUTLBEntry;
 
-/* Alpha has 4 different running levels */
-#if defined(TARGET_ALPHA)
-#define NB_MMU_MODES 4
-#elif defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
-#define NB_MMU_MODES 3
-#else
-#define NB_MMU_MODES 2
-#endif
-
 #define CPU_COMMON                                                      \
     struct TranslationBlock *current_tb; /* currently executing TB  */  \
     /* soft mmu support */                                              \
Index: cpu-exec.c
===================================================================
RCS file: /sources/qemu/qemu/cpu-exec.c,v
retrieving revision 1.119
diff -u -d -d -p -r1.119 cpu-exec.c
--- cpu-exec.c	8 Oct 2007 13:16:13 -0000	1.119
+++ cpu-exec.c	12 Oct 2007 06:55:26 -0000
@@ -884,8 +884,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_x86_handle_mmu_fault(env, address, is_write,
-                                   ((env->hflags & HF_CPL_MASK) == 3), 0);
+    ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -934,7 +933,7 @@ static inline int handle_cpu_signal(unsi
         return 1;
     }
     /* see if it is an MMU fault */
-    ret = cpu_arm_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -970,7 +969,7 @@ static inline int handle_cpu_signal(unsi
         return 1;
     }
     /* see if it is an MMU fault */
-    ret = cpu_sparc_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1007,7 +1006,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, msr_pr, 0);
+    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1056,7 +1055,7 @@ static inline int handle_cpu_signal(unsi
         return 1;
     }
     /* see if it is an MMU fault */
-    ret = cpu_m68k_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1096,7 +1095,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_mips_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1146,7 +1145,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_sh4_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1191,7 +1190,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_alpha_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1235,7 +1234,7 @@ static inline int handle_cpu_signal(unsi
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_cris_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
Index: exec-all.h
===================================================================
RCS file: /sources/qemu/qemu/exec-all.h,v
retrieving revision 1.67
diff -u -d -d -p -r1.67 exec-all.h
--- exec-all.h	8 Oct 2007 13:16:14 -0000	1.67
+++ exec-all.h	12 Oct 2007 06:55:26 -0000
@@ -117,14 +117,14 @@ void tlb_flush_page(CPUState *env, targe
 void tlb_flush(CPUState *env, int flush_global);
 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
                       target_phys_addr_t paddr, int prot,
-                      int is_user, int is_softmmu);
+                      int mmu_idx, int is_softmmu);
 static inline int tlb_set_page(CPUState *env, target_ulong vaddr,
                                target_phys_addr_t paddr, int prot,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     if (prot & PAGE_READ)
         prot |= PAGE_EXEC;
-    return tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+    return tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
 }
 
 #define CODE_GEN_MAX_SIZE        65536
@@ -562,10 +562,10 @@ extern int tb_invalidated_flag;
 
 #if !defined(CONFIG_USER_ONLY)
 
-void tlb_fill(target_ulong addr, int is_write, int is_user,
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
               void *retaddr);
 
-#define ACCESS_TYPE 3
+#define ACCESS_TYPE (NB_MMU_MODES + 1)
 #define MEMSUFFIX _code
 #define env cpu_single_env
 
@@ -598,35 +598,15 @@ static inline target_ulong get_phys_addr
    is the offset relative to phys_ram_base */
 static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
 {
-    int is_user, index, pd;
+    int mmu_idx, index, pd;
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-#if defined(TARGET_I386)
-    is_user = ((env->hflags & HF_CPL_MASK) == 3);
-#elif defined (TARGET_PPC)
-    is_user = msr_pr;
-#elif defined (TARGET_MIPS)
-    is_user = ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
-#elif defined (TARGET_SPARC)
-    is_user = (env->psrs == 0);
-#elif defined (TARGET_ARM)
-    is_user = ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR);
-#elif defined (TARGET_SH4)
-    is_user = ((env->sr & SR_MD) == 0);
-#elif defined (TARGET_ALPHA)
-    is_user = ((env->ps >> 3) & 3);
-#elif defined (TARGET_M68K)
-    is_user = ((env->sr & SR_S) == 0);
-#elif defined (TARGET_CRIS)
-    is_user = (0);
-#else
-#error unimplemented CPU
-#endif
-    if (__builtin_expect(env->tlb_table[is_user][index].addr_code !=
+    mmu_idx = cpu_mmu_index(env);
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].addr_code !=
                          (addr & TARGET_PAGE_MASK), 0)) {
         ldub_code(addr);
     }
-    pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK;
+    pd = env->tlb_table[mmu_idx][index].addr_code & ~TARGET_PAGE_MASK;
     if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
 #ifdef TARGET_SPARC
         do_unassigned_access(addr, 0, 1, 0);
@@ -634,7 +614,7 @@ static inline target_ulong get_phys_addr
         cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);
 #endif
     }
-    return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base;
+    return addr + env->tlb_table[mmu_idx][index].addend - (unsigned long)phys_ram_base;
 }
 #endif
 
Index: exec.c
===================================================================
RCS file: /sources/qemu/qemu/exec.c,v
retrieving revision 1.108
diff -u -d -d -p -r1.108 exec.c
--- exec.c	8 Oct 2007 13:16:14 -0000	1.108
+++ exec.c	12 Oct 2007 06:55:26 -0000
@@ -1608,7 +1608,7 @@ static inline void tlb_set_dirty(CPUStat
    conflicting with the host address space). */
 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
                       target_phys_addr_t paddr, int prot,
-                      int is_user, int is_softmmu)
+                      int mmu_idx, int is_softmmu)
 {
     PhysPageDesc *p;
     unsigned long pd;
@@ -1626,8 +1626,8 @@ int tlb_set_page_exec(CPUState *env, tar
         pd = p->phys_offset;
     }
 #if defined(DEBUG_TLB)
-    printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x u=%d smmu=%d pd=0x%08lx\n",
-           vaddr, (int)paddr, prot, is_user, is_softmmu, pd);
+    printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x idx=%d smmu=%d pd=0x%08lx\n",
+           vaddr, (int)paddr, prot, mmu_idx, is_softmmu, pd);
 #endif
 
     ret = 0;
@@ -1664,7 +1664,7 @@ int tlb_set_page_exec(CPUState *env, tar
 
         index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
         addend -= vaddr;
-        te = &env->tlb_table[is_user][index];
+        te = &env->tlb_table[mmu_idx][index];
         te->addend = addend;
         if (prot & PAGE_READ) {
             te->addr_read = address;
@@ -1790,7 +1790,7 @@ void tlb_flush_page(CPUState *env, targe
 
 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
                       target_phys_addr_t paddr, int prot,
-                      int is_user, int is_softmmu)
+                      int mmu_idx, int is_softmmu)
 {
     return 0;
 }
Index: softmmu_exec.h
===================================================================
RCS file: /sources/qemu/qemu/softmmu_exec.h,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 softmmu_exec.h
--- softmmu_exec.h	30 Oct 2005 18:16:26 -0000	1.1
+++ softmmu_exec.h	12 Oct 2007 06:55:26 -0000
@@ -1,10 +1,16 @@
 /* Common softmmu definitions and inline routines.  */
 
-#define ldul_user ldl_user
-#define ldul_kernel ldl_kernel
+/* XXX: find something cleaner.
+ * Furthermore, this is false for 64 bits targets
+ */
+#define ldul_user       ldl_user
+#define ldul_kernel     ldl_kernel
+#define ldul_hypv       ldl_hypv
+#define ldul_executive  ldl_executive
+#define ldul_supervisor ldl_supervisor
 
 #define ACCESS_TYPE 0
-#define MEMSUFFIX _kernel
+#define MEMSUFFIX MMU_MODE0_SUFFIX
 #define DATA_SIZE 1
 #include "softmmu_header.h"
 
@@ -20,7 +26,7 @@
 #undef MEMSUFFIX
 
 #define ACCESS_TYPE 1
-#define MEMSUFFIX _user
+#define MEMSUFFIX MMU_MODE1_SUFFIX
 #define DATA_SIZE 1
 #include "softmmu_header.h"
 
@@ -35,8 +41,50 @@
 #undef ACCESS_TYPE
 #undef MEMSUFFIX
 
-/* these access are slower, they must be as rare as possible */
+#if (NB_MMU_MODES >= 3)
+
 #define ACCESS_TYPE 2
+#define MEMSUFFIX MMU_MODE2_SUFFIX
+#define DATA_SIZE 1
+#include "softmmu_header.h"
+
+#define DATA_SIZE 2
+#include "softmmu_header.h"
+
+#define DATA_SIZE 4
+#include "softmmu_header.h"
+
+#define DATA_SIZE 8
+#include "softmmu_header.h"
+#undef ACCESS_TYPE
+#undef MEMSUFFIX
+
+#if (NB_MMU_MODES >= 4)
+
+#define ACCESS_TYPE 3
+#define MEMSUFFIX MMU_MODE3_SUFFIX
+#define DATA_SIZE 1
+#include "softmmu_header.h"
+
+#define DATA_SIZE 2
+#include "softmmu_header.h"
+
+#define DATA_SIZE 4
+#include "softmmu_header.h"
+
+#define DATA_SIZE 8
+#include "softmmu_header.h"
+#undef ACCESS_TYPE
+#undef MEMSUFFIX
+
+#if (NB_MMU_MODES > 4)
+#error "NB_MMU_MODES > 4 is not supported for now"
+#endif /* (NB_MMU_MODES > 4) */
+#endif /* (NB_MMU_MODES == 4) */
+#endif /* (NB_MMU_MODES >= 3) */
+
+/* these access are slower, they must be as rare as possible */
+#define ACCESS_TYPE (NB_MMU_MODES)
 #define MEMSUFFIX _data
 #define DATA_SIZE 1
 #include "softmmu_header.h"
Index: softmmu_header.h
===================================================================
RCS file: /sources/qemu/qemu/softmmu_header.h,v
retrieving revision 1.17
diff -u -d -d -p -r1.17 softmmu_header.h
--- softmmu_header.h	8 Oct 2007 13:16:14 -0000	1.17
+++ softmmu_header.h	12 Oct 2007 06:55:26 -0000
@@ -39,66 +39,19 @@
 #error unsupported data size
 #endif
 
-#if ACCESS_TYPE == 0
-
-#define CPU_MEM_INDEX 0
-#define MMUSUFFIX _mmu
-
-#elif ACCESS_TYPE == 1
+#if ACCESS_TYPE < (NB_MMU_MODES)
 
-#define CPU_MEM_INDEX 1
+#define CPU_MMU_INDEX ACCESS_TYPE
 #define MMUSUFFIX _mmu
 
-#elif ACCESS_TYPE == 2
+#elif ACCESS_TYPE == (NB_MMU_MODES)
 
-#ifdef TARGET_I386
-#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
-#elif defined (TARGET_PPC)
-#define CPU_MEM_INDEX (msr_pr)
-#elif defined (TARGET_MIPS)
-#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
-#elif defined (TARGET_SPARC)
-#define CPU_MEM_INDEX ((env->psrs) == 0)
-#elif defined (TARGET_ARM)
-#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
-#elif defined (TARGET_SH4)
-#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
-#elif defined (TARGET_ALPHA)
-#define CPU_MEM_INDEX ((env->ps >> 3) & 3)
-#elif defined (TARGET_M68K)
-#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)
-#elif defined (TARGET_CRIS)
-/* CRIS FIXME: I guess we want to validate supervisor mode acceses here.  */
-#define CPU_MEM_INDEX (0)
-#else
-#error unsupported CPU
-#endif
+#define CPU_MMU_INDEX (cpu_mmu_index(env))
 #define MMUSUFFIX _mmu
 
-#elif ACCESS_TYPE == 3
+#elif ACCESS_TYPE == (NB_MMU_MODES + 1)
 
-#ifdef TARGET_I386
-#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
-#elif defined (TARGET_PPC)
-#define CPU_MEM_INDEX (msr_pr)
-#elif defined (TARGET_MIPS)
-#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
-#elif defined (TARGET_SPARC)
-#define CPU_MEM_INDEX ((env->psrs) == 0)
-#elif defined (TARGET_ARM)
-#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
-#elif defined (TARGET_SH4)
-#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
-#elif defined (TARGET_ALPHA)
-#define CPU_MEM_INDEX ((env->ps >> 3) & 3)
-#elif defined (TARGET_M68K)
-#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)
-#elif defined (TARGET_CRIS)
-/* CRIS FIXME: I guess we want to validate supervisor mode acceses here.  */
-#define CPU_MEM_INDEX (0)
-#else
-#error unsupported CPU
-#endif
+#define CPU_MMU_INDEX (cpu_mmu_index(env))
 #define MMUSUFFIX _cmmu
 
 #else
@@ -111,18 +64,18 @@
 #define RES_TYPE int
 #endif
 
-#if ACCESS_TYPE == 3
+#if ACCESS_TYPE == (NB_MMU_MODES + 1)
 #define ADDR_READ addr_code
 #else
 #define ADDR_READ addr_read
 #endif
 
 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                         int is_user);
-void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int is_user);
+                                                         int mmu_idx);
+void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int mmu_idx);
 
 #if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
-    (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU)
+    (ACCESS_TYPE < NB_MMU_MODES) && defined(ASM_SOFTMMU)
 
 #define CPU_TLB_ENTRY_BITS 4
 
@@ -161,8 +114,8 @@ static inline RES_TYPE glue(glue(ld, USU
                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
-                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
-                  "i" (CPU_MEM_INDEX),
+                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
+                  "i" (CPU_MMU_INDEX),
                   "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
                   : "%eax", "%ecx", "%edx", "memory", "cc");
     return res;
@@ -208,8 +161,8 @@ static inline int glue(glue(lds, SUFFIX)
                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
-                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
-                  "i" (CPU_MEM_INDEX),
+                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
+                  "i" (CPU_MMU_INDEX),
                   "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
                   : "%eax", "%ecx", "%edx", "memory", "cc");
     return res;
@@ -260,8 +213,8 @@ static inline void glue(glue(st, SUFFIX)
                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
-                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_write)),
-                  "i" (CPU_MEM_INDEX),
+                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)),
+                  "i" (CPU_MMU_INDEX),
                   "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
                   : "%eax", "%ecx", "%edx", "memory", "cc");
 }
@@ -276,16 +229,16 @@ static inline RES_TYPE glue(glue(ld, USU
     RES_TYPE res;
     target_ulong addr;
     unsigned long physaddr;
-    int is_user;
+    int mmu_idx;
 
     addr = ptr;
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    is_user = CPU_MEM_INDEX;
-    if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
+    mmu_idx = CPU_MMU_INDEX;
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].ADDR_READ !=
                          (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
-        res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
+        res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
     } else {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
     }
     return res;
@@ -297,23 +250,23 @@ static inline int glue(glue(lds, SUFFIX)
     int res, index;
     target_ulong addr;
     unsigned long physaddr;
-    int is_user;
+    int mmu_idx;
 
     addr = ptr;
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    is_user = CPU_MEM_INDEX;
-    if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
+    mmu_idx = CPU_MMU_INDEX;
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].ADDR_READ !=
                          (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
-        res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
+        res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
     } else {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
     }
     return res;
 }
 #endif
 
-#if ACCESS_TYPE != 3
+#if ACCESS_TYPE != (NB_MMU_MODES + 1)
 
 /* generic store macro */
 
@@ -322,25 +275,25 @@ static inline void glue(glue(st, SUFFIX)
     int index;
     target_ulong addr;
     unsigned long physaddr;
-    int is_user;
+    int mmu_idx;
 
     addr = ptr;
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    is_user = CPU_MEM_INDEX;
-    if (__builtin_expect(env->tlb_table[is_user][index].addr_write !=
+    mmu_idx = CPU_MMU_INDEX;
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].addr_write !=
                          (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
-        glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user);
+        glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx);
     } else {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
     }
 }
 
-#endif /* ACCESS_TYPE != 3 */
+#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
 
 #endif /* !asm */
 
-#if ACCESS_TYPE != 3
+#if ACCESS_TYPE != (NB_MMU_MODES + 1)
 
 #if DATA_SIZE == 8
 static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
@@ -386,7 +339,7 @@ static inline void glue(stfl, MEMSUFFIX)
 }
 #endif /* DATA_SIZE == 4 */
 
-#endif /* ACCESS_TYPE != 3 */
+#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
 
 #undef RES_TYPE
 #undef DATA_TYPE
@@ -394,6 +347,6 @@ static inline void glue(stfl, MEMSUFFIX)
 #undef SUFFIX
 #undef USUFFIX
 #undef DATA_SIZE
-#undef CPU_MEM_INDEX
+#undef CPU_MMU_INDEX
 #undef MMUSUFFIX
 #undef ADDR_READ
Index: softmmu_template.h
===================================================================
RCS file: /sources/qemu/qemu/softmmu_template.h,v
retrieving revision 1.18
diff -u -d -d -p -r1.18 softmmu_template.h
--- softmmu_template.h	17 Sep 2007 08:09:45 -0000	1.18
+++ softmmu_template.h	12 Oct 2007 06:55:26 -0000
@@ -48,7 +48,7 @@
 #endif
 
 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                        int is_user,
+                                                        int mmu_idx,
                                                         void *retaddr);
 static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
                                               target_ulong tlb_addr)
@@ -76,7 +76,7 @@ static inline DATA_TYPE glue(io_read, SU
 
 /* handle all cases except unaligned access which span two pages */
 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                         int is_user)
+                                                         int mmu_idx)
 {
     DATA_TYPE res;
     int index;
@@ -88,9 +88,9 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF
     /* XXX: could done more in memory macro in a non portable way */
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
+    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -101,16 +101,16 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF
         do_unaligned_access:
             retaddr = GETPC();
 #ifdef ALIGNED_ONLY
-            do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
+            do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
 #endif
             res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
-                                                         is_user, retaddr);
+                                                         mmu_idx, retaddr);
         } else {
             /* unaligned/aligned access in the same page */
 #ifdef ALIGNED_ONLY
             if ((addr & (DATA_SIZE - 1)) != 0) {
                 retaddr = GETPC();
-                do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
+                do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
             }
 #endif
             res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr);
@@ -120,9 +120,9 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF
         retaddr = GETPC();
 #ifdef ALIGNED_ONLY
         if ((addr & (DATA_SIZE - 1)) != 0)
-            do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
+            do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
 #endif
-        tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
+        tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
         goto redo;
     }
     return res;
@@ -130,7 +130,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF
 
 /* handle all unaligned cases */
 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                        int is_user,
+                                                        int mmu_idx,
                                                         void *retaddr)
 {
     DATA_TYPE res, res1, res2;
@@ -140,9 +140,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFF
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
+    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -154,9 +154,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFF
             addr1 = addr & ~(DATA_SIZE - 1);
             addr2 = addr1 + DATA_SIZE;
             res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1,
-                                                          is_user, retaddr);
+                                                          mmu_idx, retaddr);
             res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2,
-                                                          is_user, retaddr);
+                                                          mmu_idx, retaddr);
             shift = (addr & (DATA_SIZE - 1)) * 8;
 #ifdef TARGET_WORDS_BIGENDIAN
             res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
@@ -170,7 +170,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFF
         }
     } else {
         /* the page is not in the TLB : fill it */
-        tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
+        tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
         goto redo;
     }
     return res;
@@ -180,7 +180,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFF
 
 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                    DATA_TYPE val,
-                                                   int is_user,
+                                                   int mmu_idx,
                                                    void *retaddr);
 
 static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
@@ -211,7 +211,7 @@ static inline void glue(io_write, SUFFIX
 
 void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                     DATA_TYPE val,
-                                                    int is_user)
+                                                    int mmu_idx)
 {
     target_phys_addr_t physaddr;
     target_ulong tlb_addr;
@@ -220,9 +220,9 @@ void REGPARM(2) glue(glue(__st, SUFFIX),
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].addr_write;
+    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -233,16 +233,16 @@ void REGPARM(2) glue(glue(__st, SUFFIX),
         do_unaligned_access:
             retaddr = GETPC();
 #ifdef ALIGNED_ONLY
-            do_unaligned_access(addr, 1, is_user, retaddr);
+            do_unaligned_access(addr, 1, mmu_idx, retaddr);
 #endif
             glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
-                                                   is_user, retaddr);
+                                                   mmu_idx, retaddr);
         } else {
             /* aligned/unaligned access in the same page */
 #ifdef ALIGNED_ONLY
             if ((addr & (DATA_SIZE - 1)) != 0) {
                 retaddr = GETPC();
-                do_unaligned_access(addr, 1, is_user, retaddr);
+                do_unaligned_access(addr, 1, mmu_idx, retaddr);
             }
 #endif
             glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val);
@@ -252,9 +252,9 @@ void REGPARM(2) glue(glue(__st, SUFFIX),
         retaddr = GETPC();
 #ifdef ALIGNED_ONLY
         if ((addr & (DATA_SIZE - 1)) != 0)
-            do_unaligned_access(addr, 1, is_user, retaddr);
+            do_unaligned_access(addr, 1, mmu_idx, retaddr);
 #endif
-        tlb_fill(addr, 1, is_user, retaddr);
+        tlb_fill(addr, 1, mmu_idx, retaddr);
         goto redo;
     }
 }
@@ -262,7 +262,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX),
 /* handles all unaligned cases */
 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                    DATA_TYPE val,
-                                                   int is_user,
+                                                   int mmu_idx,
                                                    void *retaddr)
 {
     target_phys_addr_t physaddr;
@@ -271,9 +271,9 @@ static void glue(glue(slow_st, SUFFIX), 
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].addr_write;
+    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -285,10 +285,10 @@ static void glue(glue(slow_st, SUFFIX), 
             for(i = 0;i < DATA_SIZE; i++) {
 #ifdef TARGET_WORDS_BIGENDIAN
                 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
-                                          is_user, retaddr);
+                                          mmu_idx, retaddr);
 #else
                 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8),
-                                          is_user, retaddr);
+                                          mmu_idx, retaddr);
 #endif
             }
         } else {
@@ -297,7 +297,7 @@ static void glue(glue(slow_st, SUFFIX), 
         }
     } else {
         /* the page is not in the TLB : fill it */
-        tlb_fill(addr, 1, is_user, retaddr);
+        tlb_fill(addr, 1, mmu_idx, retaddr);
         goto redo;
     }
 }
Index: vl.c
===================================================================
RCS file: /sources/qemu/qemu/vl.c,v
retrieving revision 1.348
diff -u -d -d -p -r1.348 vl.c
--- vl.c	12 Oct 2007 06:47:46 -0000	1.348
+++ vl.c	12 Oct 2007 06:55:27 -0000
@@ -858,8 +858,10 @@ static void rtc_stop_timer(struct qemu_a
 static struct qemu_alarm_timer alarm_timers[] = {
 #ifndef _WIN32
 #ifdef __linux__
+#if 0
     {"dynticks", ALARM_FLAG_DYNTICKS, dynticks_start_timer,
      dynticks_stop_timer, dynticks_rearm_timer, NULL},
+#endif
     /* HPET - if available - is preferred */
     {"hpet", 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},
     /* ...otherwise try RTC */
Index: hw/alpha_palcode.c
===================================================================
RCS file: /sources/qemu/qemu/hw/alpha_palcode.c,v
retrieving revision 1.3
diff -u -d -d -p -r1.3 alpha_palcode.c
--- hw/alpha_palcode.c	17 Sep 2007 08:09:46 -0000	1.3
+++ hw/alpha_palcode.c	12 Oct 2007 06:55:27 -0000
@@ -811,12 +811,14 @@ static int get_page_bits (CPUState *env)
 
 static int get_pte (uint64_t *pfnp, int *zbitsp, int *protp,
                     uint64_t ptebase, int page_bits, uint64_t level,
-                    int is_user, int rw)
+                    int mmu_idx, int rw)
 {
     uint64_t pteaddr, pte, pfn;
     uint8_t gh;
-    int ure, uwe, kre, kwe, foE, foR, foW, v, ret, ar;
+    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 */
@@ -871,7 +873,7 @@ static int get_pte (uint64_t *pfnp, int 
 
 static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot,
                            uint64_t ptebase, int page_bits,
-                           uint64_t vaddr, int is_user, int rw)
+                           uint64_t vaddr, int mmu_idx, int rw)
 {
     uint64_t pfn, page_mask, lvl_mask, level1, level2, level3;
     int lvl_bits, ret;
@@ -909,7 +911,7 @@ static int paddr_from_pte (uint64_t *pad
         break;
     }
     /* Level 3 PTE */
-    ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, is_user, rw);
+    ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, mmu_idx, rw);
     if (ret & 0x1) {
         /* Translation not valid */
         ret = 1;
@@ -943,7 +945,7 @@ static int paddr_from_pte (uint64_t *pad
 
 static int virtual_to_physical (CPUState *env, uint64_t *physp,
                                 int *zbitsp, int *protp,
-                                uint64_t virtual, int is_user, int rw)
+                                uint64_t virtual, int mmu_idx, int rw)
 {
     uint64_t sva, ptebase;
     int seg, page_bits, ret;
@@ -961,16 +963,16 @@ static int virtual_to_physical (CPUState
     case 0:
         /* seg1: 3 levels of PTE */
         ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, is_user, rw);
+                             virtual, mmu_idx, rw);
         break;
     case 1:
         /* seg1: 2 levels of PTE */
         ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, is_user, rw);
+                             virtual, mmu_idx, rw);
         break;
     case 2:
         /* kernel segment */
-        if (is_user) {
+        if (mmu_idx != 0) {
             ret = 2;
         } else {
             *physp = virtual;
@@ -979,7 +981,7 @@ static int virtual_to_physical (CPUState
     case 3:
         /* seg1: TB mapped */
         ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, is_user, rw);
+                             virtual, mmu_idx, rw);
         break;
     default:
         ret = 1;
@@ -991,7 +993,7 @@ static int virtual_to_physical (CPUState
 
 /* XXX: code provision */
 int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     uint64_t physical, page_size, end;
     int prot, zbits, ret;
@@ -1000,7 +1002,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *
         ret = 2;
     } else {
         ret = virtual_to_physical(env, &physical, &zbits, &prot,
-                                  address, is_user, rw);
+                                  address, mmu_idx, rw);
     }
     switch (ret) {
     case 0:
@@ -1009,7 +1011,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *
         address &= ~(page_size - 1);
         for (end = physical + page_size; physical < end; physical += 0x1000) {
             ret = tlb_set_page(env, address, physical, prot,
-                               is_user, is_softmmu);
+                               mmu_idx, is_softmmu);
             address += 0x1000;
         }
         break;
Index: hw/ide.c
===================================================================
RCS file: /sources/qemu/qemu/hw/ide.c,v
retrieving revision 1.69
diff -u -d -d -p -r1.69 ide.c
--- hw/ide.c	17 Sep 2007 08:09:47 -0000	1.69
+++ hw/ide.c	12 Oct 2007 06:55:27 -0000
@@ -1494,6 +1494,7 @@ static void ide_atapi_cmd(IDEState *s)
                 break;
             }
             ide_atapi_cmd_ok(s);
+            s->status |= SEEK_STAT;
         }
         break;
     case GPCMD_START_STOP_UNIT:
Index: hw/vga_template.h
===================================================================
RCS file: /sources/qemu/qemu/hw/vga_template.h,v
retrieving revision 1.15
diff -u -d -d -p -r1.15 vga_template.h
--- hw/vga_template.h	17 Sep 2007 08:09:49 -0000	1.15
+++ hw/vga_template.h	12 Oct 2007 06:55:27 -0000
@@ -327,6 +327,16 @@ static void glue(vga_draw_line8_, DEPTH)
     palette = s1->last_palette;
     width >>= 3;
     for(x = 0; x < width; x++) {
+#if defined(TARGET_WORDS_BIGENDIAN)
+        ((PIXEL_TYPE *)d)[3] = palette[s[0]];
+        ((PIXEL_TYPE *)d)[2] = palette[s[1]];
+        ((PIXEL_TYPE *)d)[1] = palette[s[2]];
+        ((PIXEL_TYPE *)d)[0] = palette[s[3]];
+        ((PIXEL_TYPE *)d)[7] = palette[s[4]];
+        ((PIXEL_TYPE *)d)[6] = palette[s[5]];
+        ((PIXEL_TYPE *)d)[5] = palette[s[6]];
+        ((PIXEL_TYPE *)d)[4] = palette[s[7]];
+#else
         ((PIXEL_TYPE *)d)[0] = palette[s[0]];
         ((PIXEL_TYPE *)d)[1] = palette[s[1]];
         ((PIXEL_TYPE *)d)[2] = palette[s[2]];
@@ -335,6 +345,7 @@ static void glue(vga_draw_line8_, DEPTH)
         ((PIXEL_TYPE *)d)[5] = palette[s[5]];
         ((PIXEL_TYPE *)d)[6] = palette[s[6]];
         ((PIXEL_TYPE *)d)[7] = palette[s[7]];
+#endif
         d += BPP * 8;
         s += 8;
     }
Index: target-alpha/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-alpha/cpu.h,v
retrieving revision 1.8
diff -u -d -d -p -r1.8 cpu.h
--- target-alpha/cpu.h	27 Sep 2007 16:44:31 -0000	1.8
+++ target-alpha/cpu.h	12 Oct 2007 06:55:27 -0000
@@ -256,6 +256,8 @@ struct pal_handler_t {
     void (*call_pal)(CPUAlphaState *env, uint32_t palcode);
 };
 
+#define NB_MMU_MODES 4
+
 struct CPUAlphaState {
     uint64_t ir[31];
     float64  fir[31];
@@ -302,6 +304,17 @@ 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;
+}
+
 #include "cpu-all.h"
 
 enum {
Index: target-alpha/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-alpha/exec.h,v
retrieving revision 1.3
diff -u -d -d -p -r1.3 exec.h
--- target-alpha/exec.h	16 Sep 2007 21:08:01 -0000	1.3
+++ target-alpha/exec.h	12 Oct 2007 06:55:27 -0000
@@ -73,7 +73,7 @@ static inline void regs_to_env(void)
 }
 
 int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
-                                int is_user, int is_softmmu);
+                                int mmu_idx, int is_softmmu);
 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);
 
Index: target-alpha/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-alpha/helper.c,v
retrieving revision 1.4
diff -u -d -d -p -r1.4 helper.c
--- target-alpha/helper.c	17 Sep 2007 08:09:51 -0000	1.4
+++ target-alpha/helper.c	12 Oct 2007 06:55:27 -0000
@@ -28,7 +28,7 @@
 #if defined(CONFIG_USER_ONLY)
 
 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                                int is_user, int is_softmmu)
+                                int mmu_idx, int is_softmmu)
 {
     if (rw == 2)
         env->exception_index = EXCP_ITB_MISS;
@@ -57,7 +57,7 @@ target_phys_addr_t cpu_get_phys_page_deb
 }
 
 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                                int is_user, int is_softmmu)
+                                int mmu_idx, int is_softmmu)
 {
     uint32_t opc;
 
Index: target-alpha/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-alpha/op_helper.c,v
retrieving revision 1.2
diff -u -d -d -p -r1.2 op_helper.c
--- target-alpha/op_helper.c	16 Sep 2007 21:08:01 -0000	1.2
+++ target-alpha/op_helper.c	12 Oct 2007 06:55:28 -0000
@@ -1164,20 +1164,20 @@ void helper_mtpr (int iprn)
 void helper_ld_phys_to_virt (void)
 {
     uint64_t tlb_addr, physaddr;
-    int index, is_user;
+    int index, mmu_idx;
     void *retaddr;
 
-    is_user = (env->ps >> 3) & 3;
+    mmu_idx = cpu_mmu_index(env);
     index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].addr_read;
+    tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
     if ((T0 & TARGET_PAGE_MASK) ==
         (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = T0 + env->tlb_table[is_user][index].addend;
+        physaddr = T0 + env->tlb_table[mmu_idx][index].addend;
     } else {
         /* the page is not in the TLB : fill it */
         retaddr = GETPC();
-        tlb_fill(T0, 0, is_user, retaddr);
+        tlb_fill(T0, 0, mmu_idx, retaddr);
         goto redo;
     }
     T0 = physaddr;
@@ -1186,20 +1186,20 @@ void helper_ld_phys_to_virt (void)
 void helper_st_phys_to_virt (void)
 {
     uint64_t tlb_addr, physaddr;
-    int index, is_user;
+    int index, mmu_idx;
     void *retaddr;
 
-    is_user = (env->ps >> 3) & 3;
+    mmu_idx = cpu_mmu_index(env);
     index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].addr_write;
+    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
     if ((T0 & TARGET_PAGE_MASK) ==
         (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = T0 + env->tlb_table[is_user][index].addend;
+        physaddr = T0 + env->tlb_table[mmu_idx][index].addend;
     } else {
         /* the page is not in the TLB : fill it */
         retaddr = GETPC();
-        tlb_fill(T0, 1, is_user, retaddr);
+        tlb_fill(T0, 1, mmu_idx, retaddr);
         goto redo;
     }
     T0 = physaddr;
@@ -1223,7 +1223,7 @@ void helper_st_phys_to_virt (void)
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -1234,7 +1234,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    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 */
Index: target-arm/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-arm/cpu.h,v
retrieving revision 1.35
diff -u -d -d -p -r1.35 cpu.h
--- target-arm/cpu.h	12 Oct 2007 06:47:46 -0000	1.35
+++ target-arm/cpu.h	12 Oct 2007 06:55:28 -0000
@@ -43,6 +43,8 @@ typedef void ARMWriteCPFunc(void *opaque
 typedef uint32_t ARMReadCPFunc(void *opaque, int cp_info,
                                int dstreg, int operand);
 
+#define NB_MMU_MODES 2
+
 /* We currently assume float and double are IEEE single and double
    precision respectively.
    Doing runtime conversions is tricky because VFP registers may contain
@@ -301,6 +303,15 @@ void cpu_arm_set_cp_io(CPUARMState *env,
 #define cpu_signal_handler cpu_arm_signal_handler
 #define cpu_list arm_cpu_list
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR ? 1 : 0;
+}
+
 #include "cpu-all.h"
 
 #endif
Index: target-arm/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-arm/exec.h,v
retrieving revision 1.13
diff -u -d -d -p -r1.13 exec.h
--- target-arm/exec.h	16 Sep 2007 21:08:01 -0000	1.13
+++ target-arm/exec.h	12 Oct 2007 06:55:28 -0000
@@ -46,7 +46,7 @@ static inline void regs_to_env(void)
 }
 
 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu);
+                              int mmu_idx, int is_softmmu);
 
 static inline int cpu_halted(CPUState *env) {
     if (!env->halted)
Index: target-arm/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-arm/helper.c,v
retrieving revision 1.22
diff -u -d -d -p -r1.22 helper.c
--- target-arm/helper.c	12 Oct 2007 06:47:46 -0000	1.22
+++ target-arm/helper.c	12 Oct 2007 06:55:28 -0000
@@ -169,7 +169,7 @@ void do_interrupt (CPUState *env)
 }
 
 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     if (rw == 2) {
         env->exception_index = EXCP_PREFETCH_ABORT;
@@ -547,18 +547,19 @@ do_fault:
 }
 
 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
-                              int access_type, int is_user, int is_softmmu)
+                              int access_type, int mmu_idx, int is_softmmu)
 {
     uint32_t phys_addr;
     int prot;
-    int ret;
+    int ret, is_user;
 
+    is_user = mmu_idx == MMU_USER_IDX;
     ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot);
     if (ret == 0) {
         /* Map a single [sub]page.  */
         phys_addr &= ~(uint32_t)0x3ff;
         address &= ~(uint32_t)0x3ff;
-        return tlb_set_page (env, address, phys_addr, prot, is_user,
+        return tlb_set_page (env, address, phys_addr, prot, mmu_idx,
                              is_softmmu);
     }
 
Index: target-arm/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-arm/op_helper.c,v
retrieving revision 1.6
diff -u -d -d -p -r1.6 op_helper.c
--- target-arm/op_helper.c	16 Sep 2007 21:08:02 -0000	1.6
+++ target-arm/op_helper.c	12 Oct 2007 06:55:28 -0000
@@ -196,7 +196,7 @@ void do_vfp_get_fpscr(void)
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -207,7 +207,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_arm_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (__builtin_expect(ret, 0)) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-cris/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-cris/cpu.h,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 cpu.h
--- target-cris/cpu.h	8 Oct 2007 13:04:02 -0000	1.1
+++ target-cris/cpu.h	12 Oct 2007 06:55:28 -0000
@@ -74,6 +74,8 @@
 /* Internal flags for the implementation.  */
 #define F_DELAYSLOT 1
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUCRISState {
 	uint32_t debug1;
 	uint32_t debug2;
@@ -229,6 +231,16 @@ void register_cris_insns (CPUCRISState *
 #define cpu_gen_code cpu_cris_gen_code
 #define cpu_signal_handler cpu_cris_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+/* CRIS FIXME: I guess we want to validate supervisor mode acceses here.  */
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return 0;
+}
+
 #include "cpu-all.h"
 
 /* Register aliases.  */
Index: target-cris/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-cris/exec.h,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 exec.h
--- target-cris/exec.h	8 Oct 2007 13:04:02 -0000	1.1
+++ target-cris/exec.h	12 Oct 2007 06:55:28 -0000
@@ -45,8 +45,8 @@ static inline void regs_to_env(void)
 }
 
 int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu);
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr);
+                              int mmu_idx, int is_softmmu);
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr);
 
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
Index: target-cris/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-cris/helper.c,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 helper.c
--- target-cris/helper.c	8 Oct 2007 13:04:02 -0000	1.1
+++ target-cris/helper.c	12 Oct 2007 06:55:28 -0000
@@ -35,7 +35,7 @@ void do_interrupt (CPUState *env)
 }
 
 int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-                             int is_user, int is_softmmu)
+                             int mmu_idx, int is_softmmu)
 {
     env->exception_index = 0xaa;
     env->debug1 = address;
@@ -52,7 +52,7 @@ target_phys_addr_t cpu_get_phys_page_deb
 #else /* !CONFIG_USER_ONLY */
 
 int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
 	struct cris_mmu_result_t res;
 	int prot, miss;
@@ -61,7 +61,7 @@ int cpu_cris_handle_mmu_fault (CPUState 
 	address &= TARGET_PAGE_MASK;
 	prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 //	printf ("%s pc=%x %x w=%d smmu=%d\n", __func__, env->pc, address, rw, is_softmmu);
-	miss = cris_mmu_translate(&res, env, address, rw, is_user);
+	miss = cris_mmu_translate(&res, env, address, rw, mmu_idx);
 	if (miss)
 	{
 		/* handle the miss.  */
@@ -73,7 +73,7 @@ int cpu_cris_handle_mmu_fault (CPUState 
 		phy = res.phy;
 	}
 //	printf ("a=%x phy=%x\n", address, phy);
-	return tlb_set_page(env, address, phy, prot, is_user, is_softmmu);
+	return tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu);
 }
 
 
Index: target-cris/mmu.c
===================================================================
RCS file: /sources/qemu/qemu/target-cris/mmu.c,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 mmu.c
--- target-cris/mmu.c	8 Oct 2007 13:11:58 -0000	1.1
+++ target-cris/mmu.c	12 Oct 2007 06:55:28 -0000
@@ -111,11 +111,12 @@ static int cris_mmu_translate_page(struc
 
 int cris_mmu_translate(struct cris_mmu_result_t *res,
 		       CPUState *env, uint32_t vaddr,
-		       int rw, int is_user)
+		       int rw, int mmu_idx)
 {
 	uint32_t phy = vaddr;
 	int seg;
 	int miss = 0;
+        int is_user = mmu_idx == MMU_USER_IDX;
 
 	if (!cris_mmu_enabled(env->sregs[SFR_RW_GC_CFG])) {
 		res->phy = vaddr;
Index: target-cris/mmu.h
===================================================================
RCS file: /sources/qemu/qemu/target-cris/mmu.h,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 mmu.h
--- target-cris/mmu.h	8 Oct 2007 13:11:58 -0000	1.1
+++ target-cris/mmu.h	12 Oct 2007 06:55:28 -0000
@@ -17,4 +17,4 @@ struct cris_mmu_result_t
 
 int cris_mmu_translate(struct cris_mmu_result_t *res,
 		       CPUState *env, uint32_t vaddr,
-		       int rw, int is_user);
+		       int rw, int mmu_idx);
Index: target-cris/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-cris/op_helper.c,v
retrieving revision 1.1
diff -u -d -d -p -r1.1 op_helper.c
--- target-cris/op_helper.c	8 Oct 2007 13:04:02 -0000	1.1
+++ target-cris/op_helper.c	12 Oct 2007 06:55:28 -0000
@@ -41,7 +41,7 @@
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -52,7 +52,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (__builtin_expect(ret, 0)) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-i386/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-i386/cpu.h,v
retrieving revision 1.50
diff -u -d -d -p -r1.50 cpu.h
--- target-i386/cpu.h	27 Sep 2007 16:44:31 -0000	1.50
+++ target-i386/cpu.h	12 Oct 2007 06:55:28 -0000
@@ -432,6 +432,8 @@ typedef union {
 #define CPU_NB_REGS 8
 #endif
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUX86State {
 #if TARGET_LONG_BITS > HOST_LONG_BITS
     /* temporaries if we cannot store them in host registers */
@@ -688,6 +690,15 @@ static inline int cpu_get_time_fast(void
 #define cpu_gen_code cpu_x86_gen_code
 #define cpu_signal_handler cpu_x86_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
+}
+
 #include "cpu-all.h"
 
 #include "svm.h"
Index: target-i386/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-i386/exec.h,v
retrieving revision 1.37
diff -u -d -d -p -r1.37 exec.h
--- target-i386/exec.h	23 Sep 2007 15:28:04 -0000	1.37
+++ target-i386/exec.h	12 Oct 2007 06:55:28 -0000
@@ -163,8 +163,8 @@ void cpu_x86_update_cr3(CPUX86State *env
 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
 void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr);
 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
-                             int is_write, int is_user, int is_softmmu);
-void tlb_fill(target_ulong addr, int is_write, int is_user,
+                             int is_write, int mmu_idx, int is_softmmu);
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
               void *retaddr);
 void __hidden cpu_lock(void);
 void __hidden cpu_unlock(void);
Index: target-i386/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-i386/helper.c,v
retrieving revision 1.89
diff -u -d -d -p -r1.89 helper.c
--- target-i386/helper.c	27 Sep 2007 01:52:00 -0000	1.89
+++ target-i386/helper.c	12 Oct 2007 06:55:28 -0000
@@ -3885,7 +3885,7 @@ void update_fp_status(void)
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     int ret;
@@ -3897,7 +3897,7 @@ void tlb_fill(target_ulong addr, int is_
     saved_env = env;
     env = cpu_single_env;
 
-    ret = cpu_x86_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (ret) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-i386/helper2.c
===================================================================
RCS file: /sources/qemu/qemu/target-i386/helper2.c,v
retrieving revision 1.52
diff -u -d -d -p -r1.52 helper2.c
--- target-i386/helper2.c	23 Sep 2007 15:28:04 -0000	1.52
+++ target-i386/helper2.c	12 Oct 2007 06:55:28 -0000
@@ -571,7 +571,7 @@ void cpu_x86_flush_tlb(CPUX86State *env,
 #if defined(CONFIG_USER_ONLY)
 
 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
-                             int is_write, int is_user, int is_softmmu)
+                             int is_write, int mmu_idx, int is_softmmu)
 {
     /* user mode only emulation */
     is_write &= 1;
@@ -598,14 +598,15 @@ target_phys_addr_t cpu_get_phys_page_deb
    2  = soft MMU activation required for this block
 */
 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
-                             int is_write1, int is_user, int is_softmmu)
+                             int is_write1, int mmu_idx, int is_softmmu)
 {
     uint64_t ptep, pte;
     uint32_t pdpe_addr, pde_addr, pte_addr;
-    int error_code, is_dirty, prot, page_size, ret, is_write;
+    int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
     unsigned long paddr, page_offset;
     target_ulong vaddr, virt_addr;
 
+    is_user = mmu_idx == MMU_USER_IDX;
 #if defined(DEBUG_MMU)
     printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
            addr, is_write1, is_user, env->eip);
@@ -862,7 +863,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State
     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
     vaddr = virt_addr + page_offset;
 
-    ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+    ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
     return ret;
  do_fault_protect:
     error_code = PG_ERROR_P_MASK;
Index: target-m68k/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-m68k/cpu.h,v
retrieving revision 1.13
diff -u -d -d -p -r1.13 cpu.h
--- target-m68k/cpu.h	17 Sep 2007 08:09:53 -0000	1.13
+++ target-m68k/cpu.h	12 Oct 2007 06:55:28 -0000
@@ -53,6 +53,8 @@
 #define EXCP_RTE            0x100
 #define EXCP_HALT_INSN      0x101
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUM68KState {
     uint32_t dregs[8];
     uint32_t aregs[8];
@@ -223,6 +225,15 @@ void register_m68k_insns (CPUM68KState *
 #define cpu_gen_code cpu_m68k_gen_code
 #define cpu_signal_handler cpu_m68k_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return (env->sr & SR_S) == 0 ? 1 : 0;
+}
+
 #include "cpu-all.h"
 
 #endif
Index: target-m68k/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-m68k/exec.h,v
retrieving revision 1.4
diff -u -d -d -p -r1.4 exec.h
--- target-m68k/exec.h	16 Sep 2007 21:08:03 -0000	1.4
+++ target-m68k/exec.h	12 Oct 2007 06:55:28 -0000
@@ -38,7 +38,7 @@ static inline void regs_to_env(void)
 }
 
 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu);
+                              int mmu_idx, int is_softmmu);
 
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
Index: target-m68k/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-m68k/helper.c,v
retrieving revision 1.7
diff -u -d -d -p -r1.7 helper.c
--- target-m68k/helper.c	16 Sep 2007 21:08:03 -0000	1.7
+++ target-m68k/helper.c	12 Oct 2007 06:55:28 -0000
@@ -301,7 +301,7 @@ target_phys_addr_t cpu_get_phys_page_deb
 #if defined(CONFIG_USER_ONLY)
 
 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     env->exception_index = EXCP_ACCESS;
     env->mmu.ar = address;
@@ -311,13 +311,13 @@ int cpu_m68k_handle_mmu_fault (CPUState 
 #else
 
 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     int prot;
 
     address &= TARGET_PAGE_MASK;
     prot = PAGE_READ | PAGE_WRITE;
-    return tlb_set_page(env, address, address, prot, is_user, is_softmmu);
+    return tlb_set_page(env, address, address, prot, mmu_idx, is_softmmu);
 }
 
 /* Notify CPU of a pending interrupt.  Prioritization and vectoring should
Index: target-m68k/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-m68k/op_helper.c,v
retrieving revision 1.6
diff -u -d -d -p -r1.6 op_helper.c
--- target-m68k/op_helper.c	16 Sep 2007 21:08:03 -0000	1.6
+++ target-m68k/op_helper.c	12 Oct 2007 06:55:28 -0000
@@ -49,7 +49,7 @@ extern int semihosting_enabled;
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -60,7 +60,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (__builtin_expect(ret, 0)) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-mips/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-mips/cpu.h,v
retrieving revision 1.48
diff -u -d -d -p -r1.48 cpu.h
--- target-mips/cpu.h	12 Oct 2007 06:47:46 -0000	1.48
+++ target-mips/cpu.h	12 Oct 2007 06:55:28 -0000
@@ -107,6 +107,8 @@ struct CPUMIPSFPUContext {
 #define FP_UNIMPLEMENTED  32
 };
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUMIPSMVPContext CPUMIPSMVPContext;
 struct CPUMIPSMVPContext {
     int32_t CP0_MVPControl;
@@ -484,6 +486,15 @@ int cpu_mips_register (CPUMIPSState *env
 #define cpu_signal_handler cpu_mips_signal_handler
 #define cpu_list mips_cpu_list
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM ? 1 : 0;
+}
+
 #include "cpu-all.h"
 
 /* Memory access type :
Index: target-mips/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-mips/exec.h,v
retrieving revision 1.38
diff -u -d -d -p -r1.38 exec.h
--- target-mips/exec.h	9 Oct 2007 03:39:58 -0000	1.38
+++ target-mips/exec.h	12 Oct 2007 06:55:28 -0000
@@ -105,7 +105,7 @@ void do_pmon (int function);
 void dump_sc (void);
 
 int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu);
+                               int mmu_idx, int is_softmmu);
 void do_interrupt (CPUState *env);
 void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra);
 
Index: target-mips/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/helper.c,v
retrieving revision 1.53
diff -u -d -d -p -r1.53 helper.c
--- target-mips/helper.c	30 Sep 2007 01:58:33 -0000	1.53
+++ target-mips/helper.c	12 Oct 2007 06:55:28 -0000
@@ -232,7 +232,7 @@ void cpu_mips_init_mmu (CPUState *env)
 #endif /* !defined(CONFIG_USER_ONLY) */
 
 int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     target_ulong physical;
     int prot;
@@ -244,8 +244,8 @@ int cpu_mips_handle_mmu_fault (CPUState 
 #if 0
         cpu_dump_state(env, logfile, fprintf, 0);
 #endif
-        fprintf(logfile, "%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d is_user %d smmu %d\n",
-                __func__, env->PC[env->current_tc], address, rw, is_user, is_softmmu);
+        fprintf(logfile, "%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d smmu %d\n",
+                __func__, env->PC[env->current_tc], address, rw, mmu_idx, is_softmmu);
     }
 
     rw &= 1;
@@ -268,7 +268,7 @@ int cpu_mips_handle_mmu_fault (CPUState 
     if (ret == TLBRET_MATCH) {
        ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
                           physical & TARGET_PAGE_MASK, prot,
-                          is_user, is_softmmu);
+                          mmu_idx, is_softmmu);
     } else if (ret < 0) {
     do_fault:
         switch (ret) {
Index: target-mips/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/op_helper.c,v
retrieving revision 1.65
diff -u -d -d -p -r1.65 op_helper.c
--- target-mips/op_helper.c	9 Oct 2007 03:39:58 -0000	1.65
+++ target-mips/op_helper.c	12 Oct 2007 06:55:29 -0000
@@ -563,7 +563,7 @@ static void do_unaligned_access (target_
     do_raise_exception ((is_write == 1) ? EXCP_AdES : EXCP_AdEL);
 }
 
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -574,7 +574,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_mips_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (ret) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-ppc/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/cpu.h,v
retrieving revision 1.79
diff -u -d -d -p -r1.79 cpu.h
--- target-ppc/cpu.h	12 Oct 2007 06:47:46 -0000	1.79
+++ target-ppc/cpu.h	12 Oct 2007 06:55:29 -0000
@@ -434,6 +434,12 @@ enum {
     POWERPC_FLAG_PMM  = 0x00000400,
 };
 
+#if defined(TARGET_PPC64H)
+#define NB_MMU_MODES 3
+#else
+#define NB_MMU_MODES 2
+#endif
+
 /*****************************************************************************/
 /* The whole PowerPC CPU context */
 struct CPUPPCState {
@@ -575,6 +581,7 @@ struct CPUPPCState {
     jmp_buf jmp_env;
     int user_mode_only; /* user mode only simulation */
     target_ulong hflags; /* hflags is a MSR & HFLAGS_MASK */
+    int mmu_idx;         /* precomputed MMU index to speed up mem accesses */
 
     /* Power management */
     int power_mode;
@@ -699,6 +706,18 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, i
 #define cpu_signal_handler cpu_ppc_signal_handler
 #define cpu_list ppc_cpu_list
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _user
+#define MMU_MODE1_SUFFIX _kernel
+#if defined(TARGET_PPC64H)
+#define MMU_MODE2_SUFFIX _hypv
+#endif
+#define MMU_USER_IDX 0
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return env->mmu_idx;
+}
+
 #include "cpu-all.h"
 
 /*****************************************************************************/
Index: target-ppc/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/exec.h,v
retrieving revision 1.28
diff -u -d -d -p -r1.28 exec.h
--- target-ppc/exec.h	7 Oct 2007 18:19:25 -0000	1.28
+++ target-ppc/exec.h	12 Oct 2007 06:55:29 -0000
@@ -112,7 +112,7 @@ static always_inline void regs_to_env (v
 }
 
 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu);
+                              int mmu_idx, int is_softmmu);
 
 static always_inline int cpu_halted (CPUState *env)
 {
Index: target-ppc/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/helper.c,v
retrieving revision 1.75
diff -u -d -d -p -r1.75 helper.c
--- target-ppc/helper.c	8 Oct 2007 02:58:07 -0000	1.75
+++ target-ppc/helper.c	12 Oct 2007 06:55:29 -0000
@@ -39,7 +39,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     int exception, error_code;
 
@@ -1349,7 +1349,7 @@ target_phys_addr_t cpu_get_phys_page_deb
 
 /* Perform address translation */
 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     mmu_ctx_t ctx;
     int access_type;
@@ -1370,7 +1370,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *
     if (ret == 0) {
         ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
                            ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
-                           is_user, is_softmmu);
+                           mmu_idx, is_softmmu);
     } else if (ret < 0) {
 #if defined (DEBUG_MMU)
         if (loglevel != 0)
@@ -2083,7 +2083,12 @@ void do_compute_hflags (CPUPPCState *env
     env->hflags |= msr_cm << MSR_CM;
     env->hflags |= (uint64_t)msr_sf << MSR_SF;
     env->hflags |= (uint64_t)msr_hv << MSR_HV;
+    /* Precompute MMU index */
+    if (msr_pr == 0 && msr_hv == 1)
+        env->mmu_idx = 2;
+    else
 #endif
+        env->mmu_idx = 1 - msr_pr;
 }
 
 /*****************************************************************************/
Index: target-ppc/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/op_helper.c,v
retrieving revision 1.49
diff -u -d -d -p -r1.49 op_helper.c
--- target-ppc/op_helper.c	7 Oct 2007 17:13:43 -0000	1.49
+++ target-ppc/op_helper.c	12 Oct 2007 06:55:29 -0000
@@ -2307,7 +2307,7 @@ DO_SPE_OP1(fsctuf);
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -2318,7 +2318,7 @@ void tlb_fill (target_ulong addr, int is
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (unlikely(ret != 0)) {
         if (likely(retaddr)) {
             /* now we have a real cpu fault */
Index: target-ppc/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/translate.c,v
retrieving revision 1.92
diff -u -d -d -p -r1.92 translate.c
--- target-ppc/translate.c	7 Oct 2007 23:10:08 -0000	1.92
+++ target-ppc/translate.c	12 Oct 2007 06:55:29 -0000
@@ -6693,15 +6693,8 @@ static always_inline int gen_intermediat
     ctx.tb = tb;
     ctx.exception = POWERPC_EXCP_NONE;
     ctx.spr_cb = env->spr_cb;
-#if defined(CONFIG_USER_ONLY)
-    supervisor = 0;
-#else
-#if defined(TARGET_PPC64H)
-    if (msr_pr == 0 && msr_hv == 1)
-        supervisor = 2;
-    else
-#endif
-        supervisor = 1 - msr_pr;
+    supervisor = env->mmu_idx;
+#if !defined(CONFIG_USER_ONLY)
     ctx.supervisor = supervisor;
 #endif
 #if defined(TARGET_PPC64)
Index: target-sh4/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/cpu.h,v
retrieving revision 1.10
diff -u -d -d -p -r1.10 cpu.h
--- target-sh4/cpu.h	16 Sep 2007 21:08:05 -0000	1.10
+++ target-sh4/cpu.h	12 Oct 2007 06:55:29 -0000
@@ -77,6 +77,8 @@ typedef struct tlb_t {
 #define UTLB_SIZE 64
 #define ITLB_SIZE 4
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUSH4State {
     uint32_t flags;		/* general execution flags */
     uint32_t gregs[24];		/* general registers */
@@ -134,6 +136,15 @@ int cpu_sh4_signal_handler(int host_sign
 #define cpu_gen_code cpu_sh4_gen_code
 #define cpu_signal_handler cpu_sh4_signal_handler
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return (env->sr & SR_MD) == 0 ? 1 : 0;
+}
+
 #include "cpu-all.h"
 
 /* Memory access type */
Index: target-sh4/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/exec.h,v
retrieving revision 1.5
diff -u -d -d -p -r1.5 exec.h
--- target-sh4/exec.h	16 Sep 2007 21:08:05 -0000	1.5
+++ target-sh4/exec.h	12 Oct 2007 06:55:29 -0000
@@ -63,7 +63,7 @@ static inline void env_to_regs(void)
 }
 
 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-			     int is_user, int is_softmmu);
+			     int mmu_idx, int is_softmmu);
 
 int find_itlb_entry(CPUState * env, target_ulong address,
 		    int use_asid, int update);
Index: target-sh4/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/helper.c,v
retrieving revision 1.4
diff -u -d -d -p -r1.4 helper.c
--- target-sh4/helper.c	16 Sep 2007 21:08:05 -0000	1.4
+++ target-sh4/helper.c	12 Oct 2007 06:55:29 -0000
@@ -36,7 +36,7 @@ void do_interrupt (CPUState *env)
 }
 
 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-			     int is_user, int is_softmmu)
+			     int mmu_idx, int is_softmmu)
 {
     env->tea = address;
     switch (rw) {
@@ -372,15 +372,15 @@ int get_physical_address(CPUState * env,
 }
 
 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-			     int is_user, int is_softmmu)
+			     int mmu_idx, int is_softmmu)
 {
     target_ulong physical, page_offset, page_size;
     int prot, ret, access_type;
 
     /* XXXXX */
 #if 0
-    fprintf(stderr, "%s pc %08x ad %08x rw %d is_user %d smmu %d\n",
-	    __func__, env->pc, address, rw, is_user, is_softmmu);
+    fprintf(stderr, "%s pc %08x ad %08x rw %d mmu_idx %d smmu %d\n",
+	    __func__, env->pc, address, rw, mmu_idx, is_softmmu);
 #endif
 
     access_type = ACCESS_INT;
@@ -426,7 +426,7 @@ int cpu_sh4_handle_mmu_fault(CPUState * 
     address = (address & TARGET_PAGE_MASK) + page_offset;
     physical = (physical & TARGET_PAGE_MASK) + page_offset;
 
-    return tlb_set_page(env, address, physical, prot, is_user, is_softmmu);
+    return tlb_set_page(env, address, physical, prot, mmu_idx, is_softmmu);
 }
 
 target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
Index: target-sh4/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/op_helper.c,v
retrieving revision 1.4
diff -u -d -d -p -r1.4 op_helper.c
--- target-sh4/op_helper.c	16 Sep 2007 21:08:05 -0000	1.4
+++ target-sh4/op_helper.c	12 Oct 2007 06:55:29 -0000
@@ -42,7 +42,7 @@ void do_raise_exception(void)
 #define SHIFT 3
 #include "softmmu_template.h"
 
-void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     CPUState *saved_env;
@@ -53,7 +53,7 @@ void tlb_fill(target_ulong addr, int is_
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (ret) {
 	if (retaddr) {
 	    /* now we have a real cpu fault */
Index: target-sparc/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/cpu.h,v
retrieving revision 1.53
diff -u -d -d -p -r1.53 cpu.h
--- target-sparc/cpu.h	12 Oct 2007 06:47:46 -0000	1.53
+++ target-sparc/cpu.h	12 Oct 2007 06:55:29 -0000
@@ -166,6 +166,8 @@
 
 typedef struct sparc_def_t sparc_def_t;
 
+#define NB_MMU_MODES 2
+
 typedef struct CPUSPARCState {
     target_ulong gregs[8]; /* general registers */
     target_ulong *regwptr; /* pointer to current register window */
@@ -317,6 +319,15 @@ void cpu_check_irqs(CPUSPARCState *env);
 #define cpu_signal_handler cpu_sparc_signal_handler
 #define cpu_list sparc_cpu_list
 
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index (CPUState *env)
+{
+    return env->psrs == 0 ? 1 : 0;
+}
+
 #include "cpu-all.h"
 
 #endif
Index: target-sparc/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/exec.h,v
retrieving revision 1.21
diff -u -d -d -p -r1.21 exec.h
--- target-sparc/exec.h	30 Sep 2007 19:38:11 -0000	1.21
+++ target-sparc/exec.h	12 Oct 2007 06:55:29 -0000
@@ -115,7 +115,7 @@ static inline void regs_to_env(void)
 }
 
 int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu);
+                               int mmu_idx, int is_softmmu);
 
 static inline int cpu_halted(CPUState *env) {
     if (!env->halted)
Index: target-sparc/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/helper.c,v
retrieving revision 1.27
diff -u -d -d -p -r1.27 helper.c
--- target-sparc/helper.c	24 Sep 2007 19:44:09 -0000	1.27
+++ target-sparc/helper.c	12 Oct 2007 06:55:30 -0000
@@ -49,7 +49,7 @@ void cpu_unlock(void)
 #if defined(CONFIG_USER_ONLY)
 
 int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     if (rw & 2)
         env->exception_index = TT_TFAULT;
@@ -100,15 +100,16 @@ static const int perm_table[2][8] = {
 
 int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
                           int *access_index, target_ulong address, int rw,
-                          int is_user)
+                          int mmu_idx)
 {
     int access_perms = 0;
     target_phys_addr_t pde_ptr;
     uint32_t pde;
     target_ulong virt_addr;
-    int error_code = 0, is_dirty;
+    int error_code = 0, is_dirty, is_user;
     unsigned long page_offset;
 
+    is_user = mmu_idx == MMU_USER_IDX;
     virt_addr = address & TARGET_PAGE_MASK;
 
     if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
@@ -216,13 +217,13 @@ int get_physical_address (CPUState *env,
 
 /* Perform address translation */
 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     target_phys_addr_t paddr;
     target_ulong vaddr;
     int error_code = 0, prot, ret = 0, access_index;
 
-    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
+    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, mmu_idx);
     if (error_code == 0) {
         vaddr = address & TARGET_PAGE_MASK;
         paddr &= TARGET_PAGE_MASK;
@@ -230,7 +231,7 @@ int cpu_sparc_handle_mmu_fault (CPUState
         printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
                TARGET_FMT_lx "\n", address, paddr, vaddr);
 #endif
-        ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
         return ret;
     }
 
@@ -246,7 +247,7 @@ int cpu_sparc_handle_mmu_fault (CPUState
         // switching to normal mode.
         vaddr = address & TARGET_PAGE_MASK;
         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
-        ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
         return ret;
     } else {
         if (rw & 2)
@@ -484,8 +485,10 @@ static int get_physical_address_code(CPU
 
 int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
                           int *access_index, target_ulong address, int rw,
-                          int is_user)
+                          int mmu_idx)
 {
+    int is_user = mmu_idx == MMU_USER_IDX;
+
     if (rw == 2)
         return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
     else
@@ -494,20 +497,20 @@ int get_physical_address(CPUState *env, 
 
 /* Perform address translation */
 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     target_ulong virt_addr, vaddr;
     target_phys_addr_t paddr;
     int error_code = 0, prot, ret = 0, access_index;
 
-    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
+    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, mmu_idx);
     if (error_code == 0) {
         virt_addr = address & TARGET_PAGE_MASK;
         vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
 #ifdef DEBUG_MMU
         printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64 "\n", address, paddr, vaddr);
 #endif
-        ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
         return ret;
     }
     // XXX
Index: target-sparc/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.41
diff -u -d -d -p -r1.41 op_helper.c
--- target-sparc/op_helper.c	1 Oct 2007 17:07:58 -0000	1.41
+++ target-sparc/op_helper.c	12 Oct 2007 06:55:30 -0000
@@ -1522,7 +1522,7 @@ static void do_unaligned_access(target_u
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
     TranslationBlock *tb;
     int ret;
@@ -1534,7 +1534,7 @@ void tlb_fill(target_ulong addr, int is_
     saved_env = env;
     env = cpu_single_env;
 
-    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (ret) {
         if (retaddr) {
             /* now we have a real cpu fault */
Index: target-sparc/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/translate.c,v
retrieving revision 1.74
diff -u -d -d -p -r1.74 translate.c
--- target-sparc/translate.c	10 Oct 2007 19:11:54 -0000	1.74
+++ target-sparc/translate.c	12 Oct 2007 06:55:30 -0000
@@ -3689,7 +3689,7 @@ target_phys_addr_t cpu_get_phys_page_deb
 #else
 extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
                                  int *access_index, target_ulong address, int rw,
-                                 int is_user);
+                                 int mmu_idx);
 
 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
 {

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

* Re: [Qemu-devel] RFC: cleanups: CPU_MEM_INDEX
  2007-10-12  7:01       ` J. Mayer
@ 2007-10-13 21:14         ` J. Mayer
  2007-10-13 22:55           ` Thiemo Seufer
  0 siblings, 1 reply; 9+ messages in thread
From: J. Mayer @ 2007-10-13 21:14 UTC (permalink / raw)
  To: qemu-devel

On Fri, 2007-10-12 at 09:01 +0200, J. Mayer wrote:
> On Thu, 2007-10-11 at 14:09 +0200, J. Mayer wrote:
> > On Wed, 2007-10-10 at 07:06 +0200, J. Mayer wrote:
> > > On Wed, 2007-10-10 at 01:12 +0100, Thiemo Seufer wrote:
> > > > J. Mayer wrote:
> > > > > Here's a proposal to add a int cpu_mem_index (CPUState *env) function in
> > > > > targets cpu.h header.
> > > > > The idea of this patch is:
> > > > > - avoid many #ifdef TARGET_xxx in exec-all.h and  softmmu_header.h then
> > > > > make the code more readable
> > > > > - avoid multiple implementation of the same code (3, in that particular
> > > > > case) this to avoid potential conflicts if the definition has to be
> > > > > updated for any reason (ie support for new memory access modes,
> > > > > emulation optimisation...)
> > > > > 
> > > > > Please comment.
> > > > > 
> > > > > -- 
> > > > > J. Mayer <l_indien@magic.fr>
> > > > > Never organized
> > > > 
> > 
> > [...]
> > 
> > Here's an updated version of the patch. My comments about it stay valid,
> > with two additions:
> > 1/ when is user is needed to maintain compatibility with existing code,
> > I now define it as:
> > int is_user = mmu_idx == MMU_USER_IDX;
> > instead of just is_user = mmu_idx.
> > This definition will then remain correct even if the definition of the
> > MMU modes are later changed for a specific target
> > 2/ I now precompute the mmu_idx on PowerPC platform as it can never
> > change inside a single TB. This may save a few instructions for every
> > memory access. I guess the same optimisation can be made for the other
> > targets, but not knowing exactly when it would have to be recomputed,
> > for most targets, I prefer not to do this optimisation myself.
> 
> Here's another update, taking care of the commit I just made (which
> changes some of the target-xxx/cpu.h files).
> It also fixes an issue in softmmu_header; this was missing:
> 
>  #if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__)
> && \
> -    (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU)
> +    (ACCESS_TYPE < NB_MMU_MODES) && defined(ASM_SOFTMMU)
>  
>  #define CPU_TLB_ENTRY_BITS 4
>  
> As this affects only the i386 target which is defined with 2 MMU modes,
> the miss had no run-time consequence but was still a bug.
>  
> > > > I presume cpu_mem_index is supposed to do more than checking for
> > > > usermode. In that case, is_user should get renamed, and the
> > > > cpu_mem_index implementation of some (most?) CPUs should have a
> > > > FIXME comment as reminder to implement the missing MMU modes.
> > > 
> > > You're right, calling this variable is_user is only valid because this
> > > code supposes it knows what cpu_mem_index means. For targets with more
> > > than 2 modes of execution, this is not correct.
> > > My first idea was to try not to change the code too much. After thinking
> > > more about the problem, it appears to me that:
> > > 1/ in the softmmu routines, we should do no assumption about the
> > > signification of the memory index
> > > 2/ then, softmmu routines should use an index and all exported
> > > interfaces (ie tlb_fill and handle_mmu_fault) should take an index
> > > instead of is_user as an argument.
> > > 3/ to maintain compatibility with the existing code, I choosed to add a
> > > is_user variable inside most handle_mmu_fault implementation,
> > > initialized with the value of the given index, which is then given to
> > > the target mmu translation routines.
> > > 4/ to ease implementation of targets with more than 2 execution modes, I
> > > choosed to define a per-target NB_MMU_MODES in each target_xxx/cpu.h
> > > (instead of the hack for PowerPC 64 and Alpha that did pre-exist) and
> > > add a local definition of the meaning of each mmu_index index. Then, for
> > > PowerPC, I choosed to use the same convention than I do in translate.c,
> > > which seems more logical to me, then: 0 => user, 1 => supervisor, 2 =>
> > > hypervisor.
> > > 5/ to avoid confusion between the memory index used in the translation
> > > context, which may contain more than the access mode information, and
> > > the one used by the softmmu routines, I choosed to name the one used in
> > > softmmu 'mmu_idx' (the one in target_xxx/translate.c is called mem_idx).
> > > 6/ I choosed to add a constant MMU_USER_IDX which is used in the
> > > user-mode handle_cpu_signal routine, then addressing your first remark.
> > > 
> > > This patch solves a problem I had no solution to until today: how to add
> > > new mmu modes (ie hypervisor for PowerPC 64, supervisor and executive
> > > for Alpha) for some specific targets.
> > > 
> > > The result is a much more invasive patch but the is supposed (!) to;
> > > 1/ do not change the behavior of the current targets implementations
> > > 2/ be less hardcoded, more flexible and extensible for any specific
> > > targets requirements.
> > > As this new version of the patch could deadly break the softmmu mode and
> > > I got no way to properly check all targets, I would greatly appreciate
> > > that some do some tests for arm, cris, m68k, mips, sh4 and sparc
> > > targets.
> > > 
> > > For now, I did a few tests, running Linux (debian hdd installation) for
> > > PowerPC on PPC 603 & 750 in 32 bits and 64 bits mode emulation on x86
> > > and amd64 and a few OSes using the i386-softmmu emulation (Linux Gentoo,
> > > solaris 10 installation CDROM, ...), with success; then I guess I did
> > > not deadly broke everything !
> > > The good point is that PowerPC runs, considering it is the only target
> > > for which I did change the mmu_idx semantics...
> > > 
> > > > Other than that it looks good to me (and reminds me to check what the
> > > > supervisor mode on MIPS actually does now :-).
> > > 
> > > This updated patch gives the opportunity to define a per-target semantic
> > > of the mmu_idx... Time to check what it means in actual CPU
> > > implementation !!!! ;-)
> > > 
> > > Thanks in advance for any comments or improvment suggestions....

What about this proposal ?
Any remarks, bugs, ... ?
I'd really like to apply it and go on working on some other
improvments...
And I'd like to commit my provision code for hypervisor mode for PowerPC
and the 4 running modes for Alpha, which depend on this one.
(the patch is still the same than the last one I did post here).

-- 
J. Mayer <l_indien@magic.fr>
Never organized

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

* Re: [Qemu-devel] RFC: cleanups: CPU_MEM_INDEX
  2007-10-13 21:14         ` J. Mayer
@ 2007-10-13 22:55           ` Thiemo Seufer
  0 siblings, 0 replies; 9+ messages in thread
From: Thiemo Seufer @ 2007-10-13 22:55 UTC (permalink / raw)
  To: J. Mayer; +Cc: qemu-devel

J. Mayer wrote:
[snip]
> > > > > Other than that it looks good to me (and reminds me to check what the
> > > > > supervisor mode on MIPS actually does now :-).
> > > > 
> > > > This updated patch gives the opportunity to define a per-target semantic
> > > > of the mmu_idx... Time to check what it means in actual CPU
> > > > implementation !!!! ;-)
> > > > 
> > > > Thanks in advance for any comments or improvment suggestions....
> 
> What about this proposal ?
> Any remarks, bugs, ... ?
> I'd really like to apply it and go on working on some other
> improvments...

Please commit.

> And I'd like to commit my provision code for hypervisor mode for PowerPC
> and the 4 running modes for Alpha, which depend on this one.
> (the patch is still the same than the last one I did post here).


Thiemo

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

end of thread, other threads:[~2007-10-13 22:55 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-10-09 19:33 [Qemu-devel] RFC: cleanups: CPU_MEM_INDEX J. Mayer
2007-10-10  0:12 ` Thiemo Seufer
2007-10-10  5:06   ` J. Mayer
2007-10-11 12:09     ` J. Mayer
2007-10-11 17:46       ` Thiemo Seufer
2007-10-11 22:27         ` J. Mayer
2007-10-12  7:01       ` J. Mayer
2007-10-13 21:14         ` J. Mayer
2007-10-13 22:55           ` Thiemo Seufer

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.