qemu/target/ppc/excp_helper.c
<<
>>
Prefs
   1/*
   2 *  PowerPC exception emulation helpers for QEMU.
   3 *
   4 *  Copyright (c) 2003-2007 Jocelyn Mayer
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2.1 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 */
  19#include "qemu/osdep.h"
  20#include "qemu/main-loop.h"
  21#include "qemu/log.h"
  22#include "cpu.h"
  23#include "exec/exec-all.h"
  24#include "internal.h"
  25#include "helper_regs.h"
  26#include "hw/ppc/ppc.h"
  27
  28#include "trace.h"
  29
  30#ifdef CONFIG_TCG
  31#include "exec/helper-proto.h"
  32#include "exec/cpu_ldst.h"
  33#endif
  34
  35/*****************************************************************************/
  36/* Exception processing */
  37#if !defined(CONFIG_USER_ONLY)
  38
  39static const char *powerpc_excp_name(int excp)
  40{
  41    switch (excp) {
  42    case POWERPC_EXCP_CRITICAL: return "CRITICAL";
  43    case POWERPC_EXCP_MCHECK:   return "MCHECK";
  44    case POWERPC_EXCP_DSI:      return "DSI";
  45    case POWERPC_EXCP_ISI:      return "ISI";
  46    case POWERPC_EXCP_EXTERNAL: return "EXTERNAL";
  47    case POWERPC_EXCP_ALIGN:    return "ALIGN";
  48    case POWERPC_EXCP_PROGRAM:  return "PROGRAM";
  49    case POWERPC_EXCP_FPU:      return "FPU";
  50    case POWERPC_EXCP_SYSCALL:  return "SYSCALL";
  51    case POWERPC_EXCP_APU:      return "APU";
  52    case POWERPC_EXCP_DECR:     return "DECR";
  53    case POWERPC_EXCP_FIT:      return "FIT";
  54    case POWERPC_EXCP_WDT:      return "WDT";
  55    case POWERPC_EXCP_DTLB:     return "DTLB";
  56    case POWERPC_EXCP_ITLB:     return "ITLB";
  57    case POWERPC_EXCP_DEBUG:    return "DEBUG";
  58    case POWERPC_EXCP_SPEU:     return "SPEU";
  59    case POWERPC_EXCP_EFPDI:    return "EFPDI";
  60    case POWERPC_EXCP_EFPRI:    return "EFPRI";
  61    case POWERPC_EXCP_EPERFM:   return "EPERFM";
  62    case POWERPC_EXCP_DOORI:    return "DOORI";
  63    case POWERPC_EXCP_DOORCI:   return "DOORCI";
  64    case POWERPC_EXCP_GDOORI:   return "GDOORI";
  65    case POWERPC_EXCP_GDOORCI:  return "GDOORCI";
  66    case POWERPC_EXCP_HYPPRIV:  return "HYPPRIV";
  67    case POWERPC_EXCP_RESET:    return "RESET";
  68    case POWERPC_EXCP_DSEG:     return "DSEG";
  69    case POWERPC_EXCP_ISEG:     return "ISEG";
  70    case POWERPC_EXCP_HDECR:    return "HDECR";
  71    case POWERPC_EXCP_TRACE:    return "TRACE";
  72    case POWERPC_EXCP_HDSI:     return "HDSI";
  73    case POWERPC_EXCP_HISI:     return "HISI";
  74    case POWERPC_EXCP_HDSEG:    return "HDSEG";
  75    case POWERPC_EXCP_HISEG:    return "HISEG";
  76    case POWERPC_EXCP_VPU:      return "VPU";
  77    case POWERPC_EXCP_PIT:      return "PIT";
  78    case POWERPC_EXCP_EMUL:     return "EMUL";
  79    case POWERPC_EXCP_IFTLB:    return "IFTLB";
  80    case POWERPC_EXCP_DLTLB:    return "DLTLB";
  81    case POWERPC_EXCP_DSTLB:    return "DSTLB";
  82    case POWERPC_EXCP_FPA:      return "FPA";
  83    case POWERPC_EXCP_DABR:     return "DABR";
  84    case POWERPC_EXCP_IABR:     return "IABR";
  85    case POWERPC_EXCP_SMI:      return "SMI";
  86    case POWERPC_EXCP_PERFM:    return "PERFM";
  87    case POWERPC_EXCP_THERM:    return "THERM";
  88    case POWERPC_EXCP_VPUA:     return "VPUA";
  89    case POWERPC_EXCP_SOFTP:    return "SOFTP";
  90    case POWERPC_EXCP_MAINT:    return "MAINT";
  91    case POWERPC_EXCP_MEXTBR:   return "MEXTBR";
  92    case POWERPC_EXCP_NMEXTBR:  return "NMEXTBR";
  93    case POWERPC_EXCP_ITLBE:    return "ITLBE";
  94    case POWERPC_EXCP_DTLBE:    return "DTLBE";
  95    case POWERPC_EXCP_VSXU:     return "VSXU";
  96    case POWERPC_EXCP_FU:       return "FU";
  97    case POWERPC_EXCP_HV_EMU:   return "HV_EMU";
  98    case POWERPC_EXCP_HV_MAINT: return "HV_MAINT";
  99    case POWERPC_EXCP_HV_FU:    return "HV_FU";
 100    case POWERPC_EXCP_SDOOR:    return "SDOOR";
 101    case POWERPC_EXCP_SDOOR_HV: return "SDOOR_HV";
 102    case POWERPC_EXCP_HVIRT:    return "HVIRT";
 103    case POWERPC_EXCP_SYSCALL_VECTORED: return "SYSCALL_VECTORED";
 104    default:
 105        g_assert_not_reached();
 106    }
 107}
 108
 109static void dump_syscall(CPUPPCState *env)
 110{
 111    qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
 112                  " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64
 113                  " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64
 114                  " nip=" TARGET_FMT_lx "\n",
 115                  ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
 116                  ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
 117                  ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7),
 118                  ppc_dump_gpr(env, 8), env->nip);
 119}
 120
 121static void dump_hcall(CPUPPCState *env)
 122{
 123    qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64
 124                  " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
 125                  " r7=%016" PRIx64 " r8=%016" PRIx64 " r9=%016" PRIx64
 126                  " r10=%016" PRIx64 " r11=%016" PRIx64 " r12=%016" PRIx64
 127                  " nip=" TARGET_FMT_lx "\n",
 128                  ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4),
 129                  ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6),
 130                  ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8),
 131                  ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10),
 132                  ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12),
 133                  env->nip);
 134}
 135
 136static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp)
 137{
 138    const char *es;
 139    target_ulong *miss, *cmp;
 140    int en;
 141
 142    if (!qemu_loglevel_mask(CPU_LOG_MMU)) {
 143        return;
 144    }
 145
 146    if (excp == POWERPC_EXCP_IFTLB) {
 147        es = "I";
 148        en = 'I';
 149        miss = &env->spr[SPR_IMISS];
 150        cmp = &env->spr[SPR_ICMP];
 151    } else {
 152        if (excp == POWERPC_EXCP_DLTLB) {
 153            es = "DL";
 154        } else {
 155            es = "DS";
 156        }
 157        en = 'D';
 158        miss = &env->spr[SPR_DMISS];
 159        cmp = &env->spr[SPR_DCMP];
 160    }
 161    qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
 162             TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
 163             TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
 164             env->spr[SPR_HASH1], env->spr[SPR_HASH2],
 165             env->error_code);
 166}
 167
 168#if defined(TARGET_PPC64)
 169static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp,
 170                                target_ulong *msr)
 171{
 172    /* We no longer are in a PM state */
 173    env->resume_as_sreset = false;
 174
 175    /* Pretend to be returning from doze always as we don't lose state */
 176    *msr |= SRR1_WS_NOLOSS;
 177
 178    /* Machine checks are sent normally */
 179    if (excp == POWERPC_EXCP_MCHECK) {
 180        return excp;
 181    }
 182    switch (excp) {
 183    case POWERPC_EXCP_RESET:
 184        *msr |= SRR1_WAKERESET;
 185        break;
 186    case POWERPC_EXCP_EXTERNAL:
 187        *msr |= SRR1_WAKEEE;
 188        break;
 189    case POWERPC_EXCP_DECR:
 190        *msr |= SRR1_WAKEDEC;
 191        break;
 192    case POWERPC_EXCP_SDOOR:
 193        *msr |= SRR1_WAKEDBELL;
 194        break;
 195    case POWERPC_EXCP_SDOOR_HV:
 196        *msr |= SRR1_WAKEHDBELL;
 197        break;
 198    case POWERPC_EXCP_HV_MAINT:
 199        *msr |= SRR1_WAKEHMI;
 200        break;
 201    case POWERPC_EXCP_HVIRT:
 202        *msr |= SRR1_WAKEHVI;
 203        break;
 204    default:
 205        cpu_abort(cs, "Unsupported exception %d in Power Save mode\n",
 206                  excp);
 207    }
 208    return POWERPC_EXCP_RESET;
 209}
 210
 211/*
 212 * AIL - Alternate Interrupt Location, a mode that allows interrupts to be
 213 * taken with the MMU on, and which uses an alternate location (e.g., so the
 214 * kernel/hv can map the vectors there with an effective address).
 215 *
 216 * An interrupt is considered to be taken "with AIL" or "AIL applies" if they
 217 * are delivered in this way. AIL requires the LPCR to be set to enable this
 218 * mode, and then a number of conditions have to be true for AIL to apply.
 219 *
 220 * First of all, SRESET, MCE, and HMI are always delivered without AIL, because
 221 * they specifically want to be in real mode (e.g., the MCE might be signaling
 222 * a SLB multi-hit which requires SLB flush before the MMU can be enabled).
 223 *
 224 * After that, behaviour depends on the current MSR[IR], MSR[DR], MSR[HV],
 225 * whether or not the interrupt changes MSR[HV] from 0 to 1, and the current
 226 * radix mode (LPCR[HR]).
 227 *
 228 * POWER8, POWER9 with LPCR[HR]=0
 229 * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL |
 230 * +-----------+-------------+---------+-------------+-----+
 231 * | a         | 00/01/10    | x       | x           | 0   |
 232 * | a         | 11          | 0       | 1           | 0   |
 233 * | a         | 11          | 1       | 1           | a   |
 234 * | a         | 11          | 0       | 0           | a   |
 235 * +-------------------------------------------------------+
 236 *
 237 * POWER9 with LPCR[HR]=1
 238 * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL |
 239 * +-----------+-------------+---------+-------------+-----+
 240 * | a         | 00/01/10    | x       | x           | 0   |
 241 * | a         | 11          | x       | x           | a   |
 242 * +-------------------------------------------------------+
 243 *
 244 * The difference with POWER9 being that MSR[HV] 0->1 interrupts can be sent to
 245 * the hypervisor in AIL mode if the guest is radix. This is good for
 246 * performance but allows the guest to influence the AIL of hypervisor
 247 * interrupts using its MSR, and also the hypervisor must disallow guest
 248 * interrupts (MSR[HV] 0->0) from using AIL if the hypervisor does not want to
 249 * use AIL for its MSR[HV] 0->1 interrupts.
 250 *
 251 * POWER10 addresses those issues with a new LPCR[HAIL] bit that is applied to
 252 * interrupts that begin execution with MSR[HV]=1 (so both MSR[HV] 0->1 and
 253 * MSR[HV] 1->1).
 254 *
 255 * HAIL=1 is equivalent to AIL=3, for interrupts delivered with MSR[HV]=1.
 256 *
 257 * POWER10 behaviour is
 258 * | LPCR[AIL] | LPCR[HAIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL |
 259 * +-----------+------------+-------------+---------+-------------+-----+
 260 * | a         | h          | 00/01/10    | 0       | 0           | 0   |
 261 * | a         | h          | 11          | 0       | 0           | a   |
 262 * | a         | h          | x           | 0       | 1           | h   |
 263 * | a         | h          | 00/01/10    | 1       | 1           | 0   |
 264 * | a         | h          | 11          | 1       | 1           | h   |
 265 * +--------------------------------------------------------------------+
 266 */
 267static void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp, target_ulong msr,
 268                               target_ulong *new_msr, target_ulong *vector)
 269{
 270    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
 271    CPUPPCState *env = &cpu->env;
 272    bool mmu_all_on = ((msr >> MSR_IR) & 1) && ((msr >> MSR_DR) & 1);
 273    bool hv_escalation = !(msr & MSR_HVB) && (*new_msr & MSR_HVB);
 274    int ail = 0;
 275
 276    if (excp == POWERPC_EXCP_MCHECK ||
 277        excp == POWERPC_EXCP_RESET ||
 278        excp == POWERPC_EXCP_HV_MAINT) {
 279        /* SRESET, MCE, HMI never apply AIL */
 280        return;
 281    }
 282
 283    if (!(pcc->lpcr_mask & LPCR_AIL)) {
 284        /* This CPU does not have AIL */
 285        return;
 286    }
 287
 288    /* P8 & P9 */
 289    if (!(pcc->lpcr_mask & LPCR_HAIL)) {
 290        if (!mmu_all_on) {
 291            /* AIL only works if MSR[IR] and MSR[DR] are both enabled. */
 292            return;
 293        }
 294        if (hv_escalation && !(env->spr[SPR_LPCR] & LPCR_HR)) {
 295            /*
 296             * AIL does not work if there is a MSR[HV] 0->1 transition and the
 297             * partition is in HPT mode. For radix guests, such interrupts are
 298             * allowed to be delivered to the hypervisor in ail mode.
 299             */
 300            return;
 301        }
 302
 303        ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
 304        if (ail == 0) {
 305            return;
 306        }
 307        if (ail == 1) {
 308            /* AIL=1 is reserved, treat it like AIL=0 */
 309            return;
 310        }
 311
 312    /* P10 and up */
 313    } else {
 314        if (!mmu_all_on && !hv_escalation) {
 315            /*
 316             * AIL works for HV interrupts even with guest MSR[IR/DR] disabled.
 317             * Guest->guest and HV->HV interrupts do require MMU on.
 318             */
 319            return;
 320        }
 321
 322        if (*new_msr & MSR_HVB) {
 323            if (!(env->spr[SPR_LPCR] & LPCR_HAIL)) {
 324                /* HV interrupts depend on LPCR[HAIL] */
 325                return;
 326            }
 327            ail = 3; /* HAIL=1 gives AIL=3 behaviour for HV interrupts */
 328        } else {
 329            ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
 330        }
 331        if (ail == 0) {
 332            return;
 333        }
 334        if (ail == 1 || ail == 2) {
 335            /* AIL=1 and AIL=2 are reserved, treat them like AIL=0 */
 336            return;
 337        }
 338    }
 339
 340    /*
 341     * AIL applies, so the new MSR gets IR and DR set, and an offset applied
 342     * to the new IP.
 343     */
 344    *new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
 345
 346    if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
 347        if (ail == 2) {
 348            *vector |= 0x0000000000018000ull;
 349        } else if (ail == 3) {
 350            *vector |= 0xc000000000004000ull;
 351        }
 352    } else {
 353        /*
 354         * scv AIL is a little different. AIL=2 does not change the address,
 355         * only the MSR. AIL=3 replaces the 0x17000 base with 0xc...3000.
 356         */
 357        if (ail == 3) {
 358            *vector &= ~0x0000000000017000ull; /* Un-apply the base offset */
 359            *vector |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */
 360        }
 361    }
 362}
 363#endif
 364
 365static void powerpc_reset_excp_state(PowerPCCPU *cpu)
 366{
 367    CPUState *cs = CPU(cpu);
 368    CPUPPCState *env = &cpu->env;
 369
 370    /* Reset exception state */
 371    cs->exception_index = POWERPC_EXCP_NONE;
 372    env->error_code = 0;
 373}
 374
 375static void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector,
 376                                   target_ulong msr)
 377{
 378    CPUPPCState *env = &cpu->env;
 379
 380    assert((msr & env->msr_mask) == msr);
 381
 382    /*
 383     * We don't use hreg_store_msr here as already have treated any
 384     * special case that could occur. Just store MSR and update hflags
 385     *
 386     * Note: We *MUST* not use hreg_store_msr() as-is anyway because it
 387     * will prevent setting of the HV bit which some exceptions might need
 388     * to do.
 389     */
 390    env->nip = vector;
 391    env->msr = msr;
 392    hreg_compute_hflags(env);
 393    ppc_maybe_interrupt(env);
 394
 395    powerpc_reset_excp_state(cpu);
 396
 397    /*
 398     * Any interrupt is context synchronizing, check if TCG TLB needs
 399     * a delayed flush on ppc64
 400     */
 401    check_tlb_flush(env, false);
 402
 403    /* Reset the reservation */
 404    env->reserve_addr = -1;
 405}
 406
 407static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
 408{
 409    CPUState *cs = CPU(cpu);
 410    CPUPPCState *env = &cpu->env;
 411    target_ulong msr, new_msr, vector;
 412    int srr0, srr1;
 413
 414    /* new srr1 value excluding must-be-zero bits */
 415    msr = env->msr & ~0x783f0000ULL;
 416
 417    /*
 418     * new interrupt handler msr preserves existing ME unless
 419     * explicitly overriden.
 420     */
 421    new_msr = env->msr & (((target_ulong)1 << MSR_ME));
 422
 423    /* target registers */
 424    srr0 = SPR_SRR0;
 425    srr1 = SPR_SRR1;
 426
 427    /*
 428     * Hypervisor emulation assistance interrupt only exists on server
 429     * arch 2.05 server or later.
 430     */
 431    if (excp == POWERPC_EXCP_HV_EMU) {
 432        excp = POWERPC_EXCP_PROGRAM;
 433    }
 434
 435    vector = env->excp_vectors[excp];
 436    if (vector == (target_ulong)-1ULL) {
 437        cpu_abort(cs, "Raised an exception without defined vector %d\n",
 438                  excp);
 439    }
 440
 441    vector |= env->excp_prefix;
 442
 443    switch (excp) {
 444    case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
 445        srr0 = SPR_40x_SRR2;
 446        srr1 = SPR_40x_SRR3;
 447        break;
 448    case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
 449        if (!FIELD_EX64(env->msr, MSR, ME)) {
 450            /*
 451             * Machine check exception is not enabled.  Enter
 452             * checkstop state.
 453             */
 454            fprintf(stderr, "Machine check while not allowed. "
 455                    "Entering checkstop state\n");
 456            if (qemu_log_separate()) {
 457                qemu_log("Machine check while not allowed. "
 458                        "Entering checkstop state\n");
 459            }
 460            cs->halted = 1;
 461            cpu_interrupt_exittb(cs);
 462        }
 463
 464        /* machine check exceptions don't have ME set */
 465        new_msr &= ~((target_ulong)1 << MSR_ME);
 466
 467        srr0 = SPR_40x_SRR2;
 468        srr1 = SPR_40x_SRR3;
 469        break;
 470    case POWERPC_EXCP_DSI:       /* Data storage exception                   */
 471        trace_ppc_excp_dsi(env->spr[SPR_40x_ESR], env->spr[SPR_40x_DEAR]);
 472        break;
 473    case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
 474        trace_ppc_excp_isi(msr, env->nip);
 475        break;
 476    case POWERPC_EXCP_EXTERNAL:  /* External input                           */
 477        break;
 478    case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
 479        break;
 480    case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
 481        switch (env->error_code & ~0xF) {
 482        case POWERPC_EXCP_FP:
 483            if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
 484                trace_ppc_excp_fp_ignore();
 485                powerpc_reset_excp_state(cpu);
 486                return;
 487            }
 488            env->spr[SPR_40x_ESR] = ESR_FP;
 489            break;
 490        case POWERPC_EXCP_INVAL:
 491            trace_ppc_excp_inval(env->nip);
 492            env->spr[SPR_40x_ESR] = ESR_PIL;
 493            break;
 494        case POWERPC_EXCP_PRIV:
 495            env->spr[SPR_40x_ESR] = ESR_PPR;
 496            break;
 497        case POWERPC_EXCP_TRAP:
 498            env->spr[SPR_40x_ESR] = ESR_PTR;
 499            break;
 500        default:
 501            cpu_abort(cs, "Invalid program exception %d. Aborting\n",
 502                      env->error_code);
 503            break;
 504        }
 505        break;
 506    case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
 507        dump_syscall(env);
 508
 509        /*
 510         * We need to correct the NIP which in this case is supposed
 511         * to point to the next instruction
 512         */
 513        env->nip += 4;
 514        break;
 515    case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
 516        trace_ppc_excp_print("FIT");
 517        break;
 518    case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
 519        trace_ppc_excp_print("WDT");
 520        break;
 521    case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
 522    case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
 523        break;
 524    case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
 525        trace_ppc_excp_print("PIT");
 526        break;
 527    case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
 528        cpu_abort(cs, "%s exception not implemented\n",
 529                  powerpc_excp_name(excp));
 530        break;
 531    default:
 532        cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
 533        break;
 534    }
 535
 536    /* Save PC */
 537    env->spr[srr0] = env->nip;
 538
 539    /* Save MSR */
 540    env->spr[srr1] = msr;
 541
 542    powerpc_set_excp_state(cpu, vector, new_msr);
 543}
 544
 545static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
 546{
 547    CPUState *cs = CPU(cpu);
 548    CPUPPCState *env = &cpu->env;
 549    target_ulong msr, new_msr, vector;
 550
 551    /* new srr1 value excluding must-be-zero bits */
 552    msr = env->msr & ~0x783f0000ULL;
 553
 554    /*
 555     * new interrupt handler msr preserves existing ME unless
 556     * explicitly overriden
 557     */
 558    new_msr = env->msr & ((target_ulong)1 << MSR_ME);
 559
 560    /*
 561     * Hypervisor emulation assistance interrupt only exists on server
 562     * arch 2.05 server or later.
 563     */
 564    if (excp == POWERPC_EXCP_HV_EMU) {
 565        excp = POWERPC_EXCP_PROGRAM;
 566    }
 567
 568    vector = env->excp_vectors[excp];
 569    if (vector == (target_ulong)-1ULL) {
 570        cpu_abort(cs, "Raised an exception without defined vector %d\n",
 571                  excp);
 572    }
 573
 574    vector |= env->excp_prefix;
 575
 576    switch (excp) {
 577    case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
 578        break;
 579    case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
 580        if (!FIELD_EX64(env->msr, MSR, ME)) {
 581            /*
 582             * Machine check exception is not enabled.  Enter
 583             * checkstop state.
 584             */
 585            fprintf(stderr, "Machine check while not allowed. "
 586                    "Entering checkstop state\n");
 587            if (qemu_log_separate()) {
 588                qemu_log("Machine check while not allowed. "
 589                        "Entering checkstop state\n");
 590            }
 591            cs->halted = 1;
 592            cpu_interrupt_exittb(cs);
 593        }
 594
 595        /* machine check exceptions don't have ME set */
 596        new_msr &= ~((target_ulong)1 << MSR_ME);
 597
 598        break;
 599    case POWERPC_EXCP_DSI:       /* Data storage exception                   */
 600        trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
 601        break;
 602    case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
 603        trace_ppc_excp_isi(msr, env->nip);
 604        msr |= env->error_code;
 605        break;
 606    case POWERPC_EXCP_EXTERNAL:  /* External input                           */
 607        break;
 608    case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
 609        /* Get rS/rD and rA from faulting opcode */
 610        /*
 611         * Note: the opcode fields will not be set properly for a
 612         * direct store load/store, but nobody cares as nobody
 613         * actually uses direct store segments.
 614         */
 615        env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
 616        break;
 617    case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
 618        switch (env->error_code & ~0xF) {
 619        case POWERPC_EXCP_FP:
 620            if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
 621                trace_ppc_excp_fp_ignore();
 622                powerpc_reset_excp_state(cpu);
 623                return;
 624            }
 625
 626            /*
 627             * FP exceptions always have NIP pointing to the faulting
 628             * instruction, so always use store_next and claim we are
 629             * precise in the MSR.
 630             */
 631            msr |= 0x00100000;
 632            break;
 633        case POWERPC_EXCP_INVAL:
 634            trace_ppc_excp_inval(env->nip);
 635            msr |= 0x00080000;
 636            break;
 637        case POWERPC_EXCP_PRIV:
 638            msr |= 0x00040000;
 639            break;
 640        case POWERPC_EXCP_TRAP:
 641            msr |= 0x00020000;
 642            break;
 643        default:
 644            /* Should never occur */
 645            cpu_abort(cs, "Invalid program exception %d. Aborting\n",
 646                      env->error_code);
 647            break;
 648        }
 649        break;
 650    case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
 651        dump_syscall(env);
 652
 653        /*
 654         * We need to correct the NIP which in this case is supposed
 655         * to point to the next instruction
 656         */
 657        env->nip += 4;
 658        break;
 659    case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
 660    case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
 661        break;
 662    case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
 663    case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
 664        break;
 665    case POWERPC_EXCP_RESET:     /* System reset exception                   */
 666        if (FIELD_EX64(env->msr, MSR, POW)) {
 667            cpu_abort(cs, "Trying to deliver power-saving system reset "
 668                      "exception %d with no HV support\n", excp);
 669        }
 670        break;
 671    case POWERPC_EXCP_TRACE:     /* Trace exception                          */
 672        break;
 673    case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
 674    case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
 675    case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
 676        /* Swap temporary saved registers with GPRs */
 677        if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
 678            new_msr |= (target_ulong)1 << MSR_TGPR;
 679            hreg_swap_gpr_tgpr(env);
 680        }
 681
 682        ppc_excp_debug_sw_tlb(env, excp);
 683
 684        msr |= env->crf[0] << 28;
 685        msr |= env->error_code; /* key, D/I, S/L bits */
 686        /* Set way using a LRU mechanism */
 687        msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
 688        break;
 689    case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */
 690    case POWERPC_EXCP_DABR:      /* Data address breakpoint                  */
 691    case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
 692    case POWERPC_EXCP_SMI:       /* System management interrupt              */
 693    case POWERPC_EXCP_MEXTBR:    /* Maskable external breakpoint             */
 694    case POWERPC_EXCP_NMEXTBR:   /* Non maskable external breakpoint         */
 695        cpu_abort(cs, "%s exception not implemented\n",
 696                  powerpc_excp_name(excp));
 697        break;
 698    default:
 699        cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
 700        break;
 701    }
 702
 703    /*
 704     * Sort out endianness of interrupt, this differs depending on the
 705     * CPU, the HV mode, etc...
 706     */
 707    if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
 708        new_msr |= (target_ulong)1 << MSR_LE;
 709    }
 710
 711    /* Save PC */
 712    env->spr[SPR_SRR0] = env->nip;
 713
 714    /* Save MSR */
 715    env->spr[SPR_SRR1] = msr;
 716
 717    powerpc_set_excp_state(cpu, vector, new_msr);
 718}
 719
 720static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
 721{
 722    CPUState *cs = CPU(cpu);
 723    CPUPPCState *env = &cpu->env;
 724    target_ulong msr, new_msr, vector;
 725
 726    /* new srr1 value excluding must-be-zero bits */
 727    msr = env->msr & ~0x783f0000ULL;
 728
 729    /*
 730     * new interrupt handler msr preserves existing ME unless
 731     * explicitly overriden
 732     */
 733    new_msr = env->msr & ((target_ulong)1 << MSR_ME);
 734
 735    /*
 736     * Hypervisor emulation assistance interrupt only exists on server
 737     * arch 2.05 server or later.
 738     */
 739    if (excp == POWERPC_EXCP_HV_EMU) {
 740        excp = POWERPC_EXCP_PROGRAM;
 741    }
 742
 743    vector = env->excp_vectors[excp];
 744    if (vector == (target_ulong)-1ULL) {
 745        cpu_abort(cs, "Raised an exception without defined vector %d\n",
 746                  excp);
 747    }
 748
 749    vector |= env->excp_prefix;
 750
 751    switch (excp) {
 752    case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
 753        if (!FIELD_EX64(env->msr, MSR, ME)) {
 754            /*
 755             * Machine check exception is not enabled.  Enter
 756             * checkstop state.
 757             */
 758            fprintf(stderr, "Machine check while not allowed. "
 759                    "Entering checkstop state\n");
 760            if (qemu_log_separate()) {
 761                qemu_log("Machine check while not allowed. "
 762                        "Entering checkstop state\n");
 763            }
 764            cs->halted = 1;
 765            cpu_interrupt_exittb(cs);
 766        }
 767
 768        /* machine check exceptions don't have ME set */
 769        new_msr &= ~((target_ulong)1 << MSR_ME);
 770
 771        break;
 772    case POWERPC_EXCP_DSI:       /* Data storage exception                   */
 773        trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
 774        break;
 775    case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
 776        trace_ppc_excp_isi(msr, env->nip);
 777        msr |= env->error_code;
 778        break;
 779    case POWERPC_EXCP_EXTERNAL:  /* External input                           */
 780        break;
 781    case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
 782        /* Get rS/rD and rA from faulting opcode */
 783        /*
 784         * Note: the opcode fields will not be set properly for a
 785         * direct store load/store, but nobody cares as nobody
 786         * actually uses direct store segments.
 787         */
 788        env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
 789        break;
 790    case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
 791        switch (env->error_code & ~0xF) {
 792        case POWERPC_EXCP_FP:
 793            if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
 794                trace_ppc_excp_fp_ignore();
 795                powerpc_reset_excp_state(cpu);
 796                return;
 797            }
 798
 799            /*
 800             * FP exceptions always have NIP pointing to the faulting
 801             * instruction, so always use store_next and claim we are
 802             * precise in the MSR.
 803             */
 804            msr |= 0x00100000;
 805            break;
 806        case POWERPC_EXCP_INVAL:
 807            trace_ppc_excp_inval(env->nip);
 808            msr |= 0x00080000;
 809            break;
 810        case POWERPC_EXCP_PRIV:
 811            msr |= 0x00040000;
 812            break;
 813        case POWERPC_EXCP_TRAP:
 814            msr |= 0x00020000;
 815            break;
 816        default:
 817            /* Should never occur */
 818            cpu_abort(cs, "Invalid program exception %d. Aborting\n",
 819                      env->error_code);
 820            break;
 821        }
 822        break;
 823    case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
 824    {
 825        int lev = env->error_code;
 826
 827        if (lev == 1 && cpu->vhyp) {
 828            dump_hcall(env);
 829        } else {
 830            dump_syscall(env);
 831        }
 832
 833        /*
 834         * We need to correct the NIP which in this case is supposed
 835         * to point to the next instruction
 836         */
 837        env->nip += 4;
 838
 839        /*
 840         * The Virtual Open Firmware (VOF) relies on the 'sc 1'
 841         * instruction to communicate with QEMU. The pegasos2 machine
 842         * uses VOF and the 7xx CPUs, so although the 7xx don't have
 843         * HV mode, we need to keep hypercall support.
 844         */
 845        if (lev == 1 && cpu->vhyp) {
 846            PPCVirtualHypervisorClass *vhc =
 847                PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
 848            vhc->hypercall(cpu->vhyp, cpu);
 849            return;
 850        }
 851
 852        break;
 853    }
 854    case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
 855    case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
 856        break;
 857    case POWERPC_EXCP_RESET:     /* System reset exception                   */
 858        if (FIELD_EX64(env->msr, MSR, POW)) {
 859            cpu_abort(cs, "Trying to deliver power-saving system reset "
 860                      "exception %d with no HV support\n", excp);
 861        }
 862        break;
 863    case POWERPC_EXCP_TRACE:     /* Trace exception                          */
 864        break;
 865    case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
 866    case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
 867    case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
 868        ppc_excp_debug_sw_tlb(env, excp);
 869
 870        msr |= env->crf[0] << 28;
 871        msr |= env->error_code; /* key, D/I, S/L bits */
 872        /* Set way using a LRU mechanism */
 873        msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
 874
 875        break;
 876    case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
 877    case POWERPC_EXCP_SMI:       /* System management interrupt              */
 878    case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
 879    case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
 880        cpu_abort(cs, "%s exception not implemented\n",
 881                  powerpc_excp_name(excp));
 882        break;
 883    default:
 884        cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
 885        break;
 886    }
 887
 888    /*
 889     * Sort out endianness of interrupt, this differs depending on the
 890     * CPU, the HV mode, etc...
 891     */
 892    if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
 893        new_msr |= (target_ulong)1 << MSR_LE;
 894    }
 895
 896    /* Save PC */
 897    env->spr[SPR_SRR0] = env->nip;
 898
 899    /* Save MSR */
 900    env->spr[SPR_SRR1] = msr;
 901
 902    powerpc_set_excp_state(cpu, vector, new_msr);
 903}
 904
 905static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
 906{
 907    CPUState *cs = CPU(cpu);
 908    CPUPPCState *env = &cpu->env;
 909    target_ulong msr, new_msr, vector;
 910
 911    /* new srr1 value excluding must-be-zero bits */
 912    msr = env->msr & ~0x783f0000ULL;
 913
 914    /*
 915     * new interrupt handler msr preserves existing ME unless
 916     * explicitly overriden
 917     */
 918    new_msr = env->msr & ((target_ulong)1 << MSR_ME);
 919
 920    /*
 921     * Hypervisor emulation assistance interrupt only exists on server
 922     * arch 2.05 server or later.
 923     */
 924    if (excp == POWERPC_EXCP_HV_EMU) {
 925        excp = POWERPC_EXCP_PROGRAM;
 926    }
 927
 928    vector = env->excp_vectors[excp];
 929    if (vector == (target_ulong)-1ULL) {
 930        cpu_abort(cs, "Raised an exception without defined vector %d\n",
 931                  excp);
 932    }
 933
 934    vector |= env->excp_prefix;
 935
 936    switch (excp) {
 937    case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
 938        if (!FIELD_EX64(env->msr, MSR, ME)) {
 939            /*
 940             * Machine check exception is not enabled.  Enter
 941             * checkstop state.
 942             */
 943            fprintf(stderr, "Machine check while not allowed. "
 944                    "Entering checkstop state\n");
 945            if (qemu_log_separate()) {
 946                qemu_log("Machine check while not allowed. "
 947                        "Entering checkstop state\n");
 948            }
 949            cs->halted = 1;
 950            cpu_interrupt_exittb(cs);
 951        }
 952
 953        /* machine check exceptions don't have ME set */
 954        new_msr &= ~((target_ulong)1 << MSR_ME);
 955
 956        break;
 957    case POWERPC_EXCP_DSI:       /* Data storage exception                   */
 958        trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
 959        break;
 960    case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
 961        trace_ppc_excp_isi(msr, env->nip);
 962        msr |= env->error_code;
 963        break;
 964    case POWERPC_EXCP_EXTERNAL:  /* External input                           */
 965        break;
 966    case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
 967        /* Get rS/rD and rA from faulting opcode */
 968        /*
 969         * Note: the opcode fields will not be set properly for a
 970         * direct store load/store, but nobody cares as nobody
 971         * actually uses direct store segments.
 972         */
 973        env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
 974        break;
 975    case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
 976        switch (env->error_code & ~0xF) {
 977        case POWERPC_EXCP_FP:
 978            if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
 979                trace_ppc_excp_fp_ignore();
 980                powerpc_reset_excp_state(cpu);
 981                return;
 982            }
 983
 984            /*
 985             * FP exceptions always have NIP pointing to the faulting
 986             * instruction, so always use store_next and claim we are
 987             * precise in the MSR.
 988             */
 989            msr |= 0x00100000;
 990            break;
 991        case POWERPC_EXCP_INVAL:
 992            trace_ppc_excp_inval(env->nip);
 993            msr |= 0x00080000;
 994            break;
 995        case POWERPC_EXCP_PRIV:
 996            msr |= 0x00040000;
 997            break;
 998        case POWERPC_EXCP_TRAP:
 999            msr |= 0x00020000;
1000            break;
1001        default:
1002            /* Should never occur */
1003            cpu_abort(cs, "Invalid program exception %d. Aborting\n",
1004                      env->error_code);
1005            break;
1006        }
1007        break;
1008    case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
1009    {
1010        int lev = env->error_code;
1011
1012        if ((lev == 1) && cpu->vhyp) {
1013            dump_hcall(env);
1014        } else {
1015            dump_syscall(env);
1016        }
1017
1018        /*
1019         * We need to correct the NIP which in this case is supposed
1020         * to point to the next instruction
1021         */
1022        env->nip += 4;
1023
1024        /*
1025         * The Virtual Open Firmware (VOF) relies on the 'sc 1'
1026         * instruction to communicate with QEMU. The pegasos2 machine
1027         * uses VOF and the 74xx CPUs, so although the 74xx don't have
1028         * HV mode, we need to keep hypercall support.
1029         */
1030        if ((lev == 1) && cpu->vhyp) {
1031            PPCVirtualHypervisorClass *vhc =
1032                PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
1033            vhc->hypercall(cpu->vhyp, cpu);
1034            return;
1035        }
1036
1037        break;
1038    }
1039    case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
1040    case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
1041        break;
1042    case POWERPC_EXCP_RESET:     /* System reset exception                   */
1043        if (FIELD_EX64(env->msr, MSR, POW)) {
1044            cpu_abort(cs, "Trying to deliver power-saving system reset "
1045                      "exception %d with no HV support\n", excp);
1046        }
1047        break;
1048    case POWERPC_EXCP_TRACE:     /* Trace exception                          */
1049        break;
1050    case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
1051        break;
1052    case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
1053    case POWERPC_EXCP_SMI:       /* System management interrupt              */
1054    case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
1055    case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
1056    case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
1057        cpu_abort(cs, "%s exception not implemented\n",
1058                  powerpc_excp_name(excp));
1059        break;
1060    default:
1061        cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1062        break;
1063    }
1064
1065    /*
1066     * Sort out endianness of interrupt, this differs depending on the
1067     * CPU, the HV mode, etc...
1068     */
1069    if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
1070        new_msr |= (target_ulong)1 << MSR_LE;
1071    }
1072
1073    /* Save PC */
1074    env->spr[SPR_SRR0] = env->nip;
1075
1076    /* Save MSR */
1077    env->spr[SPR_SRR1] = msr;
1078
1079    powerpc_set_excp_state(cpu, vector, new_msr);
1080}
1081
1082static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
1083{
1084    CPUState *cs = CPU(cpu);
1085    CPUPPCState *env = &cpu->env;
1086    target_ulong msr, new_msr, vector;
1087    int srr0, srr1;
1088
1089    msr = env->msr;
1090
1091    /*
1092     * new interrupt handler msr preserves existing ME unless
1093     * explicitly overriden
1094     */
1095    new_msr = env->msr & ((target_ulong)1 << MSR_ME);
1096
1097    /* target registers */
1098    srr0 = SPR_SRR0;
1099    srr1 = SPR_SRR1;
1100
1101    /*
1102     * Hypervisor emulation assistance interrupt only exists on server
1103     * arch 2.05 server or later.
1104     */
1105    if (excp == POWERPC_EXCP_HV_EMU) {
1106        excp = POWERPC_EXCP_PROGRAM;
1107    }
1108
1109#ifdef TARGET_PPC64
1110    /*
1111     * SPEU and VPU share the same IVOR but they exist in different
1112     * processors. SPEU is e500v1/2 only and VPU is e6500 only.
1113     */
1114    if (excp == POWERPC_EXCP_VPU) {
1115        excp = POWERPC_EXCP_SPEU;
1116    }
1117#endif
1118
1119    vector = env->excp_vectors[excp];
1120    if (vector == (target_ulong)-1ULL) {
1121        cpu_abort(cs, "Raised an exception without defined vector %d\n",
1122                  excp);
1123    }
1124
1125    vector |= env->excp_prefix;
1126
1127    switch (excp) {
1128    case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
1129        srr0 = SPR_BOOKE_CSRR0;
1130        srr1 = SPR_BOOKE_CSRR1;
1131        break;
1132    case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
1133        if (!FIELD_EX64(env->msr, MSR, ME)) {
1134            /*
1135             * Machine check exception is not enabled.  Enter
1136             * checkstop state.
1137             */
1138            fprintf(stderr, "Machine check while not allowed. "
1139                    "Entering checkstop state\n");
1140            if (qemu_log_separate()) {
1141                qemu_log("Machine check while not allowed. "
1142                        "Entering checkstop state\n");
1143            }
1144            cs->halted = 1;
1145            cpu_interrupt_exittb(cs);
1146        }
1147
1148        /* machine check exceptions don't have ME set */
1149        new_msr &= ~((target_ulong)1 << MSR_ME);
1150
1151        /* FIXME: choose one or the other based on CPU type */
1152        srr0 = SPR_BOOKE_MCSRR0;
1153        srr1 = SPR_BOOKE_MCSRR1;
1154
1155        env->spr[SPR_BOOKE_CSRR0] = env->nip;
1156        env->spr[SPR_BOOKE_CSRR1] = msr;
1157
1158        break;
1159    case POWERPC_EXCP_DSI:       /* Data storage exception                   */
1160        trace_ppc_excp_dsi(env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
1161        break;
1162    case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
1163        trace_ppc_excp_isi(msr, env->nip);
1164        break;
1165    case POWERPC_EXCP_EXTERNAL:  /* External input                           */
1166        if (env->mpic_proxy) {
1167            /* IACK the IRQ on delivery */
1168            env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
1169        }
1170        break;
1171    case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
1172        break;
1173    case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
1174        switch (env->error_code & ~0xF) {
1175        case POWERPC_EXCP_FP:
1176            if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
1177                trace_ppc_excp_fp_ignore();
1178                powerpc_reset_excp_state(cpu);
1179                return;
1180            }
1181
1182            /*
1183             * FP exceptions always have NIP pointing to the faulting
1184             * instruction, so always use store_next and claim we are
1185             * precise in the MSR.
1186             */
1187            msr |= 0x00100000;
1188            env->spr[SPR_BOOKE_ESR] = ESR_FP;
1189            break;
1190        case POWERPC_EXCP_INVAL:
1191            trace_ppc_excp_inval(env->nip);
1192            msr |= 0x00080000;
1193            env->spr[SPR_BOOKE_ESR] = ESR_PIL;
1194            break;
1195        case POWERPC_EXCP_PRIV:
1196            msr |= 0x00040000;
1197            env->spr[SPR_BOOKE_ESR] = ESR_PPR;
1198            break;
1199        case POWERPC_EXCP_TRAP:
1200            msr |= 0x00020000;
1201            env->spr[SPR_BOOKE_ESR] = ESR_PTR;
1202            break;
1203        default:
1204            /* Should never occur */
1205            cpu_abort(cs, "Invalid program exception %d. Aborting\n",
1206                      env->error_code);
1207            break;
1208        }
1209        break;
1210    case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
1211        dump_syscall(env);
1212
1213        /*
1214         * We need to correct the NIP which in this case is supposed
1215         * to point to the next instruction
1216         */
1217        env->nip += 4;
1218        break;
1219    case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
1220    case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
1221    case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
1222        break;
1223    case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
1224        /* FIT on 4xx */
1225        trace_ppc_excp_print("FIT");
1226        break;
1227    case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
1228        trace_ppc_excp_print("WDT");
1229        srr0 = SPR_BOOKE_CSRR0;
1230        srr1 = SPR_BOOKE_CSRR1;
1231        break;
1232    case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
1233    case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
1234        break;
1235    case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
1236        if (env->flags & POWERPC_FLAG_DE) {
1237            /* FIXME: choose one or the other based on CPU type */
1238            srr0 = SPR_BOOKE_DSRR0;
1239            srr1 = SPR_BOOKE_DSRR1;
1240
1241            env->spr[SPR_BOOKE_CSRR0] = env->nip;
1242            env->spr[SPR_BOOKE_CSRR1] = msr;
1243
1244            /* DBSR already modified by caller */
1245        } else {
1246            cpu_abort(cs, "Debug exception triggered on unsupported model\n");
1247        }
1248        break;
1249    case POWERPC_EXCP_SPEU:   /* SPE/embedded floating-point unavailable/VPU  */
1250        env->spr[SPR_BOOKE_ESR] = ESR_SPV;
1251        break;
1252    case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */
1253        break;
1254    case POWERPC_EXCP_DOORCI:    /* Embedded doorbell critical interrupt     */
1255        srr0 = SPR_BOOKE_CSRR0;
1256        srr1 = SPR_BOOKE_CSRR1;
1257        break;
1258    case POWERPC_EXCP_RESET:     /* System reset exception                   */
1259        if (FIELD_EX64(env->msr, MSR, POW)) {
1260            cpu_abort(cs, "Trying to deliver power-saving system reset "
1261                      "exception %d with no HV support\n", excp);
1262        }
1263        break;
1264    case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */
1265    case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */
1266        cpu_abort(cs, "%s exception not implemented\n",
1267                  powerpc_excp_name(excp));
1268        break;
1269    default:
1270        cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1271        break;
1272    }
1273
1274#if defined(TARGET_PPC64)
1275    if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
1276        /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */
1277        new_msr |= (target_ulong)1 << MSR_CM;
1278    } else {
1279        vector = (uint32_t)vector;
1280    }
1281#endif
1282
1283    /* Save PC */
1284    env->spr[srr0] = env->nip;
1285
1286    /* Save MSR */
1287    env->spr[srr1] = msr;
1288
1289    powerpc_set_excp_state(cpu, vector, new_msr);
1290}
1291
1292/*
1293 * When running a nested HV guest under vhyp, external interrupts are
1294 * delivered as HVIRT.
1295 */
1296static bool books_vhyp_promotes_external_to_hvirt(PowerPCCPU *cpu)
1297{
1298    if (cpu->vhyp) {
1299        return vhyp_cpu_in_nested(cpu);
1300    }
1301    return false;
1302}
1303
1304#ifdef TARGET_PPC64
1305/*
1306 * When running under vhyp, hcalls are always intercepted and sent to the
1307 * vhc->hypercall handler.
1308 */
1309static bool books_vhyp_handles_hcall(PowerPCCPU *cpu)
1310{
1311    if (cpu->vhyp) {
1312        return !vhyp_cpu_in_nested(cpu);
1313    }
1314    return false;
1315}
1316
1317/*
1318 * When running a nested KVM HV guest under vhyp, HV exceptions are not
1319 * delivered to the guest (because there is no concept of HV support), but
1320 * rather they are sent tothe vhyp to exit from the L2 back to the L1 and
1321 * return from the H_ENTER_NESTED hypercall.
1322 */
1323static bool books_vhyp_handles_hv_excp(PowerPCCPU *cpu)
1324{
1325    if (cpu->vhyp) {
1326        return vhyp_cpu_in_nested(cpu);
1327    }
1328    return false;
1329}
1330
1331static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
1332{
1333    CPUState *cs = CPU(cpu);
1334    CPUPPCState *env = &cpu->env;
1335    target_ulong msr, new_msr, vector;
1336    int srr0, srr1, lev = -1;
1337
1338    /* new srr1 value excluding must-be-zero bits */
1339    msr = env->msr & ~0x783f0000ULL;
1340
1341    /*
1342     * new interrupt handler msr preserves existing HV and ME unless
1343     * explicitly overriden
1344     */
1345    new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
1346
1347    /* target registers */
1348    srr0 = SPR_SRR0;
1349    srr1 = SPR_SRR1;
1350
1351    /*
1352     * check for special resume at 0x100 from doze/nap/sleep/winkle on
1353     * P7/P8/P9
1354     */
1355    if (env->resume_as_sreset) {
1356        excp = powerpc_reset_wakeup(cs, env, excp, &msr);
1357    }
1358
1359    /*
1360     * We don't want to generate a Hypervisor Emulation Assistance
1361     * Interrupt if we don't have HVB in msr_mask (PAPR mode),
1362     * unless running a nested-hv guest, in which case the L1
1363     * kernel wants the interrupt.
1364     */
1365    if (excp == POWERPC_EXCP_HV_EMU && !(env->msr_mask & MSR_HVB) &&
1366            !books_vhyp_handles_hv_excp(cpu)) {
1367        excp = POWERPC_EXCP_PROGRAM;
1368    }
1369
1370    vector = env->excp_vectors[excp];
1371    if (vector == (target_ulong)-1ULL) {
1372        cpu_abort(cs, "Raised an exception without defined vector %d\n",
1373                  excp);
1374    }
1375
1376    vector |= env->excp_prefix;
1377
1378    switch (excp) {
1379    case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
1380        if (!FIELD_EX64(env->msr, MSR, ME)) {
1381            /*
1382             * Machine check exception is not enabled.  Enter
1383             * checkstop state.
1384             */
1385            fprintf(stderr, "Machine check while not allowed. "
1386                    "Entering checkstop state\n");
1387            if (qemu_log_separate()) {
1388                qemu_log("Machine check while not allowed. "
1389                        "Entering checkstop state\n");
1390            }
1391            cs->halted = 1;
1392            cpu_interrupt_exittb(cs);
1393        }
1394        if (env->msr_mask & MSR_HVB) {
1395            /*
1396             * ISA specifies HV, but can be delivered to guest with HV
1397             * clear (e.g., see FWNMI in PAPR).
1398             */
1399            new_msr |= (target_ulong)MSR_HVB;
1400        }
1401
1402        /* machine check exceptions don't have ME set */
1403        new_msr &= ~((target_ulong)1 << MSR_ME);
1404
1405        break;
1406    case POWERPC_EXCP_DSI:       /* Data storage exception                   */
1407        trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
1408        break;
1409    case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
1410        trace_ppc_excp_isi(msr, env->nip);
1411        msr |= env->error_code;
1412        break;
1413    case POWERPC_EXCP_EXTERNAL:  /* External input                           */
1414    {
1415        bool lpes0;
1416
1417        /*
1418         * LPES0 is only taken into consideration if we support HV
1419         * mode for this CPU.
1420         */
1421        if (!env->has_hv_mode) {
1422            break;
1423        }
1424
1425        lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
1426
1427        if (!lpes0) {
1428            new_msr |= (target_ulong)MSR_HVB;
1429            new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1430            srr0 = SPR_HSRR0;
1431            srr1 = SPR_HSRR1;
1432        }
1433
1434        break;
1435    }
1436    case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
1437        /* Get rS/rD and rA from faulting opcode */
1438        /*
1439         * Note: the opcode fields will not be set properly for a
1440         * direct store load/store, but nobody cares as nobody
1441         * actually uses direct store segments.
1442         */
1443        env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
1444        break;
1445    case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
1446        switch (env->error_code & ~0xF) {
1447        case POWERPC_EXCP_FP:
1448            if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
1449                trace_ppc_excp_fp_ignore();
1450                powerpc_reset_excp_state(cpu);
1451                return;
1452            }
1453
1454            /*
1455             * FP exceptions always have NIP pointing to the faulting
1456             * instruction, so always use store_next and claim we are
1457             * precise in the MSR.
1458             */
1459            msr |= 0x00100000;
1460            break;
1461        case POWERPC_EXCP_INVAL:
1462            trace_ppc_excp_inval(env->nip);
1463            msr |= 0x00080000;
1464            break;
1465        case POWERPC_EXCP_PRIV:
1466            msr |= 0x00040000;
1467            break;
1468        case POWERPC_EXCP_TRAP:
1469            msr |= 0x00020000;
1470            break;
1471        default:
1472            /* Should never occur */
1473            cpu_abort(cs, "Invalid program exception %d. Aborting\n",
1474                      env->error_code);
1475            break;
1476        }
1477        break;
1478    case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
1479        lev = env->error_code;
1480
1481        if ((lev == 1) && cpu->vhyp) {
1482            dump_hcall(env);
1483        } else {
1484            dump_syscall(env);
1485        }
1486
1487        /*
1488         * We need to correct the NIP which in this case is supposed
1489         * to point to the next instruction
1490         */
1491        env->nip += 4;
1492
1493        /* "PAPR mode" built-in hypercall emulation */
1494        if ((lev == 1) && books_vhyp_handles_hcall(cpu)) {
1495            PPCVirtualHypervisorClass *vhc =
1496                PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
1497            vhc->hypercall(cpu->vhyp, cpu);
1498            return;
1499        }
1500        if (lev == 1) {
1501            new_msr |= (target_ulong)MSR_HVB;
1502        }
1503        break;
1504    case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception                     */
1505        lev = env->error_code;
1506        dump_syscall(env);
1507        env->nip += 4;
1508        new_msr |= env->msr & ((target_ulong)1 << MSR_EE);
1509        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1510
1511        vector += lev * 0x20;
1512
1513        env->lr = env->nip;
1514        env->ctr = msr;
1515        break;
1516    case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
1517    case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
1518        break;
1519    case POWERPC_EXCP_RESET:     /* System reset exception                   */
1520        /* A power-saving exception sets ME, otherwise it is unchanged */
1521        if (FIELD_EX64(env->msr, MSR, POW)) {
1522            /* indicate that we resumed from power save mode */
1523            msr |= 0x10000;
1524            new_msr |= ((target_ulong)1 << MSR_ME);
1525        }
1526        if (env->msr_mask & MSR_HVB) {
1527            /*
1528             * ISA specifies HV, but can be delivered to guest with HV
1529             * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU).
1530             */
1531            new_msr |= (target_ulong)MSR_HVB;
1532        } else {
1533            if (FIELD_EX64(env->msr, MSR, POW)) {
1534                cpu_abort(cs, "Trying to deliver power-saving system reset "
1535                          "exception %d with no HV support\n", excp);
1536            }
1537        }
1538        break;
1539    case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
1540    case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
1541    case POWERPC_EXCP_TRACE:     /* Trace exception                          */
1542        break;
1543    case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
1544        msr |= env->error_code;
1545        /* fall through */
1546    case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
1547    case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
1548    case POWERPC_EXCP_SDOOR_HV:  /* Hypervisor Doorbell interrupt            */
1549    case POWERPC_EXCP_HV_EMU:
1550    case POWERPC_EXCP_HVIRT:     /* Hypervisor virtualization                */
1551        srr0 = SPR_HSRR0;
1552        srr1 = SPR_HSRR1;
1553        new_msr |= (target_ulong)MSR_HVB;
1554        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1555        break;
1556    case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
1557    case POWERPC_EXCP_VSXU:       /* VSX unavailable exception               */
1558    case POWERPC_EXCP_FU:         /* Facility unavailable exception          */
1559        env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56);
1560        break;
1561    case POWERPC_EXCP_HV_FU:     /* Hypervisor Facility Unavailable Exception */
1562        env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS);
1563        srr0 = SPR_HSRR0;
1564        srr1 = SPR_HSRR1;
1565        new_msr |= (target_ulong)MSR_HVB;
1566        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1567        break;
1568    case POWERPC_EXCP_PERFM_EBB:        /* Performance Monitor EBB Exception  */
1569    case POWERPC_EXCP_EXTERNAL_EBB:     /* External EBB Exception             */
1570        env->spr[SPR_BESCR] &= ~BESCR_GE;
1571
1572        /*
1573         * Save NIP for rfebb insn in SPR_EBBRR. Next nip is
1574         * stored in the EBB Handler SPR_EBBHR.
1575         */
1576        env->spr[SPR_EBBRR] = env->nip;
1577        powerpc_set_excp_state(cpu, env->spr[SPR_EBBHR], env->msr);
1578
1579        /*
1580         * This exception is handled in userspace. No need to proceed.
1581         */
1582        return;
1583    case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
1584    case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
1585    case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
1586    case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */
1587    case POWERPC_EXCP_SDOOR:     /* Doorbell interrupt                       */
1588    case POWERPC_EXCP_HV_MAINT:  /* Hypervisor Maintenance exception         */
1589        cpu_abort(cs, "%s exception not implemented\n",
1590                  powerpc_excp_name(excp));
1591        break;
1592    default:
1593        cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1594        break;
1595    }
1596
1597    /*
1598     * Sort out endianness of interrupt, this differs depending on the
1599     * CPU, the HV mode, etc...
1600     */
1601    if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
1602        new_msr |= (target_ulong)1 << MSR_LE;
1603    }
1604
1605    new_msr |= (target_ulong)1 << MSR_SF;
1606
1607    if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
1608        /* Save PC */
1609        env->spr[srr0] = env->nip;
1610
1611        /* Save MSR */
1612        env->spr[srr1] = msr;
1613    }
1614
1615    if ((new_msr & MSR_HVB) && books_vhyp_handles_hv_excp(cpu)) {
1616        PPCVirtualHypervisorClass *vhc =
1617            PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
1618        /* Deliver interrupt to L1 by returning from the H_ENTER_NESTED call */
1619        vhc->deliver_hv_excp(cpu, excp);
1620
1621        powerpc_reset_excp_state(cpu);
1622
1623    } else {
1624        /* Sanity check */
1625        if (!(env->msr_mask & MSR_HVB) && srr0 == SPR_HSRR0) {
1626            cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
1627                      "no HV support\n", excp);
1628        }
1629
1630        /* This can update new_msr and vector if AIL applies */
1631        ppc_excp_apply_ail(cpu, excp, msr, &new_msr, &vector);
1632
1633        powerpc_set_excp_state(cpu, vector, new_msr);
1634    }
1635}
1636#else
1637static inline void powerpc_excp_books(PowerPCCPU *cpu, int excp)
1638{
1639    g_assert_not_reached();
1640}
1641#endif
1642
1643static void powerpc_excp(PowerPCCPU *cpu, int excp)
1644{
1645    CPUState *cs = CPU(cpu);
1646    CPUPPCState *env = &cpu->env;
1647
1648    if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
1649        cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1650    }
1651
1652    qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
1653                  " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp),
1654                  excp, env->error_code);
1655
1656    switch (env->excp_model) {
1657    case POWERPC_EXCP_40x:
1658        powerpc_excp_40x(cpu, excp);
1659        break;
1660    case POWERPC_EXCP_6xx:
1661        powerpc_excp_6xx(cpu, excp);
1662        break;
1663    case POWERPC_EXCP_7xx:
1664        powerpc_excp_7xx(cpu, excp);
1665        break;
1666    case POWERPC_EXCP_74xx:
1667        powerpc_excp_74xx(cpu, excp);
1668        break;
1669    case POWERPC_EXCP_BOOKE:
1670        powerpc_excp_booke(cpu, excp);
1671        break;
1672    case POWERPC_EXCP_970:
1673    case POWERPC_EXCP_POWER7:
1674    case POWERPC_EXCP_POWER8:
1675    case POWERPC_EXCP_POWER9:
1676    case POWERPC_EXCP_POWER10:
1677        powerpc_excp_books(cpu, excp);
1678        break;
1679    default:
1680        g_assert_not_reached();
1681    }
1682}
1683
1684void ppc_cpu_do_interrupt(CPUState *cs)
1685{
1686    PowerPCCPU *cpu = POWERPC_CPU(cs);
1687
1688    powerpc_excp(cpu, cs->exception_index);
1689}
1690
1691#if defined(TARGET_PPC64)
1692#define P7_UNUSED_INTERRUPTS \
1693    (PPC_INTERRUPT_RESET | PPC_INTERRUPT_HVIRT | PPC_INTERRUPT_CEXT |       \
1694     PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | PPC_INTERRUPT_FIT |      \
1695     PPC_INTERRUPT_PIT | PPC_INTERRUPT_DOORBELL | PPC_INTERRUPT_HDOORBELL | \
1696     PPC_INTERRUPT_THERM | PPC_INTERRUPT_EBB)
1697
1698static int p7_interrupt_powersave(CPUPPCState *env)
1699{
1700    if ((env->pending_interrupts & PPC_INTERRUPT_EXT) &&
1701        (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
1702        return PPC_INTERRUPT_EXT;
1703    }
1704    if ((env->pending_interrupts & PPC_INTERRUPT_DECR) &&
1705        (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
1706        return PPC_INTERRUPT_DECR;
1707    }
1708    if ((env->pending_interrupts & PPC_INTERRUPT_MCK) &&
1709        (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
1710        return PPC_INTERRUPT_MCK;
1711    }
1712    if ((env->pending_interrupts & PPC_INTERRUPT_HMI) &&
1713        (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
1714        return PPC_INTERRUPT_HMI;
1715    }
1716    if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
1717        return PPC_INTERRUPT_RESET;
1718    }
1719    return 0;
1720}
1721
1722static int p7_next_unmasked_interrupt(CPUPPCState *env)
1723{
1724    PowerPCCPU *cpu = env_archcpu(env);
1725    CPUState *cs = CPU(cpu);
1726    /* Ignore MSR[EE] when coming out of some power management states */
1727    bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
1728
1729    assert((env->pending_interrupts & P7_UNUSED_INTERRUPTS) == 0);
1730
1731    if (cs->halted) {
1732        /* LPCR[PECE] controls which interrupts can exit power-saving mode */
1733        return p7_interrupt_powersave(env);
1734    }
1735
1736    /* Machine check exception */
1737    if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
1738        return PPC_INTERRUPT_MCK;
1739    }
1740
1741    /* Hypervisor decrementer exception */
1742    if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
1743        /* LPCR will be clear when not supported so this will work */
1744        bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
1745        if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
1746            /* HDEC clears on delivery */
1747            return PPC_INTERRUPT_HDECR;
1748        }
1749    }
1750
1751    /* External interrupt can ignore MSR:EE under some circumstances */
1752    if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
1753        bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
1754        bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
1755        /* HEIC blocks delivery to the hypervisor */
1756        if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) &&
1757            !FIELD_EX64(env->msr, MSR, PR))) ||
1758            (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) {
1759            return PPC_INTERRUPT_EXT;
1760        }
1761    }
1762    if (msr_ee != 0) {
1763        /* Decrementer exception */
1764        if (env->pending_interrupts & PPC_INTERRUPT_DECR) {
1765            return PPC_INTERRUPT_DECR;
1766        }
1767        if (env->pending_interrupts & PPC_INTERRUPT_PERFM) {
1768            return PPC_INTERRUPT_PERFM;
1769        }
1770    }
1771
1772    return 0;
1773}
1774
1775#define P8_UNUSED_INTERRUPTS \
1776    (PPC_INTERRUPT_RESET | PPC_INTERRUPT_DEBUG | PPC_INTERRUPT_HVIRT |  \
1777    PPC_INTERRUPT_CEXT | PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL |  \
1778    PPC_INTERRUPT_FIT | PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM)
1779
1780static int p8_interrupt_powersave(CPUPPCState *env)
1781{
1782    if ((env->pending_interrupts & PPC_INTERRUPT_EXT) &&
1783        (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
1784        return PPC_INTERRUPT_EXT;
1785    }
1786    if ((env->pending_interrupts & PPC_INTERRUPT_DECR) &&
1787        (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
1788        return PPC_INTERRUPT_DECR;
1789    }
1790    if ((env->pending_interrupts & PPC_INTERRUPT_MCK) &&
1791        (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
1792        return PPC_INTERRUPT_MCK;
1793    }
1794    if ((env->pending_interrupts & PPC_INTERRUPT_HMI) &&
1795        (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
1796        return PPC_INTERRUPT_HMI;
1797    }
1798    if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
1799        (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
1800        return PPC_INTERRUPT_DOORBELL;
1801    }
1802    if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
1803        (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
1804        return PPC_INTERRUPT_HDOORBELL;
1805    }
1806    if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
1807        return PPC_INTERRUPT_RESET;
1808    }
1809    return 0;
1810}
1811
1812static int p8_next_unmasked_interrupt(CPUPPCState *env)
1813{
1814    PowerPCCPU *cpu = env_archcpu(env);
1815    CPUState *cs = CPU(cpu);
1816    /* Ignore MSR[EE] when coming out of some power management states */
1817    bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
1818
1819    assert((env->pending_interrupts & P8_UNUSED_INTERRUPTS) == 0);
1820
1821    if (cs->halted) {
1822        /* LPCR[PECE] controls which interrupts can exit power-saving mode */
1823        return p8_interrupt_powersave(env);
1824    }
1825
1826    /* Machine check exception */
1827    if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
1828        return PPC_INTERRUPT_MCK;
1829    }
1830
1831    /* Hypervisor decrementer exception */
1832    if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
1833        /* LPCR will be clear when not supported so this will work */
1834        bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
1835        if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
1836            /* HDEC clears on delivery */
1837            return PPC_INTERRUPT_HDECR;
1838        }
1839    }
1840
1841    /* External interrupt can ignore MSR:EE under some circumstances */
1842    if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
1843        bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
1844        bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
1845        /* HEIC blocks delivery to the hypervisor */
1846        if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) &&
1847            !FIELD_EX64(env->msr, MSR, PR))) ||
1848            (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) {
1849            return PPC_INTERRUPT_EXT;
1850        }
1851    }
1852    if (msr_ee != 0) {
1853        /* Decrementer exception */
1854        if (env->pending_interrupts & PPC_INTERRUPT_DECR) {
1855            return PPC_INTERRUPT_DECR;
1856        }
1857        if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) {
1858            return PPC_INTERRUPT_DOORBELL;
1859        }
1860        if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) {
1861            return PPC_INTERRUPT_HDOORBELL;
1862        }
1863        if (env->pending_interrupts & PPC_INTERRUPT_PERFM) {
1864            return PPC_INTERRUPT_PERFM;
1865        }
1866        /* EBB exception */
1867        if (env->pending_interrupts & PPC_INTERRUPT_EBB) {
1868            /*
1869             * EBB exception must be taken in problem state and
1870             * with BESCR_GE set.
1871             */
1872            if (FIELD_EX64(env->msr, MSR, PR) &&
1873                (env->spr[SPR_BESCR] & BESCR_GE)) {
1874                return PPC_INTERRUPT_EBB;
1875            }
1876        }
1877    }
1878
1879    return 0;
1880}
1881
1882#define P9_UNUSED_INTERRUPTS \
1883    (PPC_INTERRUPT_RESET | PPC_INTERRUPT_DEBUG | PPC_INTERRUPT_CEXT |   \
1884     PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | PPC_INTERRUPT_FIT |  \
1885     PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM)
1886
1887static int p9_interrupt_powersave(CPUPPCState *env)
1888{
1889    /* External Exception */
1890    if ((env->pending_interrupts & PPC_INTERRUPT_EXT) &&
1891        (env->spr[SPR_LPCR] & LPCR_EEE)) {
1892        bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
1893        if (!heic || !FIELD_EX64_HV(env->msr) ||
1894            FIELD_EX64(env->msr, MSR, PR)) {
1895            return PPC_INTERRUPT_EXT;
1896        }
1897    }
1898    /* Decrementer Exception */
1899    if ((env->pending_interrupts & PPC_INTERRUPT_DECR) &&
1900        (env->spr[SPR_LPCR] & LPCR_DEE)) {
1901        return PPC_INTERRUPT_DECR;
1902    }
1903    /* Machine Check or Hypervisor Maintenance Exception */
1904    if (env->spr[SPR_LPCR] & LPCR_OEE) {
1905        if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
1906            return PPC_INTERRUPT_MCK;
1907        }
1908        if (env->pending_interrupts & PPC_INTERRUPT_HMI) {
1909            return PPC_INTERRUPT_HMI;
1910        }
1911    }
1912    /* Privileged Doorbell Exception */
1913    if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
1914        (env->spr[SPR_LPCR] & LPCR_PDEE)) {
1915        return PPC_INTERRUPT_DOORBELL;
1916    }
1917    /* Hypervisor Doorbell Exception */
1918    if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
1919        (env->spr[SPR_LPCR] & LPCR_HDEE)) {
1920        return PPC_INTERRUPT_HDOORBELL;
1921    }
1922    /* Hypervisor virtualization exception */
1923    if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) &&
1924        (env->spr[SPR_LPCR] & LPCR_HVEE)) {
1925        return PPC_INTERRUPT_HVIRT;
1926    }
1927    if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
1928        return PPC_INTERRUPT_RESET;
1929    }
1930    return 0;
1931}
1932
1933static int p9_next_unmasked_interrupt(CPUPPCState *env)
1934{
1935    PowerPCCPU *cpu = env_archcpu(env);
1936    CPUState *cs = CPU(cpu);
1937    /* Ignore MSR[EE] when coming out of some power management states */
1938    bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
1939
1940    assert((env->pending_interrupts & P9_UNUSED_INTERRUPTS) == 0);
1941
1942    if (cs->halted) {
1943        if (env->spr[SPR_PSSCR] & PSSCR_EC) {
1944            /*
1945             * When PSSCR[EC] is set, LPCR[PECE] controls which interrupts can
1946             * wakeup the processor
1947             */
1948            return p9_interrupt_powersave(env);
1949        } else {
1950            /*
1951             * When it's clear, any system-caused exception exits power-saving
1952             * mode, even the ones that gate on MSR[EE].
1953             */
1954            msr_ee = true;
1955        }
1956    }
1957
1958    /* Machine check exception */
1959    if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
1960        return PPC_INTERRUPT_MCK;
1961    }
1962
1963    /* Hypervisor decrementer exception */
1964    if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
1965        /* LPCR will be clear when not supported so this will work */
1966        bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
1967        if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
1968            /* HDEC clears on delivery */
1969            return PPC_INTERRUPT_HDECR;
1970        }
1971    }
1972
1973    /* Hypervisor virtualization interrupt */
1974    if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) {
1975        /* LPCR will be clear when not supported so this will work */
1976        bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
1977        if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hvice) {
1978            return PPC_INTERRUPT_HVIRT;
1979        }
1980    }
1981
1982    /* External interrupt can ignore MSR:EE under some circumstances */
1983    if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
1984        bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
1985        bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
1986        /* HEIC blocks delivery to the hypervisor */
1987        if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) &&
1988            !FIELD_EX64(env->msr, MSR, PR))) ||
1989            (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) {
1990            return PPC_INTERRUPT_EXT;
1991        }
1992    }
1993    if (msr_ee != 0) {
1994        /* Decrementer exception */
1995        if (env->pending_interrupts & PPC_INTERRUPT_DECR) {
1996            return PPC_INTERRUPT_DECR;
1997        }
1998        if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) {
1999            return PPC_INTERRUPT_DOORBELL;
2000        }
2001        if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) {
2002            return PPC_INTERRUPT_HDOORBELL;
2003        }
2004        if (env->pending_interrupts & PPC_INTERRUPT_PERFM) {
2005            return PPC_INTERRUPT_PERFM;
2006        }
2007        /* EBB exception */
2008        if (env->pending_interrupts & PPC_INTERRUPT_EBB) {
2009            /*
2010             * EBB exception must be taken in problem state and
2011             * with BESCR_GE set.
2012             */
2013            if (FIELD_EX64(env->msr, MSR, PR) &&
2014                (env->spr[SPR_BESCR] & BESCR_GE)) {
2015                return PPC_INTERRUPT_EBB;
2016            }
2017        }
2018    }
2019
2020    return 0;
2021}
2022#endif
2023
2024static int ppc_next_unmasked_interrupt_generic(CPUPPCState *env)
2025{
2026    bool async_deliver;
2027
2028    /* External reset */
2029    if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
2030        return PPC_INTERRUPT_RESET;
2031    }
2032    /* Machine check exception */
2033    if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
2034        return PPC_INTERRUPT_MCK;
2035    }
2036#if 0 /* TODO */
2037    /* External debug exception */
2038    if (env->pending_interrupts & PPC_INTERRUPT_DEBUG) {
2039        return PPC_INTERRUPT_DEBUG;
2040    }
2041#endif
2042
2043    /*
2044     * For interrupts that gate on MSR:EE, we need to do something a
2045     * bit more subtle, as we need to let them through even when EE is
2046     * clear when coming out of some power management states (in order
2047     * for them to become a 0x100).
2048     */
2049    async_deliver = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
2050
2051    /* Hypervisor decrementer exception */
2052    if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
2053        /* LPCR will be clear when not supported so this will work */
2054        bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
2055        if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hdice) {
2056            /* HDEC clears on delivery */
2057            return PPC_INTERRUPT_HDECR;
2058        }
2059    }
2060
2061    /* Hypervisor virtualization interrupt */
2062    if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) {
2063        /* LPCR will be clear when not supported so this will work */
2064        bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
2065        if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hvice) {
2066            return PPC_INTERRUPT_HVIRT;
2067        }
2068    }
2069
2070    /* External interrupt can ignore MSR:EE under some circumstances */
2071    if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
2072        bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
2073        bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
2074        /* HEIC blocks delivery to the hypervisor */
2075        if ((async_deliver && !(heic && FIELD_EX64_HV(env->msr) &&
2076            !FIELD_EX64(env->msr, MSR, PR))) ||
2077            (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) {
2078            return PPC_INTERRUPT_EXT;
2079        }
2080    }
2081    if (FIELD_EX64(env->msr, MSR, CE)) {
2082        /* External critical interrupt */
2083        if (env->pending_interrupts & PPC_INTERRUPT_CEXT) {
2084            return PPC_INTERRUPT_CEXT;
2085        }
2086    }
2087    if (async_deliver != 0) {
2088        /* Watchdog timer on embedded PowerPC */
2089        if (env->pending_interrupts & PPC_INTERRUPT_WDT) {
2090            return PPC_INTERRUPT_WDT;
2091        }
2092        if (env->pending_interrupts & PPC_INTERRUPT_CDOORBELL) {
2093            return PPC_INTERRUPT_CDOORBELL;
2094        }
2095        /* Fixed interval timer on embedded PowerPC */
2096        if (env->pending_interrupts & PPC_INTERRUPT_FIT) {
2097            return PPC_INTERRUPT_FIT;
2098        }
2099        /* Programmable interval timer on embedded PowerPC */
2100        if (env->pending_interrupts & PPC_INTERRUPT_PIT) {
2101            return PPC_INTERRUPT_PIT;
2102        }
2103        /* Decrementer exception */
2104        if (env->pending_interrupts & PPC_INTERRUPT_DECR) {
2105            return PPC_INTERRUPT_DECR;
2106        }
2107        if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) {
2108            return PPC_INTERRUPT_DOORBELL;
2109        }
2110        if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) {
2111            return PPC_INTERRUPT_HDOORBELL;
2112        }
2113        if (env->pending_interrupts & PPC_INTERRUPT_PERFM) {
2114            return PPC_INTERRUPT_PERFM;
2115        }
2116        /* Thermal interrupt */
2117        if (env->pending_interrupts & PPC_INTERRUPT_THERM) {
2118            return PPC_INTERRUPT_THERM;
2119        }
2120        /* EBB exception */
2121        if (env->pending_interrupts & PPC_INTERRUPT_EBB) {
2122            /*
2123             * EBB exception must be taken in problem state and
2124             * with BESCR_GE set.
2125             */
2126            if (FIELD_EX64(env->msr, MSR, PR) &&
2127                (env->spr[SPR_BESCR] & BESCR_GE)) {
2128                return PPC_INTERRUPT_EBB;
2129            }
2130        }
2131    }
2132
2133    return 0;
2134}
2135
2136static int ppc_next_unmasked_interrupt(CPUPPCState *env)
2137{
2138    switch (env->excp_model) {
2139#if defined(TARGET_PPC64)
2140    case POWERPC_EXCP_POWER7:
2141        return p7_next_unmasked_interrupt(env);
2142    case POWERPC_EXCP_POWER8:
2143        return p8_next_unmasked_interrupt(env);
2144    case POWERPC_EXCP_POWER9:
2145    case POWERPC_EXCP_POWER10:
2146        return p9_next_unmasked_interrupt(env);
2147#endif
2148    default:
2149        return ppc_next_unmasked_interrupt_generic(env);
2150    }
2151}
2152
2153/*
2154 * Sets CPU_INTERRUPT_HARD if there is at least one unmasked interrupt to be
2155 * delivered and clears CPU_INTERRUPT_HARD otherwise.
2156 *
2157 * This method is called by ppc_set_interrupt when an interrupt is raised or
2158 * lowered, and should also be called whenever an interrupt masking condition
2159 * is changed, e.g.:
2160 *  - When relevant bits of MSR are altered, like EE, HV, PR, etc.;
2161 *  - When relevant bits of LPCR are altered, like PECE, HDICE, HVICE, etc.;
2162 *  - When PSSCR[EC] or env->resume_as_sreset are changed;
2163 *  - When cs->halted is changed and the CPU has a different interrupt masking
2164 *    logic in power-saving mode (e.g., POWER7/8/9/10);
2165 */
2166void ppc_maybe_interrupt(CPUPPCState *env)
2167{
2168    CPUState *cs = env_cpu(env);
2169    QEMU_IOTHREAD_LOCK_GUARD();
2170
2171    if (ppc_next_unmasked_interrupt(env)) {
2172        cpu_interrupt(cs, CPU_INTERRUPT_HARD);
2173    } else {
2174        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
2175    }
2176}
2177
2178#if defined(TARGET_PPC64)
2179static void p7_deliver_interrupt(CPUPPCState *env, int interrupt)
2180{
2181    PowerPCCPU *cpu = env_archcpu(env);
2182    CPUState *cs = env_cpu(env);
2183
2184    switch (interrupt) {
2185    case PPC_INTERRUPT_MCK: /* Machine check exception */
2186        env->pending_interrupts &= ~PPC_INTERRUPT_MCK;
2187        powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
2188        break;
2189
2190    case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */
2191        /* HDEC clears on delivery */
2192        env->pending_interrupts &= ~PPC_INTERRUPT_HDECR;
2193        powerpc_excp(cpu, POWERPC_EXCP_HDECR);
2194        break;
2195
2196    case PPC_INTERRUPT_EXT:
2197        if (books_vhyp_promotes_external_to_hvirt(cpu)) {
2198            powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2199        } else {
2200            powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
2201        }
2202        break;
2203
2204    case PPC_INTERRUPT_DECR: /* Decrementer exception */
2205        powerpc_excp(cpu, POWERPC_EXCP_DECR);
2206        break;
2207    case PPC_INTERRUPT_PERFM:
2208        env->pending_interrupts &= ~PPC_INTERRUPT_PERFM;
2209        powerpc_excp(cpu, POWERPC_EXCP_PERFM);
2210        break;
2211    case 0:
2212        /*
2213         * This is a bug ! It means that has_work took us out of halt without
2214         * anything to deliver while in a PM state that requires getting
2215         * out via a 0x100
2216         *
2217         * This means we will incorrectly execute past the power management
2218         * instruction instead of triggering a reset.
2219         *
2220         * It generally means a discrepancy between the wakeup conditions in the
2221         * processor has_work implementation and the logic in this function.
2222         */
2223        assert(!env->resume_as_sreset);
2224        break;
2225    default:
2226        cpu_abort(cs, "Invalid PowerPC interrupt %d. Aborting\n", interrupt);
2227    }
2228}
2229
2230static void p8_deliver_interrupt(CPUPPCState *env, int interrupt)
2231{
2232    PowerPCCPU *cpu = env_archcpu(env);
2233    CPUState *cs = env_cpu(env);
2234
2235    switch (interrupt) {
2236    case PPC_INTERRUPT_MCK: /* Machine check exception */
2237        env->pending_interrupts &= ~PPC_INTERRUPT_MCK;
2238        powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
2239        break;
2240
2241    case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */
2242        /* HDEC clears on delivery */
2243        env->pending_interrupts &= ~PPC_INTERRUPT_HDECR;
2244        powerpc_excp(cpu, POWERPC_EXCP_HDECR);
2245        break;
2246
2247    case PPC_INTERRUPT_EXT:
2248        if (books_vhyp_promotes_external_to_hvirt(cpu)) {
2249            powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2250        } else {
2251            powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
2252        }
2253        break;
2254
2255    case PPC_INTERRUPT_DECR: /* Decrementer exception */
2256        powerpc_excp(cpu, POWERPC_EXCP_DECR);
2257        break;
2258    case PPC_INTERRUPT_DOORBELL:
2259        env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL;
2260        if (is_book3s_arch2x(env)) {
2261            powerpc_excp(cpu, POWERPC_EXCP_SDOOR);
2262        } else {
2263            powerpc_excp(cpu, POWERPC_EXCP_DOORI);
2264        }
2265        break;
2266    case PPC_INTERRUPT_HDOORBELL:
2267        env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL;
2268        powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV);
2269        break;
2270    case PPC_INTERRUPT_PERFM:
2271        env->pending_interrupts &= ~PPC_INTERRUPT_PERFM;
2272        powerpc_excp(cpu, POWERPC_EXCP_PERFM);
2273        break;
2274    case PPC_INTERRUPT_EBB: /* EBB exception */
2275        env->pending_interrupts &= ~PPC_INTERRUPT_EBB;
2276        if (env->spr[SPR_BESCR] & BESCR_PMEO) {
2277            powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB);
2278        } else if (env->spr[SPR_BESCR] & BESCR_EEO) {
2279            powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB);
2280        }
2281        break;
2282    case 0:
2283        /*
2284         * This is a bug ! It means that has_work took us out of halt without
2285         * anything to deliver while in a PM state that requires getting
2286         * out via a 0x100
2287         *
2288         * This means we will incorrectly execute past the power management
2289         * instruction instead of triggering a reset.
2290         *
2291         * It generally means a discrepancy between the wakeup conditions in the
2292         * processor has_work implementation and the logic in this function.
2293         */
2294        assert(!env->resume_as_sreset);
2295        break;
2296    default:
2297        cpu_abort(cs, "Invalid PowerPC interrupt %d. Aborting\n", interrupt);
2298    }
2299}
2300
2301static void p9_deliver_interrupt(CPUPPCState *env, int interrupt)
2302{
2303    PowerPCCPU *cpu = env_archcpu(env);
2304    CPUState *cs = env_cpu(env);
2305
2306    if (cs->halted && !(env->spr[SPR_PSSCR] & PSSCR_EC) &&
2307        !FIELD_EX64(env->msr, MSR, EE)) {
2308        /*
2309         * A pending interrupt took us out of power-saving, but MSR[EE] says
2310         * that we should return to NIP+4 instead of delivering it.
2311         */
2312        return;
2313    }
2314
2315    switch (interrupt) {
2316    case PPC_INTERRUPT_MCK: /* Machine check exception */
2317        env->pending_interrupts &= ~PPC_INTERRUPT_MCK;
2318        powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
2319        break;
2320
2321    case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */
2322        /* HDEC clears on delivery */
2323        env->pending_interrupts &= ~PPC_INTERRUPT_HDECR;
2324        powerpc_excp(cpu, POWERPC_EXCP_HDECR);
2325        break;
2326    case PPC_INTERRUPT_HVIRT: /* Hypervisor virtualization interrupt */
2327        powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2328        break;
2329
2330    case PPC_INTERRUPT_EXT:
2331        if (books_vhyp_promotes_external_to_hvirt(cpu)) {
2332            powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2333        } else {
2334            powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
2335        }
2336        break;
2337
2338    case PPC_INTERRUPT_DECR: /* Decrementer exception */
2339        powerpc_excp(cpu, POWERPC_EXCP_DECR);
2340        break;
2341    case PPC_INTERRUPT_DOORBELL:
2342        env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL;
2343        powerpc_excp(cpu, POWERPC_EXCP_SDOOR);
2344        break;
2345    case PPC_INTERRUPT_HDOORBELL:
2346        env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL;
2347        powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV);
2348        break;
2349    case PPC_INTERRUPT_PERFM:
2350        env->pending_interrupts &= ~PPC_INTERRUPT_PERFM;
2351        powerpc_excp(cpu, POWERPC_EXCP_PERFM);
2352        break;
2353    case PPC_INTERRUPT_EBB: /* EBB exception */
2354        env->pending_interrupts &= ~PPC_INTERRUPT_EBB;
2355        if (env->spr[SPR_BESCR] & BESCR_PMEO) {
2356            powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB);
2357        } else if (env->spr[SPR_BESCR] & BESCR_EEO) {
2358            powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB);
2359        }
2360        break;
2361    case 0:
2362        /*
2363         * This is a bug ! It means that has_work took us out of halt without
2364         * anything to deliver while in a PM state that requires getting
2365         * out via a 0x100
2366         *
2367         * This means we will incorrectly execute past the power management
2368         * instruction instead of triggering a reset.
2369         *
2370         * It generally means a discrepancy between the wakeup conditions in the
2371         * processor has_work implementation and the logic in this function.
2372         */
2373        assert(!env->resume_as_sreset);
2374        break;
2375    default:
2376        cpu_abort(cs, "Invalid PowerPC interrupt %d. Aborting\n", interrupt);
2377    }
2378}
2379#endif
2380
2381static void ppc_deliver_interrupt_generic(CPUPPCState *env, int interrupt)
2382{
2383    PowerPCCPU *cpu = env_archcpu(env);
2384    CPUState *cs = env_cpu(env);
2385
2386    switch (interrupt) {
2387    case PPC_INTERRUPT_RESET: /* External reset */
2388        env->pending_interrupts &= ~PPC_INTERRUPT_RESET;
2389        powerpc_excp(cpu, POWERPC_EXCP_RESET);
2390        break;
2391    case PPC_INTERRUPT_MCK: /* Machine check exception */
2392        env->pending_interrupts &= ~PPC_INTERRUPT_MCK;
2393        powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
2394        break;
2395
2396    case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */
2397        /* HDEC clears on delivery */
2398        env->pending_interrupts &= ~PPC_INTERRUPT_HDECR;
2399        powerpc_excp(cpu, POWERPC_EXCP_HDECR);
2400        break;
2401    case PPC_INTERRUPT_HVIRT: /* Hypervisor virtualization interrupt */
2402        powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2403        break;
2404
2405    case PPC_INTERRUPT_EXT:
2406        if (books_vhyp_promotes_external_to_hvirt(cpu)) {
2407            powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2408        } else {
2409            powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
2410        }
2411        break;
2412    case PPC_INTERRUPT_CEXT: /* External critical interrupt */
2413        powerpc_excp(cpu, POWERPC_EXCP_CRITICAL);
2414        break;
2415
2416    case PPC_INTERRUPT_WDT: /* Watchdog timer on embedded PowerPC */
2417        env->pending_interrupts &= ~PPC_INTERRUPT_WDT;
2418        powerpc_excp(cpu, POWERPC_EXCP_WDT);
2419        break;
2420    case PPC_INTERRUPT_CDOORBELL:
2421        env->pending_interrupts &= ~PPC_INTERRUPT_CDOORBELL;
2422        powerpc_excp(cpu, POWERPC_EXCP_DOORCI);
2423        break;
2424    case PPC_INTERRUPT_FIT: /* Fixed interval timer on embedded PowerPC */
2425        env->pending_interrupts &= ~PPC_INTERRUPT_FIT;
2426        powerpc_excp(cpu, POWERPC_EXCP_FIT);
2427        break;
2428    case PPC_INTERRUPT_PIT: /* Programmable interval timer on embedded ppc */
2429        env->pending_interrupts &= ~PPC_INTERRUPT_PIT;
2430        powerpc_excp(cpu, POWERPC_EXCP_PIT);
2431        break;
2432    case PPC_INTERRUPT_DECR: /* Decrementer exception */
2433        if (ppc_decr_clear_on_delivery(env)) {
2434            env->pending_interrupts &= ~PPC_INTERRUPT_DECR;
2435        }
2436        powerpc_excp(cpu, POWERPC_EXCP_DECR);
2437        break;
2438    case PPC_INTERRUPT_DOORBELL:
2439        env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL;
2440        if (is_book3s_arch2x(env)) {
2441            powerpc_excp(cpu, POWERPC_EXCP_SDOOR);
2442        } else {
2443            powerpc_excp(cpu, POWERPC_EXCP_DOORI);
2444        }
2445        break;
2446    case PPC_INTERRUPT_HDOORBELL:
2447        env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL;
2448        powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV);
2449        break;
2450    case PPC_INTERRUPT_PERFM:
2451        env->pending_interrupts &= ~PPC_INTERRUPT_PERFM;
2452        powerpc_excp(cpu, POWERPC_EXCP_PERFM);
2453        break;
2454    case PPC_INTERRUPT_THERM:  /* Thermal interrupt */
2455        env->pending_interrupts &= ~PPC_INTERRUPT_THERM;
2456        powerpc_excp(cpu, POWERPC_EXCP_THERM);
2457        break;
2458    case PPC_INTERRUPT_EBB: /* EBB exception */
2459        env->pending_interrupts &= ~PPC_INTERRUPT_EBB;
2460        if (env->spr[SPR_BESCR] & BESCR_PMEO) {
2461            powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB);
2462        } else if (env->spr[SPR_BESCR] & BESCR_EEO) {
2463            powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB);
2464        }
2465        break;
2466    case 0:
2467        /*
2468         * This is a bug ! It means that has_work took us out of halt without
2469         * anything to deliver while in a PM state that requires getting
2470         * out via a 0x100
2471         *
2472         * This means we will incorrectly execute past the power management
2473         * instruction instead of triggering a reset.
2474         *
2475         * It generally means a discrepancy between the wakeup conditions in the
2476         * processor has_work implementation and the logic in this function.
2477         */
2478        assert(!env->resume_as_sreset);
2479        break;
2480    default:
2481        cpu_abort(cs, "Invalid PowerPC interrupt %d. Aborting\n", interrupt);
2482    }
2483}
2484
2485static void ppc_deliver_interrupt(CPUPPCState *env, int interrupt)
2486{
2487    switch (env->excp_model) {
2488#if defined(TARGET_PPC64)
2489    case POWERPC_EXCP_POWER7:
2490        p7_deliver_interrupt(env, interrupt);
2491        break;
2492    case POWERPC_EXCP_POWER8:
2493        p8_deliver_interrupt(env, interrupt);
2494        break;
2495    case POWERPC_EXCP_POWER9:
2496    case POWERPC_EXCP_POWER10:
2497        p9_deliver_interrupt(env, interrupt);
2498        break;
2499#endif
2500    default:
2501        ppc_deliver_interrupt_generic(env, interrupt);
2502    }
2503}
2504
2505void ppc_cpu_do_system_reset(CPUState *cs)
2506{
2507    PowerPCCPU *cpu = POWERPC_CPU(cs);
2508
2509    powerpc_excp(cpu, POWERPC_EXCP_RESET);
2510}
2511
2512void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
2513{
2514    PowerPCCPU *cpu = POWERPC_CPU(cs);
2515    CPUPPCState *env = &cpu->env;
2516    target_ulong msr = 0;
2517
2518    /*
2519     * Set MSR and NIP for the handler, SRR0/1, DAR and DSISR have already
2520     * been set by KVM.
2521     */
2522    msr = (1ULL << MSR_ME);
2523    msr |= env->msr & (1ULL << MSR_SF);
2524    if (ppc_interrupts_little_endian(cpu, false)) {
2525        msr |= (1ULL << MSR_LE);
2526    }
2527
2528    /* Anything for nested required here? MSR[HV] bit? */
2529
2530    powerpc_set_excp_state(cpu, vector, msr);
2531}
2532
2533bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
2534{
2535    PowerPCCPU *cpu = POWERPC_CPU(cs);
2536    CPUPPCState *env = &cpu->env;
2537    int interrupt;
2538
2539    if ((interrupt_request & CPU_INTERRUPT_HARD) == 0) {
2540        return false;
2541    }
2542
2543    interrupt = ppc_next_unmasked_interrupt(env);
2544    if (interrupt == 0) {
2545        return false;
2546    }
2547
2548    ppc_deliver_interrupt(env, interrupt);
2549    if (env->pending_interrupts == 0) {
2550        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
2551    }
2552    return true;
2553}
2554
2555#endif /* !CONFIG_USER_ONLY */
2556
2557/*****************************************************************************/
2558/* Exceptions processing helpers */
2559
2560void raise_exception_err_ra(CPUPPCState *env, uint32_t exception,
2561                            uint32_t error_code, uintptr_t raddr)
2562{
2563    CPUState *cs = env_cpu(env);
2564
2565    cs->exception_index = exception;
2566    env->error_code = error_code;
2567    cpu_loop_exit_restore(cs, raddr);
2568}
2569
2570void raise_exception_err(CPUPPCState *env, uint32_t exception,
2571                         uint32_t error_code)
2572{
2573    raise_exception_err_ra(env, exception, error_code, 0);
2574}
2575
2576void raise_exception(CPUPPCState *env, uint32_t exception)
2577{
2578    raise_exception_err_ra(env, exception, 0, 0);
2579}
2580
2581void raise_exception_ra(CPUPPCState *env, uint32_t exception,
2582                        uintptr_t raddr)
2583{
2584    raise_exception_err_ra(env, exception, 0, raddr);
2585}
2586
2587#ifdef CONFIG_TCG
2588void helper_raise_exception_err(CPUPPCState *env, uint32_t exception,
2589                                uint32_t error_code)
2590{
2591    raise_exception_err_ra(env, exception, error_code, 0);
2592}
2593
2594void helper_raise_exception(CPUPPCState *env, uint32_t exception)
2595{
2596    raise_exception_err_ra(env, exception, 0, 0);
2597}
2598#endif
2599
2600#if !defined(CONFIG_USER_ONLY)
2601#ifdef CONFIG_TCG
2602void helper_store_msr(CPUPPCState *env, target_ulong val)
2603{
2604    uint32_t excp = hreg_store_msr(env, val, 0);
2605
2606    if (excp != 0) {
2607        CPUState *cs = env_cpu(env);
2608        cpu_interrupt_exittb(cs);
2609        raise_exception(env, excp);
2610    }
2611}
2612
2613void helper_ppc_maybe_interrupt(CPUPPCState *env)
2614{
2615    ppc_maybe_interrupt(env);
2616}
2617
2618#if defined(TARGET_PPC64)
2619void helper_scv(CPUPPCState *env, uint32_t lev)
2620{
2621    if (env->spr[SPR_FSCR] & (1ull << FSCR_SCV)) {
2622        raise_exception_err(env, POWERPC_EXCP_SYSCALL_VECTORED, lev);
2623    } else {
2624        raise_exception_err(env, POWERPC_EXCP_FU, FSCR_IC_SCV);
2625    }
2626}
2627
2628void helper_pminsn(CPUPPCState *env, uint32_t insn)
2629{
2630    CPUState *cs;
2631
2632    cs = env_cpu(env);
2633    cs->halted = 1;
2634
2635    /* Condition for waking up at 0x100 */
2636    env->resume_as_sreset = (insn != PPC_PM_STOP) ||
2637        (env->spr[SPR_PSSCR] & PSSCR_EC);
2638
2639    /* HDECR is not to wake from PM state, it may have already fired */
2640    if (env->resume_as_sreset) {
2641        PowerPCCPU *cpu = env_archcpu(env);
2642        ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 0);
2643    }
2644
2645    ppc_maybe_interrupt(env);
2646}
2647#endif /* defined(TARGET_PPC64) */
2648
2649static void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
2650{
2651    CPUState *cs = env_cpu(env);
2652
2653    /* MSR:POW cannot be set by any form of rfi */
2654    msr &= ~(1ULL << MSR_POW);
2655
2656    /* MSR:TGPR cannot be set by any form of rfi */
2657    if (env->flags & POWERPC_FLAG_TGPR)
2658        msr &= ~(1ULL << MSR_TGPR);
2659
2660#if defined(TARGET_PPC64)
2661    /* Switching to 32-bit ? Crop the nip */
2662    if (!msr_is_64bit(env, msr)) {
2663        nip = (uint32_t)nip;
2664    }
2665#else
2666    nip = (uint32_t)nip;
2667#endif
2668    /* XXX: beware: this is false if VLE is supported */
2669    env->nip = nip & ~((target_ulong)0x00000003);
2670    hreg_store_msr(env, msr, 1);
2671    trace_ppc_excp_rfi(env->nip, env->msr);
2672    /*
2673     * No need to raise an exception here, as rfi is always the last
2674     * insn of a TB
2675     */
2676    cpu_interrupt_exittb(cs);
2677    /* Reset the reservation */
2678    env->reserve_addr = -1;
2679
2680    /* Context synchronizing: check if TCG TLB needs flush */
2681    check_tlb_flush(env, false);
2682}
2683
2684void helper_rfi(CPUPPCState *env)
2685{
2686    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
2687}
2688
2689#if defined(TARGET_PPC64)
2690void helper_rfid(CPUPPCState *env)
2691{
2692    /*
2693     * The architecture defines a number of rules for which bits can
2694     * change but in practice, we handle this in hreg_store_msr()
2695     * which will be called by do_rfi(), so there is no need to filter
2696     * here
2697     */
2698    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
2699}
2700
2701void helper_rfscv(CPUPPCState *env)
2702{
2703    do_rfi(env, env->lr, env->ctr);
2704}
2705
2706void helper_hrfid(CPUPPCState *env)
2707{
2708    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
2709}
2710#endif
2711
2712#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
2713void helper_rfebb(CPUPPCState *env, target_ulong s)
2714{
2715    target_ulong msr = env->msr;
2716
2717    /*
2718     * Handling of BESCR bits 32:33 according to PowerISA v3.1:
2719     *
2720     * "If BESCR 32:33 != 0b00 the instruction is treated as if
2721     *  the instruction form were invalid."
2722     */
2723    if (env->spr[SPR_BESCR] & BESCR_INVALID) {
2724        raise_exception_err(env, POWERPC_EXCP_PROGRAM,
2725                            POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
2726    }
2727
2728    env->nip = env->spr[SPR_EBBRR];
2729
2730    /* Switching to 32-bit ? Crop the nip */
2731    if (!msr_is_64bit(env, msr)) {
2732        env->nip = (uint32_t)env->spr[SPR_EBBRR];
2733    }
2734
2735    if (s) {
2736        env->spr[SPR_BESCR] |= BESCR_GE;
2737    } else {
2738        env->spr[SPR_BESCR] &= ~BESCR_GE;
2739    }
2740}
2741
2742/*
2743 * Triggers or queues an 'ebb_excp' EBB exception. All checks
2744 * but FSCR, HFSCR and msr_pr must be done beforehand.
2745 *
2746 * PowerISA v3.1 isn't clear about whether an EBB should be
2747 * postponed or cancelled if the EBB facility is unavailable.
2748 * Our assumption here is that the EBB is cancelled if both
2749 * FSCR and HFSCR EBB facilities aren't available.
2750 */
2751static void do_ebb(CPUPPCState *env, int ebb_excp)
2752{
2753    PowerPCCPU *cpu = env_archcpu(env);
2754
2755    /*
2756     * FSCR_EBB and FSCR_IC_EBB are the same bits used with
2757     * HFSCR.
2758     */
2759    helper_fscr_facility_check(env, FSCR_EBB, 0, FSCR_IC_EBB);
2760    helper_hfscr_facility_check(env, FSCR_EBB, "EBB", FSCR_IC_EBB);
2761
2762    if (ebb_excp == POWERPC_EXCP_PERFM_EBB) {
2763        env->spr[SPR_BESCR] |= BESCR_PMEO;
2764    } else if (ebb_excp == POWERPC_EXCP_EXTERNAL_EBB) {
2765        env->spr[SPR_BESCR] |= BESCR_EEO;
2766    }
2767
2768    if (FIELD_EX64(env->msr, MSR, PR)) {
2769        powerpc_excp(cpu, ebb_excp);
2770    } else {
2771        ppc_set_irq(cpu, PPC_INTERRUPT_EBB, 1);
2772    }
2773}
2774
2775void raise_ebb_perfm_exception(CPUPPCState *env)
2776{
2777    bool perfm_ebb_enabled = env->spr[SPR_POWER_MMCR0] & MMCR0_EBE &&
2778                             env->spr[SPR_BESCR] & BESCR_PME &&
2779                             env->spr[SPR_BESCR] & BESCR_GE;
2780
2781    if (!perfm_ebb_enabled) {
2782        return;
2783    }
2784
2785    do_ebb(env, POWERPC_EXCP_PERFM_EBB);
2786}
2787#endif
2788
2789/*****************************************************************************/
2790/* Embedded PowerPC specific helpers */
2791void helper_40x_rfci(CPUPPCState *env)
2792{
2793    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
2794}
2795
2796void helper_rfci(CPUPPCState *env)
2797{
2798    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
2799}
2800
2801void helper_rfdi(CPUPPCState *env)
2802{
2803    /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
2804    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
2805}
2806
2807void helper_rfmci(CPUPPCState *env)
2808{
2809    /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
2810    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
2811}
2812#endif /* CONFIG_TCG */
2813#endif /* !defined(CONFIG_USER_ONLY) */
2814
2815#ifdef CONFIG_TCG
2816void helper_tw(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
2817               uint32_t flags)
2818{
2819    if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) ||
2820                  ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) ||
2821                  ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) ||
2822                  ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) ||
2823                  ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) {
2824        raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2825                               POWERPC_EXCP_TRAP, GETPC());
2826    }
2827}
2828
2829#if defined(TARGET_PPC64)
2830void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
2831               uint32_t flags)
2832{
2833    if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) ||
2834                  ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) ||
2835                  ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) ||
2836                  ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) ||
2837                  ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) {
2838        raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2839                               POWERPC_EXCP_TRAP, GETPC());
2840    }
2841}
2842#endif
2843#endif
2844
2845#ifdef CONFIG_TCG
2846static uint32_t helper_SIMON_LIKE_32_64(uint32_t x, uint64_t key, uint32_t lane)
2847{
2848    const uint16_t c = 0xfffc;
2849    const uint64_t z0 = 0xfa2561cdf44ac398ULL;
2850    uint16_t z = 0, temp;
2851    uint16_t k[32], eff_k[32], xleft[33], xright[33], fxleft[32];
2852
2853    for (int i = 3; i >= 0; i--) {
2854        k[i] = key & 0xffff;
2855        key >>= 16;
2856    }
2857    xleft[0] = x & 0xffff;
2858    xright[0] = (x >> 16) & 0xffff;
2859
2860    for (int i = 0; i < 28; i++) {
2861        z = (z0 >> (63 - i)) & 1;
2862        temp = ror16(k[i + 3], 3) ^ k[i + 1];
2863        k[i + 4] = c ^ z ^ k[i] ^ temp ^ ror16(temp, 1);
2864    }
2865
2866    for (int i = 0; i < 8; i++) {
2867        eff_k[4 * i + 0] = k[4 * i + ((0 + lane) % 4)];
2868        eff_k[4 * i + 1] = k[4 * i + ((1 + lane) % 4)];
2869        eff_k[4 * i + 2] = k[4 * i + ((2 + lane) % 4)];
2870        eff_k[4 * i + 3] = k[4 * i + ((3 + lane) % 4)];
2871    }
2872
2873    for (int i = 0; i < 32; i++) {
2874        fxleft[i] = (rol16(xleft[i], 1) &
2875            rol16(xleft[i], 8)) ^ rol16(xleft[i], 2);
2876        xleft[i + 1] = xright[i] ^ fxleft[i] ^ eff_k[i];
2877        xright[i + 1] = xleft[i];
2878    }
2879
2880    return (((uint32_t)xright[32]) << 16) | xleft[32];
2881}
2882
2883static uint64_t hash_digest(uint64_t ra, uint64_t rb, uint64_t key)
2884{
2885    uint64_t stage0_h = 0ULL, stage0_l = 0ULL;
2886    uint64_t stage1_h, stage1_l;
2887
2888    for (int i = 0; i < 4; i++) {
2889        stage0_h |= ror64(rb & 0xff, 8 * (2 * i + 1));
2890        stage0_h |= ((ra >> 32) & 0xff) << (8 * 2 * i);
2891        stage0_l |= ror64((rb >> 32) & 0xff, 8 * (2 * i + 1));
2892        stage0_l |= (ra & 0xff) << (8 * 2 * i);
2893        rb >>= 8;
2894        ra >>= 8;
2895    }
2896
2897    stage1_h = (uint64_t)helper_SIMON_LIKE_32_64(stage0_h >> 32, key, 0) << 32;
2898    stage1_h |= helper_SIMON_LIKE_32_64(stage0_h, key, 1);
2899    stage1_l = (uint64_t)helper_SIMON_LIKE_32_64(stage0_l >> 32, key, 2) << 32;
2900    stage1_l |= helper_SIMON_LIKE_32_64(stage0_l, key, 3);
2901
2902    return stage1_h ^ stage1_l;
2903}
2904
2905static void do_hash(CPUPPCState *env, target_ulong ea, target_ulong ra,
2906                    target_ulong rb, uint64_t key, bool store)
2907{
2908    uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash;
2909
2910    if (store) {
2911        cpu_stq_data_ra(env, ea, calculated_hash, GETPC());
2912    } else {
2913        loaded_hash = cpu_ldq_data_ra(env, ea, GETPC());
2914        if (loaded_hash != calculated_hash) {
2915            raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2916                POWERPC_EXCP_TRAP, GETPC());
2917        }
2918    }
2919}
2920
2921#include "qemu/guest-random.h"
2922
2923#ifdef TARGET_PPC64
2924#define HELPER_HASH(op, key, store, dexcr_aspect)                             \
2925void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra,          \
2926                 target_ulong rb)                                             \
2927{                                                                             \
2928    if (env->msr & R_MSR_PR_MASK) {                                           \
2929        if (!(env->spr[SPR_DEXCR] & R_DEXCR_PRO_##dexcr_aspect##_MASK ||      \
2930            env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK))       \
2931            return;                                                           \
2932    } else if (!(env->msr & R_MSR_HV_MASK)) {                                 \
2933        if (!(env->spr[SPR_DEXCR] & R_DEXCR_PNH_##dexcr_aspect##_MASK ||      \
2934            env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK))       \
2935            return;                                                           \
2936    } else if (!(env->msr & R_MSR_S_MASK)) {                                  \
2937        if (!(env->spr[SPR_HDEXCR] & R_HDEXCR_HNU_##dexcr_aspect##_MASK))     \
2938            return;                                                           \
2939    }                                                                         \
2940                                                                              \
2941    do_hash(env, ea, ra, rb, key, store);                                     \
2942}
2943#else
2944#define HELPER_HASH(op, key, store, dexcr_aspect)                             \
2945void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra,          \
2946                 target_ulong rb)                                             \
2947{                                                                             \
2948    do_hash(env, ea, ra, rb, key, store);                                     \
2949}
2950#endif /* TARGET_PPC64 */
2951
2952HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true, NPHIE)
2953HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false, NPHIE)
2954HELPER_HASH(HASHSTP, env->spr[SPR_HASHPKEYR], true, PHIE)
2955HELPER_HASH(HASHCHKP, env->spr[SPR_HASHPKEYR], false, PHIE)
2956#endif /* CONFIG_TCG */
2957
2958#if !defined(CONFIG_USER_ONLY)
2959
2960#ifdef CONFIG_TCG
2961
2962/* Embedded.Processor Control */
2963static int dbell2irq(target_ulong rb)
2964{
2965    int msg = rb & DBELL_TYPE_MASK;
2966    int irq = -1;
2967
2968    switch (msg) {
2969    case DBELL_TYPE_DBELL:
2970        irq = PPC_INTERRUPT_DOORBELL;
2971        break;
2972    case DBELL_TYPE_DBELL_CRIT:
2973        irq = PPC_INTERRUPT_CDOORBELL;
2974        break;
2975    case DBELL_TYPE_G_DBELL:
2976    case DBELL_TYPE_G_DBELL_CRIT:
2977    case DBELL_TYPE_G_DBELL_MC:
2978        /* XXX implement */
2979    default:
2980        break;
2981    }
2982
2983    return irq;
2984}
2985
2986void helper_msgclr(CPUPPCState *env, target_ulong rb)
2987{
2988    int irq = dbell2irq(rb);
2989
2990    if (irq < 0) {
2991        return;
2992    }
2993
2994    ppc_set_irq(env_archcpu(env), irq, 0);
2995}
2996
2997void helper_msgsnd(target_ulong rb)
2998{
2999    int irq = dbell2irq(rb);
3000    int pir = rb & DBELL_PIRTAG_MASK;
3001    CPUState *cs;
3002
3003    if (irq < 0) {
3004        return;
3005    }
3006
3007    qemu_mutex_lock_iothread();
3008    CPU_FOREACH(cs) {
3009        PowerPCCPU *cpu = POWERPC_CPU(cs);
3010        CPUPPCState *cenv = &cpu->env;
3011
3012        if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
3013            ppc_set_irq(cpu, irq, 1);
3014        }
3015    }
3016    qemu_mutex_unlock_iothread();
3017}
3018
3019/* Server Processor Control */
3020
3021static bool dbell_type_server(target_ulong rb)
3022{
3023    /*
3024     * A Directed Hypervisor Doorbell message is sent only if the
3025     * message type is 5. All other types are reserved and the
3026     * instruction is a no-op
3027     */
3028    return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER;
3029}
3030
3031void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb)
3032{
3033    if (!dbell_type_server(rb)) {
3034        return;
3035    }
3036
3037    ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_HDOORBELL, 0);
3038}
3039
3040static void book3s_msgsnd_common(int pir, int irq)
3041{
3042    CPUState *cs;
3043
3044    qemu_mutex_lock_iothread();
3045    CPU_FOREACH(cs) {
3046        PowerPCCPU *cpu = POWERPC_CPU(cs);
3047        CPUPPCState *cenv = &cpu->env;
3048
3049        /* TODO: broadcast message to all threads of the same  processor */
3050        if (cenv->spr_cb[SPR_PIR].default_value == pir) {
3051            ppc_set_irq(cpu, irq, 1);
3052        }
3053    }
3054    qemu_mutex_unlock_iothread();
3055}
3056
3057void helper_book3s_msgsnd(target_ulong rb)
3058{
3059    int pir = rb & DBELL_PROCIDTAG_MASK;
3060
3061    if (!dbell_type_server(rb)) {
3062        return;
3063    }
3064
3065    book3s_msgsnd_common(pir, PPC_INTERRUPT_HDOORBELL);
3066}
3067
3068#if defined(TARGET_PPC64)
3069void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb)
3070{
3071    helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP);
3072
3073    if (!dbell_type_server(rb)) {
3074        return;
3075    }
3076
3077    ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_HDOORBELL, 0);
3078}
3079
3080/*
3081 * sends a message to other threads that are on the same
3082 * multi-threaded processor
3083 */
3084void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb)
3085{
3086    int pir = env->spr_cb[SPR_PIR].default_value;
3087
3088    helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP);
3089
3090    if (!dbell_type_server(rb)) {
3091        return;
3092    }
3093
3094    /* TODO: TCG supports only one thread */
3095
3096    book3s_msgsnd_common(pir, PPC_INTERRUPT_DOORBELL);
3097}
3098#endif /* TARGET_PPC64 */
3099
3100void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
3101                                 MMUAccessType access_type,
3102                                 int mmu_idx, uintptr_t retaddr)
3103{
3104    CPUPPCState *env = cs->env_ptr;
3105    uint32_t insn;
3106
3107    /* Restore state and reload the insn we executed, for filling in DSISR.  */
3108    cpu_restore_state(cs, retaddr);
3109    insn = cpu_ldl_code(env, env->nip);
3110
3111    switch (env->mmu_model) {
3112    case POWERPC_MMU_SOFT_4xx:
3113        env->spr[SPR_40x_DEAR] = vaddr;
3114        break;
3115    case POWERPC_MMU_BOOKE:
3116    case POWERPC_MMU_BOOKE206:
3117        env->spr[SPR_BOOKE_DEAR] = vaddr;
3118        break;
3119    default:
3120        env->spr[SPR_DAR] = vaddr;
3121        break;
3122    }
3123
3124    cs->exception_index = POWERPC_EXCP_ALIGN;
3125    env->error_code = insn & 0x03FF0000;
3126    cpu_loop_exit(cs);
3127}
3128#endif /* CONFIG_TCG */
3129#endif /* !CONFIG_USER_ONLY */
3130