These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / target-ppc / excp_helper.c
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 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 "cpu.h"
21 #include "exec/helper-proto.h"
22 #include "exec/cpu_ldst.h"
23
24 #include "helper_regs.h"
25
26 //#define DEBUG_OP
27 //#define DEBUG_SOFTWARE_TLB
28 //#define DEBUG_EXCEPTIONS
29
30 #ifdef DEBUG_EXCEPTIONS
31 #  define LOG_EXCP(...) qemu_log(__VA_ARGS__)
32 #else
33 #  define LOG_EXCP(...) do { } while (0)
34 #endif
35
36 /*****************************************************************************/
37 /* PowerPC Hypercall emulation */
38
39 void (*cpu_ppc_hypercall)(PowerPCCPU *);
40
41 /*****************************************************************************/
42 /* Exception processing */
43 #if defined(CONFIG_USER_ONLY)
44 void ppc_cpu_do_interrupt(CPUState *cs)
45 {
46     PowerPCCPU *cpu = POWERPC_CPU(cs);
47     CPUPPCState *env = &cpu->env;
48
49     cs->exception_index = POWERPC_EXCP_NONE;
50     env->error_code = 0;
51 }
52
53 static void ppc_hw_interrupt(CPUPPCState *env)
54 {
55     CPUState *cs = CPU(ppc_env_get_cpu(env));
56
57     cs->exception_index = POWERPC_EXCP_NONE;
58     env->error_code = 0;
59 }
60 #else /* defined(CONFIG_USER_ONLY) */
61 static inline void dump_syscall(CPUPPCState *env)
62 {
63     qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 " r3=%016" PRIx64
64                   " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
65                   " nip=" TARGET_FMT_lx "\n",
66                   ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
67                   ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
68                   ppc_dump_gpr(env, 6), env->nip);
69 }
70
71 /* Note that this function should be greatly optimized
72  * when called with a constant excp, from ppc_hw_interrupt
73  */
74 static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
75 {
76     CPUState *cs = CPU(cpu);
77     CPUPPCState *env = &cpu->env;
78     target_ulong msr, new_msr, vector;
79     int srr0, srr1, asrr0, asrr1;
80     int lpes0, lpes1, lev, ail;
81
82     if (0) {
83         /* XXX: find a suitable condition to enable the hypervisor mode */
84         lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;
85         lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;
86     } else {
87         /* Those values ensure we won't enter the hypervisor mode */
88         lpes0 = 0;
89         lpes1 = 1;
90     }
91
92     qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
93                   " => %08x (%02x)\n", env->nip, excp, env->error_code);
94
95     /* new srr1 value excluding must-be-zero bits */
96     if (excp_model == POWERPC_EXCP_BOOKE) {
97         msr = env->msr;
98     } else {
99         msr = env->msr & ~0x783f0000ULL;
100     }
101
102     /* new interrupt handler msr */
103     new_msr = env->msr & ((target_ulong)1 << MSR_ME);
104
105     /* target registers */
106     srr0 = SPR_SRR0;
107     srr1 = SPR_SRR1;
108     asrr0 = -1;
109     asrr1 = -1;
110
111     /* Exception targetting modifiers
112      *
113      * AIL is initialized here but can be cleared by
114      * selected exceptions
115      */
116 #if defined(TARGET_PPC64)
117     if (excp_model == POWERPC_EXCP_POWER7 ||
118         excp_model == POWERPC_EXCP_POWER8) {
119         if (excp_model == POWERPC_EXCP_POWER8) {
120             ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
121         } else {
122             ail = 0;
123         }
124     } else
125 #endif /* defined(TARGET_PPC64) */
126     {
127         ail = 0;
128     }
129
130     switch (excp) {
131     case POWERPC_EXCP_NONE:
132         /* Should never happen */
133         return;
134     case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
135         switch (excp_model) {
136         case POWERPC_EXCP_40x:
137             srr0 = SPR_40x_SRR2;
138             srr1 = SPR_40x_SRR3;
139             break;
140         case POWERPC_EXCP_BOOKE:
141             srr0 = SPR_BOOKE_CSRR0;
142             srr1 = SPR_BOOKE_CSRR1;
143             break;
144         case POWERPC_EXCP_G2:
145             break;
146         default:
147             goto excp_invalid;
148         }
149         goto store_next;
150     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
151         if (msr_me == 0) {
152             /* Machine check exception is not enabled.
153              * Enter checkstop state.
154              */
155             fprintf(stderr, "Machine check while not allowed. "
156                     "Entering checkstop state\n");
157             if (qemu_log_separate()) {
158                 qemu_log("Machine check while not allowed. "
159                         "Entering checkstop state\n");
160             }
161             cs->halted = 1;
162             cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
163         }
164         if (0) {
165             /* XXX: find a suitable condition to enable the hypervisor mode */
166             new_msr |= (target_ulong)MSR_HVB;
167         }
168         ail = 0;
169
170         /* machine check exceptions don't have ME set */
171         new_msr &= ~((target_ulong)1 << MSR_ME);
172
173         /* XXX: should also have something loaded in DAR / DSISR */
174         switch (excp_model) {
175         case POWERPC_EXCP_40x:
176             srr0 = SPR_40x_SRR2;
177             srr1 = SPR_40x_SRR3;
178             break;
179         case POWERPC_EXCP_BOOKE:
180             /* FIXME: choose one or the other based on CPU type */
181             srr0 = SPR_BOOKE_MCSRR0;
182             srr1 = SPR_BOOKE_MCSRR1;
183             asrr0 = SPR_BOOKE_CSRR0;
184             asrr1 = SPR_BOOKE_CSRR1;
185             break;
186         default:
187             break;
188         }
189         goto store_next;
190     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
191         LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
192                  "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
193         if (lpes1 == 0) {
194             new_msr |= (target_ulong)MSR_HVB;
195         }
196         goto store_next;
197     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
198         LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
199                  "\n", msr, env->nip);
200         if (lpes1 == 0) {
201             new_msr |= (target_ulong)MSR_HVB;
202         }
203         msr |= env->error_code;
204         goto store_next;
205     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
206         cs = CPU(cpu);
207
208         if (lpes0 == 1) {
209             new_msr |= (target_ulong)MSR_HVB;
210         }
211         if (env->mpic_proxy) {
212             /* IACK the IRQ on delivery */
213             env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
214         }
215         goto store_next;
216     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
217         if (lpes1 == 0) {
218             new_msr |= (target_ulong)MSR_HVB;
219         }
220         /* XXX: this is false */
221         /* Get rS/rD and rA from faulting opcode */
222         env->spr[SPR_DSISR] |= (cpu_ldl_code(env, (env->nip - 4))
223                                 & 0x03FF0000) >> 16;
224         goto store_next;
225     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
226         switch (env->error_code & ~0xF) {
227         case POWERPC_EXCP_FP:
228             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
229                 LOG_EXCP("Ignore floating point exception\n");
230                 cs->exception_index = POWERPC_EXCP_NONE;
231                 env->error_code = 0;
232                 return;
233             }
234             if (lpes1 == 0) {
235                 new_msr |= (target_ulong)MSR_HVB;
236             }
237             msr |= 0x00100000;
238             if (msr_fe0 == msr_fe1) {
239                 goto store_next;
240             }
241             msr |= 0x00010000;
242             break;
243         case POWERPC_EXCP_INVAL:
244             LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
245             if (lpes1 == 0) {
246                 new_msr |= (target_ulong)MSR_HVB;
247             }
248             msr |= 0x00080000;
249             env->spr[SPR_BOOKE_ESR] = ESR_PIL;
250             break;
251         case POWERPC_EXCP_PRIV:
252             if (lpes1 == 0) {
253                 new_msr |= (target_ulong)MSR_HVB;
254             }
255             msr |= 0x00040000;
256             env->spr[SPR_BOOKE_ESR] = ESR_PPR;
257             break;
258         case POWERPC_EXCP_TRAP:
259             if (lpes1 == 0) {
260                 new_msr |= (target_ulong)MSR_HVB;
261             }
262             msr |= 0x00020000;
263             env->spr[SPR_BOOKE_ESR] = ESR_PTR;
264             break;
265         default:
266             /* Should never occur */
267             cpu_abort(cs, "Invalid program exception %d. Aborting\n",
268                       env->error_code);
269             break;
270         }
271         goto store_current;
272     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
273         if (lpes1 == 0) {
274             new_msr |= (target_ulong)MSR_HVB;
275         }
276         goto store_current;
277     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
278         dump_syscall(env);
279         lev = env->error_code;
280         if ((lev == 1) && cpu_ppc_hypercall) {
281             cpu_ppc_hypercall(cpu);
282             return;
283         }
284         if (lev == 1 || (lpes0 == 0 && lpes1 == 0)) {
285             new_msr |= (target_ulong)MSR_HVB;
286         }
287         goto store_next;
288     case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
289         goto store_current;
290     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
291         if (lpes1 == 0) {
292             new_msr |= (target_ulong)MSR_HVB;
293         }
294         goto store_next;
295     case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
296         /* FIT on 4xx */
297         LOG_EXCP("FIT exception\n");
298         goto store_next;
299     case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
300         LOG_EXCP("WDT exception\n");
301         switch (excp_model) {
302         case POWERPC_EXCP_BOOKE:
303             srr0 = SPR_BOOKE_CSRR0;
304             srr1 = SPR_BOOKE_CSRR1;
305             break;
306         default:
307             break;
308         }
309         goto store_next;
310     case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
311         goto store_next;
312     case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
313         goto store_next;
314     case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
315         switch (excp_model) {
316         case POWERPC_EXCP_BOOKE:
317             /* FIXME: choose one or the other based on CPU type */
318             srr0 = SPR_BOOKE_DSRR0;
319             srr1 = SPR_BOOKE_DSRR1;
320             asrr0 = SPR_BOOKE_CSRR0;
321             asrr1 = SPR_BOOKE_CSRR1;
322             break;
323         default:
324             break;
325         }
326         /* XXX: TODO */
327         cpu_abort(cs, "Debug exception is not implemented yet !\n");
328         goto store_next;
329     case POWERPC_EXCP_SPEU:      /* SPE/embedded floating-point unavailable  */
330         env->spr[SPR_BOOKE_ESR] = ESR_SPV;
331         goto store_current;
332     case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */
333         /* XXX: TODO */
334         cpu_abort(cs, "Embedded floating point data exception "
335                   "is not implemented yet !\n");
336         env->spr[SPR_BOOKE_ESR] = ESR_SPV;
337         goto store_next;
338     case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */
339         /* XXX: TODO */
340         cpu_abort(cs, "Embedded floating point round exception "
341                   "is not implemented yet !\n");
342         env->spr[SPR_BOOKE_ESR] = ESR_SPV;
343         goto store_next;
344     case POWERPC_EXCP_EPERFM:    /* Embedded performance monitor interrupt   */
345         /* XXX: TODO */
346         cpu_abort(cs,
347                   "Performance counter exception is not implemented yet !\n");
348         goto store_next;
349     case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */
350         goto store_next;
351     case POWERPC_EXCP_DOORCI:    /* Embedded doorbell critical interrupt     */
352         srr0 = SPR_BOOKE_CSRR0;
353         srr1 = SPR_BOOKE_CSRR1;
354         goto store_next;
355     case POWERPC_EXCP_RESET:     /* System reset exception                   */
356         if (msr_pow) {
357             /* indicate that we resumed from power save mode */
358             msr |= 0x10000;
359         } else {
360             new_msr &= ~((target_ulong)1 << MSR_ME);
361         }
362
363         if (0) {
364             /* XXX: find a suitable condition to enable the hypervisor mode */
365             new_msr |= (target_ulong)MSR_HVB;
366         }
367         ail = 0;
368         goto store_next;
369     case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
370         if (lpes1 == 0) {
371             new_msr |= (target_ulong)MSR_HVB;
372         }
373         goto store_next;
374     case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
375         if (lpes1 == 0) {
376             new_msr |= (target_ulong)MSR_HVB;
377         }
378         goto store_next;
379     case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
380         srr0 = SPR_HSRR0;
381         srr1 = SPR_HSRR1;
382         new_msr |= (target_ulong)MSR_HVB;
383         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
384         goto store_next;
385     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
386         if (lpes1 == 0) {
387             new_msr |= (target_ulong)MSR_HVB;
388         }
389         goto store_next;
390     case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
391         srr0 = SPR_HSRR0;
392         srr1 = SPR_HSRR1;
393         new_msr |= (target_ulong)MSR_HVB;
394         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
395         goto store_next;
396     case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
397         srr0 = SPR_HSRR0;
398         srr1 = SPR_HSRR1;
399         new_msr |= (target_ulong)MSR_HVB;
400         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
401         goto store_next;
402     case POWERPC_EXCP_HDSEG:     /* Hypervisor data segment exception        */
403         srr0 = SPR_HSRR0;
404         srr1 = SPR_HSRR1;
405         new_msr |= (target_ulong)MSR_HVB;
406         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
407         goto store_next;
408     case POWERPC_EXCP_HISEG:     /* Hypervisor instruction segment exception */
409         srr0 = SPR_HSRR0;
410         srr1 = SPR_HSRR1;
411         new_msr |= (target_ulong)MSR_HVB;
412         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
413         goto store_next;
414     case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
415         if (lpes1 == 0) {
416             new_msr |= (target_ulong)MSR_HVB;
417         }
418         goto store_current;
419     case POWERPC_EXCP_VSXU:       /* VSX unavailable exception               */
420         if (lpes1 == 0) {
421             new_msr |= (target_ulong)MSR_HVB;
422         }
423         goto store_current;
424     case POWERPC_EXCP_FU:         /* Facility unavailable exception          */
425         if (lpes1 == 0) {
426             new_msr |= (target_ulong)MSR_HVB;
427         }
428         goto store_current;
429     case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
430         LOG_EXCP("PIT exception\n");
431         goto store_next;
432     case POWERPC_EXCP_IO:        /* IO error exception                       */
433         /* XXX: TODO */
434         cpu_abort(cs, "601 IO error exception is not implemented yet !\n");
435         goto store_next;
436     case POWERPC_EXCP_RUNM:      /* Run mode exception                       */
437         /* XXX: TODO */
438         cpu_abort(cs, "601 run mode exception is not implemented yet !\n");
439         goto store_next;
440     case POWERPC_EXCP_EMUL:      /* Emulation trap exception                 */
441         /* XXX: TODO */
442         cpu_abort(cs, "602 emulation trap exception "
443                   "is not implemented yet !\n");
444         goto store_next;
445     case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
446         if (lpes1 == 0) { /* XXX: check this */
447             new_msr |= (target_ulong)MSR_HVB;
448         }
449         switch (excp_model) {
450         case POWERPC_EXCP_602:
451         case POWERPC_EXCP_603:
452         case POWERPC_EXCP_603E:
453         case POWERPC_EXCP_G2:
454             goto tlb_miss_tgpr;
455         case POWERPC_EXCP_7x5:
456             goto tlb_miss;
457         case POWERPC_EXCP_74xx:
458             goto tlb_miss_74xx;
459         default:
460             cpu_abort(cs, "Invalid instruction TLB miss exception\n");
461             break;
462         }
463         break;
464     case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
465         if (lpes1 == 0) { /* XXX: check this */
466             new_msr |= (target_ulong)MSR_HVB;
467         }
468         switch (excp_model) {
469         case POWERPC_EXCP_602:
470         case POWERPC_EXCP_603:
471         case POWERPC_EXCP_603E:
472         case POWERPC_EXCP_G2:
473             goto tlb_miss_tgpr;
474         case POWERPC_EXCP_7x5:
475             goto tlb_miss;
476         case POWERPC_EXCP_74xx:
477             goto tlb_miss_74xx;
478         default:
479             cpu_abort(cs, "Invalid data load TLB miss exception\n");
480             break;
481         }
482         break;
483     case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
484         if (lpes1 == 0) { /* XXX: check this */
485             new_msr |= (target_ulong)MSR_HVB;
486         }
487         switch (excp_model) {
488         case POWERPC_EXCP_602:
489         case POWERPC_EXCP_603:
490         case POWERPC_EXCP_603E:
491         case POWERPC_EXCP_G2:
492         tlb_miss_tgpr:
493             /* Swap temporary saved registers with GPRs */
494             if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
495                 new_msr |= (target_ulong)1 << MSR_TGPR;
496                 hreg_swap_gpr_tgpr(env);
497             }
498             goto tlb_miss;
499         case POWERPC_EXCP_7x5:
500         tlb_miss:
501 #if defined(DEBUG_SOFTWARE_TLB)
502             if (qemu_log_enabled()) {
503                 const char *es;
504                 target_ulong *miss, *cmp;
505                 int en;
506
507                 if (excp == POWERPC_EXCP_IFTLB) {
508                     es = "I";
509                     en = 'I';
510                     miss = &env->spr[SPR_IMISS];
511                     cmp = &env->spr[SPR_ICMP];
512                 } else {
513                     if (excp == POWERPC_EXCP_DLTLB) {
514                         es = "DL";
515                     } else {
516                         es = "DS";
517                     }
518                     en = 'D';
519                     miss = &env->spr[SPR_DMISS];
520                     cmp = &env->spr[SPR_DCMP];
521                 }
522                 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
523                          TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
524                          TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
525                          env->spr[SPR_HASH1], env->spr[SPR_HASH2],
526                          env->error_code);
527             }
528 #endif
529             msr |= env->crf[0] << 28;
530             msr |= env->error_code; /* key, D/I, S/L bits */
531             /* Set way using a LRU mechanism */
532             msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
533             break;
534         case POWERPC_EXCP_74xx:
535         tlb_miss_74xx:
536 #if defined(DEBUG_SOFTWARE_TLB)
537             if (qemu_log_enabled()) {
538                 const char *es;
539                 target_ulong *miss, *cmp;
540                 int en;
541
542                 if (excp == POWERPC_EXCP_IFTLB) {
543                     es = "I";
544                     en = 'I';
545                     miss = &env->spr[SPR_TLBMISS];
546                     cmp = &env->spr[SPR_PTEHI];
547                 } else {
548                     if (excp == POWERPC_EXCP_DLTLB) {
549                         es = "DL";
550                     } else {
551                         es = "DS";
552                     }
553                     en = 'D';
554                     miss = &env->spr[SPR_TLBMISS];
555                     cmp = &env->spr[SPR_PTEHI];
556                 }
557                 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
558                          TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
559                          env->error_code);
560             }
561 #endif
562             msr |= env->error_code; /* key bit */
563             break;
564         default:
565             cpu_abort(cs, "Invalid data store TLB miss exception\n");
566             break;
567         }
568         goto store_next;
569     case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */
570         /* XXX: TODO */
571         cpu_abort(cs, "Floating point assist exception "
572                   "is not implemented yet !\n");
573         goto store_next;
574     case POWERPC_EXCP_DABR:      /* Data address breakpoint                  */
575         /* XXX: TODO */
576         cpu_abort(cs, "DABR exception is not implemented yet !\n");
577         goto store_next;
578     case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
579         /* XXX: TODO */
580         cpu_abort(cs, "IABR exception is not implemented yet !\n");
581         goto store_next;
582     case POWERPC_EXCP_SMI:       /* System management interrupt              */
583         /* XXX: TODO */
584         cpu_abort(cs, "SMI exception is not implemented yet !\n");
585         goto store_next;
586     case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
587         /* XXX: TODO */
588         cpu_abort(cs, "Thermal management exception "
589                   "is not implemented yet !\n");
590         goto store_next;
591     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
592         if (lpes1 == 0) {
593             new_msr |= (target_ulong)MSR_HVB;
594         }
595         /* XXX: TODO */
596         cpu_abort(cs,
597                   "Performance counter exception is not implemented yet !\n");
598         goto store_next;
599     case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
600         /* XXX: TODO */
601         cpu_abort(cs, "VPU assist exception is not implemented yet !\n");
602         goto store_next;
603     case POWERPC_EXCP_SOFTP:     /* Soft patch exception                     */
604         /* XXX: TODO */
605         cpu_abort(cs,
606                   "970 soft-patch exception is not implemented yet !\n");
607         goto store_next;
608     case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */
609         /* XXX: TODO */
610         cpu_abort(cs,
611                   "970 maintenance exception is not implemented yet !\n");
612         goto store_next;
613     case POWERPC_EXCP_MEXTBR:    /* Maskable external breakpoint             */
614         /* XXX: TODO */
615         cpu_abort(cs, "Maskable external exception "
616                   "is not implemented yet !\n");
617         goto store_next;
618     case POWERPC_EXCP_NMEXTBR:   /* Non maskable external breakpoint         */
619         /* XXX: TODO */
620         cpu_abort(cs, "Non maskable external exception "
621                   "is not implemented yet !\n");
622         goto store_next;
623     default:
624     excp_invalid:
625         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
626         break;
627     store_current:
628         /* save current instruction location */
629         env->spr[srr0] = env->nip - 4;
630         break;
631     store_next:
632         /* save next instruction location */
633         env->spr[srr0] = env->nip;
634         break;
635     }
636     /* Save MSR */
637     env->spr[srr1] = msr;
638     /* If any alternate SRR register are defined, duplicate saved values */
639     if (asrr0 != -1) {
640         env->spr[asrr0] = env->spr[srr0];
641     }
642     if (asrr1 != -1) {
643         env->spr[asrr1] = env->spr[srr1];
644     }
645
646     if (env->spr[SPR_LPCR] & LPCR_AIL) {
647         new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
648     } else if (msr & ((1 << MSR_IR) | (1 << MSR_DR))) {
649         /* If we disactivated any translation, flush TLBs */
650         tlb_flush(cs, 1);
651     }
652
653 #ifdef TARGET_PPC64
654     if (excp_model == POWERPC_EXCP_POWER7 ||
655         excp_model == POWERPC_EXCP_POWER8) {
656         if (env->spr[SPR_LPCR] & LPCR_ILE) {
657             new_msr |= (target_ulong)1 << MSR_LE;
658         }
659     } else if (msr_ile) {
660         new_msr |= (target_ulong)1 << MSR_LE;
661     }
662 #else
663     if (msr_ile) {
664         new_msr |= (target_ulong)1 << MSR_LE;
665     }
666 #endif
667
668     /* Jump to handler */
669     vector = env->excp_vectors[excp];
670     if (vector == (target_ulong)-1ULL) {
671         cpu_abort(cs, "Raised an exception without defined vector %d\n",
672                   excp);
673     }
674     vector |= env->excp_prefix;
675
676     /* AIL only works if there is no HV transition and we are running with
677      * translations enabled
678      */
679     if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1)) {
680         ail = 0;
681     }
682     /* Handle AIL */
683     if (ail) {
684         new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
685         switch(ail) {
686         case AIL_0001_8000:
687             vector |= 0x18000;
688             break;
689         case AIL_C000_0000_0000_4000:
690             vector |= 0xc000000000004000ull;
691             break;
692         default:
693             cpu_abort(cs, "Invalid AIL combination %d\n", ail);
694             break;
695         }
696     }
697
698 #if defined(TARGET_PPC64)
699     if (excp_model == POWERPC_EXCP_BOOKE) {
700         if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
701             /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */
702             new_msr |= (target_ulong)1 << MSR_CM;
703         } else {
704             vector = (uint32_t)vector;
705         }
706     } else {
707         if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) {
708             vector = (uint32_t)vector;
709         } else {
710             new_msr |= (target_ulong)1 << MSR_SF;
711         }
712     }
713 #endif
714     /* XXX: we don't use hreg_store_msr here as already have treated
715      *      any special case that could occur. Just store MSR and update hflags
716      */
717     env->msr = new_msr & env->msr_mask;
718     hreg_compute_hflags(env);
719     env->nip = vector;
720     /* Reset exception state */
721     cs->exception_index = POWERPC_EXCP_NONE;
722     env->error_code = 0;
723
724     if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
725         (env->mmu_model == POWERPC_MMU_BOOKE206)) {
726         /* XXX: The BookE changes address space when switching modes,
727                 we should probably implement that as different MMU indexes,
728                 but for the moment we do it the slow way and flush all.  */
729         tlb_flush(cs, 1);
730     }
731 }
732
733 void ppc_cpu_do_interrupt(CPUState *cs)
734 {
735     PowerPCCPU *cpu = POWERPC_CPU(cs);
736     CPUPPCState *env = &cpu->env;
737
738     powerpc_excp(cpu, env->excp_model, cs->exception_index);
739 }
740
741 static void ppc_hw_interrupt(CPUPPCState *env)
742 {
743     PowerPCCPU *cpu = ppc_env_get_cpu(env);
744     int hdice;
745 #if 0
746     CPUState *cs = CPU(cpu);
747
748     qemu_log_mask(CPU_LOG_INT, "%s: %p pending %08x req %08x me %d ee %d\n",
749                   __func__, env, env->pending_interrupts,
750                   cs->interrupt_request, (int)msr_me, (int)msr_ee);
751 #endif
752     /* External reset */
753     if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
754         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
755         powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET);
756         return;
757     }
758     /* Machine check exception */
759     if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
760         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
761         powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_MCHECK);
762         return;
763     }
764 #if 0 /* TODO */
765     /* External debug exception */
766     if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
767         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
768         powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DEBUG);
769         return;
770     }
771 #endif
772     if (0) {
773         /* XXX: find a suitable condition to enable the hypervisor mode */
774         hdice = env->spr[SPR_LPCR] & 1;
775     } else {
776         hdice = 0;
777     }
778     if ((msr_ee != 0 || msr_hv == 0 || msr_pr != 0) && hdice != 0) {
779         /* Hypervisor decrementer exception */
780         if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
781             powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HDECR);
782             return;
783         }
784     }
785     if (msr_ce != 0) {
786         /* External critical interrupt */
787         if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
788             /* Taking a critical external interrupt does not clear the external
789              * critical interrupt status
790              */
791 #if 0
792             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CEXT);
793 #endif
794             powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_CRITICAL);
795             return;
796         }
797     }
798     if (msr_ee != 0) {
799         /* Watchdog timer on embedded PowerPC */
800         if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
801             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
802             powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_WDT);
803             return;
804         }
805         if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
806             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
807             powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORCI);
808             return;
809         }
810         /* Fixed interval timer on embedded PowerPC */
811         if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
812             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
813             powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_FIT);
814             return;
815         }
816         /* Programmable interval timer on embedded PowerPC */
817         if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
818             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
819             powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PIT);
820             return;
821         }
822         /* Decrementer exception */
823         if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
824             if (ppc_decr_clear_on_delivery(env)) {
825                 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
826             }
827             powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DECR);
828             return;
829         }
830         /* External interrupt */
831         if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
832             /* Taking an external interrupt does not clear the external
833              * interrupt status
834              */
835 #if 0
836             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
837 #endif
838             powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL);
839             return;
840         }
841         if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
842             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
843             powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI);
844             return;
845         }
846         if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
847             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
848             powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PERFM);
849             return;
850         }
851         /* Thermal interrupt */
852         if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
853             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
854             powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_THERM);
855             return;
856         }
857     }
858 }
859
860 void ppc_cpu_do_system_reset(CPUState *cs)
861 {
862     PowerPCCPU *cpu = POWERPC_CPU(cs);
863     CPUPPCState *env = &cpu->env;
864
865     powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET);
866 }
867 #endif /* !CONFIG_USER_ONLY */
868
869 bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
870 {
871     PowerPCCPU *cpu = POWERPC_CPU(cs);
872     CPUPPCState *env = &cpu->env;
873
874     if (interrupt_request & CPU_INTERRUPT_HARD) {
875         ppc_hw_interrupt(env);
876         if (env->pending_interrupts == 0) {
877             cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
878         }
879         return true;
880     }
881     return false;
882 }
883
884 #if defined(DEBUG_OP)
885 static void cpu_dump_rfi(target_ulong RA, target_ulong msr)
886 {
887     qemu_log("Return from exception at " TARGET_FMT_lx " with flags "
888              TARGET_FMT_lx "\n", RA, msr);
889 }
890 #endif
891
892 /*****************************************************************************/
893 /* Exceptions processing helpers */
894
895 void helper_raise_exception_err(CPUPPCState *env, uint32_t exception,
896                                 uint32_t error_code)
897 {
898     CPUState *cs = CPU(ppc_env_get_cpu(env));
899
900 #if 0
901     printf("Raise exception %3x code : %d\n", exception, error_code);
902 #endif
903     cs->exception_index = exception;
904     env->error_code = error_code;
905     cpu_loop_exit(cs);
906 }
907
908 void helper_raise_exception(CPUPPCState *env, uint32_t exception)
909 {
910     helper_raise_exception_err(env, exception, 0);
911 }
912
913 #if !defined(CONFIG_USER_ONLY)
914 void helper_store_msr(CPUPPCState *env, target_ulong val)
915 {
916     CPUState *cs;
917
918     val = hreg_store_msr(env, val, 0);
919     if (val != 0) {
920         cs = CPU(ppc_env_get_cpu(env));
921         cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
922         helper_raise_exception(env, val);
923     }
924 }
925
926 static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
927                           target_ulong msrm, int keep_msrh)
928 {
929     CPUState *cs = CPU(ppc_env_get_cpu(env));
930
931 #if defined(TARGET_PPC64)
932     if (msr_is_64bit(env, msr)) {
933         nip = (uint64_t)nip;
934         msr &= (uint64_t)msrm;
935     } else {
936         nip = (uint32_t)nip;
937         msr = (uint32_t)(msr & msrm);
938         if (keep_msrh) {
939             msr |= env->msr & ~((uint64_t)0xFFFFFFFF);
940         }
941     }
942 #else
943     nip = (uint32_t)nip;
944     msr &= (uint32_t)msrm;
945 #endif
946     /* XXX: beware: this is false if VLE is supported */
947     env->nip = nip & ~((target_ulong)0x00000003);
948     hreg_store_msr(env, msr, 1);
949 #if defined(DEBUG_OP)
950     cpu_dump_rfi(env->nip, env->msr);
951 #endif
952     /* No need to raise an exception here,
953      * as rfi is always the last insn of a TB
954      */
955     cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
956 }
957
958 void helper_rfi(CPUPPCState *env)
959 {
960     if (env->excp_model == POWERPC_EXCP_BOOKE) {
961         do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
962                ~((target_ulong)0), 0);
963     } else {
964         do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
965                ~((target_ulong)0x783F0000), 1);
966     }
967 }
968
969 #if defined(TARGET_PPC64)
970 void helper_rfid(CPUPPCState *env)
971 {
972     do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
973            ~((target_ulong)0x783F0000), 0);
974 }
975
976 void helper_hrfid(CPUPPCState *env)
977 {
978     do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1],
979            ~((target_ulong)0x783F0000), 0);
980 }
981 #endif
982
983 /*****************************************************************************/
984 /* Embedded PowerPC specific helpers */
985 void helper_40x_rfci(CPUPPCState *env)
986 {
987     do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3],
988            ~((target_ulong)0xFFFF0000), 0);
989 }
990
991 void helper_rfci(CPUPPCState *env)
992 {
993     do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
994            ~((target_ulong)0), 0);
995 }
996
997 void helper_rfdi(CPUPPCState *env)
998 {
999     /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
1000     do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1],
1001            ~((target_ulong)0), 0);
1002 }
1003
1004 void helper_rfmci(CPUPPCState *env)
1005 {
1006     /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
1007     do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1],
1008            ~((target_ulong)0), 0);
1009 }
1010 #endif
1011
1012 void helper_tw(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
1013                uint32_t flags)
1014 {
1015     if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) ||
1016                   ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) ||
1017                   ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) ||
1018                   ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) ||
1019                   ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) {
1020         helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
1021                                    POWERPC_EXCP_TRAP);
1022     }
1023 }
1024
1025 #if defined(TARGET_PPC64)
1026 void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
1027                uint32_t flags)
1028 {
1029     if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) ||
1030                   ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) ||
1031                   ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) ||
1032                   ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) ||
1033                   ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) {
1034         helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
1035                                    POWERPC_EXCP_TRAP);
1036     }
1037 }
1038 #endif
1039
1040 #if !defined(CONFIG_USER_ONLY)
1041 /*****************************************************************************/
1042 /* PowerPC 601 specific instructions (POWER bridge) */
1043
1044 void helper_rfsvc(CPUPPCState *env)
1045 {
1046     do_rfi(env, env->lr, env->ctr, 0x0000FFFF, 0);
1047 }
1048
1049 /* Embedded.Processor Control */
1050 static int dbell2irq(target_ulong rb)
1051 {
1052     int msg = rb & DBELL_TYPE_MASK;
1053     int irq = -1;
1054
1055     switch (msg) {
1056     case DBELL_TYPE_DBELL:
1057         irq = PPC_INTERRUPT_DOORBELL;
1058         break;
1059     case DBELL_TYPE_DBELL_CRIT:
1060         irq = PPC_INTERRUPT_CDOORBELL;
1061         break;
1062     case DBELL_TYPE_G_DBELL:
1063     case DBELL_TYPE_G_DBELL_CRIT:
1064     case DBELL_TYPE_G_DBELL_MC:
1065         /* XXX implement */
1066     default:
1067         break;
1068     }
1069
1070     return irq;
1071 }
1072
1073 void helper_msgclr(CPUPPCState *env, target_ulong rb)
1074 {
1075     int irq = dbell2irq(rb);
1076
1077     if (irq < 0) {
1078         return;
1079     }
1080
1081     env->pending_interrupts &= ~(1 << irq);
1082 }
1083
1084 void helper_msgsnd(target_ulong rb)
1085 {
1086     int irq = dbell2irq(rb);
1087     int pir = rb & DBELL_PIRTAG_MASK;
1088     CPUState *cs;
1089
1090     if (irq < 0) {
1091         return;
1092     }
1093
1094     CPU_FOREACH(cs) {
1095         PowerPCCPU *cpu = POWERPC_CPU(cs);
1096         CPUPPCState *cenv = &cpu->env;
1097
1098         if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
1099             cenv->pending_interrupts |= 1 << irq;
1100             cpu_interrupt(cs, CPU_INTERRUPT_HARD);
1101         }
1102     }
1103 }
1104 #endif