cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

excp_helper.c (50045B)


      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 "cpu.h"
     22#include "exec/exec-all.h"
     23#include "internal.h"
     24#include "helper_regs.h"
     25
     26#include "trace.h"
     27
     28#ifdef CONFIG_TCG
     29#include "exec/helper-proto.h"
     30#include "exec/cpu_ldst.h"
     31#endif
     32
     33/* #define DEBUG_SOFTWARE_TLB */
     34
     35/*****************************************************************************/
     36/* Exception processing */
     37#if !defined(CONFIG_USER_ONLY)
     38
     39static inline void dump_syscall(CPUPPCState *env)
     40{
     41    qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
     42                  " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64
     43                  " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64
     44                  " nip=" TARGET_FMT_lx "\n",
     45                  ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
     46                  ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
     47                  ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7),
     48                  ppc_dump_gpr(env, 8), env->nip);
     49}
     50
     51static inline void dump_hcall(CPUPPCState *env)
     52{
     53    qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64
     54                  " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
     55                  " r7=%016" PRIx64 " r8=%016" PRIx64 " r9=%016" PRIx64
     56                  " r10=%016" PRIx64 " r11=%016" PRIx64 " r12=%016" PRIx64
     57                  " nip=" TARGET_FMT_lx "\n",
     58                  ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4),
     59                  ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6),
     60                  ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8),
     61                  ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10),
     62                  ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12),
     63                  env->nip);
     64}
     65
     66static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp,
     67                                target_ulong *msr)
     68{
     69    /* We no longer are in a PM state */
     70    env->resume_as_sreset = false;
     71
     72    /* Pretend to be returning from doze always as we don't lose state */
     73    *msr |= SRR1_WS_NOLOSS;
     74
     75    /* Machine checks are sent normally */
     76    if (excp == POWERPC_EXCP_MCHECK) {
     77        return excp;
     78    }
     79    switch (excp) {
     80    case POWERPC_EXCP_RESET:
     81        *msr |= SRR1_WAKERESET;
     82        break;
     83    case POWERPC_EXCP_EXTERNAL:
     84        *msr |= SRR1_WAKEEE;
     85        break;
     86    case POWERPC_EXCP_DECR:
     87        *msr |= SRR1_WAKEDEC;
     88        break;
     89    case POWERPC_EXCP_SDOOR:
     90        *msr |= SRR1_WAKEDBELL;
     91        break;
     92    case POWERPC_EXCP_SDOOR_HV:
     93        *msr |= SRR1_WAKEHDBELL;
     94        break;
     95    case POWERPC_EXCP_HV_MAINT:
     96        *msr |= SRR1_WAKEHMI;
     97        break;
     98    case POWERPC_EXCP_HVIRT:
     99        *msr |= SRR1_WAKEHVI;
    100        break;
    101    default:
    102        cpu_abort(cs, "Unsupported exception %d in Power Save mode\n",
    103                  excp);
    104    }
    105    return POWERPC_EXCP_RESET;
    106}
    107
    108/*
    109 * AIL - Alternate Interrupt Location, a mode that allows interrupts to be
    110 * taken with the MMU on, and which uses an alternate location (e.g., so the
    111 * kernel/hv can map the vectors there with an effective address).
    112 *
    113 * An interrupt is considered to be taken "with AIL" or "AIL applies" if they
    114 * are delivered in this way. AIL requires the LPCR to be set to enable this
    115 * mode, and then a number of conditions have to be true for AIL to apply.
    116 *
    117 * First of all, SRESET, MCE, and HMI are always delivered without AIL, because
    118 * they specifically want to be in real mode (e.g., the MCE might be signaling
    119 * a SLB multi-hit which requires SLB flush before the MMU can be enabled).
    120 *
    121 * After that, behaviour depends on the current MSR[IR], MSR[DR], MSR[HV],
    122 * whether or not the interrupt changes MSR[HV] from 0 to 1, and the current
    123 * radix mode (LPCR[HR]).
    124 *
    125 * POWER8, POWER9 with LPCR[HR]=0
    126 * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL |
    127 * +-----------+-------------+---------+-------------+-----+
    128 * | a         | 00/01/10    | x       | x           | 0   |
    129 * | a         | 11          | 0       | 1           | 0   |
    130 * | a         | 11          | 1       | 1           | a   |
    131 * | a         | 11          | 0       | 0           | a   |
    132 * +-------------------------------------------------------+
    133 *
    134 * POWER9 with LPCR[HR]=1
    135 * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL |
    136 * +-----------+-------------+---------+-------------+-----+
    137 * | a         | 00/01/10    | x       | x           | 0   |
    138 * | a         | 11          | x       | x           | a   |
    139 * +-------------------------------------------------------+
    140 *
    141 * The difference with POWER9 being that MSR[HV] 0->1 interrupts can be sent to
    142 * the hypervisor in AIL mode if the guest is radix. This is good for
    143 * performance but allows the guest to influence the AIL of hypervisor
    144 * interrupts using its MSR, and also the hypervisor must disallow guest
    145 * interrupts (MSR[HV] 0->0) from using AIL if the hypervisor does not want to
    146 * use AIL for its MSR[HV] 0->1 interrupts.
    147 *
    148 * POWER10 addresses those issues with a new LPCR[HAIL] bit that is applied to
    149 * interrupts that begin execution with MSR[HV]=1 (so both MSR[HV] 0->1 and
    150 * MSR[HV] 1->1).
    151 *
    152 * HAIL=1 is equivalent to AIL=3, for interrupts delivered with MSR[HV]=1.
    153 *
    154 * POWER10 behaviour is
    155 * | LPCR[AIL] | LPCR[HAIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL |
    156 * +-----------+------------+-------------+---------+-------------+-----+
    157 * | a         | h          | 00/01/10    | 0       | 0           | 0   |
    158 * | a         | h          | 11          | 0       | 0           | a   |
    159 * | a         | h          | x           | 0       | 1           | h   |
    160 * | a         | h          | 00/01/10    | 1       | 1           | 0   |
    161 * | a         | h          | 11          | 1       | 1           | h   |
    162 * +--------------------------------------------------------------------+
    163 */
    164static inline void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int excp,
    165                                      target_ulong msr,
    166                                      target_ulong *new_msr,
    167                                      target_ulong *vector)
    168{
    169#if defined(TARGET_PPC64)
    170    CPUPPCState *env = &cpu->env;
    171    bool mmu_all_on = ((msr >> MSR_IR) & 1) && ((msr >> MSR_DR) & 1);
    172    bool hv_escalation = !(msr & MSR_HVB) && (*new_msr & MSR_HVB);
    173    int ail = 0;
    174
    175    if (excp == POWERPC_EXCP_MCHECK ||
    176        excp == POWERPC_EXCP_RESET ||
    177        excp == POWERPC_EXCP_HV_MAINT) {
    178        /* SRESET, MCE, HMI never apply AIL */
    179        return;
    180    }
    181
    182    if (excp_model == POWERPC_EXCP_POWER8 ||
    183        excp_model == POWERPC_EXCP_POWER9) {
    184        if (!mmu_all_on) {
    185            /* AIL only works if MSR[IR] and MSR[DR] are both enabled. */
    186            return;
    187        }
    188        if (hv_escalation && !(env->spr[SPR_LPCR] & LPCR_HR)) {
    189            /*
    190             * AIL does not work if there is a MSR[HV] 0->1 transition and the
    191             * partition is in HPT mode. For radix guests, such interrupts are
    192             * allowed to be delivered to the hypervisor in ail mode.
    193             */
    194            return;
    195        }
    196
    197        ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
    198        if (ail == 0) {
    199            return;
    200        }
    201        if (ail == 1) {
    202            /* AIL=1 is reserved, treat it like AIL=0 */
    203            return;
    204        }
    205
    206    } else if (excp_model == POWERPC_EXCP_POWER10) {
    207        if (!mmu_all_on && !hv_escalation) {
    208            /*
    209             * AIL works for HV interrupts even with guest MSR[IR/DR] disabled.
    210             * Guest->guest and HV->HV interrupts do require MMU on.
    211             */
    212            return;
    213        }
    214
    215        if (*new_msr & MSR_HVB) {
    216            if (!(env->spr[SPR_LPCR] & LPCR_HAIL)) {
    217                /* HV interrupts depend on LPCR[HAIL] */
    218                return;
    219            }
    220            ail = 3; /* HAIL=1 gives AIL=3 behaviour for HV interrupts */
    221        } else {
    222            ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
    223        }
    224        if (ail == 0) {
    225            return;
    226        }
    227        if (ail == 1 || ail == 2) {
    228            /* AIL=1 and AIL=2 are reserved, treat them like AIL=0 */
    229            return;
    230        }
    231    } else {
    232        /* Other processors do not support AIL */
    233        return;
    234    }
    235
    236    /*
    237     * AIL applies, so the new MSR gets IR and DR set, and an offset applied
    238     * to the new IP.
    239     */
    240    *new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
    241
    242    if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
    243        if (ail == 2) {
    244            *vector |= 0x0000000000018000ull;
    245        } else if (ail == 3) {
    246            *vector |= 0xc000000000004000ull;
    247        }
    248    } else {
    249        /*
    250         * scv AIL is a little different. AIL=2 does not change the address,
    251         * only the MSR. AIL=3 replaces the 0x17000 base with 0xc...3000.
    252         */
    253        if (ail == 3) {
    254            *vector &= ~0x0000000000017000ull; /* Un-apply the base offset */
    255            *vector |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */
    256        }
    257    }
    258#endif
    259}
    260
    261static inline void powerpc_set_excp_state(PowerPCCPU *cpu,
    262                                          target_ulong vector, target_ulong msr)
    263{
    264    CPUState *cs = CPU(cpu);
    265    CPUPPCState *env = &cpu->env;
    266
    267    /*
    268     * We don't use hreg_store_msr here as already have treated any
    269     * special case that could occur. Just store MSR and update hflags
    270     *
    271     * Note: We *MUST* not use hreg_store_msr() as-is anyway because it
    272     * will prevent setting of the HV bit which some exceptions might need
    273     * to do.
    274     */
    275    env->msr = msr & env->msr_mask;
    276    hreg_compute_hflags(env);
    277    env->nip = vector;
    278    /* Reset exception state */
    279    cs->exception_index = POWERPC_EXCP_NONE;
    280    env->error_code = 0;
    281
    282    /* Reset the reservation */
    283    env->reserve_addr = -1;
    284
    285    /*
    286     * Any interrupt is context synchronizing, check if TCG TLB needs
    287     * a delayed flush on ppc64
    288     */
    289    check_tlb_flush(env, false);
    290}
    291
    292/*
    293 * Note that this function should be greatly optimized when called
    294 * with a constant excp, from ppc_hw_interrupt
    295 */
    296static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
    297{
    298    CPUState *cs = CPU(cpu);
    299    CPUPPCState *env = &cpu->env;
    300    target_ulong msr, new_msr, vector;
    301    int srr0, srr1, asrr0, asrr1, lev = -1;
    302
    303    qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
    304                  " => %08x (%02x)\n", env->nip, excp, env->error_code);
    305
    306    /* new srr1 value excluding must-be-zero bits */
    307    if (excp_model == POWERPC_EXCP_BOOKE) {
    308        msr = env->msr;
    309    } else {
    310        msr = env->msr & ~0x783f0000ULL;
    311    }
    312
    313    /*
    314     * new interrupt handler msr preserves existing HV and ME unless
    315     * explicitly overriden
    316     */
    317    new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
    318
    319    /* target registers */
    320    srr0 = SPR_SRR0;
    321    srr1 = SPR_SRR1;
    322    asrr0 = -1;
    323    asrr1 = -1;
    324
    325    /*
    326     * check for special resume at 0x100 from doze/nap/sleep/winkle on
    327     * P7/P8/P9
    328     */
    329    if (env->resume_as_sreset) {
    330        excp = powerpc_reset_wakeup(cs, env, excp, &msr);
    331    }
    332
    333    /*
    334     * Hypervisor emulation assistance interrupt only exists on server
    335     * arch 2.05 server or later. We also don't want to generate it if
    336     * we don't have HVB in msr_mask (PAPR mode).
    337     */
    338    if (excp == POWERPC_EXCP_HV_EMU
    339#if defined(TARGET_PPC64)
    340        && !(mmu_is_64bit(env->mmu_model) && (env->msr_mask & MSR_HVB))
    341#endif /* defined(TARGET_PPC64) */
    342
    343    ) {
    344        excp = POWERPC_EXCP_PROGRAM;
    345    }
    346
    347    switch (excp) {
    348    case POWERPC_EXCP_NONE:
    349        /* Should never happen */
    350        return;
    351    case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
    352        switch (excp_model) {
    353        case POWERPC_EXCP_40x:
    354            srr0 = SPR_40x_SRR2;
    355            srr1 = SPR_40x_SRR3;
    356            break;
    357        case POWERPC_EXCP_BOOKE:
    358            srr0 = SPR_BOOKE_CSRR0;
    359            srr1 = SPR_BOOKE_CSRR1;
    360            break;
    361        case POWERPC_EXCP_G2:
    362            break;
    363        default:
    364            goto excp_invalid;
    365        }
    366        break;
    367    case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
    368        if (msr_me == 0) {
    369            /*
    370             * Machine check exception is not enabled.  Enter
    371             * checkstop state.
    372             */
    373            fprintf(stderr, "Machine check while not allowed. "
    374                    "Entering checkstop state\n");
    375            if (qemu_log_separate()) {
    376                qemu_log("Machine check while not allowed. "
    377                        "Entering checkstop state\n");
    378            }
    379            cs->halted = 1;
    380            cpu_interrupt_exittb(cs);
    381        }
    382        if (env->msr_mask & MSR_HVB) {
    383            /*
    384             * ISA specifies HV, but can be delivered to guest with HV
    385             * clear (e.g., see FWNMI in PAPR).
    386             */
    387            new_msr |= (target_ulong)MSR_HVB;
    388        }
    389
    390        /* machine check exceptions don't have ME set */
    391        new_msr &= ~((target_ulong)1 << MSR_ME);
    392
    393        /* XXX: should also have something loaded in DAR / DSISR */
    394        switch (excp_model) {
    395        case POWERPC_EXCP_40x:
    396            srr0 = SPR_40x_SRR2;
    397            srr1 = SPR_40x_SRR3;
    398            break;
    399        case POWERPC_EXCP_BOOKE:
    400            /* FIXME: choose one or the other based on CPU type */
    401            srr0 = SPR_BOOKE_MCSRR0;
    402            srr1 = SPR_BOOKE_MCSRR1;
    403            asrr0 = SPR_BOOKE_CSRR0;
    404            asrr1 = SPR_BOOKE_CSRR1;
    405            break;
    406        default:
    407            break;
    408        }
    409        break;
    410    case POWERPC_EXCP_DSI:       /* Data storage exception                   */
    411        trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
    412        break;
    413    case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
    414        trace_ppc_excp_isi(msr, env->nip);
    415        msr |= env->error_code;
    416        break;
    417    case POWERPC_EXCP_EXTERNAL:  /* External input                           */
    418    {
    419        bool lpes0;
    420
    421        cs = CPU(cpu);
    422
    423        /*
    424         * Exception targeting modifiers
    425         *
    426         * LPES0 is supported on POWER7/8/9
    427         * LPES1 is not supported (old iSeries mode)
    428         *
    429         * On anything else, we behave as if LPES0 is 1
    430         * (externals don't alter MSR:HV)
    431         */
    432#if defined(TARGET_PPC64)
    433        if (excp_model == POWERPC_EXCP_POWER7 ||
    434            excp_model == POWERPC_EXCP_POWER8 ||
    435            excp_model == POWERPC_EXCP_POWER9 ||
    436            excp_model == POWERPC_EXCP_POWER10) {
    437            lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
    438        } else
    439#endif /* defined(TARGET_PPC64) */
    440        {
    441            lpes0 = true;
    442        }
    443
    444        if (!lpes0) {
    445            new_msr |= (target_ulong)MSR_HVB;
    446            new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
    447            srr0 = SPR_HSRR0;
    448            srr1 = SPR_HSRR1;
    449        }
    450        if (env->mpic_proxy) {
    451            /* IACK the IRQ on delivery */
    452            env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
    453        }
    454        break;
    455    }
    456    case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
    457        /* Get rS/rD and rA from faulting opcode */
    458        /*
    459         * Note: the opcode fields will not be set properly for a
    460         * direct store load/store, but nobody cares as nobody
    461         * actually uses direct store segments.
    462         */
    463        env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
    464        break;
    465    case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
    466        switch (env->error_code & ~0xF) {
    467        case POWERPC_EXCP_FP:
    468            if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
    469                trace_ppc_excp_fp_ignore();
    470                cs->exception_index = POWERPC_EXCP_NONE;
    471                env->error_code = 0;
    472                return;
    473            }
    474
    475            /*
    476             * FP exceptions always have NIP pointing to the faulting
    477             * instruction, so always use store_next and claim we are
    478             * precise in the MSR.
    479             */
    480            msr |= 0x00100000;
    481            env->spr[SPR_BOOKE_ESR] = ESR_FP;
    482            break;
    483        case POWERPC_EXCP_INVAL:
    484            trace_ppc_excp_inval(env->nip);
    485            msr |= 0x00080000;
    486            env->spr[SPR_BOOKE_ESR] = ESR_PIL;
    487            break;
    488        case POWERPC_EXCP_PRIV:
    489            msr |= 0x00040000;
    490            env->spr[SPR_BOOKE_ESR] = ESR_PPR;
    491            break;
    492        case POWERPC_EXCP_TRAP:
    493            msr |= 0x00020000;
    494            env->spr[SPR_BOOKE_ESR] = ESR_PTR;
    495            break;
    496        default:
    497            /* Should never occur */
    498            cpu_abort(cs, "Invalid program exception %d. Aborting\n",
    499                      env->error_code);
    500            break;
    501        }
    502        break;
    503    case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
    504        lev = env->error_code;
    505
    506        if ((lev == 1) && cpu->vhyp) {
    507            dump_hcall(env);
    508        } else {
    509            dump_syscall(env);
    510        }
    511
    512        /*
    513         * We need to correct the NIP which in this case is supposed
    514         * to point to the next instruction
    515         */
    516        env->nip += 4;
    517
    518        /* "PAPR mode" built-in hypercall emulation */
    519        if ((lev == 1) && cpu->vhyp) {
    520            PPCVirtualHypervisorClass *vhc =
    521                PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
    522            vhc->hypercall(cpu->vhyp, cpu);
    523            return;
    524        }
    525        if (lev == 1) {
    526            new_msr |= (target_ulong)MSR_HVB;
    527        }
    528        break;
    529    case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception                     */
    530        lev = env->error_code;
    531        dump_syscall(env);
    532        env->nip += 4;
    533        new_msr |= env->msr & ((target_ulong)1 << MSR_EE);
    534        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
    535        break;
    536    case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
    537    case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
    538    case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
    539        break;
    540    case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
    541        /* FIT on 4xx */
    542        trace_ppc_excp_print("FIT");
    543        break;
    544    case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
    545        trace_ppc_excp_print("WDT");
    546        switch (excp_model) {
    547        case POWERPC_EXCP_BOOKE:
    548            srr0 = SPR_BOOKE_CSRR0;
    549            srr1 = SPR_BOOKE_CSRR1;
    550            break;
    551        default:
    552            break;
    553        }
    554        break;
    555    case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
    556    case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
    557        break;
    558    case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
    559        if (env->flags & POWERPC_FLAG_DE) {
    560            /* FIXME: choose one or the other based on CPU type */
    561            srr0 = SPR_BOOKE_DSRR0;
    562            srr1 = SPR_BOOKE_DSRR1;
    563            asrr0 = SPR_BOOKE_CSRR0;
    564            asrr1 = SPR_BOOKE_CSRR1;
    565            /* DBSR already modified by caller */
    566        } else {
    567            cpu_abort(cs, "Debug exception triggered on unsupported model\n");
    568        }
    569        break;
    570    case POWERPC_EXCP_SPEU:      /* SPE/embedded floating-point unavailable  */
    571        env->spr[SPR_BOOKE_ESR] = ESR_SPV;
    572        break;
    573    case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */
    574        /* XXX: TODO */
    575        cpu_abort(cs, "Embedded floating point data exception "
    576                  "is not implemented yet !\n");
    577        env->spr[SPR_BOOKE_ESR] = ESR_SPV;
    578        break;
    579    case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */
    580        /* XXX: TODO */
    581        cpu_abort(cs, "Embedded floating point round exception "
    582                  "is not implemented yet !\n");
    583        env->spr[SPR_BOOKE_ESR] = ESR_SPV;
    584        break;
    585    case POWERPC_EXCP_EPERFM:    /* Embedded performance monitor interrupt   */
    586        /* XXX: TODO */
    587        cpu_abort(cs,
    588                  "Performance counter exception is not implemented yet !\n");
    589        break;
    590    case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */
    591        break;
    592    case POWERPC_EXCP_DOORCI:    /* Embedded doorbell critical interrupt     */
    593        srr0 = SPR_BOOKE_CSRR0;
    594        srr1 = SPR_BOOKE_CSRR1;
    595        break;
    596    case POWERPC_EXCP_RESET:     /* System reset exception                   */
    597        /* A power-saving exception sets ME, otherwise it is unchanged */
    598        if (msr_pow) {
    599            /* indicate that we resumed from power save mode */
    600            msr |= 0x10000;
    601            new_msr |= ((target_ulong)1 << MSR_ME);
    602        }
    603        if (env->msr_mask & MSR_HVB) {
    604            /*
    605             * ISA specifies HV, but can be delivered to guest with HV
    606             * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU).
    607             */
    608            new_msr |= (target_ulong)MSR_HVB;
    609        } else {
    610            if (msr_pow) {
    611                cpu_abort(cs, "Trying to deliver power-saving system reset "
    612                          "exception %d with no HV support\n", excp);
    613            }
    614        }
    615        break;
    616    case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
    617    case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
    618    case POWERPC_EXCP_TRACE:     /* Trace exception                          */
    619        break;
    620    case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
    621        msr |= env->error_code;
    622        /* fall through */
    623    case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
    624    case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
    625    case POWERPC_EXCP_HDSEG:     /* Hypervisor data segment exception        */
    626    case POWERPC_EXCP_HISEG:     /* Hypervisor instruction segment exception */
    627    case POWERPC_EXCP_SDOOR_HV:  /* Hypervisor Doorbell interrupt            */
    628    case POWERPC_EXCP_HV_EMU:
    629    case POWERPC_EXCP_HVIRT:     /* Hypervisor virtualization                */
    630        srr0 = SPR_HSRR0;
    631        srr1 = SPR_HSRR1;
    632        new_msr |= (target_ulong)MSR_HVB;
    633        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
    634        break;
    635    case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
    636    case POWERPC_EXCP_VSXU:       /* VSX unavailable exception               */
    637    case POWERPC_EXCP_FU:         /* Facility unavailable exception          */
    638#ifdef TARGET_PPC64
    639        env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56);
    640#endif
    641        break;
    642    case POWERPC_EXCP_HV_FU:     /* Hypervisor Facility Unavailable Exception */
    643#ifdef TARGET_PPC64
    644        env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS);
    645        srr0 = SPR_HSRR0;
    646        srr1 = SPR_HSRR1;
    647        new_msr |= (target_ulong)MSR_HVB;
    648        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
    649#endif
    650        break;
    651    case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
    652        trace_ppc_excp_print("PIT");
    653        break;
    654    case POWERPC_EXCP_IO:        /* IO error exception                       */
    655        /* XXX: TODO */
    656        cpu_abort(cs, "601 IO error exception is not implemented yet !\n");
    657        break;
    658    case POWERPC_EXCP_RUNM:      /* Run mode exception                       */
    659        /* XXX: TODO */
    660        cpu_abort(cs, "601 run mode exception is not implemented yet !\n");
    661        break;
    662    case POWERPC_EXCP_EMUL:      /* Emulation trap exception                 */
    663        /* XXX: TODO */
    664        cpu_abort(cs, "602 emulation trap exception "
    665                  "is not implemented yet !\n");
    666        break;
    667    case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
    668    case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
    669    case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
    670        switch (excp_model) {
    671        case POWERPC_EXCP_602:
    672        case POWERPC_EXCP_603:
    673        case POWERPC_EXCP_603E:
    674        case POWERPC_EXCP_G2:
    675            /* Swap temporary saved registers with GPRs */
    676            if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
    677                new_msr |= (target_ulong)1 << MSR_TGPR;
    678                hreg_swap_gpr_tgpr(env);
    679            }
    680            /* fall through */
    681        case POWERPC_EXCP_7x5:
    682#if defined(DEBUG_SOFTWARE_TLB)
    683            if (qemu_log_enabled()) {
    684                const char *es;
    685                target_ulong *miss, *cmp;
    686                int en;
    687
    688                if (excp == POWERPC_EXCP_IFTLB) {
    689                    es = "I";
    690                    en = 'I';
    691                    miss = &env->spr[SPR_IMISS];
    692                    cmp = &env->spr[SPR_ICMP];
    693                } else {
    694                    if (excp == POWERPC_EXCP_DLTLB) {
    695                        es = "DL";
    696                    } else {
    697                        es = "DS";
    698                    }
    699                    en = 'D';
    700                    miss = &env->spr[SPR_DMISS];
    701                    cmp = &env->spr[SPR_DCMP];
    702                }
    703                qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
    704                         TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
    705                         TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
    706                         env->spr[SPR_HASH1], env->spr[SPR_HASH2],
    707                         env->error_code);
    708            }
    709#endif
    710            msr |= env->crf[0] << 28;
    711            msr |= env->error_code; /* key, D/I, S/L bits */
    712            /* Set way using a LRU mechanism */
    713            msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
    714            break;
    715        case POWERPC_EXCP_74xx:
    716#if defined(DEBUG_SOFTWARE_TLB)
    717            if (qemu_log_enabled()) {
    718                const char *es;
    719                target_ulong *miss, *cmp;
    720                int en;
    721
    722                if (excp == POWERPC_EXCP_IFTLB) {
    723                    es = "I";
    724                    en = 'I';
    725                    miss = &env->spr[SPR_TLBMISS];
    726                    cmp = &env->spr[SPR_PTEHI];
    727                } else {
    728                    if (excp == POWERPC_EXCP_DLTLB) {
    729                        es = "DL";
    730                    } else {
    731                        es = "DS";
    732                    }
    733                    en = 'D';
    734                    miss = &env->spr[SPR_TLBMISS];
    735                    cmp = &env->spr[SPR_PTEHI];
    736                }
    737                qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
    738                         TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
    739                         env->error_code);
    740            }
    741#endif
    742            msr |= env->error_code; /* key bit */
    743            break;
    744        default:
    745            cpu_abort(cs, "Invalid TLB miss exception\n");
    746            break;
    747        }
    748        break;
    749    case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */
    750        /* XXX: TODO */
    751        cpu_abort(cs, "Floating point assist exception "
    752                  "is not implemented yet !\n");
    753        break;
    754    case POWERPC_EXCP_DABR:      /* Data address breakpoint                  */
    755        /* XXX: TODO */
    756        cpu_abort(cs, "DABR exception is not implemented yet !\n");
    757        break;
    758    case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
    759        /* XXX: TODO */
    760        cpu_abort(cs, "IABR exception is not implemented yet !\n");
    761        break;
    762    case POWERPC_EXCP_SMI:       /* System management interrupt              */
    763        /* XXX: TODO */
    764        cpu_abort(cs, "SMI exception is not implemented yet !\n");
    765        break;
    766    case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
    767        /* XXX: TODO */
    768        cpu_abort(cs, "Thermal management exception "
    769                  "is not implemented yet !\n");
    770        break;
    771    case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
    772        /* XXX: TODO */
    773        cpu_abort(cs,
    774                  "Performance counter exception is not implemented yet !\n");
    775        break;
    776    case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
    777        /* XXX: TODO */
    778        cpu_abort(cs, "VPU assist exception is not implemented yet !\n");
    779        break;
    780    case POWERPC_EXCP_SOFTP:     /* Soft patch exception                     */
    781        /* XXX: TODO */
    782        cpu_abort(cs,
    783                  "970 soft-patch exception is not implemented yet !\n");
    784        break;
    785    case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */
    786        /* XXX: TODO */
    787        cpu_abort(cs,
    788                  "970 maintenance exception is not implemented yet !\n");
    789        break;
    790    case POWERPC_EXCP_MEXTBR:    /* Maskable external breakpoint             */
    791        /* XXX: TODO */
    792        cpu_abort(cs, "Maskable external exception "
    793                  "is not implemented yet !\n");
    794        break;
    795    case POWERPC_EXCP_NMEXTBR:   /* Non maskable external breakpoint         */
    796        /* XXX: TODO */
    797        cpu_abort(cs, "Non maskable external exception "
    798                  "is not implemented yet !\n");
    799        break;
    800    default:
    801    excp_invalid:
    802        cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
    803        break;
    804    }
    805
    806    /* Sanity check */
    807    if (!(env->msr_mask & MSR_HVB)) {
    808        if (new_msr & MSR_HVB) {
    809            cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
    810                      "no HV support\n", excp);
    811        }
    812        if (srr0 == SPR_HSRR0) {
    813            cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
    814                      "no HV support\n", excp);
    815        }
    816    }
    817
    818    /*
    819     * Sort out endianness of interrupt, this differs depending on the
    820     * CPU, the HV mode, etc...
    821     */
    822#ifdef TARGET_PPC64
    823    if (excp_model == POWERPC_EXCP_POWER7) {
    824        if (!(new_msr & MSR_HVB) && (env->spr[SPR_LPCR] & LPCR_ILE)) {
    825            new_msr |= (target_ulong)1 << MSR_LE;
    826        }
    827    } else if (excp_model == POWERPC_EXCP_POWER8) {
    828        if (new_msr & MSR_HVB) {
    829            if (env->spr[SPR_HID0] & HID0_HILE) {
    830                new_msr |= (target_ulong)1 << MSR_LE;
    831            }
    832        } else if (env->spr[SPR_LPCR] & LPCR_ILE) {
    833            new_msr |= (target_ulong)1 << MSR_LE;
    834        }
    835    } else if (excp_model == POWERPC_EXCP_POWER9 ||
    836               excp_model == POWERPC_EXCP_POWER10) {
    837        if (new_msr & MSR_HVB) {
    838            if (env->spr[SPR_HID0] & HID0_POWER9_HILE) {
    839                new_msr |= (target_ulong)1 << MSR_LE;
    840            }
    841        } else if (env->spr[SPR_LPCR] & LPCR_ILE) {
    842            new_msr |= (target_ulong)1 << MSR_LE;
    843        }
    844    } else if (msr_ile) {
    845        new_msr |= (target_ulong)1 << MSR_LE;
    846    }
    847#else
    848    if (msr_ile) {
    849        new_msr |= (target_ulong)1 << MSR_LE;
    850    }
    851#endif
    852
    853    vector = env->excp_vectors[excp];
    854    if (vector == (target_ulong)-1ULL) {
    855        cpu_abort(cs, "Raised an exception without defined vector %d\n",
    856                  excp);
    857    }
    858
    859    vector |= env->excp_prefix;
    860
    861    /* If any alternate SRR register are defined, duplicate saved values */
    862    if (asrr0 != -1) {
    863        env->spr[asrr0] = env->nip;
    864    }
    865    if (asrr1 != -1) {
    866        env->spr[asrr1] = msr;
    867    }
    868
    869#if defined(TARGET_PPC64)
    870    if (excp_model == POWERPC_EXCP_BOOKE) {
    871        if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
    872            /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */
    873            new_msr |= (target_ulong)1 << MSR_CM;
    874        } else {
    875            vector = (uint32_t)vector;
    876        }
    877    } else {
    878        if (!msr_isf && !mmu_is_64bit(env->mmu_model)) {
    879            vector = (uint32_t)vector;
    880        } else {
    881            new_msr |= (target_ulong)1 << MSR_SF;
    882        }
    883    }
    884#endif
    885
    886    if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
    887        /* Save PC */
    888        env->spr[srr0] = env->nip;
    889
    890        /* Save MSR */
    891        env->spr[srr1] = msr;
    892
    893#if defined(TARGET_PPC64)
    894    } else {
    895        vector += lev * 0x20;
    896
    897        env->lr = env->nip;
    898        env->ctr = msr;
    899#endif
    900    }
    901
    902    /* This can update new_msr and vector if AIL applies */
    903    ppc_excp_apply_ail(cpu, excp_model, excp, msr, &new_msr, &vector);
    904
    905    powerpc_set_excp_state(cpu, vector, new_msr);
    906}
    907
    908void ppc_cpu_do_interrupt(CPUState *cs)
    909{
    910    PowerPCCPU *cpu = POWERPC_CPU(cs);
    911    CPUPPCState *env = &cpu->env;
    912
    913    powerpc_excp(cpu, env->excp_model, cs->exception_index);
    914}
    915
    916static void ppc_hw_interrupt(CPUPPCState *env)
    917{
    918    PowerPCCPU *cpu = env_archcpu(env);
    919    bool async_deliver;
    920
    921    /* External reset */
    922    if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
    923        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
    924        powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET);
    925        return;
    926    }
    927    /* Machine check exception */
    928    if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
    929        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
    930        powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_MCHECK);
    931        return;
    932    }
    933#if 0 /* TODO */
    934    /* External debug exception */
    935    if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
    936        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
    937        powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DEBUG);
    938        return;
    939    }
    940#endif
    941
    942    /*
    943     * For interrupts that gate on MSR:EE, we need to do something a
    944     * bit more subtle, as we need to let them through even when EE is
    945     * clear when coming out of some power management states (in order
    946     * for them to become a 0x100).
    947     */
    948    async_deliver = (msr_ee != 0) || env->resume_as_sreset;
    949
    950    /* Hypervisor decrementer exception */
    951    if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
    952        /* LPCR will be clear when not supported so this will work */
    953        bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
    954        if ((async_deliver || msr_hv == 0) && hdice) {
    955            /* HDEC clears on delivery */
    956            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
    957            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HDECR);
    958            return;
    959        }
    960    }
    961
    962    /* Hypervisor virtualization interrupt */
    963    if (env->pending_interrupts & (1 << PPC_INTERRUPT_HVIRT)) {
    964        /* LPCR will be clear when not supported so this will work */
    965        bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
    966        if ((async_deliver || msr_hv == 0) && hvice) {
    967            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HVIRT);
    968            return;
    969        }
    970    }
    971
    972    /* External interrupt can ignore MSR:EE under some circumstances */
    973    if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
    974        bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
    975        bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
    976        /* HEIC blocks delivery to the hypervisor */
    977        if ((async_deliver && !(heic && msr_hv && !msr_pr)) ||
    978            (env->has_hv_mode && msr_hv == 0 && !lpes0)) {
    979            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL);
    980            return;
    981        }
    982    }
    983    if (msr_ce != 0) {
    984        /* External critical interrupt */
    985        if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
    986            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_CRITICAL);
    987            return;
    988        }
    989    }
    990    if (async_deliver != 0) {
    991        /* Watchdog timer on embedded PowerPC */
    992        if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
    993            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
    994            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_WDT);
    995            return;
    996        }
    997        if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
    998            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
    999            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORCI);
   1000            return;
   1001        }
   1002        /* Fixed interval timer on embedded PowerPC */
   1003        if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
   1004            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
   1005            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_FIT);
   1006            return;
   1007        }
   1008        /* Programmable interval timer on embedded PowerPC */
   1009        if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
   1010            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
   1011            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PIT);
   1012            return;
   1013        }
   1014        /* Decrementer exception */
   1015        if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
   1016            if (ppc_decr_clear_on_delivery(env)) {
   1017                env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
   1018            }
   1019            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DECR);
   1020            return;
   1021        }
   1022        if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
   1023            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
   1024            if (is_book3s_arch2x(env)) {
   1025                powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_SDOOR);
   1026            } else {
   1027                powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI);
   1028            }
   1029            return;
   1030        }
   1031        if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) {
   1032            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL);
   1033            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_SDOOR_HV);
   1034            return;
   1035        }
   1036        if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
   1037            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
   1038            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PERFM);
   1039            return;
   1040        }
   1041        /* Thermal interrupt */
   1042        if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
   1043            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
   1044            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_THERM);
   1045            return;
   1046        }
   1047    }
   1048
   1049    if (env->resume_as_sreset) {
   1050        /*
   1051         * This is a bug ! It means that has_work took us out of halt without
   1052         * anything to deliver while in a PM state that requires getting
   1053         * out via a 0x100
   1054         *
   1055         * This means we will incorrectly execute past the power management
   1056         * instruction instead of triggering a reset.
   1057         *
   1058         * It generally means a discrepancy between the wakeup conditions in the
   1059         * processor has_work implementation and the logic in this function.
   1060         */
   1061        cpu_abort(env_cpu(env),
   1062                  "Wakeup from PM state but interrupt Undelivered");
   1063    }
   1064}
   1065
   1066void ppc_cpu_do_system_reset(CPUState *cs)
   1067{
   1068    PowerPCCPU *cpu = POWERPC_CPU(cs);
   1069    CPUPPCState *env = &cpu->env;
   1070
   1071    powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET);
   1072}
   1073
   1074void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
   1075{
   1076    PowerPCCPU *cpu = POWERPC_CPU(cs);
   1077    CPUPPCState *env = &cpu->env;
   1078    target_ulong msr = 0;
   1079
   1080    /*
   1081     * Set MSR and NIP for the handler, SRR0/1, DAR and DSISR have already
   1082     * been set by KVM.
   1083     */
   1084    msr = (1ULL << MSR_ME);
   1085    msr |= env->msr & (1ULL << MSR_SF);
   1086    if (ppc_interrupts_little_endian(cpu)) {
   1087        msr |= (1ULL << MSR_LE);
   1088    }
   1089
   1090    powerpc_set_excp_state(cpu, vector, msr);
   1091}
   1092
   1093bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
   1094{
   1095    PowerPCCPU *cpu = POWERPC_CPU(cs);
   1096    CPUPPCState *env = &cpu->env;
   1097
   1098    if (interrupt_request & CPU_INTERRUPT_HARD) {
   1099        ppc_hw_interrupt(env);
   1100        if (env->pending_interrupts == 0) {
   1101            cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
   1102        }
   1103        return true;
   1104    }
   1105    return false;
   1106}
   1107
   1108#endif /* !CONFIG_USER_ONLY */
   1109
   1110/*****************************************************************************/
   1111/* Exceptions processing helpers */
   1112
   1113void raise_exception_err_ra(CPUPPCState *env, uint32_t exception,
   1114                            uint32_t error_code, uintptr_t raddr)
   1115{
   1116    CPUState *cs = env_cpu(env);
   1117
   1118    cs->exception_index = exception;
   1119    env->error_code = error_code;
   1120    cpu_loop_exit_restore(cs, raddr);
   1121}
   1122
   1123void raise_exception_err(CPUPPCState *env, uint32_t exception,
   1124                         uint32_t error_code)
   1125{
   1126    raise_exception_err_ra(env, exception, error_code, 0);
   1127}
   1128
   1129void raise_exception(CPUPPCState *env, uint32_t exception)
   1130{
   1131    raise_exception_err_ra(env, exception, 0, 0);
   1132}
   1133
   1134void raise_exception_ra(CPUPPCState *env, uint32_t exception,
   1135                        uintptr_t raddr)
   1136{
   1137    raise_exception_err_ra(env, exception, 0, raddr);
   1138}
   1139
   1140#ifdef CONFIG_TCG
   1141void helper_raise_exception_err(CPUPPCState *env, uint32_t exception,
   1142                                uint32_t error_code)
   1143{
   1144    raise_exception_err_ra(env, exception, error_code, 0);
   1145}
   1146
   1147void helper_raise_exception(CPUPPCState *env, uint32_t exception)
   1148{
   1149    raise_exception_err_ra(env, exception, 0, 0);
   1150}
   1151#endif
   1152
   1153#if !defined(CONFIG_USER_ONLY)
   1154#ifdef CONFIG_TCG
   1155void helper_store_msr(CPUPPCState *env, target_ulong val)
   1156{
   1157    uint32_t excp = hreg_store_msr(env, val, 0);
   1158
   1159    if (excp != 0) {
   1160        CPUState *cs = env_cpu(env);
   1161        cpu_interrupt_exittb(cs);
   1162        raise_exception(env, excp);
   1163    }
   1164}
   1165
   1166#if defined(TARGET_PPC64)
   1167void helper_scv(CPUPPCState *env, uint32_t lev)
   1168{
   1169    if (env->spr[SPR_FSCR] & (1ull << FSCR_SCV)) {
   1170        raise_exception_err(env, POWERPC_EXCP_SYSCALL_VECTORED, lev);
   1171    } else {
   1172        raise_exception_err(env, POWERPC_EXCP_FU, FSCR_IC_SCV);
   1173    }
   1174}
   1175
   1176void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn)
   1177{
   1178    CPUState *cs;
   1179
   1180    cs = env_cpu(env);
   1181    cs->halted = 1;
   1182
   1183    /* Condition for waking up at 0x100 */
   1184    env->resume_as_sreset = (insn != PPC_PM_STOP) ||
   1185        (env->spr[SPR_PSSCR] & PSSCR_EC);
   1186}
   1187#endif /* defined(TARGET_PPC64) */
   1188#endif /* CONFIG_TCG */
   1189
   1190static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
   1191{
   1192    CPUState *cs = env_cpu(env);
   1193
   1194    /* MSR:POW cannot be set by any form of rfi */
   1195    msr &= ~(1ULL << MSR_POW);
   1196
   1197#if defined(TARGET_PPC64)
   1198    /* Switching to 32-bit ? Crop the nip */
   1199    if (!msr_is_64bit(env, msr)) {
   1200        nip = (uint32_t)nip;
   1201    }
   1202#else
   1203    nip = (uint32_t)nip;
   1204#endif
   1205    /* XXX: beware: this is false if VLE is supported */
   1206    env->nip = nip & ~((target_ulong)0x00000003);
   1207    hreg_store_msr(env, msr, 1);
   1208    trace_ppc_excp_rfi(env->nip, env->msr);
   1209    /*
   1210     * No need to raise an exception here, as rfi is always the last
   1211     * insn of a TB
   1212     */
   1213    cpu_interrupt_exittb(cs);
   1214    /* Reset the reservation */
   1215    env->reserve_addr = -1;
   1216
   1217    /* Context synchronizing: check if TCG TLB needs flush */
   1218    check_tlb_flush(env, false);
   1219}
   1220
   1221#ifdef CONFIG_TCG
   1222void helper_rfi(CPUPPCState *env)
   1223{
   1224    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
   1225}
   1226
   1227#define MSR_BOOK3S_MASK
   1228#if defined(TARGET_PPC64)
   1229void helper_rfid(CPUPPCState *env)
   1230{
   1231    /*
   1232     * The architecture defines a number of rules for which bits can
   1233     * change but in practice, we handle this in hreg_store_msr()
   1234     * which will be called by do_rfi(), so there is no need to filter
   1235     * here
   1236     */
   1237    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
   1238}
   1239
   1240void helper_rfscv(CPUPPCState *env)
   1241{
   1242    do_rfi(env, env->lr, env->ctr);
   1243}
   1244
   1245void helper_hrfid(CPUPPCState *env)
   1246{
   1247    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
   1248}
   1249#endif
   1250
   1251/*****************************************************************************/
   1252/* Embedded PowerPC specific helpers */
   1253void helper_40x_rfci(CPUPPCState *env)
   1254{
   1255    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
   1256}
   1257
   1258void helper_rfci(CPUPPCState *env)
   1259{
   1260    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
   1261}
   1262
   1263void helper_rfdi(CPUPPCState *env)
   1264{
   1265    /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
   1266    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
   1267}
   1268
   1269void helper_rfmci(CPUPPCState *env)
   1270{
   1271    /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
   1272    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
   1273}
   1274#endif /* CONFIG_TCG */
   1275#endif /* !defined(CONFIG_USER_ONLY) */
   1276
   1277#ifdef CONFIG_TCG
   1278void helper_tw(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
   1279               uint32_t flags)
   1280{
   1281    if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) ||
   1282                  ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) ||
   1283                  ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) ||
   1284                  ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) ||
   1285                  ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) {
   1286        raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
   1287                               POWERPC_EXCP_TRAP, GETPC());
   1288    }
   1289}
   1290
   1291#if defined(TARGET_PPC64)
   1292void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
   1293               uint32_t flags)
   1294{
   1295    if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) ||
   1296                  ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) ||
   1297                  ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) ||
   1298                  ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) ||
   1299                  ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) {
   1300        raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
   1301                               POWERPC_EXCP_TRAP, GETPC());
   1302    }
   1303}
   1304#endif
   1305#endif
   1306
   1307#if !defined(CONFIG_USER_ONLY)
   1308/*****************************************************************************/
   1309/* PowerPC 601 specific instructions (POWER bridge) */
   1310
   1311#ifdef CONFIG_TCG
   1312void helper_rfsvc(CPUPPCState *env)
   1313{
   1314    do_rfi(env, env->lr, env->ctr & 0x0000FFFF);
   1315}
   1316
   1317/* Embedded.Processor Control */
   1318static int dbell2irq(target_ulong rb)
   1319{
   1320    int msg = rb & DBELL_TYPE_MASK;
   1321    int irq = -1;
   1322
   1323    switch (msg) {
   1324    case DBELL_TYPE_DBELL:
   1325        irq = PPC_INTERRUPT_DOORBELL;
   1326        break;
   1327    case DBELL_TYPE_DBELL_CRIT:
   1328        irq = PPC_INTERRUPT_CDOORBELL;
   1329        break;
   1330    case DBELL_TYPE_G_DBELL:
   1331    case DBELL_TYPE_G_DBELL_CRIT:
   1332    case DBELL_TYPE_G_DBELL_MC:
   1333        /* XXX implement */
   1334    default:
   1335        break;
   1336    }
   1337
   1338    return irq;
   1339}
   1340
   1341void helper_msgclr(CPUPPCState *env, target_ulong rb)
   1342{
   1343    int irq = dbell2irq(rb);
   1344
   1345    if (irq < 0) {
   1346        return;
   1347    }
   1348
   1349    env->pending_interrupts &= ~(1 << irq);
   1350}
   1351
   1352void helper_msgsnd(target_ulong rb)
   1353{
   1354    int irq = dbell2irq(rb);
   1355    int pir = rb & DBELL_PIRTAG_MASK;
   1356    CPUState *cs;
   1357
   1358    if (irq < 0) {
   1359        return;
   1360    }
   1361
   1362    qemu_mutex_lock_iothread();
   1363    CPU_FOREACH(cs) {
   1364        PowerPCCPU *cpu = POWERPC_CPU(cs);
   1365        CPUPPCState *cenv = &cpu->env;
   1366
   1367        if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
   1368            cenv->pending_interrupts |= 1 << irq;
   1369            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
   1370        }
   1371    }
   1372    qemu_mutex_unlock_iothread();
   1373}
   1374
   1375/* Server Processor Control */
   1376
   1377static bool dbell_type_server(target_ulong rb)
   1378{
   1379    /*
   1380     * A Directed Hypervisor Doorbell message is sent only if the
   1381     * message type is 5. All other types are reserved and the
   1382     * instruction is a no-op
   1383     */
   1384    return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER;
   1385}
   1386
   1387void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb)
   1388{
   1389    if (!dbell_type_server(rb)) {
   1390        return;
   1391    }
   1392
   1393    env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL);
   1394}
   1395
   1396static void book3s_msgsnd_common(int pir, int irq)
   1397{
   1398    CPUState *cs;
   1399
   1400    qemu_mutex_lock_iothread();
   1401    CPU_FOREACH(cs) {
   1402        PowerPCCPU *cpu = POWERPC_CPU(cs);
   1403        CPUPPCState *cenv = &cpu->env;
   1404
   1405        /* TODO: broadcast message to all threads of the same  processor */
   1406        if (cenv->spr_cb[SPR_PIR].default_value == pir) {
   1407            cenv->pending_interrupts |= 1 << irq;
   1408            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
   1409        }
   1410    }
   1411    qemu_mutex_unlock_iothread();
   1412}
   1413
   1414void helper_book3s_msgsnd(target_ulong rb)
   1415{
   1416    int pir = rb & DBELL_PROCIDTAG_MASK;
   1417
   1418    if (!dbell_type_server(rb)) {
   1419        return;
   1420    }
   1421
   1422    book3s_msgsnd_common(pir, PPC_INTERRUPT_HDOORBELL);
   1423}
   1424
   1425#if defined(TARGET_PPC64)
   1426void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb)
   1427{
   1428    helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP);
   1429
   1430    if (!dbell_type_server(rb)) {
   1431        return;
   1432    }
   1433
   1434    env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
   1435}
   1436
   1437/*
   1438 * sends a message to other threads that are on the same
   1439 * multi-threaded processor
   1440 */
   1441void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb)
   1442{
   1443    int pir = env->spr_cb[SPR_PIR].default_value;
   1444
   1445    helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP);
   1446
   1447    if (!dbell_type_server(rb)) {
   1448        return;
   1449    }
   1450
   1451    /* TODO: TCG supports only one thread */
   1452
   1453    book3s_msgsnd_common(pir, PPC_INTERRUPT_DOORBELL);
   1454}
   1455#endif
   1456#endif /* CONFIG_TCG */
   1457#endif
   1458
   1459#ifdef CONFIG_TCG
   1460void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
   1461                                 MMUAccessType access_type,
   1462                                 int mmu_idx, uintptr_t retaddr)
   1463{
   1464    CPUPPCState *env = cs->env_ptr;
   1465    uint32_t insn;
   1466
   1467    /* Restore state and reload the insn we executed, for filling in DSISR.  */
   1468    cpu_restore_state(cs, retaddr, true);
   1469    insn = cpu_ldl_code(env, env->nip);
   1470
   1471    cs->exception_index = POWERPC_EXCP_ALIGN;
   1472    env->error_code = insn & 0x03FF0000;
   1473    cpu_loop_exit(cs);
   1474}
   1475#endif