All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/10] rework exception model to support the HV mode
@ 2016-06-21 21:48 Cédric Le Goater
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation Cédric Le Goater
                   ` (9 more replies)
  0 siblings, 10 replies; 30+ messages in thread
From: Cédric Le Goater @ 2016-06-21 21:48 UTC (permalink / raw)
  To: qemu-ppc
  Cc: David Gibson, Alexander Graf, qemu-devel, Benjamin Herrenschmidt,
	Cedric Le Goater

Hello,

Here is a new set bringing more changes required for the powernv
platform. The major one is the rework of the exception model to
support the HV mode.

It was tested with a pseries guest, KVM and TCG, and with a mac99
guest !

The next serie will cover a rework of XICS to support native mode and
it should be the last one before the first powernv core patches.

Cheers,

C.

Benjamin Herrenschmidt (10):
  ppc: Fix rfi/rfid/hrfi/... emulation
  ppc: define a default LPCR value
  ppc: fix exception model for HV mode
  ppc: Fix POWER7 and POWER8 exception definitions
  ppc: Fix generation if ISI/DSI vs. HV mode
  ppc: Rework generation of priv and inval interrupts
  ppc: Add real mode CI load/store instructions for P7 and P8
  ppc: Turn a bunch of booleans from int to bool
  ppc: Move exception generation code out of line
  ppc: Add P7/P8 Power Management instructions

 linux-user/main.c           |   1 +
 target-ppc/cpu-qom.h        |   9 +
 target-ppc/cpu.h            |  32 +-
 target-ppc/excp_helper.c    | 263 ++++++++------
 target-ppc/helper.h         |   1 +
 target-ppc/mmu-hash64.c     |  69 +++-
 target-ppc/translate.c      | 864 ++++++++++++++++++++++----------------------
 target-ppc/translate_init.c | 139 ++++++-
 8 files changed, 795 insertions(+), 583 deletions(-)

-- 
2.1.4

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

* [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-21 21:48 [Qemu-devel] [PATCH v2 00/10] rework exception model to support the HV mode Cédric Le Goater
@ 2016-06-21 21:48 ` Cédric Le Goater
  2016-06-22  2:46   ` David Gibson
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 02/10] ppc: define a default LPCR value Cédric Le Goater
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Cédric Le Goater @ 2016-06-21 21:48 UTC (permalink / raw)
  To: qemu-ppc
  Cc: David Gibson, Alexander Graf, qemu-devel, Benjamin Herrenschmidt,
	Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

This reworks emulation of the various "rfi" variants. I removed
some masking bits that I couldn't make sense of, the only bit that
I am aware we should mask here is POW, the CPU's MSR mask should
take care of the rest.

This also fixes some problems when running 32-bit userspace under
a 64-bit kernel.

This patch broke 32bit OpenBIOS when run under a 970 cpu. A fix was
proposed here :

    https://www.coreboot.org/pipermail/openbios/2016-June/009452.html

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
[clg: updated the commit log with the reference of the openbios fix ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---

 target-ppc/excp_helper.c | 51 +++++++++++++++++++-----------------------------
 target-ppc/translate.c   |  8 ++++++++
 2 files changed, 28 insertions(+), 31 deletions(-)

diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 30e960e30b63..aa0b63f4b0de 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -922,25 +922,20 @@ void helper_store_msr(CPUPPCState *env, target_ulong val)
     }
 }
 
-static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
-                          target_ulong msrm, int keep_msrh)
+static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
 {
     CPUState *cs = CPU(ppc_env_get_cpu(env));
 
+    /* MSR:POW cannot be set by any form of rfi */
+    msr &= ~(1ULL << MSR_POW);
+
 #if defined(TARGET_PPC64)
-    if (msr_is_64bit(env, msr)) {
-        nip = (uint64_t)nip;
-        msr &= (uint64_t)msrm;
-    } else {
+    /* Switching to 32-bit ? Crop the nip */
+    if (!msr_is_64bit(env, msr)) {
         nip = (uint32_t)nip;
-        msr = (uint32_t)(msr & msrm);
-        if (keep_msrh) {
-            msr |= env->msr & ~((uint64_t)0xFFFFFFFF);
-        }
     }
 #else
     nip = (uint32_t)nip;
-    msr &= (uint32_t)msrm;
 #endif
     /* XXX: beware: this is false if VLE is supported */
     env->nip = nip & ~((target_ulong)0x00000003);
@@ -959,26 +954,24 @@ static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
 
 void helper_rfi(CPUPPCState *env)
 {
-    if (env->excp_model == POWERPC_EXCP_BOOKE) {
-        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
-               ~((target_ulong)0), 0);
-    } else {
-        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
-               ~((target_ulong)0x783F0000), 1);
-    }
+    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
 }
 
+#define MSR_BOOK3S_MASK
 #if defined(TARGET_PPC64)
 void helper_rfid(CPUPPCState *env)
 {
-    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
-           ~((target_ulong)0x783F0000), 0);
+    /* The architeture defines a number of rules for which bits
+     * can change but in practice, we handle this in hreg_store_msr()
+     * which will be called by do_rfi(), so there is no need to filter
+     * here
+     */
+    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
 }
 
 void helper_hrfid(CPUPPCState *env)
 {
-    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1],
-           ~((target_ulong)0x783F0000), 0);
+    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
 }
 #endif
 
@@ -986,28 +979,24 @@ void helper_hrfid(CPUPPCState *env)
 /* Embedded PowerPC specific helpers */
 void helper_40x_rfci(CPUPPCState *env)
 {
-    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3],
-           ~((target_ulong)0xFFFF0000), 0);
+    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
 }
 
 void helper_rfci(CPUPPCState *env)
 {
-    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
-           ~((target_ulong)0), 0);
+    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
 }
 
 void helper_rfdi(CPUPPCState *env)
 {
     /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
-    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1],
-           ~((target_ulong)0), 0);
+    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
 }
 
 void helper_rfmci(CPUPPCState *env)
 {
     /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
-    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1],
-           ~((target_ulong)0), 0);
+    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
 }
 #endif
 
@@ -1045,7 +1034,7 @@ void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
 
 void helper_rfsvc(CPUPPCState *env)
 {
-    do_rfi(env, env->lr, env->ctr, 0x0000FFFF, 0);
+    do_rfi(env, env->lr, env->ctr & 0x0000FFFF);
 }
 
 /* Embedded.Processor Control */
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index b6894751e8df..81481955a589 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -4087,6 +4087,14 @@ static void gen_rfi(DisasContext *ctx)
 #if defined(CONFIG_USER_ONLY)
     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
+    /* This instruction doesn't exist anymore on 64-bit server
+     * processors compliant with arch 2.x
+     */
+    if (ctx->insns_flags & PPC_SEGMENT_64B) {
+        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
+        return;
+    }
+
     /* Restore CPU state */
     if (unlikely(ctx->pr)) {
         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-- 
2.1.4

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

* [Qemu-devel] [PATCH v2 02/10] ppc: define a default LPCR value
  2016-06-21 21:48 [Qemu-devel] [PATCH v2 00/10] rework exception model to support the HV mode Cédric Le Goater
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation Cédric Le Goater
@ 2016-06-21 21:48 ` Cédric Le Goater
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 03/10] ppc: fix exception model for HV mode Cédric Le Goater
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 30+ messages in thread
From: Cédric Le Goater @ 2016-06-21 21:48 UTC (permalink / raw)
  To: qemu-ppc
  Cc: David Gibson, Alexander Graf, qemu-devel, Benjamin Herrenschmidt,
	Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

This allows us to set the appropriate LPCR bits which will be used
when fixing the exception model for the HV mode.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
[clg: previous commit 26a7f1291bb5 did not include the LPCR setting as
      it was not needed at the time, adapted commit log ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 target-ppc/translate_init.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index ca894ff4af45..edfd91a85425 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8509,6 +8509,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
 void cpu_ppc_set_papr(PowerPCCPU *cpu)
 {
     CPUPPCState *env = &cpu->env;
+    ppc_spr_t *lpcr = &env->spr_cb[SPR_LPCR];
     ppc_spr_t *amor = &env->spr_cb[SPR_AMOR];
 
     /* PAPR always has exception vectors in RAM not ROM. To ensure this,
@@ -8518,6 +8519,19 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu)
      */
     env->msr_mask &= ~((1ull << MSR_EP) | MSR_HVB);
 
+    /* Set emulated LPCR to not send interrupts to hypervisor. Note that
+     * under KVM, the actual HW LPCR will be set differently by KVM itself,
+     * the settings below ensure proper operations with TCG in absence of
+     * a real hypervisor
+     */
+    lpcr->default_value &= ~(LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV);
+    lpcr->default_value |= LPCR_LPES0 | LPCR_LPES1;
+
+    /* We should be followed by a CPU reset but update the active value
+     * just in case...
+     */
+    env->spr[SPR_LPCR] = lpcr->default_value;
+
     /* Set a full AMOR so guest can use the AMR as it sees fit */
     env->spr[SPR_AMOR] = amor->default_value = 0xffffffffffffffffull;
 
-- 
2.1.4

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

* [Qemu-devel] [PATCH v2 03/10] ppc: fix exception model for HV mode
  2016-06-21 21:48 [Qemu-devel] [PATCH v2 00/10] rework exception model to support the HV mode Cédric Le Goater
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation Cédric Le Goater
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 02/10] ppc: define a default LPCR value Cédric Le Goater
@ 2016-06-21 21:48 ` Cédric Le Goater
  2016-06-22  6:27   ` David Gibson
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 04/10] ppc: Fix POWER7 and POWER8 exception definitions Cédric Le Goater
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Cédric Le Goater @ 2016-06-21 21:48 UTC (permalink / raw)
  To: qemu-ppc
  Cc: David Gibson, Alexander Graf, qemu-devel, Benjamin Herrenschmidt,
	Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

This properly implements LPES0 handling for HV vs. !HV mode and
removes the unsupported LPES1. This has been removed from the specs
since ISA v2.07.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[clg: AIL implementation was fixed in commit 5c94b2a5e5ef. This patch
      only contains the bits of the original patch related to LPES0
      handling, adapted commit log.
      fixed checkpatch.pl errors. ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 target-ppc/excp_helper.c | 134 ++++++++++++++++-------------------------------
 1 file changed, 45 insertions(+), 89 deletions(-)

diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index aa0b63f4b0de..7c44c102db39 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -77,18 +77,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
     target_ulong msr, new_msr, vector;
-    int srr0, srr1, asrr0, asrr1;
-    int lpes0, lpes1, lev, ail;
-
-    if (0) {
-        /* XXX: find a suitable condition to enable the hypervisor mode */
-        lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;
-        lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;
-    } else {
-        /* Those values ensure we won't enter the hypervisor mode */
-        lpes0 = 0;
-        lpes1 = 1;
-    }
+    int srr0, srr1, asrr0, asrr1, lev, ail;
+    bool lpes0;
 
     qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
                   " => %08x (%02x)\n", env->nip, excp, env->error_code);
@@ -100,8 +90,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         msr = env->msr & ~0x783f0000ULL;
     }
 
-    /* new interrupt handler msr */
-    new_msr = env->msr & ((target_ulong)1 << MSR_ME);
+    /* new interrupt handler msr preserves existing HV and ME unless
+     * explicitly overriden
+     */
+    new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
 
     /* target registers */
     srr0 = SPR_SRR0;
@@ -111,12 +103,19 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
 
     /* Exception targetting modifiers
      *
+     * LPES0 is supported on POWER7/8
+     * LPES1 is not supported (old iSeries mode)
+     *
+     * On anything else, we behave as if LPES0 is 1
+     * (externals don't alter MSR:HV)
+     *
      * AIL is initialized here but can be cleared by
      * selected exceptions
      */
 #if defined(TARGET_PPC64)
     if (excp_model == POWERPC_EXCP_POWER7 ||
         excp_model == POWERPC_EXCP_POWER8) {
+        lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
         if (excp_model == POWERPC_EXCP_POWER8) {
             ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
         } else {
@@ -125,6 +124,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     } else
 #endif /* defined(TARGET_PPC64) */
     {
+        lpes0 = true;
         ail = 0;
     }
 
@@ -162,10 +162,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             cs->halted = 1;
             cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
         }
-        if (0) {
-            /* XXX: find a suitable condition to enable the hypervisor mode */
-            new_msr |= (target_ulong)MSR_HVB;
-        }
+        new_msr |= (target_ulong)MSR_HVB;
         ail = 0;
 
         /* machine check exceptions don't have ME set */
@@ -191,23 +188,20 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
         LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
                  "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_next;
     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
         LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
                  "\n", msr, env->nip);
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         msr |= env->error_code;
         goto store_next;
     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
         cs = CPU(cpu);
 
-        if (lpes0 == 1) {
+        if (!lpes0) {
             new_msr |= (target_ulong)MSR_HVB;
+            new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
+            srr0 = SPR_HSRR0;
+            srr1 = SPR_HSRR1;
         }
         if (env->mpic_proxy) {
             /* IACK the IRQ on delivery */
@@ -215,9 +209,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         }
         goto store_next;
     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         /* XXX: this is false */
         /* Get rS/rD and rA from faulting opcode */
         env->spr[SPR_DSISR] |= (cpu_ldl_code(env, (env->nip - 4))
@@ -232,9 +223,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
                 env->error_code = 0;
                 return;
             }
-            if (lpes1 == 0) {
-                new_msr |= (target_ulong)MSR_HVB;
-            }
             msr |= 0x00100000;
             if (msr_fe0 == msr_fe1) {
                 goto store_next;
@@ -243,23 +231,14 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             break;
         case POWERPC_EXCP_INVAL:
             LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
-            if (lpes1 == 0) {
-                new_msr |= (target_ulong)MSR_HVB;
-            }
             msr |= 0x00080000;
             env->spr[SPR_BOOKE_ESR] = ESR_PIL;
             break;
         case POWERPC_EXCP_PRIV:
-            if (lpes1 == 0) {
-                new_msr |= (target_ulong)MSR_HVB;
-            }
             msr |= 0x00040000;
             env->spr[SPR_BOOKE_ESR] = ESR_PPR;
             break;
         case POWERPC_EXCP_TRAP:
-            if (lpes1 == 0) {
-                new_msr |= (target_ulong)MSR_HVB;
-            }
             msr |= 0x00020000;
             env->spr[SPR_BOOKE_ESR] = ESR_PTR;
             break;
@@ -271,27 +250,23 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         }
         goto store_current;
     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_current;
     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
         dump_syscall(env);
         lev = env->error_code;
+
+        /* "PAPR mode" built-in hypercall emulation */
         if ((lev == 1) && cpu_ppc_hypercall) {
             cpu_ppc_hypercall(cpu);
             return;
         }
-        if (lev == 1 || (lpes0 == 0 && lpes1 == 0)) {
+        if (lev == 1) {
             new_msr |= (target_ulong)MSR_HVB;
         }
         goto store_next;
     case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
         goto store_current;
     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_next;
     case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
         /* FIT on 4xx */
@@ -361,21 +336,12 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             new_msr &= ~((target_ulong)1 << MSR_ME);
         }
 
-        if (0) {
-            /* XXX: find a suitable condition to enable the hypervisor mode */
-            new_msr |= (target_ulong)MSR_HVB;
-        }
+        new_msr |= (target_ulong)MSR_HVB;
         ail = 0;
         goto store_next;
     case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_next;
     case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_next;
     case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
         srr0 = SPR_HSRR0;
@@ -384,9 +350,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
         goto store_next;
     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_next;
     case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
         srr0 = SPR_HSRR0;
@@ -413,19 +376,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
         goto store_next;
     case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_current;
     case POWERPC_EXCP_VSXU:       /* VSX unavailable exception               */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_current;
     case POWERPC_EXCP_FU:         /* Facility unavailable exception          */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_current;
     case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
         LOG_EXCP("PIT exception\n");
@@ -444,9 +398,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
                   "is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
-        if (lpes1 == 0) { /* XXX: check this */
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         switch (excp_model) {
         case POWERPC_EXCP_602:
         case POWERPC_EXCP_603:
@@ -463,9 +414,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         }
         break;
     case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
-        if (lpes1 == 0) { /* XXX: check this */
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         switch (excp_model) {
         case POWERPC_EXCP_602:
         case POWERPC_EXCP_603:
@@ -482,9 +430,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         }
         break;
     case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
-        if (lpes1 == 0) { /* XXX: check this */
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         switch (excp_model) {
         case POWERPC_EXCP_602:
         case POWERPC_EXCP_603:
@@ -590,9 +535,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
                   "is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         /* XXX: TODO */
         cpu_abort(cs,
                   "Performance counter exception is not implemented yet !\n");
@@ -636,6 +578,13 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     }
     /* Save MSR */
     env->spr[srr1] = msr;
+
+    /* Sanity check */
+    if (!(env->msr_mask & MSR_HVB) && (srr0 == SPR_HSRR0)) {
+        cpu_abort(cs, "Trying to deliver HV exception %d with "
+                  "no HV support\n", excp);
+    }
+
     /* If any alternate SRR register are defined, duplicate saved values */
     if (asrr0 != -1) {
         env->spr[asrr0] = env->spr[srr0];
@@ -644,14 +593,20 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         env->spr[asrr1] = env->spr[srr1];
     }
 
-    if (env->spr[SPR_LPCR] & LPCR_AIL) {
-        new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
-    }
-
+    /* Sort out endianness of interrupt, this differs depending on the
+     * CPU, the HV mode, etc...
+     */
 #ifdef TARGET_PPC64
-    if (excp_model == POWERPC_EXCP_POWER7 ||
-        excp_model == POWERPC_EXCP_POWER8) {
-        if (env->spr[SPR_LPCR] & LPCR_ILE) {
+    if (excp_model == POWERPC_EXCP_POWER7) {
+        if (!(new_msr & MSR_HVB) && (env->spr[SPR_LPCR] & LPCR_ILE)) {
+            new_msr |= (target_ulong)1 << MSR_LE;
+        }
+    } else if (excp_model == POWERPC_EXCP_POWER8) {
+        if (new_msr & MSR_HVB) {
+            if (env->spr[SPR_HID0] & HID0_HILE) {
+                new_msr |= (target_ulong)1 << MSR_LE;
+            }
+        } else if (env->spr[SPR_LPCR] & LPCR_ILE) {
             new_msr |= (target_ulong)1 << MSR_LE;
         }
     } else if (msr_ile) {
@@ -674,7 +629,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     /* AIL only works if there is no HV transition and we are running with
      * translations enabled
      */
-    if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1)) {
+    if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1) ||
+        ((new_msr & MSR_HVB) && !(msr & MSR_HVB))) {
         ail = 0;
     }
     /* Handle AIL */
-- 
2.1.4

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

* [Qemu-devel] [PATCH v2 04/10] ppc: Fix POWER7 and POWER8 exception definitions
  2016-06-21 21:48 [Qemu-devel] [PATCH v2 00/10] rework exception model to support the HV mode Cédric Le Goater
                   ` (2 preceding siblings ...)
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 03/10] ppc: fix exception model for HV mode Cédric Le Goater
@ 2016-06-21 21:48 ` Cédric Le Goater
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 05/10] ppc: Fix generation if ISI/DSI vs. HV mode Cédric Le Goater
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 30+ messages in thread
From: Cédric Le Goater @ 2016-06-21 21:48 UTC (permalink / raw)
  To: qemu-ppc
  Cc: David Gibson, Alexander Graf, qemu-devel, Benjamin Herrenschmidt,
	Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

We were initializing unused ones and missing some

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
[clg: fixed checkpatch.pl errors ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 target-ppc/cpu.h            | 11 ++++++++++-
 target-ppc/translate_init.c | 27 +++++++++++++++++++++------
 2 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 93c2dd5a65a1..f005549c352e 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -116,6 +116,9 @@ enum {
     POWERPC_EXCP_HYPPRIV  = 41, /* Embedded hypervisor priv instruction      */
     /* Vectors 42 to 63 are reserved                                         */
     /* Exceptions defined in the PowerPC server specification                */
+    /* Server doorbell variants */
+#define POWERPC_EXCP_SDOOR      POWERPC_EXCP_GDOORI
+#define POWERPC_EXCP_SDOOR_HV   POWERPC_EXCP_DOORI
     POWERPC_EXCP_RESET    = 64, /* System reset exception                    */
     POWERPC_EXCP_DSEG     = 65, /* Data segment exception                    */
     POWERPC_EXCP_ISEG     = 66, /* Instruction segment exception             */
@@ -158,8 +161,12 @@ enum {
     /* VSX Unavailable (Power ISA 2.06 and later)                            */
     POWERPC_EXCP_VSXU     = 94, /* VSX Unavailable                           */
     POWERPC_EXCP_FU       = 95, /* Facility Unavailable                      */
+    /* Additional ISA 2.06 and later server exceptions                       */
+    POWERPC_EXCP_HV_EMU   = 96, /* HV emulation assistance                   */
+    POWERPC_EXCP_HV_MAINT = 97, /* HMI                                       */
+    POWERPC_EXCP_HV_FU    = 98, /* Hypervisor Facility unavailable           */
     /* EOL                                                                   */
-    POWERPC_EXCP_NB       = 96,
+    POWERPC_EXCP_NB       = 99,
     /* QEMU exceptions: used internally during code translation              */
     POWERPC_EXCP_STOP         = 0x200, /* stop translation                   */
     POWERPC_EXCP_BRANCH       = 0x201, /* branch instruction                 */
@@ -2196,6 +2203,8 @@ enum {
     PPC_INTERRUPT_CDOORBELL,      /* Critical doorbell interrupt          */
     PPC_INTERRUPT_DOORBELL,       /* Doorbell interrupt                   */
     PPC_INTERRUPT_PERFM,          /* Performance monitor interrupt        */
+    PPC_INTERRUPT_HMI,            /* Hypervisor Maintainance interrupt    */
+    PPC_INTERRUPT_HDOORBELL,      /* Hypervisor Doorbell interrupt        */
 };
 
 /* Processor Compatibility mask (PCR) */
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index edfd91a85425..3b4234b325d1 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -3171,18 +3171,30 @@ static void init_excp_POWER7 (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_HDECR]    = 0x00000980;
     env->excp_vectors[POWERPC_EXCP_SYSCALL]  = 0x00000C00;
     env->excp_vectors[POWERPC_EXCP_TRACE]    = 0x00000D00;
+    env->excp_vectors[POWERPC_EXCP_HDSI]     = 0x00000E00;
+    env->excp_vectors[POWERPC_EXCP_HISI]     = 0x00000E20;
+    env->excp_vectors[POWERPC_EXCP_HV_EMU]   = 0x00000E40;
+    env->excp_vectors[POWERPC_EXCP_HV_MAINT] = 0x00000E60;
     env->excp_vectors[POWERPC_EXCP_PERFM]    = 0x00000F00;
     env->excp_vectors[POWERPC_EXCP_VPU]      = 0x00000F20;
     env->excp_vectors[POWERPC_EXCP_VSXU]     = 0x00000F40;
-    env->excp_vectors[POWERPC_EXCP_FU]       = 0x00000F60;
-    env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
-    env->excp_vectors[POWERPC_EXCP_MAINT]    = 0x00001600;
-    env->excp_vectors[POWERPC_EXCP_VPUA]     = 0x00001700;
-    env->excp_vectors[POWERPC_EXCP_THERM]    = 0x00001800;
     /* Hardware reset vector */
     env->hreset_vector = 0x0000000000000100ULL;
 #endif
 }
+
+static void init_excp_POWER8(CPUPPCState *env)
+{
+    init_excp_POWER7(env);
+
+#if !defined(CONFIG_USER_ONLY)
+    env->excp_vectors[POWERPC_EXCP_SDOOR]    = 0x00000A00;
+    env->excp_vectors[POWERPC_EXCP_FU]       = 0x00000F60;
+    env->excp_vectors[POWERPC_EXCP_HV_FU]    = 0x00000F80;
+    env->excp_vectors[POWERPC_EXCP_SDOOR_HV] = 0x00000E80;
+#endif
+}
+
 #endif
 
 /*****************************************************************************/
@@ -8123,10 +8135,13 @@ static void init_proc_book3s_64(CPUPPCState *env, int version)
         ppc970_irq_init(ppc_env_get_cpu(env));
         break;
     case BOOK3S_CPU_POWER7:
-    case BOOK3S_CPU_POWER8:
         init_excp_POWER7(env);
         ppcPOWER7_irq_init(ppc_env_get_cpu(env));
         break;
+    case BOOK3S_CPU_POWER8:
+        init_excp_POWER8(env);
+        ppcPOWER7_irq_init(ppc_env_get_cpu(env));
+        break;
     default:
         g_assert_not_reached();
     }
-- 
2.1.4

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

* [Qemu-devel] [PATCH v2 05/10] ppc: Fix generation if ISI/DSI vs. HV mode
  2016-06-21 21:48 [Qemu-devel] [PATCH v2 00/10] rework exception model to support the HV mode Cédric Le Goater
                   ` (3 preceding siblings ...)
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 04/10] ppc: Fix POWER7 and POWER8 exception definitions Cédric Le Goater
@ 2016-06-21 21:48 ` Cédric Le Goater
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 06/10] ppc: Rework generation of priv and inval interrupts Cédric Le Goater
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 30+ messages in thread
From: Cédric Le Goater @ 2016-06-21 21:48 UTC (permalink / raw)
  To: qemu-ppc
  Cc: David Gibson, Alexander Graf, qemu-devel, Benjamin Herrenschmidt,
	Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Under some circumstances, we need to direct ISI and DSI interrupts
at the hypervisor, turning them into HISI/HDSI, and using different
SPRs (HDSISR and HDAR) depending on the combination of MSR_DR and
the corresponding VPM bits in LPCR.

This moves part of the code into helpers that are fixed to select
the right exception type and registers. On pre-P7 processors, LPCR
is 0 which provides the old behaviour of directing the interrupts
at the supervisor.

Thanks to Andrei Warkentin for finding a bug when HV=1

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
[clg: Merged a fix on POWERPC_EXCP_HDSI fixing the condition on
      msr_hv, from Andrei Warkentin <andrey.warkentin@gmail.com> ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 target-ppc/mmu-hash64.c | 69 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 50 insertions(+), 19 deletions(-)

diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 668da5e22653..5b7b5e9eb10c 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -613,6 +613,47 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
     return 0;
 }
 
+static void ppc_hash64_set_isi(CPUState *cs, CPUPPCState *env,
+                               uint64_t error_code)
+{
+    bool vpm;
+
+    if (msr_ir) {
+        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
+    } else {
+        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
+    }
+    if (vpm && !msr_hv) {
+        cs->exception_index = POWERPC_EXCP_HISI;
+    } else {
+        cs->exception_index = POWERPC_EXCP_ISI;
+    }
+    env->error_code = error_code;
+}
+
+static void ppc_hash64_set_dsi(CPUState *cs, CPUPPCState *env, uint64_t dar,
+                               uint64_t dsisr)
+{
+    bool vpm;
+
+    if (msr_dr) {
+        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
+    } else {
+        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
+    }
+    if (vpm && !msr_hv) {
+        cs->exception_index = POWERPC_EXCP_HDSI;
+        env->spr[SPR_HDAR] = dar;
+        env->spr[SPR_HDSISR] = dsisr;
+    } else {
+        cs->exception_index = POWERPC_EXCP_DSI;
+        env->spr[SPR_DAR] = dar;
+        env->spr[SPR_DSISR] = dsisr;
+   }
+    env->error_code = 0;
+}
+
+
 int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
                                 int rwx, int mmu_idx)
 {
@@ -623,7 +664,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
     hwaddr pte_offset;
     ppc_hash_pte64_t pte;
     int pp_prot, amr_prot, prot;
-    uint64_t new_pte1;
+    uint64_t new_pte1, dsisr;
     const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
     hwaddr raddr;
 
@@ -657,26 +698,21 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
 
     /* 3. Check for segment level no-execute violation */
     if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) {
-        cs->exception_index = POWERPC_EXCP_ISI;
-        env->error_code = 0x10000000;
+        ppc_hash64_set_isi(cs, env, 0x10000000);
         return 1;
     }
 
     /* 4. Locate the PTE in the hash table */
     pte_offset = ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte);
     if (pte_offset == -1) {
+        dsisr = 0x40000000;
         if (rwx == 2) {
-            cs->exception_index = POWERPC_EXCP_ISI;
-            env->error_code = 0x40000000;
+            ppc_hash64_set_isi(cs, env, dsisr);
         } else {
-            cs->exception_index = POWERPC_EXCP_DSI;
-            env->error_code = 0;
-            env->spr[SPR_DAR] = eaddr;
             if (rwx == 1) {
-                env->spr[SPR_DSISR] = 0x42000000;
-            } else {
-                env->spr[SPR_DSISR] = 0x40000000;
+                dsisr |= 0x02000000;
             }
+            ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
         }
         return 1;
     }
@@ -705,14 +741,9 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
         /* Access right violation */
         qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
         if (rwx == 2) {
-            cs->exception_index = POWERPC_EXCP_ISI;
-            env->error_code = 0x08000000;
+            ppc_hash64_set_isi(cs, env, 0x08000000);
         } else {
-            target_ulong dsisr = 0;
-
-            cs->exception_index = POWERPC_EXCP_DSI;
-            env->error_code = 0;
-            env->spr[SPR_DAR] = eaddr;
+            dsisr = 0;
             if (need_prot[rwx] & ~pp_prot) {
                 dsisr |= 0x08000000;
             }
@@ -722,7 +753,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
             if (need_prot[rwx] & ~amr_prot) {
                 dsisr |= 0x00200000;
             }
-            env->spr[SPR_DSISR] = dsisr;
+            ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
         }
         return 1;
     }
-- 
2.1.4

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

* [Qemu-devel] [PATCH v2 06/10] ppc: Rework generation of priv and inval interrupts
  2016-06-21 21:48 [Qemu-devel] [PATCH v2 00/10] rework exception model to support the HV mode Cédric Le Goater
                   ` (4 preceding siblings ...)
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 05/10] ppc: Fix generation if ISI/DSI vs. HV mode Cédric Le Goater
@ 2016-06-21 21:48 ` Cédric Le Goater
  2016-06-22  6:51   ` David Gibson
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 07/10] ppc: Add real mode CI load/store instructions for P7 and P8 Cédric Le Goater
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Cédric Le Goater @ 2016-06-21 21:48 UTC (permalink / raw)
  To: qemu-ppc
  Cc: David Gibson, Alexander Graf, qemu-devel, Benjamin Herrenschmidt,
	Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Recent server processors use the Hypervisor Emulation Assistance
interrupt for illegal instructions and *some* type of SPR accesses.

Also the code was always generating inval instructions even for priv
violations due to setting the wrong flags

Finally, the checking for PR/HV was open coded everywhere.

This reworks it all, using little helper macros for checking, and
adding the HV interrupt (which gets converted back to program check
in the slow path of excp_helper.c on CPUs that don't want it).

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[clg: fixed checkpatch.pl errors ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 linux-user/main.c        |   1 +
 target-ppc/excp_helper.c |  19 ++
 target-ppc/translate.c   | 690 ++++++++++++++++++++---------------------------
 3 files changed, 311 insertions(+), 399 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index f8a8764ae97a..9e9b88b458c4 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1721,6 +1721,7 @@ void cpu_loop(CPUPPCState *env)
             queue_signal(env, info.si_signo, &info);
             break;
         case POWERPC_EXCP_PROGRAM:  /* Program exception                     */
+        case POWERPC_EXCP_HV_EMU:   /* HV emulation                          */
             /* XXX: check this */
             switch (env->error_code & ~0xF) {
             case POWERPC_EXCP_FP:
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 7c44c102db39..054c12de3bff 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -128,6 +128,19 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         ail = 0;
     }
 
+    /* Hypervisor emulation assistance interrupt only exists on server
+     * arch 2.05 server or later. We also don't want to generate it if
+     * we don't have HVB in msr_mask (PAPR mode).
+     */
+    if (excp == POWERPC_EXCP_HV_EMU
+#if defined(TARGET_PPC64)
+        && !((env->mmu_model & POWERPC_MMU_64) && (env->msr_mask & MSR_HVB))
+#endif /* defined(TARGET_PPC64) */
+
+    ) {
+        excp = POWERPC_EXCP_PROGRAM;
+    }
+
     switch (excp) {
     case POWERPC_EXCP_NONE:
         /* Should never happen */
@@ -249,6 +262,12 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             break;
         }
         goto store_current;
+    case POWERPC_EXCP_HV_EMU:
+        srr0 = SPR_HSRR0;
+        srr1 = SPR_HSRR1;
+        new_msr |= (target_ulong)MSR_HVB;
+        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
+        goto store_current;
     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
         goto store_current;
     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 81481955a589..4da92dae69fd 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -325,7 +325,19 @@ static inline void gen_debug_exception(DisasContext *ctx)
 
 static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
 {
-    gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error);
+    /* Will be converted to program check if needed */
+    gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_INVAL | error);
+}
+
+static inline void gen_priv_exception(DisasContext *ctx, uint32_t error)
+{
+    gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_PRIV | error);
+}
+
+static inline void gen_hvpriv_exception(DisasContext *ctx, uint32_t error)
+{
+    /* Will be converted to program check if needed */
+    gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_PRIV | error);
 }
 
 /* Stop translation */
@@ -366,6 +378,33 @@ typedef struct opcode_t {
     const char *oname;
 } opcode_t;
 
+/* Helpers for priv. check */
+#define GEN_PRIV                                                \
+    do {                                                        \
+        gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; \
+    } while (0)
+
+#if defined(CONFIG_USER_ONLY)
+#define CHK_HV GEN_PRIV
+#define CHK_SV GEN_PRIV
+#else
+#define CHK_HV                                                          \
+    do {                                                                \
+        if (unlikely(ctx->pr || !ctx->hv)) {                            \
+            GEN_PRIV;                                                   \
+        }                                                               \
+    } while (0)
+#define CHK_SV                   \
+    do {                         \
+        if (unlikely(ctx->pr)) { \
+            GEN_PRIV;            \
+        }                        \
+    } while (0)
+#endif
+
+#define CHK_NONE
+
+
 /*****************************************************************************/
 /***                           Instruction decoding                        ***/
 #define EXTRACT_HELPER(name, shift, nb)                                       \
@@ -2929,7 +2968,7 @@ static void gen_lq(DisasContext *ctx)
     bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
 
     if (!legal_in_user_mode && ctx->pr) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
         return;
     }
 
@@ -3055,7 +3094,7 @@ static void gen_std(DisasContext *ctx)
         }
 
         if (!legal_in_user_mode && ctx->pr) {
-            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
             return;
         }
 
@@ -4085,7 +4124,7 @@ static void gen_mcrf(DisasContext *ctx)
 static void gen_rfi(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     /* This instruction doesn't exist anymore on 64-bit server
      * processors compliant with arch 2.x
@@ -4096,10 +4135,7 @@ static void gen_rfi(DisasContext *ctx)
     }
 
     /* Restore CPU state */
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_update_cfar(ctx, ctx->nip);
     gen_helper_rfi(cpu_env);
     gen_sync_exception(ctx);
@@ -4110,13 +4146,10 @@ static void gen_rfi(DisasContext *ctx)
 static void gen_rfid(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     /* Restore CPU state */
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_update_cfar(ctx, ctx->nip);
     gen_helper_rfid(cpu_env);
     gen_sync_exception(ctx);
@@ -4126,13 +4159,10 @@ static void gen_rfid(DisasContext *ctx)
 static void gen_hrfid(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     /* Restore CPU state */
-    if (unlikely(ctx->pr || !ctx->hv)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_HV;
     gen_helper_hrfid(cpu_env);
     gen_sync_exception(ctx);
 #endif
@@ -4295,15 +4325,8 @@ static void gen_mfcr(DisasContext *ctx)
 /* mfmsr */
 static void gen_mfmsr(DisasContext *ctx)
 {
-#if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-#else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
-#endif
 }
 
 static void spr_noaccess(DisasContext *ctx, int gprn, int sprn)
@@ -4349,9 +4372,15 @@ static inline void gen_op_mfspr(DisasContext *ctx)
                              TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
                 }
             }
-            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
         }
     } else {
+        /* ISA 2.07 defines these as no-ops */
+        if ((ctx->insns_flags2 & PPC2_ISA207S) &&
+            (sprn >= 808 && sprn <= 811)) {
+            /* This is a nop */
+            return;
+        }
         /* Not defined */
         fprintf(stderr, "Trying to read invalid spr %d (0x%03x) at "
                 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
@@ -4359,9 +4388,18 @@ static inline void gen_op_mfspr(DisasContext *ctx)
             qemu_log("Trying to read invalid spr %d (0x%03x) at "
                      TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
         }
-        /* Only generate an exception in user space, otherwise this is a nop */
-        if (ctx->pr) {
-            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+
+        /* The behaviour depends on MSR:PR and SPR# bit 0x10,
+         * it can generate a priv, a hv emu or a no-op
+         */
+        if (sprn & 0x10) {
+            if (ctx->pr) {
+                gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+            }
+        } else {
+            if (ctx->pr || sprn == 0 || sprn == 4 || sprn == 5 || sprn == 6) {
+                gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+            }
         }
     }
 }
@@ -4409,13 +4447,9 @@ static void gen_mtcrf(DisasContext *ctx)
 #if defined(TARGET_PPC64)
 static void gen_mtmsrd(DisasContext *ctx)
 {
-#if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-#else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
+
+#if !defined(CONFIG_USER_ONLY)
     if (ctx->opcode & 0x00010000) {
         /* Special form that does not need any synchronisation */
         TCGv t0 = tcg_temp_new();
@@ -4434,20 +4468,16 @@ static void gen_mtmsrd(DisasContext *ctx)
         /* Note that mtmsr is not always defined as context-synchronizing */
         gen_stop_exception(ctx);
     }
-#endif
+#endif /* !defined(CONFIG_USER_ONLY) */
 }
-#endif
+#endif /* defined(TARGET_PPC64) */
 
 static void gen_mtmsr(DisasContext *ctx)
 {
-#if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-#else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
-    if (ctx->opcode & 0x00010000) {
+    CHK_SV;
+
+#if !defined(CONFIG_USER_ONLY)
+   if (ctx->opcode & 0x00010000) {
         /* Special form that does not need any synchronisation */
         TCGv t0 = tcg_temp_new();
         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
@@ -4504,9 +4534,16 @@ static void gen_mtspr(DisasContext *ctx)
                 qemu_log("Trying to write privileged spr %d (0x%03x) at "
                          TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
             }
-            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
         }
     } else {
+        /* ISA 2.07 defines these as no-ops */
+        if ((ctx->insns_flags2 & PPC2_ISA207S) &&
+            (sprn >= 808 && sprn <= 811)) {
+            /* This is a nop */
+            return;
+        }
+
         /* Not defined */
         if (qemu_log_separate()) {
             qemu_log("Trying to write invalid spr %d (0x%03x) at "
@@ -4515,9 +4552,18 @@ static void gen_mtspr(DisasContext *ctx)
         fprintf(stderr, "Trying to write invalid spr %d (0x%03x) at "
                 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
 
-        /* Only generate an exception in user space, otherwise this is a nop */
-        if (ctx->pr) {
-            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+
+        /* The behaviour depends on MSR:PR and SPR# bit 0x10,
+         * it can generate a priv, a hv emu or a no-op
+         */
+        if (sprn & 0x10) {
+            if (ctx->pr) {
+                gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+            }
+        } else {
+            if (ctx->pr || sprn == 0) {
+                gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+            }
         }
     }
 }
@@ -4540,13 +4586,11 @@ static void gen_dcbf(DisasContext *ctx)
 static void gen_dcbi(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv EA, val;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     EA = tcg_temp_new();
     gen_set_access_type(ctx, ACCESS_CACHE);
     gen_addr_reg_index(ctx, EA);
@@ -4556,7 +4600,7 @@ static void gen_dcbi(DisasContext *ctx)
     gen_qemu_st8(ctx, val, EA);
     tcg_temp_free(val);
     tcg_temp_free(EA);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* dcdst */
@@ -4677,72 +4721,64 @@ static void gen_dcba(DisasContext *ctx)
 static void gen_mfsr(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_const_tl(SR(ctx->opcode));
     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mfsrin */
 static void gen_mfsrin(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mtsr */
 static void gen_mtsr(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_const_tl(SR(ctx->opcode));
     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mtsrin */
 static void gen_mtsrin(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
+
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rD(ctx->opcode)]);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 #if defined(TARGET_PPC64)
@@ -4752,115 +4788,101 @@ static void gen_mtsrin(DisasContext *ctx)
 static void gen_mfsr_64b(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_const_tl(SR(ctx->opcode));
     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mfsrin */
 static void gen_mfsrin_64b(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mtsr */
 static void gen_mtsr_64b(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_const_tl(SR(ctx->opcode));
     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mtsrin */
 static void gen_mtsrin_64b(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* slbmte */
 static void gen_slbmte(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
+
     gen_helper_store_slb(cpu_env, cpu_gpr[rB(ctx->opcode)],
                          cpu_gpr[rS(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_slbmfee(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
+
     gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env,
                              cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_slbmfev(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
+
     gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
                              cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_slbfee_(DisasContext *ctx)
@@ -4896,40 +4918,34 @@ static void gen_slbfee_(DisasContext *ctx)
 static void gen_tlbia(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr || !ctx->hv)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_HV;
+
     gen_helper_tlbia(cpu_env);
-#endif
+#endif  /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbiel */
 static void gen_tlbiel(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
+
     gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbie */
 static void gen_tlbie(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr || !ctx->hv)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_HV;
+
     if (NARROW_MODE(ctx)) {
         TCGv t0 = tcg_temp_new();
         tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
@@ -4938,25 +4954,23 @@ static void gen_tlbie(DisasContext *ctx)
     } else {
         gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbsync */
 static void gen_tlbsync(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr || !ctx->hv)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_HV;
+
     /* tlbsync is a nop for server, ptesync handles delayed tlb flush,
      * embedded however needs to deal with tlbsync. We don't try to be
      * fancy and swallow the overhead of checking for both.
      */
     gen_check_tlb_flush(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 #if defined(TARGET_PPC64)
@@ -4964,30 +4978,26 @@ static void gen_tlbsync(DisasContext *ctx)
 static void gen_slbia(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
+
     gen_helper_slbia(cpu_env);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* slbie */
 static void gen_slbie(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
+
     gen_helper_slbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
-#endif
+#endif  /* defined(TARGET_PPC64) */
 
 /***                              External control                         ***/
 /* Optional: */
@@ -5686,14 +5696,11 @@ static void gen_esa(DisasContext *ctx)
 static void gen_mfrom(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* 602 - 603 - G2 TLB management */
@@ -5702,28 +5709,22 @@ static void gen_mfrom(DisasContext *ctx)
 static void gen_tlbld_6xx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_helper_6xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbli */
 static void gen_tlbli_6xx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_helper_6xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* 74xx TLB management */
@@ -5732,28 +5733,22 @@ static void gen_tlbli_6xx(DisasContext *ctx)
 static void gen_tlbld_74xx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_helper_74xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbli */
 static void gen_tlbli_74xx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_helper_74xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* POWER instructions not in PowerPC 601 */
@@ -5767,15 +5762,12 @@ static void gen_clf(DisasContext *ctx)
 /* cli */
 static void gen_cli(DisasContext *ctx)
 {
-    /* Cache line invalidate: privileged and treated as no-op */
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
-#endif
+    /* Cache line invalidate: privileged and treated as no-op */
+    CHK_SV;
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* dclst */
@@ -5787,15 +5779,13 @@ static void gen_dclst(DisasContext *ctx)
 static void gen_mfsri(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     int ra = rA(ctx->opcode);
     int rd = rD(ctx->opcode);
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
     tcg_gen_shri_tl(t0, t0, 28);
@@ -5804,38 +5794,34 @@ static void gen_mfsri(DisasContext *ctx)
     tcg_temp_free(t0);
     if (ra != 0 && ra != rd)
         tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_rac(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
     gen_helper_rac(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_rfsvc(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
+
     gen_helper_rfsvc(cpu_env);
     gen_sync_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* svc is not implemented for now */
@@ -5988,18 +5974,16 @@ static void gen_mfapidi(DisasContext *ctx)
 static void gen_tlbiva(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
     gen_helper_tlbiva(cpu_env, cpu_gpr[rB(ctx->opcode)]);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* All 405 MAC instructions are translated here */
@@ -6221,38 +6205,34 @@ GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
 static void gen_mfdcr(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv dcrn;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
     dcrn = tcg_const_tl(SPR(ctx->opcode));
     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn);
     tcg_temp_free(dcrn);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mtdcr */
 static void gen_mtdcr(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv dcrn;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
     dcrn = tcg_const_tl(SPR(ctx->opcode));
     gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(dcrn);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mfdcrx */
@@ -6260,18 +6240,15 @@ static void gen_mtdcr(DisasContext *ctx)
 static void gen_mfdcrx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
                         cpu_gpr[rA(ctx->opcode)]);
     /* Note: Rc update flag set leads to undefined state of Rc0 */
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mtdcrx */
@@ -6279,18 +6256,15 @@ static void gen_mfdcrx(DisasContext *ctx)
 static void gen_mtdcrx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
     gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
                          cpu_gpr[rS(ctx->opcode)]);
     /* Note: Rc update flag set leads to undefined state of Rc0 */
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mfdcrux (PPC 460) : user-mode access to DCR */
@@ -6316,28 +6290,19 @@ static void gen_mtdcrux(DisasContext *ctx)
 /* dccci */
 static void gen_dccci(DisasContext *ctx)
 {
-#if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-#else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     /* interpreted as no-op */
-#endif
 }
 
 /* dcread */
 static void gen_dcread(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv EA, val;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     gen_set_access_type(ctx, ACCESS_CACHE);
     EA = tcg_temp_new();
     gen_addr_reg_index(ctx, EA);
@@ -6346,7 +6311,7 @@ static void gen_dcread(DisasContext *ctx)
     tcg_temp_free(val);
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
     tcg_temp_free(EA);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* icbt */
@@ -6361,60 +6326,40 @@ static void gen_icbt_40x(DisasContext *ctx)
 /* iccci */
 static void gen_iccci(DisasContext *ctx)
 {
-#if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-#else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     /* interpreted as no-op */
-#endif
 }
 
 /* icread */
 static void gen_icread(DisasContext *ctx)
 {
-#if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-#else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     /* interpreted as no-op */
-#endif
 }
 
 /* rfci (supervisor only) */
 static void gen_rfci_40x(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     /* Restore CPU state */
     gen_helper_40x_rfci(cpu_env);
     gen_sync_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_rfci(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     /* Restore CPU state */
     gen_helper_rfci(cpu_env);
     gen_sync_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* BookE specific */
@@ -6423,32 +6368,26 @@ static void gen_rfci(DisasContext *ctx)
 static void gen_rfdi(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     /* Restore CPU state */
     gen_helper_rfdi(cpu_env);
     gen_sync_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* XXX: not implemented on 440 ? */
 static void gen_rfmci(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     /* Restore CPU state */
     gen_helper_rfmci(cpu_env);
     gen_sync_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* TLB management - PowerPC 405 implementation */
@@ -6457,12 +6396,9 @@ static void gen_rfmci(DisasContext *ctx)
 static void gen_tlbre_40x(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     switch (rB(ctx->opcode)) {
     case 0:
         gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_env,
@@ -6476,20 +6412,18 @@ static void gen_tlbre_40x(DisasContext *ctx)
         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
         break;
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbsx - tlbsx. */
 static void gen_tlbsx_40x(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
     gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
@@ -6501,19 +6435,17 @@ static void gen_tlbsx_40x(DisasContext *ctx)
         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
         gen_set_label(l1);
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbwe */
 static void gen_tlbwe_40x(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
+
     switch (rB(ctx->opcode)) {
     case 0:
         gen_helper_4xx_tlbwe_hi(cpu_env, cpu_gpr[rA(ctx->opcode)],
@@ -6527,7 +6459,7 @@ static void gen_tlbwe_40x(DisasContext *ctx)
         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
         break;
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* TLB management - PowerPC 440 implementation */
@@ -6536,12 +6468,10 @@ static void gen_tlbwe_40x(DisasContext *ctx)
 static void gen_tlbre_440(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
+
     switch (rB(ctx->opcode)) {
     case 0:
     case 1:
@@ -6557,20 +6487,18 @@ static void gen_tlbre_440(DisasContext *ctx)
         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
         break;
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbsx - tlbsx. */
 static void gen_tlbsx_440(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
     gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
@@ -6582,19 +6510,16 @@ static void gen_tlbsx_440(DisasContext *ctx)
         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
         gen_set_label(l1);
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbwe */
 static void gen_tlbwe_440(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     switch (rB(ctx->opcode)) {
     case 0:
     case 1:
@@ -6610,7 +6535,7 @@ static void gen_tlbwe_440(DisasContext *ctx)
         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
         break;
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* TLB management - PowerPC BookE 2.06 implementation */
@@ -6618,30 +6543,23 @@ static void gen_tlbwe_440(DisasContext *ctx)
 /* tlbre */
 static void gen_tlbre_booke206(DisasContext *ctx)
 {
-#if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ #if defined(CONFIG_USER_ONLY)
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
-
+   CHK_SV;
     gen_helper_booke206_tlbre(cpu_env);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbsx - tlbsx. */
 static void gen_tlbsx_booke206(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
 
+    CHK_SV;
     if (rA(ctx->opcode)) {
         t0 = tcg_temp_new();
         tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]);
@@ -6652,54 +6570,44 @@ static void gen_tlbsx_booke206(DisasContext *ctx)
     tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
     gen_helper_booke206_tlbsx(cpu_env, t0);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbwe */
 static void gen_tlbwe_booke206(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_update_nip(ctx, ctx->nip - 4);
     gen_helper_booke206_tlbwe(cpu_env);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_tlbivax_booke206(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
 
+    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
-
     gen_helper_booke206_tlbivax(cpu_env, t0);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_tlbilx_booke206(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
 
+    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
 
@@ -6719,7 +6627,7 @@ static void gen_tlbilx_booke206(DisasContext *ctx)
     }
 
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 
@@ -6727,13 +6635,11 @@ static void gen_tlbilx_booke206(DisasContext *ctx)
 static void gen_wrtee(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
     tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
@@ -6743,19 +6649,16 @@ static void gen_wrtee(DisasContext *ctx)
      * if we just set msr_ee to 1
      */
     gen_stop_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* wrteei */
 static void gen_wrteei(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     if (ctx->opcode & 0x00008000) {
         tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
         /* Stop translation to have a chance to raise an exception */
@@ -6763,7 +6666,7 @@ static void gen_wrteei(DisasContext *ctx)
     } else {
         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* PowerPC 440 specific instructions */
@@ -6803,29 +6706,21 @@ static void gen_icbt_440(DisasContext *ctx)
 static void gen_msgclr(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
-
+    CHK_SV;
     gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_msgsnd(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
-
+    CHK_SV;
     gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /***                      Altivec vector extension                         ***/
@@ -9827,7 +9722,7 @@ static void gen_tcheck(DisasContext *ctx)
 #define GEN_TM_PRIV_NOOP(name)                                 \
 static inline void gen_##name(DisasContext *ctx)               \
 {                                                              \
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);           \
+    gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);           \
 }
 
 #else
@@ -9835,10 +9730,7 @@ static inline void gen_##name(DisasContext *ctx)               \
 #define GEN_TM_PRIV_NOOP(name)                                 \
 static inline void gen_##name(DisasContext *ctx)               \
 {                                                              \
-    if (unlikely(ctx->pr)) {                                   \
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);       \
-        return;                                                \
-    }                                                          \
+    CHK_SV;                                                    \
     if (unlikely(!ctx->tm_enabled)) {                          \
         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);   \
         return;                                                \
-- 
2.1.4

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

* [Qemu-devel] [PATCH v2 07/10] ppc: Add real mode CI load/store instructions for P7 and P8
  2016-06-21 21:48 [Qemu-devel] [PATCH v2 00/10] rework exception model to support the HV mode Cédric Le Goater
                   ` (5 preceding siblings ...)
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 06/10] ppc: Rework generation of priv and inval interrupts Cédric Le Goater
@ 2016-06-21 21:48 ` Cédric Le Goater
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 08/10] ppc: Turn a bunch of booleans from int to bool Cédric Le Goater
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 30+ messages in thread
From: Cédric Le Goater @ 2016-06-21 21:48 UTC (permalink / raw)
  To: qemu-ppc
  Cc: David Gibson, Alexander Graf, qemu-devel, Benjamin Herrenschmidt,
	Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Those instructions are only available in hypervisor real mode and
allow cache inhibited garded access to devices in that mode.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[clg: fixed checkpatch.pl errors ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 target-ppc/cpu.h            |  4 ++-
 target-ppc/translate.c      | 59 ++++++++++++++++++++++++++++++++++++---------
 target-ppc/translate_init.c |  6 +++--
 3 files changed, 55 insertions(+), 14 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index f005549c352e..61a24b19ffce 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1912,6 +1912,8 @@ enum {
     PPC_POPCNTB        = 0x0000000000001000ULL,
     /*   string load / store                                                 */
     PPC_STRING         = 0x0000000000002000ULL,
+    /*   real mode cache inhibited load / store                              */
+    PPC_CILDST         = 0x0000000000004000ULL,
 
     /* Floating-point unit extensions                                        */
     /*   Optional floating point instructions                                */
@@ -2026,7 +2028,7 @@ enum {
                         | PPC_MFAPIDI | PPC_TLBIVA | PPC_TLBIVAX \
                         | PPC_4xx_COMMON | PPC_40x_ICBT | PPC_RFMCI \
                         | PPC_RFDI | PPC_DCR | PPC_DCRX | PPC_DCRUX \
-                        | PPC_POPCNTWD)
+                        | PPC_POPCNTWD | PPC_CILDST)
 
     /* extended type values */
 
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 4da92dae69fd..ca7036b22678 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -192,7 +192,7 @@ struct DisasContext {
     uint32_t opcode;
     uint32_t exception;
     /* Routine used to access memory */
-    bool pr, hv;
+    bool pr, hv, dr;
     bool lazy_tlb_flush;
     int mem_idx;
     int access_type;
@@ -387,6 +387,7 @@ typedef struct opcode_t {
 #if defined(CONFIG_USER_ONLY)
 #define CHK_HV GEN_PRIV
 #define CHK_SV GEN_PRIV
+#define CHK_HVRM GEN_PRIV
 #else
 #define CHK_HV                                                          \
     do {                                                                \
@@ -400,6 +401,12 @@ typedef struct opcode_t {
             GEN_PRIV;            \
         }                        \
     } while (0)
+#define CHK_HVRM                                            \
+    do {                                                    \
+        if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) {     \
+            GEN_PRIV;                                       \
+        }                                                   \
+    } while (0)
 #endif
 
 #define CHK_NONE
@@ -2895,18 +2902,23 @@ static void glue(gen_, name##ux)(DisasContext *ctx)
     tcg_temp_free(EA);                                                        \
 }
 
-#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2)                        \
+#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk)                   \
 static void glue(gen_, name##x)(DisasContext *ctx)                            \
 {                                                                             \
     TCGv EA;                                                                  \
+    chk;                                                                      \
     gen_set_access_type(ctx, ACCESS_INT);                                     \
     EA = tcg_temp_new();                                                      \
     gen_addr_reg_index(ctx, EA);                                              \
     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
     tcg_temp_free(EA);                                                        \
 }
+
 #define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
-    GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE)
+    GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_NONE)
+
+#define GEN_LDX_HVRM(name, ldop, opc2, opc3, type)                            \
+    GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
 
 #define GEN_LDS(name, ldop, op, type)                                         \
 GEN_LD(name, ldop, op | 0x20, type);                                          \
@@ -2932,6 +2944,12 @@ GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B);
 /* ldx */
 GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B);
 
+/* CI load/store variants */
+GEN_LDX_HVRM(ldcix, ld64, 0x15, 0x1b, PPC_CILDST)
+GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x15, PPC_CILDST)
+GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
+GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
+
 static void gen_ld(DisasContext *ctx)
 {
     TCGv EA;
@@ -3050,10 +3068,11 @@ static void glue(gen_, name##ux)(DisasContext *ctx)
     tcg_temp_free(EA);                                                        \
 }
 
-#define GEN_STX_E(name, stop, opc2, opc3, type, type2)                        \
+#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk)                   \
 static void glue(gen_, name##x)(DisasContext *ctx)                            \
 {                                                                             \
     TCGv EA;                                                                  \
+    chk;                                                                      \
     gen_set_access_type(ctx, ACCESS_INT);                                     \
     EA = tcg_temp_new();                                                      \
     gen_addr_reg_index(ctx, EA);                                              \
@@ -3061,7 +3080,10 @@ static void glue(gen_, name##x)(DisasContext *ctx)                            \
     tcg_temp_free(EA);                                                        \
 }
 #define GEN_STX(name, stop, opc2, opc3, type)                                 \
-    GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE)
+    GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_NONE)
+
+#define GEN_STX_HVRM(name, stop, opc2, opc3, type)                            \
+    GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
 
 #define GEN_STS(name, stop, op, type)                                         \
 GEN_ST(name, stop, op | 0x20, type);                                          \
@@ -3078,6 +3100,10 @@ GEN_STS(stw, st32, 0x04, PPC_INTEGER);
 #if defined(TARGET_PPC64)
 GEN_STUX(std, st64, 0x15, 0x05, PPC_64B);
 GEN_STX(std, st64, 0x15, 0x04, PPC_64B);
+GEN_STX_HVRM(stdcix, st64, 0x15, 0x1f, PPC_CILDST)
+GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
+GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
+GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
 
 static void gen_std(DisasContext *ctx)
 {
@@ -3166,7 +3192,7 @@ static inline void gen_qemu_ld64ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
     TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
     tcg_gen_qemu_ld_i64(arg1, arg2, ctx->mem_idx, op);
 }
-GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX);
+GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE);
 #endif  /* TARGET_PPC64 */
 
 /* sthbrx */
@@ -3192,7 +3218,7 @@ static inline void gen_qemu_st64r(DisasContext *ctx, TCGv arg1, TCGv arg2)
     TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
     tcg_gen_qemu_st_i64(arg1, arg2, ctx->mem_idx, op);
 }
-GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX);
+GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE);
 #endif  /* TARGET_PPC64 */
 
 /***                    Integer load and store multiple                    ***/
@@ -10210,7 +10236,7 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
 #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
-#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2)                        \
+#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk)                   \
 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
 #define GEN_LDS(name, ldop, op, type)                                         \
 GEN_LD(name, ldop, op | 0x20, type)                                           \
@@ -10227,7 +10253,13 @@ GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
 GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
 GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
 GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
-GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX)
+GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE)
+
+/* HV/P7 and later only */
+GEN_LDX_HVRM(ldcix, ld64, 0x15, 0x1b, PPC_CILDST)
+GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x18, PPC_CILDST)
+GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
+GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
 #endif
 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
@@ -10243,7 +10275,7 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
 GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
 #define GEN_STUX(name, stop, opc2, opc3, type)                                \
 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
-#define GEN_STX_E(name, stop, opc2, opc3, type, type2)                        \
+#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk)                   \
 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
 #define GEN_STS(name, stop, op, type)                                         \
 GEN_ST(name, stop, op | 0x20, type)                                           \
@@ -10257,7 +10289,11 @@ GEN_STS(stw, st32, 0x04, PPC_INTEGER)
 #if defined(TARGET_PPC64)
 GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
 GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
-GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX)
+GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE)
+GEN_STX_HVRM(stdcix, st64, 0x15, 0x1f, PPC_CILDST)
+GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
+GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
+GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
 #endif
 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
@@ -11425,6 +11461,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
     ctx.spr_cb = env->spr_cb;
     ctx.pr = msr_pr;
     ctx.mem_idx = env->dmmu_idx;
+    ctx.dr = msr_dr;
 #if !defined(CONFIG_USER_ONLY)
     ctx.hv = msr_hv || !env->has_hv_mode;
 #endif
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 3b4234b325d1..6f2f760728bb 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8395,7 +8395,8 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
                        PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
                        PPC_SEGMENT_64B | PPC_SLBI |
-                       PPC_POPCNTB | PPC_POPCNTWD;
+                       PPC_POPCNTB | PPC_POPCNTWD |
+                       PPC_CILDST;
     pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
                         PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
@@ -8476,7 +8477,8 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
                        PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
                        PPC_SEGMENT_64B | PPC_SLBI |
-                       PPC_POPCNTB | PPC_POPCNTWD;
+                       PPC_POPCNTB | PPC_POPCNTWD |
+                       PPC_CILDST;
     pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
                         PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
-- 
2.1.4

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

* [Qemu-devel] [PATCH v2 08/10] ppc: Turn a bunch of booleans from int to bool
  2016-06-21 21:48 [Qemu-devel] [PATCH v2 00/10] rework exception model to support the HV mode Cédric Le Goater
                   ` (6 preceding siblings ...)
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 07/10] ppc: Add real mode CI load/store instructions for P7 and P8 Cédric Le Goater
@ 2016-06-21 21:48 ` Cédric Le Goater
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 09/10] ppc: Move exception generation code out of line Cédric Le Goater
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 10/10] ppc: Add P7/P8 Power Management instructions Cédric Le Goater
  9 siblings, 0 replies; 30+ messages in thread
From: Cédric Le Goater @ 2016-06-21 21:48 UTC (permalink / raw)
  To: qemu-ppc
  Cc: David Gibson, Alexander Graf, qemu-devel, Benjamin Herrenschmidt,
	Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 target-ppc/translate.c | 37 ++++++++++++++++++-------------------
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index ca7036b22678..83ec2dd7707b 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -192,22 +192,21 @@ struct DisasContext {
     uint32_t opcode;
     uint32_t exception;
     /* Routine used to access memory */
-    bool pr, hv, dr;
+    bool pr, hv, dr, le_mode;
     bool lazy_tlb_flush;
     int mem_idx;
     int access_type;
     /* Translation flags */
-    int le_mode;
     TCGMemOp default_tcg_memop_mask;
 #if defined(TARGET_PPC64)
-    int sf_mode;
-    int has_cfar;
+    bool sf_mode;
+    bool has_cfar;
 #endif
-    int fpu_enabled;
-    int altivec_enabled;
-    int vsx_enabled;
-    int spe_enabled;
-    int tm_enabled;
+    bool fpu_enabled;
+    bool altivec_enabled;
+    bool vsx_enabled;
+    bool spe_enabled;
+    bool tm_enabled;
     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
     int singlestep_enabled;
     uint64_t insns_flags;
@@ -11468,7 +11467,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
     ctx.insns_flags = env->insns_flags;
     ctx.insns_flags2 = env->insns_flags2;
     ctx.access_type = -1;
-    ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
+    ctx.le_mode = !!(env->hflags & (1 << MSR_LE));
     ctx.default_tcg_memop_mask = ctx.le_mode ? MO_LE : MO_BE;
 #if defined(TARGET_PPC64)
     ctx.sf_mode = msr_is_64bit(env, env->msr);
@@ -11479,25 +11478,25 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
         (env->mmu_model & POWERPC_MMU_64B))
             ctx.lazy_tlb_flush = true;
 
-    ctx.fpu_enabled = msr_fp;
+    ctx.fpu_enabled = !!msr_fp;
     if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
-        ctx.spe_enabled = msr_spe;
+        ctx.spe_enabled = !!msr_spe;
     else
-        ctx.spe_enabled = 0;
+        ctx.spe_enabled = false;
     if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
-        ctx.altivec_enabled = msr_vr;
+        ctx.altivec_enabled = !!msr_vr;
     else
-        ctx.altivec_enabled = 0;
+        ctx.altivec_enabled = false;
     if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) {
-        ctx.vsx_enabled = msr_vsx;
+        ctx.vsx_enabled = !!msr_vsx;
     } else {
-        ctx.vsx_enabled = 0;
+        ctx.vsx_enabled = false;
     }
 #if defined(TARGET_PPC64)
     if ((env->flags & POWERPC_FLAG_TM) && msr_tm) {
-        ctx.tm_enabled = msr_tm;
+        ctx.tm_enabled = !!msr_tm;
     } else {
-        ctx.tm_enabled = 0;
+        ctx.tm_enabled = false;
     }
 #endif
     if ((env->flags & POWERPC_FLAG_SE) && msr_se)
-- 
2.1.4

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

* [Qemu-devel] [PATCH v2 09/10] ppc: Move exception generation code out of line
  2016-06-21 21:48 [Qemu-devel] [PATCH v2 00/10] rework exception model to support the HV mode Cédric Le Goater
                   ` (7 preceding siblings ...)
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 08/10] ppc: Turn a bunch of booleans from int to bool Cédric Le Goater
@ 2016-06-21 21:48 ` Cédric Le Goater
  2016-06-22  6:57   ` David Gibson
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 10/10] ppc: Add P7/P8 Power Management instructions Cédric Le Goater
  9 siblings, 1 reply; 30+ messages in thread
From: Cédric Le Goater @ 2016-06-21 21:48 UTC (permalink / raw)
  To: qemu-ppc
  Cc: David Gibson, Alexander Graf, qemu-devel, Benjamin Herrenschmidt,
	Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

There's no point inlining this, if you hit the exception case you exit
anyway, and not inlining saves about 100K of code size (and cache
footprint).

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[clg: removed '__attribute__((noinline))' from original patch ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 target-ppc/translate.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 83ec2dd7707b..365fe3d34461 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -283,7 +283,7 @@ void gen_update_current_nip(void *opaque)
     tcg_gen_movi_tl(cpu_nip, ctx->nip);
 }
 
-static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
+static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
 {
     TCGv_i32 t0, t1;
     if (ctx->exception == POWERPC_EXCP_NONE) {
@@ -297,7 +297,7 @@ static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t
     ctx->exception = (excp);
 }
 
-static inline void gen_exception(DisasContext *ctx, uint32_t excp)
+static void gen_exception(DisasContext *ctx, uint32_t excp)
 {
     TCGv_i32 t0;
     if (ctx->exception == POWERPC_EXCP_NONE) {
@@ -309,7 +309,7 @@ static inline void gen_exception(DisasContext *ctx, uint32_t excp)
     ctx->exception = (excp);
 }
 
-static inline void gen_debug_exception(DisasContext *ctx)
+static void gen_debug_exception(DisasContext *ctx)
 {
     TCGv_i32 t0;
 
-- 
2.1.4

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

* [Qemu-devel] [PATCH v2 10/10] ppc: Add P7/P8 Power Management instructions
  2016-06-21 21:48 [Qemu-devel] [PATCH v2 00/10] rework exception model to support the HV mode Cédric Le Goater
                   ` (8 preceding siblings ...)
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 09/10] ppc: Move exception generation code out of line Cédric Le Goater
@ 2016-06-21 21:48 ` Cédric Le Goater
  9 siblings, 0 replies; 30+ messages in thread
From: Cédric Le Goater @ 2016-06-21 21:48 UTC (permalink / raw)
  To: qemu-ppc
  Cc: David Gibson, Alexander Graf, qemu-devel, Benjamin Herrenschmidt,
	Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

This adds the ISA 2.06 and later power management instructions
(doze, nap, sleep and rvwinkle) and associated wakeup cause testing
in LPCR

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[clg: fixed checkpatch.pl errors ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 target-ppc/cpu-qom.h        |  9 +++++
 target-ppc/cpu.h            | 17 ++++++++-
 target-ppc/excp_helper.c    | 59 +++++++++++++++++++++++++++++
 target-ppc/helper.h         |  1 +
 target-ppc/translate.c      | 66 ++++++++++++++++++++++++++++++++
 target-ppc/translate_init.c | 92 ++++++++++++++++++++++++++++++++++++++++++++-
 6 files changed, 241 insertions(+), 3 deletions(-)

diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index 969ecdfbd40a..0fad2def0a94 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -126,6 +126,15 @@ enum powerpc_excp_t {
 };
 
 /*****************************************************************************/
+/* PM instructions */
+typedef enum {
+    PPC_PM_DOZE,
+    PPC_PM_NAP,
+    PPC_PM_SLEEP,
+    PPC_PM_RVWINKLE,
+} powerpc_pm_insn_t;
+
+/*****************************************************************************/
 /* Input pins model                                                          */
 typedef enum powerpc_input_t powerpc_input_t;
 enum powerpc_input_t {
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 61a24b19ffce..b1354a4791db 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -383,6 +383,14 @@ struct ppc_slb_t {
 #define LPCR_LPES1        (1ull << (63 - 61))
 #define LPCR_AIL_SHIFT    (63 - 40)      /* Alternate interrupt location */
 #define LPCR_AIL          (3ull << LPCR_AIL_SHIFT)
+#define LPCR_P7_PECE0     (1ull << (63 - 49))
+#define LPCR_P7_PECE1     (1ull << (63 - 50))
+#define LPCR_P7_PECE2     (1ull << (63 - 51))
+#define LPCR_P8_PECE0     (1ull << (63 - 47))
+#define LPCR_P8_PECE1     (1ull << (63 - 48))
+#define LPCR_P8_PECE2     (1ull << (63 - 49))
+#define LPCR_P8_PECE3     (1ull << (63 - 50))
+#define LPCR_P8_PECE4     (1ull << (63 - 51))
 
 #define msr_sf   ((env->msr >> MSR_SF)   & 1)
 #define msr_isf  ((env->msr >> MSR_ISF)  & 1)
@@ -1059,6 +1067,11 @@ struct CPUPPCState {
      * instructions and SPRs are diallowed if MSR:HV is 0
      */
     bool has_hv_mode;
+    /* On P7/P8, set when in PM state, we need to handle resume
+     * in a special way (such as routing some resume causes to
+     * 0x100), so flag this here.
+     */
+    bool in_pm_state;
 #endif
 
     /* Those resources are used only during code translation */
@@ -2068,6 +2081,8 @@ enum {
     PPC2_FP_CVT_S64    = 0x0000000000010000ULL,
     /* Transactional Memory (ISA 2.07, Book II)                              */
     PPC2_TM            = 0x0000000000020000ULL,
+    /* Server PM instructgions (ISA 2.06, Book III)                          */
+    PPC2_PM_ISA206     = 0x0000000000040000ULL,
 
 #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
                         PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
@@ -2075,7 +2090,7 @@ enum {
                         PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | \
                         PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | \
                         PPC2_ALTIVEC_207 | PPC2_ISA207S | PPC2_DFP | \
-                        PPC2_FP_CVT_S64 | PPC2_TM)
+                        PPC2_FP_CVT_S64 | PPC2_TM | PPC2_PM_ISA206)
 };
 
 /*****************************************************************************/
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 054c12de3bff..533866b87b60 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -101,6 +101,44 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     asrr0 = -1;
     asrr1 = -1;
 
+    /* check for special resume at 0x100 from doze/nap/sleep/winkle on P7/P8 */
+    if (env->in_pm_state) {
+        env->in_pm_state = false;
+
+        /* Pretend to be returning from doze always as we don't lose state */
+        msr |= (0x1ull << (63 - 47));
+
+        /* Non-machine check are routed to 0x100 with a wakeup cause
+         * encoded in SRR1
+         */
+        if (excp != POWERPC_EXCP_MCHECK) {
+            switch (excp) {
+            case POWERPC_EXCP_RESET:
+                msr |= 0x4ull << (63 - 45);
+                break;
+            case POWERPC_EXCP_EXTERNAL:
+                msr |= 0x8ull << (63 - 45);
+                break;
+            case POWERPC_EXCP_DECR:
+                msr |= 0x6ull << (63 - 45);
+                break;
+            case POWERPC_EXCP_SDOOR:
+                msr |= 0x5ull << (63 - 45);
+                break;
+            case POWERPC_EXCP_SDOOR_HV:
+                msr |= 0x3ull << (63 - 45);
+                break;
+            case POWERPC_EXCP_HV_MAINT:
+                msr |= 0xaull << (63 - 45);
+                break;
+            default:
+                cpu_abort(cs, "Unsupported exception %d in Power Save mode\n",
+                          excp);
+            }
+            excp = POWERPC_EXCP_RESET;
+        }
+    }
+
     /* Exception targetting modifiers
      *
      * LPES0 is supported on POWER7/8
@@ -897,6 +935,27 @@ void helper_store_msr(CPUPPCState *env, target_ulong val)
     }
 }
 
+#if defined(TARGET_PPC64)
+void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn)
+{
+    CPUState *cs;
+
+    cs = CPU(ppc_env_get_cpu(env));
+    cs->halted = 1;
+    env->in_pm_state = true;
+
+    /* Technically, nap doesn't set EE, but if we don't set it
+     * then ppc_hw_interrupt() won't deliver. We could add some
+     * other tests there based on LPCR but it's simpler to just
+     * whack EE in. It will be cleared by the 0x100 at wakeup
+     * anyway. It will still be observable by the guest in SRR1
+     * but this doesn't seem to be a problem.
+     */
+    env->msr |= (1ull << MSR_EE);
+    helper_raise_exception(env, EXCP_HLT);
+}
+#endif /* defined(TARGET_PPC64) */
+
 static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
 {
     CPUState *cs = CPU(ppc_env_get_cpu(env));
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index f4410a836954..ab9592926f7b 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -13,6 +13,7 @@ DEF_HELPER_1(rfci, void, env)
 DEF_HELPER_1(rfdi, void, env)
 DEF_HELPER_1(rfmci, void, env)
 #if defined(TARGET_PPC64)
+DEF_HELPER_2(pminsn, void, env, i32)
 DEF_HELPER_1(rfid, void, env)
 DEF_HELPER_1(hrfid, void, env)
 #endif
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 365fe3d34461..b94f0dff0307 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3571,6 +3571,68 @@ static void gen_wait(DisasContext *ctx)
     gen_exception_err(ctx, EXCP_HLT, 1);
 }
 
+#if defined(TARGET_PPC64)
+static void gen_doze(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+    GEN_PRIV;
+#else
+    TCGv_i32 t;
+
+    CHK_HV;
+    t = tcg_const_i32(PPC_PM_DOZE);
+    gen_helper_pminsn(cpu_env, t);
+    tcg_temp_free_i32(t);
+    gen_stop_exception(ctx);
+#endif /* defined(CONFIG_USER_ONLY) */
+}
+
+static void gen_nap(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+    GEN_PRIV;
+#else
+    TCGv_i32 t;
+
+    CHK_HV;
+    t = tcg_const_i32(PPC_PM_NAP);
+    gen_helper_pminsn(cpu_env, t);
+    tcg_temp_free_i32(t);
+    gen_stop_exception(ctx);
+#endif /* defined(CONFIG_USER_ONLY) */
+}
+
+static void gen_sleep(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+    GEN_PRIV;
+#else
+    TCGv_i32 t;
+
+    CHK_HV;
+    t = tcg_const_i32(PPC_PM_SLEEP);
+    gen_helper_pminsn(cpu_env, t);
+    tcg_temp_free_i32(t);
+    gen_stop_exception(ctx);
+#endif /* defined(CONFIG_USER_ONLY) */
+}
+
+static void gen_rvwinkle(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+    GEN_PRIV;
+#else
+    TCGv_i32 t;
+
+    CHK_HV;
+    t = tcg_const_i32(PPC_PM_RVWINKLE);
+    gen_helper_pminsn(cpu_env, t);
+    tcg_temp_free_i32(t);
+    gen_stop_exception(ctx);
+#endif /* defined(CONFIG_USER_ONLY) */
+}
+#endif /* #if defined(TARGET_PPC64) */
+
 /***                         Floating-point load                           ***/
 #define GEN_LDF(name, ldop, opc, type)                                        \
 static void glue(gen_, name)(DisasContext *ctx)                                       \
@@ -9883,6 +9945,10 @@ GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
 #if defined(TARGET_PPC64)
 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
+GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
+GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
+GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
+GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
 GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
 #endif
 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 6f2f760728bb..0b39a088458d 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8371,10 +8371,45 @@ static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr)
     return false;
 }
 
+static bool cpu_has_work_POWER7(CPUState *cs)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    if (cs->halted) {
+        if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
+            return false;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
+            (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
+            (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
+            (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
+            (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
+            return true;
+        }
+        if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
+            return true;
+        }
+        return false;
+    } else {
+        return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
+    }
+}
+
 POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
     PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(oc);
 
     dc->fw_name = "PowerPC,POWER7";
     dc->desc = "POWER7";
@@ -8384,6 +8419,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
     pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
     pcc->init_proc = init_proc_POWER7;
     pcc->check_pow = check_pow_nocheck;
+    cc->has_work = cpu_has_work_POWER7;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -8400,7 +8436,8 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
     pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
                         PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
-                        PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64;
+                        PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 |
+                        PPC2_PM_ISA206;
     pcc->msr_mask = (1ull << MSR_SF) |
                     (1ull << MSR_VR) |
                     (1ull << MSR_VSX) |
@@ -8453,10 +8490,53 @@ static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr)
     return false;
 }
 
+static bool cpu_has_work_POWER8(CPUState *cs)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    if (cs->halted) {
+        if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
+            return false;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
+            (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
+            (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
+            (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
+            (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
+            (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
+            (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
+            return true;
+        }
+        if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
+            return true;
+        }
+        return false;
+    } else {
+        return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
+    }
+}
+
 POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
     PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(oc);
 
     dc->fw_name = "PowerPC,POWER8";
     dc->desc = "POWER8";
@@ -8466,6 +8546,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
     pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
     pcc->init_proc = init_proc_POWER8;
     pcc->check_pow = check_pow_nocheck;
+    cc->has_work = cpu_has_work_POWER8;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -8485,7 +8566,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                         PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
                         PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
                         PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
-                        PPC2_TM;
+                        PPC2_TM | PPC2_PM_ISA206;
     pcc->msr_mask = (1ull << MSR_SF) |
                     (1ull << MSR_SHV) |
                     (1ull << MSR_TM) |
@@ -8544,6 +8625,13 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu)
     lpcr->default_value &= ~(LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV);
     lpcr->default_value |= LPCR_LPES0 | LPCR_LPES1;
 
+    /* P7 and P8 has slightly different PECE bits, mostly because P8 adds
+     * bit 47 and 48 which are reserved on P7. Here we set them all, which
+     * will work as expected for both implementations
+     */
+    lpcr->default_value |= LPCR_P8_PECE0 | LPCR_P8_PECE1 | LPCR_P8_PECE2 |
+                           LPCR_P8_PECE3 | LPCR_P8_PECE4;
+
     /* We should be followed by a CPU reset but update the active value
      * just in case...
      */
-- 
2.1.4

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

* Re: [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation Cédric Le Goater
@ 2016-06-22  2:46   ` David Gibson
  2016-06-22  6:48     ` Cédric Le Goater
  0 siblings, 1 reply; 30+ messages in thread
From: David Gibson @ 2016-06-22  2:46 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: qemu-ppc, Alexander Graf, qemu-devel, Benjamin Herrenschmidt

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

On Tue, Jun 21, 2016 at 11:48:46PM +0200, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> 
> This reworks emulation of the various "rfi" variants. I removed
> some masking bits that I couldn't make sense of, the only bit that
> I am aware we should mask here is POW, the CPU's MSR mask should
> take care of the rest.
> 
> This also fixes some problems when running 32-bit userspace under
> a 64-bit kernel.
> 
> This patch broke 32bit OpenBIOS when run under a 970 cpu. A fix was
> proposed here :
> 
>     https://www.coreboot.org/pipermail/openbios/2016-June/009452.html
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> [clg: updated the commit log with the reference of the openbios fix ]
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

I'm not comfortable merging this until the openbios change is pulled
back into the qemu tree (submodule and pre-built binary).

Again - sure you don't want to apply this with rfi still enabled for
64-bit for now, letting the rest of this series go in as well, then
clean up the rfi/64 behaviour later?

> ---
> 
>  target-ppc/excp_helper.c | 51 +++++++++++++++++++-----------------------------
>  target-ppc/translate.c   |  8 ++++++++
>  2 files changed, 28 insertions(+), 31 deletions(-)
> 
> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
> index 30e960e30b63..aa0b63f4b0de 100644
> --- a/target-ppc/excp_helper.c
> +++ b/target-ppc/excp_helper.c
> @@ -922,25 +922,20 @@ void helper_store_msr(CPUPPCState *env, target_ulong val)
>      }
>  }
>  
> -static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
> -                          target_ulong msrm, int keep_msrh)
> +static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
>  {
>      CPUState *cs = CPU(ppc_env_get_cpu(env));
>  
> +    /* MSR:POW cannot be set by any form of rfi */
> +    msr &= ~(1ULL << MSR_POW);
> +
>  #if defined(TARGET_PPC64)
> -    if (msr_is_64bit(env, msr)) {
> -        nip = (uint64_t)nip;
> -        msr &= (uint64_t)msrm;
> -    } else {
> +    /* Switching to 32-bit ? Crop the nip */
> +    if (!msr_is_64bit(env, msr)) {
>          nip = (uint32_t)nip;
> -        msr = (uint32_t)(msr & msrm);
> -        if (keep_msrh) {
> -            msr |= env->msr & ~((uint64_t)0xFFFFFFFF);
> -        }
>      }
>  #else
>      nip = (uint32_t)nip;
> -    msr &= (uint32_t)msrm;
>  #endif
>      /* XXX: beware: this is false if VLE is supported */
>      env->nip = nip & ~((target_ulong)0x00000003);
> @@ -959,26 +954,24 @@ static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
>  
>  void helper_rfi(CPUPPCState *env)
>  {
> -    if (env->excp_model == POWERPC_EXCP_BOOKE) {
> -        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
> -               ~((target_ulong)0), 0);
> -    } else {
> -        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
> -               ~((target_ulong)0x783F0000), 1);
> -    }
> +    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
>  }
>  
> +#define MSR_BOOK3S_MASK
>  #if defined(TARGET_PPC64)
>  void helper_rfid(CPUPPCState *env)
>  {
> -    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
> -           ~((target_ulong)0x783F0000), 0);
> +    /* The architeture defines a number of rules for which bits
> +     * can change but in practice, we handle this in hreg_store_msr()
> +     * which will be called by do_rfi(), so there is no need to filter
> +     * here
> +     */
> +    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
>  }
>  
>  void helper_hrfid(CPUPPCState *env)
>  {
> -    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1],
> -           ~((target_ulong)0x783F0000), 0);
> +    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
>  }
>  #endif
>  
> @@ -986,28 +979,24 @@ void helper_hrfid(CPUPPCState *env)
>  /* Embedded PowerPC specific helpers */
>  void helper_40x_rfci(CPUPPCState *env)
>  {
> -    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3],
> -           ~((target_ulong)0xFFFF0000), 0);
> +    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
>  }
>  
>  void helper_rfci(CPUPPCState *env)
>  {
> -    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
> -           ~((target_ulong)0), 0);
> +    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
>  }
>  
>  void helper_rfdi(CPUPPCState *env)
>  {
>      /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
> -    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1],
> -           ~((target_ulong)0), 0);
> +    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
>  }
>  
>  void helper_rfmci(CPUPPCState *env)
>  {
>      /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
> -    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1],
> -           ~((target_ulong)0), 0);
> +    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
>  }
>  #endif
>  
> @@ -1045,7 +1034,7 @@ void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
>  
>  void helper_rfsvc(CPUPPCState *env)
>  {
> -    do_rfi(env, env->lr, env->ctr, 0x0000FFFF, 0);
> +    do_rfi(env, env->lr, env->ctr & 0x0000FFFF);
>  }
>  
>  /* Embedded.Processor Control */
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index b6894751e8df..81481955a589 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -4087,6 +4087,14 @@ static void gen_rfi(DisasContext *ctx)
>  #if defined(CONFIG_USER_ONLY)
>      gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
>  #else
> +    /* This instruction doesn't exist anymore on 64-bit server
> +     * processors compliant with arch 2.x
> +     */
> +    if (ctx->insns_flags & PPC_SEGMENT_64B) {
> +        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
> +        return;
> +    }
> +
>      /* Restore CPU state */
>      if (unlikely(ctx->pr)) {
>          gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 03/10] ppc: fix exception model for HV mode
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 03/10] ppc: fix exception model for HV mode Cédric Le Goater
@ 2016-06-22  6:27   ` David Gibson
  0 siblings, 0 replies; 30+ messages in thread
From: David Gibson @ 2016-06-22  6:27 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: qemu-ppc, Alexander Graf, qemu-devel, Benjamin Herrenschmidt

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

On Tue, Jun 21, 2016 at 11:48:48PM +0200, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> 
> This properly implements LPES0 handling for HV vs. !HV mode and
> removes the unsupported LPES1. This has been removed from the specs
> since ISA v2.07.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> [clg: AIL implementation was fixed in commit 5c94b2a5e5ef. This patch
>       only contains the bits of the original patch related to LPES0
>       handling, adapted commit log.
>       fixed checkpatch.pl errors. ]
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  target-ppc/excp_helper.c | 134 ++++++++++++++++-------------------------------
>  1 file changed, 45 insertions(+), 89 deletions(-)
> 
> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
> index aa0b63f4b0de..7c44c102db39 100644
> --- a/target-ppc/excp_helper.c
> +++ b/target-ppc/excp_helper.c
> @@ -77,18 +77,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      CPUState *cs = CPU(cpu);
>      CPUPPCState *env = &cpu->env;
>      target_ulong msr, new_msr, vector;
> -    int srr0, srr1, asrr0, asrr1;
> -    int lpes0, lpes1, lev, ail;
> -
> -    if (0) {
> -        /* XXX: find a suitable condition to enable the hypervisor mode */
> -        lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;
> -        lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;
> -    } else {
> -        /* Those values ensure we won't enter the hypervisor mode */
> -        lpes0 = 0;
> -        lpes1 = 1;
> -    }
> +    int srr0, srr1, asrr0, asrr1, lev, ail;
> +    bool lpes0;
>  
>      qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
>                    " => %08x (%02x)\n", env->nip, excp, env->error_code);
> @@ -100,8 +90,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          msr = env->msr & ~0x783f0000ULL;
>      }
>  
> -    /* new interrupt handler msr */
> -    new_msr = env->msr & ((target_ulong)1 << MSR_ME);
> +    /* new interrupt handler msr preserves existing HV and ME unless
> +     * explicitly overriden
> +     */
> +    new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
>  
>      /* target registers */
>      srr0 = SPR_SRR0;
> @@ -111,12 +103,19 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>  
>      /* Exception targetting modifiers
>       *
> +     * LPES0 is supported on POWER7/8
> +     * LPES1 is not supported (old iSeries mode)
> +     *
> +     * On anything else, we behave as if LPES0 is 1
> +     * (externals don't alter MSR:HV)
> +     *
>       * AIL is initialized here but can be cleared by
>       * selected exceptions
>       */
>  #if defined(TARGET_PPC64)
>      if (excp_model == POWERPC_EXCP_POWER7 ||
>          excp_model == POWERPC_EXCP_POWER8) {
> +        lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
>          if (excp_model == POWERPC_EXCP_POWER8) {
>              ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
>          } else {
> @@ -125,6 +124,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      } else
>  #endif /* defined(TARGET_PPC64) */
>      {
> +        lpes0 = true;
>          ail = 0;
>      }
>  
> @@ -162,10 +162,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>              cs->halted = 1;
>              cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
>          }
> -        if (0) {
> -            /* XXX: find a suitable condition to enable the hypervisor mode */
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
> +        new_msr |= (target_ulong)MSR_HVB;
>          ail = 0;
>  
>          /* machine check exceptions don't have ME set */
> @@ -191,23 +188,20 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      case POWERPC_EXCP_DSI:       /* Data storage exception                   */
>          LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
>                   "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_next;
>      case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
>          LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
>                   "\n", msr, env->nip);
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          msr |= env->error_code;
>          goto store_next;
>      case POWERPC_EXCP_EXTERNAL:  /* External input                           */
>          cs = CPU(cpu);
>  
> -        if (lpes0 == 1) {
> +        if (!lpes0) {
>              new_msr |= (target_ulong)MSR_HVB;
> +            new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
> +            srr0 = SPR_HSRR0;
> +            srr1 = SPR_HSRR1;
>          }
>          if (env->mpic_proxy) {
>              /* IACK the IRQ on delivery */
> @@ -215,9 +209,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          }
>          goto store_next;
>      case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          /* XXX: this is false */
>          /* Get rS/rD and rA from faulting opcode */
>          env->spr[SPR_DSISR] |= (cpu_ldl_code(env, (env->nip - 4))
> @@ -232,9 +223,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>                  env->error_code = 0;
>                  return;
>              }
> -            if (lpes1 == 0) {
> -                new_msr |= (target_ulong)MSR_HVB;
> -            }
>              msr |= 0x00100000;
>              if (msr_fe0 == msr_fe1) {
>                  goto store_next;
> @@ -243,23 +231,14 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>              break;
>          case POWERPC_EXCP_INVAL:
>              LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
> -            if (lpes1 == 0) {
> -                new_msr |= (target_ulong)MSR_HVB;
> -            }
>              msr |= 0x00080000;
>              env->spr[SPR_BOOKE_ESR] = ESR_PIL;
>              break;
>          case POWERPC_EXCP_PRIV:
> -            if (lpes1 == 0) {
> -                new_msr |= (target_ulong)MSR_HVB;
> -            }
>              msr |= 0x00040000;
>              env->spr[SPR_BOOKE_ESR] = ESR_PPR;
>              break;
>          case POWERPC_EXCP_TRAP:
> -            if (lpes1 == 0) {
> -                new_msr |= (target_ulong)MSR_HVB;
> -            }
>              msr |= 0x00020000;
>              env->spr[SPR_BOOKE_ESR] = ESR_PTR;
>              break;
> @@ -271,27 +250,23 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          }
>          goto store_current;
>      case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_current;
>      case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
>          dump_syscall(env);
>          lev = env->error_code;
> +
> +        /* "PAPR mode" built-in hypercall emulation */
>          if ((lev == 1) && cpu_ppc_hypercall) {
>              cpu_ppc_hypercall(cpu);
>              return;
>          }
> -        if (lev == 1 || (lpes0 == 0 && lpes1 == 0)) {
> +        if (lev == 1) {
>              new_msr |= (target_ulong)MSR_HVB;
>          }
>          goto store_next;
>      case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
>          goto store_current;
>      case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_next;
>      case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
>          /* FIT on 4xx */
> @@ -361,21 +336,12 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>              new_msr &= ~((target_ulong)1 << MSR_ME);
>          }
>  
> -        if (0) {
> -            /* XXX: find a suitable condition to enable the hypervisor mode */
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
> +        new_msr |= (target_ulong)MSR_HVB;
>          ail = 0;
>          goto store_next;
>      case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_next;
>      case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_next;
>      case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
>          srr0 = SPR_HSRR0;
> @@ -384,9 +350,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
>          goto store_next;
>      case POWERPC_EXCP_TRACE:     /* Trace exception                          */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_next;
>      case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
>          srr0 = SPR_HSRR0;
> @@ -413,19 +376,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
>          goto store_next;
>      case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_current;
>      case POWERPC_EXCP_VSXU:       /* VSX unavailable exception               */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_current;
>      case POWERPC_EXCP_FU:         /* Facility unavailable exception          */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_current;
>      case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
>          LOG_EXCP("PIT exception\n");
> @@ -444,9 +398,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>                    "is not implemented yet !\n");
>          goto store_next;
>      case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
> -        if (lpes1 == 0) { /* XXX: check this */
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          switch (excp_model) {
>          case POWERPC_EXCP_602:
>          case POWERPC_EXCP_603:
> @@ -463,9 +414,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          }
>          break;
>      case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
> -        if (lpes1 == 0) { /* XXX: check this */
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          switch (excp_model) {
>          case POWERPC_EXCP_602:
>          case POWERPC_EXCP_603:
> @@ -482,9 +430,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          }
>          break;
>      case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
> -        if (lpes1 == 0) { /* XXX: check this */
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          switch (excp_model) {
>          case POWERPC_EXCP_602:
>          case POWERPC_EXCP_603:
> @@ -590,9 +535,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>                    "is not implemented yet !\n");
>          goto store_next;
>      case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          /* XXX: TODO */
>          cpu_abort(cs,
>                    "Performance counter exception is not implemented yet !\n");
> @@ -636,6 +578,13 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      }
>      /* Save MSR */
>      env->spr[srr1] = msr;
> +
> +    /* Sanity check */
> +    if (!(env->msr_mask & MSR_HVB) && (srr0 == SPR_HSRR0)) {
> +        cpu_abort(cs, "Trying to deliver HV exception %d with "
> +                  "no HV support\n", excp);
> +    }
> +
>      /* If any alternate SRR register are defined, duplicate saved values */
>      if (asrr0 != -1) {
>          env->spr[asrr0] = env->spr[srr0];
> @@ -644,14 +593,20 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          env->spr[asrr1] = env->spr[srr1];
>      }
>  
> -    if (env->spr[SPR_LPCR] & LPCR_AIL) {
> -        new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
> -    }
> -
> +    /* Sort out endianness of interrupt, this differs depending on the
> +     * CPU, the HV mode, etc...
> +     */
>  #ifdef TARGET_PPC64
> -    if (excp_model == POWERPC_EXCP_POWER7 ||
> -        excp_model == POWERPC_EXCP_POWER8) {
> -        if (env->spr[SPR_LPCR] & LPCR_ILE) {
> +    if (excp_model == POWERPC_EXCP_POWER7) {
> +        if (!(new_msr & MSR_HVB) && (env->spr[SPR_LPCR] & LPCR_ILE)) {
> +            new_msr |= (target_ulong)1 << MSR_LE;
> +        }
> +    } else if (excp_model == POWERPC_EXCP_POWER8) {
> +        if (new_msr & MSR_HVB) {
> +            if (env->spr[SPR_HID0] & HID0_HILE) {
> +                new_msr |= (target_ulong)1 << MSR_LE;
> +            }
> +        } else if (env->spr[SPR_LPCR] & LPCR_ILE) {
>              new_msr |= (target_ulong)1 << MSR_LE;
>          }
>      } else if (msr_ile) {
> @@ -674,7 +629,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      /* AIL only works if there is no HV transition and we are running with
>       * translations enabled
>       */
> -    if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1)) {
> +    if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1) ||
> +        ((new_msr & MSR_HVB) && !(msr & MSR_HVB))) {
>          ail = 0;
>      }
>      /* Handle AIL */

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-22  2:46   ` David Gibson
@ 2016-06-22  6:48     ` Cédric Le Goater
  2016-06-23  5:50       ` David Gibson
  0 siblings, 1 reply; 30+ messages in thread
From: Cédric Le Goater @ 2016-06-22  6:48 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, Alexander Graf, qemu-devel, Benjamin Herrenschmidt

On 06/22/2016 04:46 AM, David Gibson wrote:
> I'm not comfortable merging this until the openbios change is pulled
> back into the qemu tree (submodule and pre-built binary).
> 
> Again - sure you don't want to apply this with rfi still enabled for
> 64-bit for now, letting the rest of this series go in as well, then
> clean up the rfi/64 behaviour later?

Sure. I don't think it has an impact on the serie anyway so we can keep
it for later.

Thanks,

C.

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

* Re: [Qemu-devel] [PATCH v2 06/10] ppc: Rework generation of priv and inval interrupts
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 06/10] ppc: Rework generation of priv and inval interrupts Cédric Le Goater
@ 2016-06-22  6:51   ` David Gibson
  0 siblings, 0 replies; 30+ messages in thread
From: David Gibson @ 2016-06-22  6:51 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: qemu-ppc, Alexander Graf, qemu-devel, Benjamin Herrenschmidt

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

On Tue, Jun 21, 2016 at 11:48:51PM +0200, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> 
> Recent server processors use the Hypervisor Emulation Assistance
> interrupt for illegal instructions and *some* type of SPR accesses.
> 
> Also the code was always generating inval instructions even for priv
> violations due to setting the wrong flags
> 
> Finally, the checking for PR/HV was open coded everywhere.
> 
> This reworks it all, using little helper macros for checking, and
> adding the HV interrupt (which gets converted back to program check
> in the slow path of excp_helper.c on CPUs that don't want it).
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> [clg: fixed checkpatch.pl errors ]
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 09/10] ppc: Move exception generation code out of line
  2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 09/10] ppc: Move exception generation code out of line Cédric Le Goater
@ 2016-06-22  6:57   ` David Gibson
  0 siblings, 0 replies; 30+ messages in thread
From: David Gibson @ 2016-06-22  6:57 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: qemu-ppc, Alexander Graf, qemu-devel, Benjamin Herrenschmidt

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

On Tue, Jun 21, 2016 at 11:48:54PM +0200, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> 
> There's no point inlining this, if you hit the exception case you exit
> anyway, and not inlining saves about 100K of code size (and cache
> footprint).
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> [clg: removed '__attribute__((noinline))' from original patch ]
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  target-ppc/translate.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index 83ec2dd7707b..365fe3d34461 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -283,7 +283,7 @@ void gen_update_current_nip(void *opaque)
>      tcg_gen_movi_tl(cpu_nip, ctx->nip);
>  }
>  
> -static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
> +static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
>  {
>      TCGv_i32 t0, t1;
>      if (ctx->exception == POWERPC_EXCP_NONE) {
> @@ -297,7 +297,7 @@ static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t
>      ctx->exception = (excp);
>  }
>  
> -static inline void gen_exception(DisasContext *ctx, uint32_t excp)
> +static void gen_exception(DisasContext *ctx, uint32_t excp)
>  {
>      TCGv_i32 t0;
>      if (ctx->exception == POWERPC_EXCP_NONE) {
> @@ -309,7 +309,7 @@ static inline void gen_exception(DisasContext *ctx, uint32_t excp)
>      ctx->exception = (excp);
>  }
>  
> -static inline void gen_debug_exception(DisasContext *ctx)
> +static void gen_debug_exception(DisasContext *ctx)
>  {
>      TCGv_i32 t0;
>  

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-22  6:48     ` Cédric Le Goater
@ 2016-06-23  5:50       ` David Gibson
  2016-06-23  6:08         ` Cédric Le Goater
  2016-09-05 20:25         ` [Qemu-devel] " Thomas Huth
  0 siblings, 2 replies; 30+ messages in thread
From: David Gibson @ 2016-06-23  5:50 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: qemu-ppc, Alexander Graf, qemu-devel, Benjamin Herrenschmidt

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

On Wed, Jun 22, 2016 at 08:48:14AM +0200, Cédric Le Goater wrote:
> On 06/22/2016 04:46 AM, David Gibson wrote:
> > I'm not comfortable merging this until the openbios change is pulled
> > back into the qemu tree (submodule and pre-built binary).
> > 
> > Again - sure you don't want to apply this with rfi still enabled for
> > 64-bit for now, letting the rest of this series go in as well, then
> > clean up the rfi/64 behaviour later?
> 
> Sure. I don't think it has an impact on the serie anyway so we can keep
> it for later.

Ok, I modified 1/10 to leave rfi in for 64-bit cpus for now, and
applied the full series to ppc-for-2.7.  I've also now sent a pull
request including this.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-23  5:50       ` David Gibson
@ 2016-06-23  6:08         ` Cédric Le Goater
  2016-06-23  6:14           ` David Gibson
  2016-09-05 20:25         ` [Qemu-devel] " Thomas Huth
  1 sibling, 1 reply; 30+ messages in thread
From: Cédric Le Goater @ 2016-06-23  6:08 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, Alexander Graf, qemu-devel, Benjamin Herrenschmidt

On 06/23/2016 07:50 AM, David Gibson wrote:
> On Wed, Jun 22, 2016 at 08:48:14AM +0200, Cédric Le Goater wrote:
>> On 06/22/2016 04:46 AM, David Gibson wrote:
>>> I'm not comfortable merging this until the openbios change is pulled
>>> back into the qemu tree (submodule and pre-built binary).
>>>
>>> Again - sure you don't want to apply this with rfi still enabled for
>>> 64-bit for now, letting the rest of this series go in as well, then
>>> clean up the rfi/64 behaviour later?
>>
>> Sure. I don't think it has an impact on the serie anyway so we can keep
>> it for later.
> 
> Ok, I modified 1/10 to leave rfi in for 64-bit cpus for now, and
> applied the full series to ppc-for-2.7.  I've also now sent a pull
> request including this.

Perfect. I was wondering if we should not just remove the instruction from 
the 64bit set.

Thanks,

C.

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

* Re: [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-23  6:08         ` Cédric Le Goater
@ 2016-06-23  6:14           ` David Gibson
  2016-07-15 15:17             ` [Qemu-devel] [Qemu-ppc] " Mark Cave-Ayland
  0 siblings, 1 reply; 30+ messages in thread
From: David Gibson @ 2016-06-23  6:14 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: qemu-ppc, Alexander Graf, qemu-devel, Benjamin Herrenschmidt

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

On Thu, Jun 23, 2016 at 08:08:38AM +0200, Cédric Le Goater wrote:
> On 06/23/2016 07:50 AM, David Gibson wrote:
> > On Wed, Jun 22, 2016 at 08:48:14AM +0200, Cédric Le Goater wrote:
> >> On 06/22/2016 04:46 AM, David Gibson wrote:
> >>> I'm not comfortable merging this until the openbios change is pulled
> >>> back into the qemu tree (submodule and pre-built binary).
> >>>
> >>> Again - sure you don't want to apply this with rfi still enabled for
> >>> 64-bit for now, letting the rest of this series go in as well, then
> >>> clean up the rfi/64 behaviour later?
> >>
> >> Sure. I don't think it has an impact on the serie anyway so we can keep
> >> it for later.
> > 
> > Ok, I modified 1/10 to leave rfi in for 64-bit cpus for now, and
> > applied the full series to ppc-for-2.7.  I've also now sent a pull
> > request including this.
> 
> Perfect. I was wondering if we should not just remove the instruction from 
> the 64bit set.

We should, but I don't want to do so until OpenBIOS is updated to
cope.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-23  6:14           ` David Gibson
@ 2016-07-15 15:17             ` Mark Cave-Ayland
  0 siblings, 0 replies; 30+ messages in thread
From: Mark Cave-Ayland @ 2016-07-15 15:17 UTC (permalink / raw)
  To: David Gibson, Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

On 23/06/16 07:14, David Gibson wrote:

> On Thu, Jun 23, 2016 at 08:08:38AM +0200, Cédric Le Goater wrote:
>> On 06/23/2016 07:50 AM, David Gibson wrote:
>>> On Wed, Jun 22, 2016 at 08:48:14AM +0200, Cédric Le Goater wrote:
>>>> On 06/22/2016 04:46 AM, David Gibson wrote:
>>>>> I'm not comfortable merging this until the openbios change is pulled
>>>>> back into the qemu tree (submodule and pre-built binary).
>>>>>
>>>>> Again - sure you don't want to apply this with rfi still enabled for
>>>>> 64-bit for now, letting the rest of this series go in as well, then
>>>>> clean up the rfi/64 behaviour later?
>>>>
>>>> Sure. I don't think it has an impact on the serie anyway so we can keep
>>>> it for later.
>>>
>>> Ok, I modified 1/10 to leave rfi in for 64-bit cpus for now, and
>>> applied the full series to ppc-for-2.7.  I've also now sent a pull
>>> request including this.
>>
>> Perfect. I was wondering if we should not just remove the instruction from 
>> the 64bit set.
> 
> We should, but I don't want to do so until OpenBIOS is updated to
> cope.

FWIW I've just sent a pull request to update the OpenBIOS images which
contains Cédric's v4 patch as reviewed by Alex:
https://www.coreboot.org/pipermail/openbios/2016-June/009461.html.


ATB,

Mark.

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

* Re: [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-23  5:50       ` David Gibson
  2016-06-23  6:08         ` Cédric Le Goater
@ 2016-09-05 20:25         ` Thomas Huth
  2016-09-05 20:30           ` Cédric Le Goater
  1 sibling, 1 reply; 30+ messages in thread
From: Thomas Huth @ 2016-09-05 20:25 UTC (permalink / raw)
  To: David Gibson, Cédric Le Goater
  Cc: qemu-ppc, Alexander Graf, qemu-devel, Benjamin Herrenschmidt,
	Mark Cave-Ayland

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

On 23.06.2016 07:50, David Gibson wrote:
> On Wed, Jun 22, 2016 at 08:48:14AM +0200, Cédric Le Goater wrote:
>> On 06/22/2016 04:46 AM, David Gibson wrote:
>>> I'm not comfortable merging this until the openbios change is pulled
>>> back into the qemu tree (submodule and pre-built binary).
>>>
>>> Again - sure you don't want to apply this with rfi still enabled for
>>> 64-bit for now, letting the rest of this series go in as well, then
>>> clean up the rfi/64 behaviour later?
>>
>> Sure. I don't think it has an impact on the serie anyway so we can keep
>> it for later.
> 
> Ok, I modified 1/10 to leave rfi in for 64-bit cpus for now, and
> applied the full series to ppc-for-2.7.  I've also now sent a pull
> request including this.

Shall we disable rfi now for QEMU 2.8 ? Cédric, could you maybe send a
patch with that hunk again?

 Thomas



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-09-05 20:25         ` [Qemu-devel] " Thomas Huth
@ 2016-09-05 20:30           ` Cédric Le Goater
  2016-09-05 20:51             ` Mark Cave-Ayland
  0 siblings, 1 reply; 30+ messages in thread
From: Cédric Le Goater @ 2016-09-05 20:30 UTC (permalink / raw)
  To: Thomas Huth, David Gibson
  Cc: qemu-ppc, Alexander Graf, qemu-devel, Benjamin Herrenschmidt,
	Mark Cave-Ayland

On 09/05/2016 10:25 PM, Thomas Huth wrote:
> On 23.06.2016 07:50, David Gibson wrote:
>> On Wed, Jun 22, 2016 at 08:48:14AM +0200, Cédric Le Goater wrote:
>>> On 06/22/2016 04:46 AM, David Gibson wrote:
>>>> I'm not comfortable merging this until the openbios change is pulled
>>>> back into the qemu tree (submodule and pre-built binary).
>>>>
>>>> Again - sure you don't want to apply this with rfi still enabled for
>>>> 64-bit for now, letting the rest of this series go in as well, then
>>>> clean up the rfi/64 behaviour later?
>>>
>>> Sure. I don't think it has an impact on the serie anyway so we can keep
>>> it for later.
>>
>> Ok, I modified 1/10 to leave rfi in for 64-bit cpus for now, and
>> applied the full series to ppc-for-2.7.  I've also now sent a pull
>> request including this.
> 
> Shall we disable rfi now for QEMU 2.8 ? Cédric, could you maybe send a
> patch with that hunk again?

Sure. I have kept it in a warm place here : 
 
	https://github.com/legoater/qemu/commit/492a631e4e817863be312c1a34957cd8d679a56c

Mark, is openbios at the right level now ? I have lost track of the 
recent changes.

Thanks,

C.

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

* Re: [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-09-05 20:30           ` Cédric Le Goater
@ 2016-09-05 20:51             ` Mark Cave-Ayland
  2016-09-06  0:16               ` David Gibson
  0 siblings, 1 reply; 30+ messages in thread
From: Mark Cave-Ayland @ 2016-09-05 20:51 UTC (permalink / raw)
  To: Cédric Le Goater, Thomas Huth, David Gibson
  Cc: qemu-ppc, Alexander Graf, qemu-devel, Benjamin Herrenschmidt

On 05/09/16 21:30, Cédric Le Goater wrote:

>> Shall we disable rfi now for QEMU 2.8 ? Cédric, could you maybe send a
>> patch with that hunk again?
> 
> Sure. I have kept it in a warm place here : 
>  
> 	https://github.com/legoater/qemu/commit/492a631e4e817863be312c1a34957cd8d679a56c
> 
> Mark, is openbios at the right level now ? I have lost track of the 
> recent changes.

The following patch is already in the current OpenBIOS binaries:
https://github.com/openbios/openbios/commit/b747b6acc272f6ab839728193042455c9b36e26a.
Is that the one you're looking for?


ATB,

Mark.

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

* Re: [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-09-05 20:51             ` Mark Cave-Ayland
@ 2016-09-06  0:16               ` David Gibson
  2016-09-06  7:07                 ` Mark Cave-Ayland
  0 siblings, 1 reply; 30+ messages in thread
From: David Gibson @ 2016-09-06  0:16 UTC (permalink / raw)
  To: Mark Cave-Ayland
  Cc: Cédric Le Goater, Thomas Huth, qemu-ppc, Alexander Graf,
	qemu-devel, Benjamin Herrenschmidt

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

On Mon, Sep 05, 2016 at 09:51:09PM +0100, Mark Cave-Ayland wrote:
> On 05/09/16 21:30, Cédric Le Goater wrote:
> 
> >> Shall we disable rfi now for QEMU 2.8 ? Cédric, could you maybe send a
> >> patch with that hunk again?
> > 
> > Sure. I have kept it in a warm place here : 
> >  
> > 	https://github.com/legoater/qemu/commit/492a631e4e817863be312c1a34957cd8d679a56c
> > 
> > Mark, is openbios at the right level now ? I have lost track of the 
> > recent changes.
> 
> The following patch is already in the current OpenBIOS binaries:
> https://github.com/openbios/openbios/commit/b747b6acc272f6ab839728193042455c9b36e26a.
> Is that the one you're looking for?

Right, the relevant question is whether the updated openbios is in the
qemu submodule and canned binary.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-09-06  0:16               ` David Gibson
@ 2016-09-06  7:07                 ` Mark Cave-Ayland
  2016-09-07 10:50                   ` Cédric Le Goater
  0 siblings, 1 reply; 30+ messages in thread
From: Mark Cave-Ayland @ 2016-09-06  7:07 UTC (permalink / raw)
  To: David Gibson
  Cc: Thomas Huth, qemu-devel, Alexander Graf, qemu-ppc, Cédric Le Goater

On 06/09/16 01:16, David Gibson wrote:

> On Mon, Sep 05, 2016 at 09:51:09PM +0100, Mark Cave-Ayland wrote:
>> On 05/09/16 21:30, Cédric Le Goater wrote:
>>
>>>> Shall we disable rfi now for QEMU 2.8 ? Cédric, could you maybe send a
>>>> patch with that hunk again?
>>>
>>> Sure. I have kept it in a warm place here : 
>>>  
>>> 	https://github.com/legoater/qemu/commit/492a631e4e817863be312c1a34957cd8d679a56c
>>>
>>> Mark, is openbios at the right level now ? I have lost track of the 
>>> recent changes.
>>
>> The following patch is already in the current OpenBIOS binaries:
>> https://github.com/openbios/openbios/commit/b747b6acc272f6ab839728193042455c9b36e26a.
>> Is that the one you're looking for?
> 
> Right, the relevant question is whether the updated openbios is in the
> qemu submodule and canned binary.

Yes, it was included in last merge for 2.7.


ATB,

Mark.

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

* Re: [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-09-06  7:07                 ` Mark Cave-Ayland
@ 2016-09-07 10:50                   ` Cédric Le Goater
  2016-09-07 11:08                     ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 30+ messages in thread
From: Cédric Le Goater @ 2016-09-07 10:50 UTC (permalink / raw)
  To: Mark Cave-Ayland, David Gibson
  Cc: Thomas Huth, qemu-devel, Alexander Graf, qemu-ppc,
	Benjamin Herrenschmidt

On 09/06/2016 09:07 AM, Mark Cave-Ayland wrote:
> On 06/09/16 01:16, David Gibson wrote:
> 
>> On Mon, Sep 05, 2016 at 09:51:09PM +0100, Mark Cave-Ayland wrote:
>>> On 05/09/16 21:30, Cédric Le Goater wrote:
>>>
>>>>> Shall we disable rfi now for QEMU 2.8 ? Cédric, could you maybe send a
>>>>> patch with that hunk again?
>>>>
>>>> Sure. I have kept it in a warm place here : 
>>>>  
>>>> 	https://github.com/legoater/qemu/commit/492a631e4e817863be312c1a34957cd8d679a56c
>>>>
>>>> Mark, is openbios at the right level now ? I have lost track of the 
>>>> recent changes.
>>>
>>> The following patch is already in the current OpenBIOS binaries:
>>> https://github.com/openbios/openbios/commit/b747b6acc272f6ab839728193042455c9b36e26a.
>>> Is that the one you're looking for?
>>
>> Right, the relevant question is whether the updated openbios is in the
>> qemu submodule and canned binary.
> 
> Yes, it was included in last merge for 2.7.

make check-qtest-ppc now runs fine with original patch :

	https://github.com/legoater/qemu/commit/492a631e4e817863be312c1a34957cd8d679a56c

but we could also just remove the rfi instruction from the 
instruction set of the processors not supporting it. This is 
where it gets complicated :)

I suppose the impact is on 60x, 75x, 74xx, embedded (all the 
32bits) but not the 64bits  :  

	POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
	POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
	POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
	POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
	POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
	POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)

This is a bit broader than Ben's patch which used PPC_SEGMENT_64B. 
it's basically !PPC_64B which includes the e5500.

If so, here is a proposal below adding a new PPC_RFI in the 
"PowerPC Instructions types definitions" enum for that purpose. 
Not much bits left there.

Thanks,

C. 


From: Cédric Le Goater <clg@kaod.org>
Subject: [PATCH] ppc: enable rfi support for 32bits CPUs only
Date: Wed, 07 Sep 2016 11:55:43 +0200
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Add a new PPC_RFI bit in the PowerPC Instructions types definitions
for this purpose and update the insns_flags of the target CPUs.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 target-ppc/cpu.h            |    5 +-
 target-ppc/translate.c      |    2 
 target-ppc/translate_init.c |   92 ++++++++++++++++++++++----------------------
 3 files changed, 51 insertions(+), 48 deletions(-)

Index: qemu-dgibson-for-2.8.git/target-ppc/translate.c
===================================================================
--- qemu-dgibson-for-2.8.git.orig/target-ppc/translate.c
+++ qemu-dgibson-for-2.8.git/target-ppc/translate.c
@@ -6297,7 +6297,7 @@ GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x0
 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
 GEN_HANDLER_E(bctar, 0x13, 0x10, 0x11, 0, PPC_NONE, PPC2_BCTAR_ISA207),
 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
-GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
+GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_RFI),
 #if defined(TARGET_PPC64)
 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
 GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
Index: qemu-dgibson-for-2.8.git/target-ppc/cpu.h
===================================================================
--- qemu-dgibson-for-2.8.git.orig/target-ppc/cpu.h
+++ qemu-dgibson-for-2.8.git/target-ppc/cpu.h
@@ -1997,6 +1997,9 @@ enum {
     /*   SLB management                                                      */
     PPC_SLBI           = 0x0000400000000000ULL,
 
+    /*   rfi support                                                          */
+    PPC_RFI           = 0x0000800000000000ULL,
+
     /* Embedded PowerPC dedicated instructions                               */
     PPC_WRTEE          = 0x0001000000000000ULL,
     /* PowerPC 40x exception model                                           */
@@ -2047,7 +2050,7 @@ enum {
                         | PPC_CACHE_DCBA | PPC_CACHE_LOCK \
                         | PPC_EXTERN | PPC_SEGMENT | PPC_6xx_TLB \
                         | PPC_74xx_TLB | PPC_40x_TLB | PPC_SEGMENT_64B \
-                        | PPC_SLBI | PPC_WRTEE | PPC_40x_EXCP \
+                        | PPC_SLBI | PPC_RFI | PPC_WRTEE | PPC_40x_EXCP \
                         | PPC_405_MAC | PPC_440_SPEC | PPC_BOOKE \
                         | PPC_MFAPIDI | PPC_TLBIVA | PPC_TLBIVAX \
                         | PPC_4xx_COMMON | PPC_40x_ICBT | PPC_RFMCI \
Index: qemu-dgibson-for-2.8.git/target-ppc/translate_init.c
===================================================================
--- qemu-dgibson-for-2.8.git.orig/target-ppc/translate_init.c
+++ qemu-dgibson-for-2.8.git/target-ppc/translate_init.c
@@ -3325,7 +3325,7 @@ POWERPC_FAMILY(401)(ObjectClass *oc, voi
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
                        PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
-                       PPC_4xx_COMMON | PPC_40x_EXCP;
+                       PPC_4xx_COMMON | PPC_40x_EXCP | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_KEY) |
                     (1ull << MSR_POW) |
                     (1ull << MSR_CE) |
@@ -3380,7 +3380,7 @@ POWERPC_FAMILY(401x2)(ObjectClass *oc, v
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
-                       PPC_4xx_COMMON | PPC_40x_EXCP;
+                       PPC_4xx_COMMON | PPC_40x_EXCP | PPC_RFI;
     pcc->msr_mask = (1ull << 20) |
                     (1ull << MSR_KEY) |
                     (1ull << MSR_POW) |
@@ -3432,7 +3432,7 @@ POWERPC_FAMILY(401x3)(ObjectClass *oc, v
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
-                       PPC_4xx_COMMON | PPC_40x_EXCP;
+                       PPC_4xx_COMMON | PPC_40x_EXCP | PPC_RFI;
     pcc->msr_mask = (1ull << 20) |
                     (1ull << MSR_KEY) |
                     (1ull << MSR_POW) |
@@ -3491,7 +3491,7 @@ POWERPC_FAMILY(IOP480)(ObjectClass *oc,
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
-                       PPC_4xx_COMMON | PPC_40x_EXCP;
+                       PPC_4xx_COMMON | PPC_40x_EXCP | PPC_RFI;
     pcc->msr_mask = (1ull << 20) |
                     (1ull << MSR_KEY) |
                     (1ull << MSR_POW) |
@@ -3541,7 +3541,7 @@ POWERPC_FAMILY(403)(ObjectClass *oc, voi
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
                        PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
-                       PPC_4xx_COMMON | PPC_40x_EXCP;
+                       PPC_4xx_COMMON | PPC_40x_EXCP | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_CE) |
                     (1ull << MSR_ILE) |
@@ -3608,7 +3608,7 @@ POWERPC_FAMILY(403GCX)(ObjectClass *oc,
                        PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
-                       PPC_4xx_COMMON | PPC_40x_EXCP;
+                       PPC_4xx_COMMON | PPC_40x_EXCP | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_CE) |
                     (1ull << MSR_ILE) |
@@ -3674,7 +3674,7 @@ POWERPC_FAMILY(405)(ObjectClass *oc, voi
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
-                       PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP;
+                       PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_CE) |
                     (1ull << MSR_EE) |
@@ -3775,7 +3775,7 @@ POWERPC_FAMILY(440EP)(ObjectClass *oc, v
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
                        PPC_MEM_TLBSYNC | PPC_MFTB |
                        PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
-                       PPC_440_SPEC;
+                       PPC_440_SPEC | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_CE) |
                     (1ull << MSR_EE) |
@@ -3858,7 +3858,7 @@ POWERPC_FAMILY(440GP)(ObjectClass *oc, v
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
                        PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB |
                        PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
-                       PPC_440_SPEC;
+                       PPC_440_SPEC | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_CE) |
                     (1ull << MSR_EE) |
@@ -3941,7 +3941,7 @@ POWERPC_FAMILY(440x4)(ObjectClass *oc, v
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
                        PPC_MEM_TLBSYNC | PPC_MFTB |
                        PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
-                       PPC_440_SPEC;
+                       PPC_440_SPEC | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_CE) |
                     (1ull << MSR_EE) |
@@ -4042,7 +4042,7 @@ POWERPC_FAMILY(440x5)(ObjectClass *oc, v
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
                        PPC_MEM_TLBSYNC | PPC_MFTB |
                        PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
-                       PPC_440_SPEC;
+                       PPC_440_SPEC | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_CE) |
                     (1ull << MSR_EE) |
@@ -4079,7 +4079,7 @@ POWERPC_FAMILY(440x5wDFPU)(ObjectClass *
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
                        PPC_MEM_TLBSYNC | PPC_MFTB |
                        PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
-                       PPC_440_SPEC;
+                       PPC_440_SPEC | PPC_RFI;
     pcc->insns_flags2 = PPC2_FP_CVT_S64;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_CE) |
@@ -4187,7 +4187,7 @@ POWERPC_FAMILY(460)(ObjectClass *oc, voi
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
                        PPC_MEM_TLBSYNC | PPC_TLBIVA |
                        PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
-                       PPC_440_SPEC;
+                       PPC_440_SPEC | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_CE) |
                     (1ull << MSR_EE) |
@@ -4297,7 +4297,7 @@ POWERPC_FAMILY(460F)(ObjectClass *oc, vo
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
                        PPC_MEM_TLBSYNC | PPC_TLBIVA |
                        PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
-                       PPC_440_SPEC;
+                       PPC_440_SPEC | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_CE) |
                     (1ull << MSR_EE) |
@@ -4341,7 +4341,7 @@ POWERPC_FAMILY(MPC5xx)(ObjectClass *oc,
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
                        PPC_MEM_EIEIO | PPC_MEM_SYNC |
                        PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX |
-                       PPC_MFTB;
+                       PPC_MFTB | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_ILE) |
                     (1ull << MSR_EE) |
                     (1ull << MSR_PR) |
@@ -4384,7 +4384,7 @@ POWERPC_FAMILY(MPC8xx)(ObjectClass *oc,
     pcc->check_pow = check_pow_none;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING  |
                        PPC_MEM_EIEIO | PPC_MEM_SYNC |
-                       PPC_CACHE_ICBI | PPC_MFTB;
+                       PPC_CACHE_ICBI | PPC_MFTB | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_ILE) |
                     (1ull << MSR_EE) |
                     (1ull << MSR_PR) |
@@ -4461,7 +4461,7 @@ POWERPC_FAMILY(G2)(ObjectClass *oc, void
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_TGPR) |
                     (1ull << MSR_EE) |
@@ -4540,7 +4540,7 @@ POWERPC_FAMILY(G2LE)(ObjectClass *oc, vo
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_TGPR) |
                     (1ull << MSR_ILE) |
@@ -4696,7 +4696,7 @@ POWERPC_FAMILY(e200)(ObjectClass *oc, vo
                        PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
                        PPC_MEM_TLBSYNC | PPC_TLBIVAX |
-                       PPC_BOOKE;
+                       PPC_BOOKE | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_UCLE) |
                     (1ull << MSR_SPE) |
                     (1ull << MSR_POW) |
@@ -4793,7 +4793,7 @@ POWERPC_FAMILY(e300)(ObjectClass *oc, vo
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_TGPR) |
                     (1ull << MSR_ILE) |
@@ -5052,7 +5052,7 @@ POWERPC_FAMILY(e500v1)(ObjectClass *oc,
                        PPC_WRTEE | PPC_RFDI |
                        PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
-                       PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
+                       PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC | PPC_RFI;
     pcc->insns_flags2 = PPC2_BOOKE206;
     pcc->msr_mask = (1ull << MSR_UCLE) |
                     (1ull << MSR_SPE) |
@@ -5095,7 +5095,7 @@ POWERPC_FAMILY(e500v2)(ObjectClass *oc,
                        PPC_WRTEE | PPC_RFDI |
                        PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
-                       PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
+                       PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC | PPC_RFI;
     pcc->insns_flags2 = PPC2_BOOKE206;
     pcc->msr_mask = (1ull << MSR_UCLE) |
                     (1ull << MSR_SPE) |
@@ -5140,7 +5140,7 @@ POWERPC_FAMILY(e500mc)(ObjectClass *oc,
                        PPC_FLOAT | PPC_FLOAT_FRES |
                        PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
                        PPC_FLOAT_STFIWX | PPC_WAIT |
-                       PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
+                       PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC | PPC_RFI;
     pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL;
     pcc->msr_mask = (1ull << MSR_GS) |
                     (1ull << MSR_UCLE) |
@@ -5290,7 +5290,7 @@ POWERPC_FAMILY(601)(ObjectClass *oc, voi
                        PPC_FLOAT |
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_EE) |
                     (1ull << MSR_PR) |
                     (1ull << MSR_FP) |
@@ -5335,7 +5335,7 @@ POWERPC_FAMILY(601v)(ObjectClass *oc, vo
                        PPC_FLOAT |
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_EE) |
                     (1ull << MSR_PR) |
                     (1ull << MSR_FP) |
@@ -5396,7 +5396,7 @@ POWERPC_FAMILY(602)(ObjectClass *oc, voi
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_6xx_TLB | PPC_MEM_TLBSYNC |
-                       PPC_SEGMENT | PPC_602_SPEC;
+                       PPC_SEGMENT | PPC_602_SPEC | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_VSX) |
                     (1ull << MSR_SA) |
                     (1ull << MSR_POW) |
@@ -5465,7 +5465,7 @@ POWERPC_FAMILY(603)(ObjectClass *oc, voi
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_TGPR) |
                     (1ull << MSR_ILE) |
@@ -5531,7 +5531,7 @@ POWERPC_FAMILY(603E)(ObjectClass *oc, vo
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_TGPR) |
                     (1ull << MSR_ILE) |
@@ -5591,7 +5591,7 @@ POWERPC_FAMILY(604)(ObjectClass *oc, voi
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
                     (1ull << MSR_EE) |
@@ -5674,7 +5674,7 @@ POWERPC_FAMILY(604E)(ObjectClass *oc, vo
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
                     (1ull << MSR_EE) |
@@ -5744,7 +5744,7 @@ POWERPC_FAMILY(740)(ObjectClass *oc, voi
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
                     (1ull << MSR_EE) |
@@ -5822,7 +5822,7 @@ POWERPC_FAMILY(750)(ObjectClass *oc, voi
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
                     (1ull << MSR_EE) |
@@ -6023,7 +6023,7 @@ POWERPC_FAMILY(750cl)(ObjectClass *oc, v
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
                     (1ull << MSR_EE) |
@@ -6105,7 +6105,7 @@ POWERPC_FAMILY(750cx)(ObjectClass *oc, v
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
                     (1ull << MSR_EE) |
@@ -6192,7 +6192,7 @@ POWERPC_FAMILY(750fx)(ObjectClass *oc, v
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
                     (1ull << MSR_EE) |
@@ -6279,7 +6279,7 @@ POWERPC_FAMILY(750gx)(ObjectClass *oc, v
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
                     (1ull << MSR_EE) |
@@ -6357,7 +6357,7 @@ POWERPC_FAMILY(745)(ObjectClass *oc, voi
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
                     (1ull << MSR_EE) |
@@ -6443,7 +6443,7 @@ POWERPC_FAMILY(755)(ObjectClass *oc, voi
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
-                       PPC_SEGMENT | PPC_EXTERN;
+                       PPC_SEGMENT | PPC_EXTERN | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
                     (1ull << MSR_EE) |
@@ -6516,7 +6516,7 @@ POWERPC_FAMILY(7400)(ObjectClass *oc, vo
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
                        PPC_MEM_TLBIA |
                        PPC_SEGMENT | PPC_EXTERN |
-                       PPC_ALTIVEC;
+                       PPC_ALTIVEC | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_VR) |
                     (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
@@ -6600,7 +6600,7 @@ POWERPC_FAMILY(7410)(ObjectClass *oc, vo
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
                        PPC_MEM_TLBIA |
                        PPC_SEGMENT | PPC_EXTERN |
-                       PPC_ALTIVEC;
+                       PPC_ALTIVEC | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_VR) |
                     (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
@@ -6710,7 +6710,7 @@ POWERPC_FAMILY(7440)(ObjectClass *oc, vo
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
                        PPC_MEM_TLBIA | PPC_74xx_TLB |
                        PPC_SEGMENT | PPC_EXTERN |
-                       PPC_ALTIVEC;
+                       PPC_ALTIVEC | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_VR) |
                     (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
@@ -6843,7 +6843,7 @@ POWERPC_FAMILY(7450)(ObjectClass *oc, vo
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
                        PPC_MEM_TLBIA | PPC_74xx_TLB |
                        PPC_SEGMENT | PPC_EXTERN |
-                       PPC_ALTIVEC;
+                       PPC_ALTIVEC | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_VR) |
                     (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
@@ -6979,7 +6979,7 @@ POWERPC_FAMILY(7445)(ObjectClass *oc, vo
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
                        PPC_MEM_TLBIA | PPC_74xx_TLB |
                        PPC_SEGMENT | PPC_EXTERN |
-                       PPC_ALTIVEC;
+                       PPC_ALTIVEC | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_VR) |
                     (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
@@ -7117,7 +7117,7 @@ POWERPC_FAMILY(7455)(ObjectClass *oc, vo
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
                        PPC_MEM_TLBIA | PPC_74xx_TLB |
                        PPC_SEGMENT | PPC_EXTERN |
-                       PPC_ALTIVEC;
+                       PPC_ALTIVEC | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_VR) |
                     (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
@@ -7279,7 +7279,7 @@ POWERPC_FAMILY(7457)(ObjectClass *oc, vo
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
                        PPC_MEM_TLBIA | PPC_74xx_TLB |
                        PPC_SEGMENT | PPC_EXTERN |
-                       PPC_ALTIVEC;
+                       PPC_ALTIVEC | PPC_RFI;
     pcc->msr_mask = (1ull << MSR_VR) |
                     (1ull << MSR_POW) |
                     (1ull << MSR_ILE) |
@@ -7416,7 +7416,7 @@ POWERPC_FAMILY(e600)(ObjectClass *oc, vo
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
                        PPC_MEM_TLBIA | PPC_74xx_TLB |
                        PPC_SEGMENT | PPC_EXTERN |
-                       PPC_ALTIVEC;
+                       PPC_ALTIVEC| PPC_RFI;
     pcc->insns_flags2 = PPC_NONE;
     pcc->msr_mask = (1ull << MSR_VR) |
                     (1ull << MSR_POW) |

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

* Re: [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-09-07 10:50                   ` Cédric Le Goater
@ 2016-09-07 11:08                     ` Benjamin Herrenschmidt
  2016-09-07 12:13                       ` Cédric Le Goater
  0 siblings, 1 reply; 30+ messages in thread
From: Benjamin Herrenschmidt @ 2016-09-07 11:08 UTC (permalink / raw)
  To: Cédric Le Goater, Mark Cave-Ayland, David Gibson
  Cc: Thomas Huth, qemu-devel, Alexander Graf, qemu-ppc

On Wed, 2016-09-07 at 12:50 +0200, Cédric Le Goater wrote:
> This is a bit broader than Ben's patch which used PPC_SEGMENT_64B. 
> it's basically !PPC_64B which includes the e5500.
> 
> If so, here is a proposal below adding a new PPC_RFI in the 
> "PowerPC Instructions types definitions" enum for that purpose. 
> Not much bits left there.

Why not stick to PPC_SEGMENT_64B ?

rfi exists on all 32-bit processors and all non-Book3S (aka server aka
segment/hash) 64-bit. So PPC_SEGMENT_64B is the test we want.

IE. rfi does exist on e5500

Cheers,
Ben.

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

* Re: [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-09-07 11:08                     ` Benjamin Herrenschmidt
@ 2016-09-07 12:13                       ` Cédric Le Goater
  2016-09-07 21:48                         ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 30+ messages in thread
From: Cédric Le Goater @ 2016-09-07 12:13 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Mark Cave-Ayland, David Gibson
  Cc: Thomas Huth, qemu-ppc, qemu-devel, Alexander Graf

On 09/07/2016 01:08 PM, Benjamin Herrenschmidt wrote:
> On Wed, 2016-09-07 at 12:50 +0200, Cédric Le Goater wrote:
>> This is a bit broader than Ben's patch which used PPC_SEGMENT_64B. 
>> it's basically !PPC_64B which includes the e5500.
>>
>> If so, here is a proposal below adding a new PPC_RFI in the 
>> "PowerPC Instructions types definitions" enum for that purpose. 
>> Not much bits left there.
> 
> Why not stick to PPC_SEGMENT_64B ?

I am trying to remove the rfi instruction from the set of the CPU 
and I think we need to introduce a new PPC_* bit for GEN_HANDLER to :

+GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_RFI),

we can also keep the test on PPC_SEGMENT_64B in the handler which 
works perfectly fine. 

> rfi exists on all 32-bit processors and all non-Book3S (aka server aka
> segment/hash) 64-bit. So PPC_SEGMENT_64B is the test we want.
> 
> IE. rfi does exist on e5500

ok.

Cheers,
C.

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

* Re: [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-09-07 12:13                       ` Cédric Le Goater
@ 2016-09-07 21:48                         ` Benjamin Herrenschmidt
  2016-09-08  6:59                           ` Cédric Le Goater
  0 siblings, 1 reply; 30+ messages in thread
From: Benjamin Herrenschmidt @ 2016-09-07 21:48 UTC (permalink / raw)
  To: Cédric Le Goater, Mark Cave-Ayland, David Gibson
  Cc: Thomas Huth, qemu-ppc, qemu-devel, Alexander Graf

On Wed, 2016-09-07 at 14:13 +0200, Cédric Le Goater wrote:
> On 09/07/2016 01:08 PM, Benjamin Herrenschmidt wrote:
> > 
> > On Wed, 2016-09-07 at 12:50 +0200, Cédric Le Goater wrote:
> > > 
> > > This is a bit broader than Ben's patch which used
> > > PPC_SEGMENT_64B. 
> > > it's basically !PPC_64B which includes the e5500.
> > > 
> > > If so, here is a proposal below adding a new PPC_RFI in the 
> > > "PowerPC Instructions types definitions" enum for that purpose. 
> > > Not much bits left there.
> > 
> > Why not stick to PPC_SEGMENT_64B ?
> 
> I am trying to remove the rfi instruction from the set of the CPU 
> and I think we need to introduce a new PPC_* bit for GEN_HANDLER to :

What does it buy you instead of just having the test in the handler ?

> +GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_RFI),
> 
> we can also keep the test on PPC_SEGMENT_64B in the handler which 
> works perfectly fine. 
> 
> > 
> > rfi exists on all 32-bit processors and all non-Book3S (aka server
> > aka
> > segment/hash) 64-bit. So PPC_SEGMENT_64B is the test we want.
> > 
> > IE. rfi does exist on e5500
> 
> ok.
> 
> Cheers,
> C.

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

* Re: [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-09-07 21:48                         ` Benjamin Herrenschmidt
@ 2016-09-08  6:59                           ` Cédric Le Goater
  0 siblings, 0 replies; 30+ messages in thread
From: Cédric Le Goater @ 2016-09-08  6:59 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Mark Cave-Ayland, David Gibson
  Cc: Thomas Huth, qemu-ppc, qemu-devel, Alexander Graf

On 09/07/2016 11:48 PM, Benjamin Herrenschmidt wrote:
> On Wed, 2016-09-07 at 14:13 +0200, Cédric Le Goater wrote:
>> On 09/07/2016 01:08 PM, Benjamin Herrenschmidt wrote:
>>>
>>> On Wed, 2016-09-07 at 12:50 +0200, Cédric Le Goater wrote:
>>>>
>>>> This is a bit broader than Ben's patch which used
>>>> PPC_SEGMENT_64B. 
>>>> it's basically !PPC_64B which includes the e5500.
>>>>
>>>> If so, here is a proposal below adding a new PPC_RFI in the 
>>>> "PowerPC Instructions types definitions" enum for that purpose. 
>>>> Not much bits left there.
>>>
>>> Why not stick to PPC_SEGMENT_64B ?
>>
>> I am trying to remove the rfi instruction from the set of the CPU 
>> and I think we need to introduce a new PPC_* bit for GEN_HANDLER to :
> 
> What does it buy you instead of just having the test in the handler ?

not much. I will send the remaining bit of the original patch.

Thanks,
C.


>> +GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_RFI),
>>
>> we can also keep the test on PPC_SEGMENT_64B in the handler which 
>> works perfectly fine. 
>>
>>>
>>> rfi exists on all 32-bit processors and all non-Book3S (aka server
>>> aka
>>> segment/hash) 64-bit. So PPC_SEGMENT_64B is the test we want.
>>>
>>> IE. rfi does exist on e5500
>>
>> ok.
>>
>> Cheers,
>> C.

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

end of thread, other threads:[~2016-09-08  6:59 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-21 21:48 [Qemu-devel] [PATCH v2 00/10] rework exception model to support the HV mode Cédric Le Goater
2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 01/10] ppc: Fix rfi/rfid/hrfi/... emulation Cédric Le Goater
2016-06-22  2:46   ` David Gibson
2016-06-22  6:48     ` Cédric Le Goater
2016-06-23  5:50       ` David Gibson
2016-06-23  6:08         ` Cédric Le Goater
2016-06-23  6:14           ` David Gibson
2016-07-15 15:17             ` [Qemu-devel] [Qemu-ppc] " Mark Cave-Ayland
2016-09-05 20:25         ` [Qemu-devel] " Thomas Huth
2016-09-05 20:30           ` Cédric Le Goater
2016-09-05 20:51             ` Mark Cave-Ayland
2016-09-06  0:16               ` David Gibson
2016-09-06  7:07                 ` Mark Cave-Ayland
2016-09-07 10:50                   ` Cédric Le Goater
2016-09-07 11:08                     ` Benjamin Herrenschmidt
2016-09-07 12:13                       ` Cédric Le Goater
2016-09-07 21:48                         ` Benjamin Herrenschmidt
2016-09-08  6:59                           ` Cédric Le Goater
2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 02/10] ppc: define a default LPCR value Cédric Le Goater
2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 03/10] ppc: fix exception model for HV mode Cédric Le Goater
2016-06-22  6:27   ` David Gibson
2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 04/10] ppc: Fix POWER7 and POWER8 exception definitions Cédric Le Goater
2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 05/10] ppc: Fix generation if ISI/DSI vs. HV mode Cédric Le Goater
2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 06/10] ppc: Rework generation of priv and inval interrupts Cédric Le Goater
2016-06-22  6:51   ` David Gibson
2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 07/10] ppc: Add real mode CI load/store instructions for P7 and P8 Cédric Le Goater
2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 08/10] ppc: Turn a bunch of booleans from int to bool Cédric Le Goater
2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 09/10] ppc: Move exception generation code out of line Cédric Le Goater
2016-06-22  6:57   ` David Gibson
2016-06-21 21:48 ` [Qemu-devel] [PATCH v2 10/10] ppc: Add P7/P8 Power Management instructions Cédric Le Goater

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.