281b56a479eb434aba266d2de85ec02cbb51f5ba
[qemu] / target-ppc / helper.c
1 /*
2  *  PowerPC 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 <stdarg.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <inttypes.h>
24 #include <signal.h>
25
26 #include "cpu.h"
27 #include "exec-all.h"
28 #include "helper_regs.h"
29 #include "qemu-common.h"
30 #include "kvm.h"
31
32 //#define DEBUG_MMU
33 //#define DEBUG_BATS
34 //#define DEBUG_SLB
35 //#define DEBUG_SOFTWARE_TLB
36 //#define DUMP_PAGE_TABLES
37 //#define DEBUG_EXCEPTIONS
38 //#define FLUSH_ALL_TLBS
39
40 #ifdef DEBUG_MMU
41 #  define LOG_MMU(...) qemu_log(__VA_ARGS__)
42 #  define LOG_MMU_STATE(env) log_cpu_state((env), 0)
43 #else
44 #  define LOG_MMU(...) do { } while (0)
45 #  define LOG_MMU_STATE(...) do { } while (0)
46 #endif
47
48
49 #ifdef DEBUG_SOFTWARE_TLB
50 #  define LOG_SWTLB(...) qemu_log(__VA_ARGS__)
51 #else
52 #  define LOG_SWTLB(...) do { } while (0)
53 #endif
54
55 #ifdef DEBUG_BATS
56 #  define LOG_BATS(...) qemu_log(__VA_ARGS__)
57 #else
58 #  define LOG_BATS(...) do { } while (0)
59 #endif
60
61 #ifdef DEBUG_SLB
62 #  define LOG_SLB(...) qemu_log(__VA_ARGS__)
63 #else
64 #  define LOG_SLB(...) do { } while (0)
65 #endif
66
67 #ifdef DEBUG_EXCEPTIONS
68 #  define LOG_EXCP(...) qemu_log(__VA_ARGS__)
69 #else
70 #  define LOG_EXCP(...) do { } while (0)
71 #endif
72
73
74 /*****************************************************************************/
75 /* PowerPC MMU emulation */
76
77 #if defined(CONFIG_USER_ONLY)
78 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
79                               int mmu_idx, int is_softmmu)
80 {
81     int exception, error_code;
82
83     if (rw == 2) {
84         exception = POWERPC_EXCP_ISI;
85         error_code = 0x40000000;
86     } else {
87         exception = POWERPC_EXCP_DSI;
88         error_code = 0x40000000;
89         if (rw)
90             error_code |= 0x02000000;
91         env->spr[SPR_DAR] = address;
92         env->spr[SPR_DSISR] = error_code;
93     }
94     env->exception_index = exception;
95     env->error_code = error_code;
96
97     return 1;
98 }
99
100 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
101 {
102     return addr;
103 }
104
105 #else
106 /* Common routines used by software and hardware TLBs emulation */
107 static inline int pte_is_valid(target_ulong pte0)
108 {
109     return pte0 & 0x80000000 ? 1 : 0;
110 }
111
112 static inline void pte_invalidate(target_ulong *pte0)
113 {
114     *pte0 &= ~0x80000000;
115 }
116
117 #if defined(TARGET_PPC64)
118 static inline int pte64_is_valid(target_ulong pte0)
119 {
120     return pte0 & 0x0000000000000001ULL ? 1 : 0;
121 }
122
123 static inline void pte64_invalidate(target_ulong *pte0)
124 {
125     *pte0 &= ~0x0000000000000001ULL;
126 }
127 #endif
128
129 #define PTE_PTEM_MASK 0x7FFFFFBF
130 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
131 #if defined(TARGET_PPC64)
132 #define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
133 #define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
134 #endif
135
136 static inline int pp_check(int key, int pp, int nx)
137 {
138     int access;
139
140     /* Compute access rights */
141     /* When pp is 3/7, the result is undefined. Set it to noaccess */
142     access = 0;
143     if (key == 0) {
144         switch (pp) {
145         case 0x0:
146         case 0x1:
147         case 0x2:
148             access |= PAGE_WRITE;
149             /* No break here */
150         case 0x3:
151         case 0x6:
152             access |= PAGE_READ;
153             break;
154         }
155     } else {
156         switch (pp) {
157         case 0x0:
158         case 0x6:
159             access = 0;
160             break;
161         case 0x1:
162         case 0x3:
163             access = PAGE_READ;
164             break;
165         case 0x2:
166             access = PAGE_READ | PAGE_WRITE;
167             break;
168         }
169     }
170     if (nx == 0)
171         access |= PAGE_EXEC;
172
173     return access;
174 }
175
176 static inline int check_prot(int prot, int rw, int access_type)
177 {
178     int ret;
179
180     if (access_type == ACCESS_CODE) {
181         if (prot & PAGE_EXEC)
182             ret = 0;
183         else
184             ret = -2;
185     } else if (rw) {
186         if (prot & PAGE_WRITE)
187             ret = 0;
188         else
189             ret = -2;
190     } else {
191         if (prot & PAGE_READ)
192             ret = 0;
193         else
194             ret = -2;
195     }
196
197     return ret;
198 }
199
200 static inline int _pte_check(mmu_ctx_t *ctx, int is_64b, target_ulong pte0,
201                              target_ulong pte1, int h, int rw, int type)
202 {
203     target_ulong ptem, mmask;
204     int access, ret, pteh, ptev, pp;
205
206     access = 0;
207     ret = -1;
208     /* Check validity and table match */
209 #if defined(TARGET_PPC64)
210     if (is_64b) {
211         ptev = pte64_is_valid(pte0);
212         pteh = (pte0 >> 1) & 1;
213     } else
214 #endif
215     {
216         ptev = pte_is_valid(pte0);
217         pteh = (pte0 >> 6) & 1;
218     }
219     if (ptev && h == pteh) {
220         /* Check vsid & api */
221 #if defined(TARGET_PPC64)
222         if (is_64b) {
223             ptem = pte0 & PTE64_PTEM_MASK;
224             mmask = PTE64_CHECK_MASK;
225             pp = (pte1 & 0x00000003) | ((pte1 >> 61) & 0x00000004);
226             ctx->nx  = (pte1 >> 2) & 1; /* No execute bit */
227             ctx->nx |= (pte1 >> 3) & 1; /* Guarded bit    */
228         } else
229 #endif
230         {
231             ptem = pte0 & PTE_PTEM_MASK;
232             mmask = PTE_CHECK_MASK;
233             pp = pte1 & 0x00000003;
234         }
235         if (ptem == ctx->ptem) {
236             if (ctx->raddr != (target_phys_addr_t)-1ULL) {
237                 /* all matches should have equal RPN, WIMG & PP */
238                 if ((ctx->raddr & mmask) != (pte1 & mmask)) {
239                     qemu_log("Bad RPN/WIMG/PP\n");
240                     return -3;
241                 }
242             }
243             /* Compute access rights */
244             access = pp_check(ctx->key, pp, ctx->nx);
245             /* Keep the matching PTE informations */
246             ctx->raddr = pte1;
247             ctx->prot = access;
248             ret = check_prot(ctx->prot, rw, type);
249             if (ret == 0) {
250                 /* Access granted */
251                 LOG_MMU("PTE access granted !\n");
252             } else {
253                 /* Access right violation */
254                 LOG_MMU("PTE access rejected\n");
255             }
256         }
257     }
258
259     return ret;
260 }
261
262 static inline int pte32_check(mmu_ctx_t *ctx, target_ulong pte0,
263                               target_ulong pte1, int h, int rw, int type)
264 {
265     return _pte_check(ctx, 0, pte0, pte1, h, rw, type);
266 }
267
268 #if defined(TARGET_PPC64)
269 static inline int pte64_check(mmu_ctx_t *ctx, target_ulong pte0,
270                               target_ulong pte1, int h, int rw, int type)
271 {
272     return _pte_check(ctx, 1, pte0, pte1, h, rw, type);
273 }
274 #endif
275
276 static inline int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
277                                    int ret, int rw)
278 {
279     int store = 0;
280
281     /* Update page flags */
282     if (!(*pte1p & 0x00000100)) {
283         /* Update accessed flag */
284         *pte1p |= 0x00000100;
285         store = 1;
286     }
287     if (!(*pte1p & 0x00000080)) {
288         if (rw == 1 && ret == 0) {
289             /* Update changed flag */
290             *pte1p |= 0x00000080;
291             store = 1;
292         } else {
293             /* Force page fault for first write access */
294             ctx->prot &= ~PAGE_WRITE;
295         }
296     }
297
298     return store;
299 }
300
301 /* Software driven TLB helpers */
302 static inline int ppc6xx_tlb_getnum(CPUState *env, target_ulong eaddr, int way,
303                                     int is_code)
304 {
305     int nr;
306
307     /* Select TLB num in a way from address */
308     nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1);
309     /* Select TLB way */
310     nr += env->tlb_per_way * way;
311     /* 6xx have separate TLBs for instructions and data */
312     if (is_code && env->id_tlbs == 1)
313         nr += env->nb_tlb;
314
315     return nr;
316 }
317
318 static inline void ppc6xx_tlb_invalidate_all(CPUState *env)
319 {
320     ppc6xx_tlb_t *tlb;
321     int nr, max;
322
323     //LOG_SWTLB("Invalidate all TLBs\n");
324     /* Invalidate all defined software TLB */
325     max = env->nb_tlb;
326     if (env->id_tlbs == 1)
327         max *= 2;
328     for (nr = 0; nr < max; nr++) {
329         tlb = &env->tlb[nr].tlb6;
330         pte_invalidate(&tlb->pte0);
331     }
332     tlb_flush(env, 1);
333 }
334
335 static inline void __ppc6xx_tlb_invalidate_virt(CPUState *env,
336                                                 target_ulong eaddr,
337                                                 int is_code, int match_epn)
338 {
339 #if !defined(FLUSH_ALL_TLBS)
340     ppc6xx_tlb_t *tlb;
341     int way, nr;
342
343     /* Invalidate ITLB + DTLB, all ways */
344     for (way = 0; way < env->nb_ways; way++) {
345         nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code);
346         tlb = &env->tlb[nr].tlb6;
347         if (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) {
348             LOG_SWTLB("TLB invalidate %d/%d " ADDRX "\n",
349                         nr, env->nb_tlb, eaddr);
350             pte_invalidate(&tlb->pte0);
351             tlb_flush_page(env, tlb->EPN);
352         }
353     }
354 #else
355     /* XXX: PowerPC specification say this is valid as well */
356     ppc6xx_tlb_invalidate_all(env);
357 #endif
358 }
359
360 static inline void ppc6xx_tlb_invalidate_virt(CPUState *env,
361                                               target_ulong eaddr, int is_code)
362 {
363     __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
364 }
365
366 void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
367                        target_ulong pte0, target_ulong pte1)
368 {
369     ppc6xx_tlb_t *tlb;
370     int nr;
371
372     nr = ppc6xx_tlb_getnum(env, EPN, way, is_code);
373     tlb = &env->tlb[nr].tlb6;
374     LOG_SWTLB("Set TLB %d/%d EPN " ADDRX " PTE0 " ADDRX
375                 " PTE1 " ADDRX "\n", nr, env->nb_tlb, EPN, pte0, pte1);
376     /* Invalidate any pending reference in Qemu for this virtual address */
377     __ppc6xx_tlb_invalidate_virt(env, EPN, is_code, 1);
378     tlb->pte0 = pte0;
379     tlb->pte1 = pte1;
380     tlb->EPN = EPN;
381     /* Store last way for LRU mechanism */
382     env->last_way = way;
383 }
384
385 static inline int ppc6xx_tlb_check(CPUState *env, mmu_ctx_t *ctx,
386                                    target_ulong eaddr, int rw, int access_type)
387 {
388     ppc6xx_tlb_t *tlb;
389     int nr, best, way;
390     int ret;
391
392     best = -1;
393     ret = -1; /* No TLB found */
394     for (way = 0; way < env->nb_ways; way++) {
395         nr = ppc6xx_tlb_getnum(env, eaddr, way,
396                                access_type == ACCESS_CODE ? 1 : 0);
397         tlb = &env->tlb[nr].tlb6;
398         /* This test "emulates" the PTE index match for hardware TLBs */
399         if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {
400             LOG_SWTLB("TLB %d/%d %s [" ADDRX " " ADDRX
401                         "] <> " ADDRX "\n",
402                         nr, env->nb_tlb,
403                         pte_is_valid(tlb->pte0) ? "valid" : "inval",
404                         tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);
405             continue;
406         }
407         LOG_SWTLB("TLB %d/%d %s " ADDRX " <> " ADDRX " " ADDRX
408                     " %c %c\n",
409                     nr, env->nb_tlb,
410                     pte_is_valid(tlb->pte0) ? "valid" : "inval",
411                     tlb->EPN, eaddr, tlb->pte1,
412                     rw ? 'S' : 'L', access_type == ACCESS_CODE ? 'I' : 'D');
413         switch (pte32_check(ctx, tlb->pte0, tlb->pte1, 0, rw, access_type)) {
414         case -3:
415             /* TLB inconsistency */
416             return -1;
417         case -2:
418             /* Access violation */
419             ret = -2;
420             best = nr;
421             break;
422         case -1:
423         default:
424             /* No match */
425             break;
426         case 0:
427             /* access granted */
428             /* XXX: we should go on looping to check all TLBs consistency
429              *      but we can speed-up the whole thing as the
430              *      result would be undefined if TLBs are not consistent.
431              */
432             ret = 0;
433             best = nr;
434             goto done;
435         }
436     }
437     if (best != -1) {
438     done:
439         LOG_SWTLB("found TLB at addr " PADDRX " prot=%01x ret=%d\n",
440                     ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
441         /* Update page flags */
442         pte_update_flags(ctx, &env->tlb[best].tlb6.pte1, ret, rw);
443     }
444
445     return ret;
446 }
447
448 /* Perform BAT hit & translation */
449 static inline void bat_size_prot(CPUState *env, target_ulong *blp, int *validp,
450                                  int *protp, target_ulong *BATu,
451                                  target_ulong *BATl)
452 {
453     target_ulong bl;
454     int pp, valid, prot;
455
456     bl = (*BATu & 0x00001FFC) << 15;
457     valid = 0;
458     prot = 0;
459     if (((msr_pr == 0) && (*BATu & 0x00000002)) ||
460         ((msr_pr != 0) && (*BATu & 0x00000001))) {
461         valid = 1;
462         pp = *BATl & 0x00000003;
463         if (pp != 0) {
464             prot = PAGE_READ | PAGE_EXEC;
465             if (pp == 0x2)
466                 prot |= PAGE_WRITE;
467         }
468     }
469     *blp = bl;
470     *validp = valid;
471     *protp = prot;
472 }
473
474 static inline void bat_601_size_prot(CPUState *env, target_ulong *blp,
475                                      int *validp, int *protp,
476                                      target_ulong *BATu, target_ulong *BATl)
477 {
478     target_ulong bl;
479     int key, pp, valid, prot;
480
481     bl = (*BATl & 0x0000003F) << 17;
482     LOG_BATS("b %02x ==> bl " ADDRX " msk " ADDRX "\n",
483                 (uint8_t)(*BATl & 0x0000003F), bl, ~bl);
484     prot = 0;
485     valid = (*BATl >> 6) & 1;
486     if (valid) {
487         pp = *BATu & 0x00000003;
488         if (msr_pr == 0)
489             key = (*BATu >> 3) & 1;
490         else
491             key = (*BATu >> 2) & 1;
492         prot = pp_check(key, pp, 0);
493     }
494     *blp = bl;
495     *validp = valid;
496     *protp = prot;
497 }
498
499 static inline int get_bat(CPUState *env, mmu_ctx_t *ctx, target_ulong virtual,
500                           int rw, int type)
501 {
502     target_ulong *BATlt, *BATut, *BATu, *BATl;
503     target_ulong base, BEPIl, BEPIu, bl;
504     int i, valid, prot;
505     int ret = -1;
506
507     LOG_BATS("%s: %cBAT v " ADDRX "\n", __func__,
508                 type == ACCESS_CODE ? 'I' : 'D', virtual);
509     switch (type) {
510     case ACCESS_CODE:
511         BATlt = env->IBAT[1];
512         BATut = env->IBAT[0];
513         break;
514     default:
515         BATlt = env->DBAT[1];
516         BATut = env->DBAT[0];
517         break;
518     }
519     base = virtual & 0xFFFC0000;
520     for (i = 0; i < env->nb_BATs; i++) {
521         BATu = &BATut[i];
522         BATl = &BATlt[i];
523         BEPIu = *BATu & 0xF0000000;
524         BEPIl = *BATu & 0x0FFE0000;
525         if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
526             bat_601_size_prot(env, &bl, &valid, &prot, BATu, BATl);
527         } else {
528             bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
529         }
530         LOG_BATS("%s: %cBAT%d v " ADDRX " BATu " ADDRX
531                     " BATl " ADDRX "\n", __func__,
532                     type == ACCESS_CODE ? 'I' : 'D', i, virtual, *BATu, *BATl);
533         if ((virtual & 0xF0000000) == BEPIu &&
534             ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
535             /* BAT matches */
536             if (valid != 0) {
537                 /* Get physical address */
538                 ctx->raddr = (*BATl & 0xF0000000) |
539                     ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
540                     (virtual & 0x0001F000);
541                 /* Compute access rights */
542                 ctx->prot = prot;
543                 ret = check_prot(ctx->prot, rw, type);
544                 if (ret == 0)
545                     LOG_BATS("BAT %d match: r " PADDRX " prot=%c%c\n",
546                              i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-',
547                              ctx->prot & PAGE_WRITE ? 'W' : '-');
548                 break;
549             }
550         }
551     }
552     if (ret < 0) {
553 #if defined(DEBUG_BATS)
554         if (qemu_log_enabled()) {
555             LOG_BATS("no BAT match for " ADDRX ":\n", virtual);
556             for (i = 0; i < 4; i++) {
557                 BATu = &BATut[i];
558                 BATl = &BATlt[i];
559                 BEPIu = *BATu & 0xF0000000;
560                 BEPIl = *BATu & 0x0FFE0000;
561                 bl = (*BATu & 0x00001FFC) << 15;
562                 LOG_BATS("%s: %cBAT%d v " ADDRX " BATu " ADDRX
563                          " BATl " ADDRX " \n\t" ADDRX " " ADDRX " " ADDRX "\n",
564                          __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
565                          *BATu, *BATl, BEPIu, BEPIl, bl);
566             }
567         }
568 #endif
569     }
570     /* No hit */
571     return ret;
572 }
573
574 /* PTE table lookup */
575 static inline int _find_pte(mmu_ctx_t *ctx, int is_64b, int h, int rw,
576                             int type, int target_page_bits)
577 {
578     target_ulong base, pte0, pte1;
579     int i, good = -1;
580     int ret, r;
581
582     ret = -1; /* No entry found */
583     base = ctx->pg_addr[h];
584     for (i = 0; i < 8; i++) {
585 #if defined(TARGET_PPC64)
586         if (is_64b) {
587             pte0 = ldq_phys(base + (i * 16));
588             pte1 = ldq_phys(base + (i * 16) + 8);
589
590             /* We have a TLB that saves 4K pages, so let's
591              * split a huge page to 4k chunks */
592             if (target_page_bits != TARGET_PAGE_BITS)
593                 pte1 |= (ctx->eaddr & (( 1 << target_page_bits ) - 1))
594                         & TARGET_PAGE_MASK;
595
596             r = pte64_check(ctx, pte0, pte1, h, rw, type);
597             LOG_MMU("Load pte from " ADDRX " => " ADDRX " " ADDRX
598                         " %d %d %d " ADDRX "\n",
599                         base + (i * 16), pte0, pte1,
600                         (int)(pte0 & 1), h, (int)((pte0 >> 1) & 1),
601                         ctx->ptem);
602         } else
603 #endif
604         {
605             pte0 = ldl_phys(base + (i * 8));
606             pte1 =  ldl_phys(base + (i * 8) + 4);
607             r = pte32_check(ctx, pte0, pte1, h, rw, type);
608             LOG_MMU("Load pte from " ADDRX " => " ADDRX " " ADDRX
609                         " %d %d %d " ADDRX "\n",
610                         base + (i * 8), pte0, pte1,
611                         (int)(pte0 >> 31), h, (int)((pte0 >> 6) & 1),
612                         ctx->ptem);
613         }
614         switch (r) {
615         case -3:
616             /* PTE inconsistency */
617             return -1;
618         case -2:
619             /* Access violation */
620             ret = -2;
621             good = i;
622             break;
623         case -1:
624         default:
625             /* No PTE match */
626             break;
627         case 0:
628             /* access granted */
629             /* XXX: we should go on looping to check all PTEs consistency
630              *      but if we can speed-up the whole thing as the
631              *      result would be undefined if PTEs are not consistent.
632              */
633             ret = 0;
634             good = i;
635             goto done;
636         }
637     }
638     if (good != -1) {
639     done:
640         LOG_MMU("found PTE at addr " PADDRX " prot=%01x ret=%d\n",
641                     ctx->raddr, ctx->prot, ret);
642         /* Update page flags */
643         pte1 = ctx->raddr;
644         if (pte_update_flags(ctx, &pte1, ret, rw) == 1) {
645 #if defined(TARGET_PPC64)
646             if (is_64b) {
647                 stq_phys_notdirty(base + (good * 16) + 8, pte1);
648             } else
649 #endif
650             {
651                 stl_phys_notdirty(base + (good * 8) + 4, pte1);
652             }
653         }
654     }
655
656     return ret;
657 }
658
659 static inline int find_pte32(mmu_ctx_t *ctx, int h, int rw, int type,
660                              int target_page_bits)
661 {
662     return _find_pte(ctx, 0, h, rw, type, target_page_bits);
663 }
664
665 #if defined(TARGET_PPC64)
666 static inline int find_pte64(mmu_ctx_t *ctx, int h, int rw, int type,
667                              int target_page_bits)
668 {
669     return _find_pte(ctx, 1, h, rw, type, target_page_bits);
670 }
671 #endif
672
673 static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
674                            int type, int target_page_bits)
675 {
676 #if defined(TARGET_PPC64)
677     if (env->mmu_model & POWERPC_MMU_64)
678         return find_pte64(ctx, h, rw, type, target_page_bits);
679 #endif
680
681     return find_pte32(ctx, h, rw, type, target_page_bits);
682 }
683
684 #if defined(TARGET_PPC64)
685 static ppc_slb_t *slb_get_entry(CPUPPCState *env, int nr)
686 {
687     ppc_slb_t *retval = &env->slb[nr];
688
689 #if 0 // XXX implement bridge mode?
690     if (env->spr[SPR_ASR] & 1) {
691         target_phys_addr_t sr_base;
692
693         sr_base = env->spr[SPR_ASR] & 0xfffffffffffff000;
694         sr_base += (12 * nr);
695
696         retval->tmp64 = ldq_phys(sr_base);
697         retval->tmp = ldl_phys(sr_base + 8);
698     }
699 #endif
700
701     return retval;
702 }
703
704 static void slb_set_entry(CPUPPCState *env, int nr, ppc_slb_t *slb)
705 {
706     ppc_slb_t *entry = &env->slb[nr];
707
708     if (slb == entry)
709         return;
710
711     entry->tmp64 = slb->tmp64;
712     entry->tmp = slb->tmp;
713 }
714
715 static inline int slb_is_valid(ppc_slb_t *slb)
716 {
717     return (int)(slb->tmp64 & 0x0000000008000000ULL);
718 }
719
720 static inline void slb_invalidate(ppc_slb_t *slb)
721 {
722     slb->tmp64 &= ~0x0000000008000000ULL;
723 }
724
725 static inline int slb_lookup(CPUPPCState *env, target_ulong eaddr,
726                              target_ulong *vsid, target_ulong *page_mask,
727                              int *attr, int *target_page_bits)
728 {
729     target_ulong mask;
730     int n, ret;
731
732     ret = -5;
733     LOG_SLB("%s: eaddr " ADDRX "\n", __func__, eaddr);
734     mask = 0x0000000000000000ULL; /* Avoid gcc warning */
735     for (n = 0; n < env->slb_nr; n++) {
736         ppc_slb_t *slb = slb_get_entry(env, n);
737
738         LOG_SLB("%s: seg %d %016" PRIx64 " %08"
739                     PRIx32 "\n", __func__, n, slb->tmp64, slb->tmp);
740         if (slb_is_valid(slb)) {
741             /* SLB entry is valid */
742             if (slb->tmp & 0x8) {
743                 /* 1 TB Segment */
744                 mask = 0xFFFF000000000000ULL;
745                 if (target_page_bits)
746                     *target_page_bits = 24; // XXX 16M pages?
747             } else {
748                 /* 256MB Segment */
749                 mask = 0xFFFFFFFFF0000000ULL;
750                 if (target_page_bits)
751                     *target_page_bits = TARGET_PAGE_BITS;
752             }
753             if ((eaddr & mask) == (slb->tmp64 & mask)) {
754                 /* SLB match */
755                 *vsid = ((slb->tmp64 << 24) | (slb->tmp >> 8)) & 0x0003FFFFFFFFFFFFULL;
756                 *page_mask = ~mask;
757                 *attr = slb->tmp & 0xFF;
758                 ret = n;
759                 break;
760             }
761         }
762     }
763
764     return ret;
765 }
766
767 void ppc_slb_invalidate_all (CPUPPCState *env)
768 {
769     int n, do_invalidate;
770
771     do_invalidate = 0;
772     /* XXX: Warning: slbia never invalidates the first segment */
773     for (n = 1; n < env->slb_nr; n++) {
774         ppc_slb_t *slb = slb_get_entry(env, n);
775
776         if (slb_is_valid(slb)) {
777             slb_invalidate(slb);
778             slb_set_entry(env, n, slb);
779             /* XXX: given the fact that segment size is 256 MB or 1TB,
780              *      and we still don't have a tlb_flush_mask(env, n, mask)
781              *      in Qemu, we just invalidate all TLBs
782              */
783             do_invalidate = 1;
784         }
785     }
786     if (do_invalidate)
787         tlb_flush(env, 1);
788 }
789
790 void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
791 {
792     target_ulong vsid, page_mask;
793     int attr;
794     int n;
795
796     n = slb_lookup(env, T0, &vsid, &page_mask, &attr, NULL);
797     if (n >= 0) {
798         ppc_slb_t *slb = slb_get_entry(env, n);
799
800         if (slb_is_valid(slb)) {
801             slb_invalidate(slb);
802             slb_set_entry(env, n, slb);
803             /* XXX: given the fact that segment size is 256 MB or 1TB,
804              *      and we still don't have a tlb_flush_mask(env, n, mask)
805              *      in Qemu, we just invalidate all TLBs
806              */
807             tlb_flush(env, 1);
808         }
809     }
810 }
811
812 target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr)
813 {
814     target_ulong rt;
815     ppc_slb_t *slb = slb_get_entry(env, slb_nr);
816
817     if (slb_is_valid(slb)) {
818         /* SLB entry is valid */
819         /* Copy SLB bits 62:88 to Rt 37:63 (VSID 23:49) */
820         rt = slb->tmp >> 8;             /* 65:88 => 40:63 */
821         rt |= (slb->tmp64 & 0x7) << 24; /* 62:64 => 37:39 */
822         /* Copy SLB bits 89:92 to Rt 33:36 (KsKpNL) */
823         rt |= ((slb->tmp >> 4) & 0xF) << 27;
824     } else {
825         rt = 0;
826     }
827     LOG_SLB("%s: %016" PRIx64 " %08" PRIx32 " => %d "
828                 ADDRX "\n", __func__, slb->tmp64, slb->tmp, slb_nr, rt);
829
830     return rt;
831 }
832
833 void ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs)
834 {
835     ppc_slb_t *slb;
836
837     uint64_t vsid;
838     uint64_t esid;
839     int flags, valid, slb_nr;
840
841     vsid = rs >> 12;
842     flags = ((rs >> 8) & 0xf);
843
844     esid = rb >> 28;
845     valid = (rb & (1 << 27));
846     slb_nr = rb & 0xfff;
847
848     slb = slb_get_entry(env, slb_nr);
849     slb->tmp64 = (esid << 28) | valid | (vsid >> 24);
850     slb->tmp = (vsid << 8) | (flags << 3);
851
852     LOG_SLB("%s: %d " ADDRX " - " ADDRX " => %016" PRIx64
853             " %08" PRIx32 "\n", __func__,
854             slb_nr, rb, rs, slb->tmp64, slb->tmp);
855
856     slb_set_entry(env, slb_nr, slb);
857 }
858 #endif /* defined(TARGET_PPC64) */
859
860 /* Perform segment based translation */
861 static inline target_phys_addr_t get_pgaddr(target_phys_addr_t sdr1,
862                                             int sdr_sh,
863                                             target_phys_addr_t hash,
864                                             target_phys_addr_t mask)
865 {
866     return (sdr1 & ((target_phys_addr_t)(-1ULL) << sdr_sh)) | (hash & mask);
867 }
868
869 static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
870                               target_ulong eaddr, int rw, int type)
871 {
872     target_phys_addr_t sdr, hash, mask, sdr_mask, htab_mask;
873     target_ulong sr, vsid, vsid_mask, pgidx, page_mask;
874 #if defined(TARGET_PPC64)
875     int attr;
876 #endif
877     int ds, vsid_sh, sdr_sh, pr, target_page_bits;
878     int ret, ret2;
879
880     pr = msr_pr;
881 #if defined(TARGET_PPC64)
882     if (env->mmu_model & POWERPC_MMU_64) {
883         LOG_MMU("Check SLBs\n");
884         ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr,
885                          &target_page_bits);
886         if (ret < 0)
887             return ret;
888         ctx->key = ((attr & 0x40) && (pr != 0)) ||
889             ((attr & 0x80) && (pr == 0)) ? 1 : 0;
890         ds = 0;
891         ctx->nx = attr & 0x10 ? 1 : 0;
892         ctx->eaddr = eaddr;
893         vsid_mask = 0x00003FFFFFFFFF80ULL;
894         vsid_sh = 7;
895         sdr_sh = 18;
896         sdr_mask = 0x3FF80;
897     } else
898 #endif /* defined(TARGET_PPC64) */
899     {
900         sr = env->sr[eaddr >> 28];
901         page_mask = 0x0FFFFFFF;
902         ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
903                     ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
904         ds = sr & 0x80000000 ? 1 : 0;
905         ctx->nx = sr & 0x10000000 ? 1 : 0;
906         vsid = sr & 0x00FFFFFF;
907         vsid_mask = 0x01FFFFC0;
908         vsid_sh = 6;
909         sdr_sh = 16;
910         sdr_mask = 0xFFC0;
911         target_page_bits = TARGET_PAGE_BITS;
912         LOG_MMU("Check segment v=" ADDRX " %d " ADDRX
913                     " nip=" ADDRX " lr=" ADDRX " ir=%d dr=%d pr=%d %d t=%d\n",
914                     eaddr, (int)(eaddr >> 28), sr, env->nip,
915                     env->lr, (int)msr_ir, (int)msr_dr, pr != 0 ? 1 : 0,
916                     rw, type);
917     }
918     LOG_MMU("pte segment: key=%d ds %d nx %d vsid " ADDRX "\n",
919                 ctx->key, ds, ctx->nx, vsid);
920     ret = -1;
921     if (!ds) {
922         /* Check if instruction fetch is allowed, if needed */
923         if (type != ACCESS_CODE || ctx->nx == 0) {
924             /* Page address translation */
925             /* Primary table address */
926             sdr = env->sdr1;
927             pgidx = (eaddr & page_mask) >> target_page_bits;
928 #if defined(TARGET_PPC64)
929             if (env->mmu_model & POWERPC_MMU_64) {
930                 htab_mask = 0x0FFFFFFF >> (28 - (sdr & 0x1F));
931                 /* XXX: this is false for 1 TB segments */
932                 hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
933             } else
934 #endif
935             {
936                 htab_mask = sdr & 0x000001FF;
937                 hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
938             }
939             mask = (htab_mask << sdr_sh) | sdr_mask;
940             LOG_MMU("sdr " PADDRX " sh %d hash " PADDRX
941                         " mask " PADDRX " " ADDRX "\n",
942                         sdr, sdr_sh, hash, mask, page_mask);
943             ctx->pg_addr[0] = get_pgaddr(sdr, sdr_sh, hash, mask);
944             /* Secondary table address */
945             hash = (~hash) & vsid_mask;
946             LOG_MMU("sdr " PADDRX " sh %d hash " PADDRX
947                         " mask " PADDRX "\n",
948                         sdr, sdr_sh, hash, mask);
949             ctx->pg_addr[1] = get_pgaddr(sdr, sdr_sh, hash, mask);
950 #if defined(TARGET_PPC64)
951             if (env->mmu_model & POWERPC_MMU_64) {
952                 /* Only 5 bits of the page index are used in the AVPN */
953                 if (target_page_bits > 23) {
954                     ctx->ptem = (vsid << 12) |
955                                 ((pgidx << (target_page_bits - 16)) & 0xF80);
956                 } else {
957                     ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80);
958                 }
959             } else
960 #endif
961             {
962                 ctx->ptem = (vsid << 7) | (pgidx >> 10);
963             }
964             /* Initialize real address with an invalid value */
965             ctx->raddr = (target_phys_addr_t)-1ULL;
966             if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx ||
967                          env->mmu_model == POWERPC_MMU_SOFT_74xx)) {
968                 /* Software TLB search */
969                 ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
970             } else {
971                 LOG_MMU("0 sdr1=" PADDRX " vsid=" ADDRX " "
972                             "api=" ADDRX " hash=" PADDRX
973                             " pg_addr=" PADDRX "\n",
974                             sdr, vsid, pgidx, hash, ctx->pg_addr[0]);
975                 /* Primary table lookup */
976                 ret = find_pte(env, ctx, 0, rw, type, target_page_bits);
977                 if (ret < 0) {
978                     /* Secondary table lookup */
979                     if (eaddr != 0xEFFFFFFF)
980                         LOG_MMU("1 sdr1=" PADDRX " vsid=" ADDRX " "
981                                 "api=" ADDRX " hash=" PADDRX
982                                 " pg_addr=" PADDRX "\n",
983                                 sdr, vsid, pgidx, hash, ctx->pg_addr[1]);
984                     ret2 = find_pte(env, ctx, 1, rw, type,
985                                     target_page_bits);
986                     if (ret2 != -1)
987                         ret = ret2;
988                 }
989             }
990 #if defined (DUMP_PAGE_TABLES)
991             if (qemu_log_enabled()) {
992                 target_phys_addr_t curaddr;
993                 uint32_t a0, a1, a2, a3;
994                 qemu_log("Page table: " PADDRX " len " PADDRX "\n",
995                           sdr, mask + 0x80);
996                 for (curaddr = sdr; curaddr < (sdr + mask + 0x80);
997                      curaddr += 16) {
998                     a0 = ldl_phys(curaddr);
999                     a1 = ldl_phys(curaddr + 4);
1000                     a2 = ldl_phys(curaddr + 8);
1001                     a3 = ldl_phys(curaddr + 12);
1002                     if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
1003                         qemu_log(PADDRX ": %08x %08x %08x %08x\n",
1004                                   curaddr, a0, a1, a2, a3);
1005                     }
1006                 }
1007             }
1008 #endif
1009         } else {
1010             LOG_MMU("No access allowed\n");
1011             ret = -3;
1012         }
1013     } else {
1014         LOG_MMU("direct store...\n");
1015         /* Direct-store segment : absolutely *BUGGY* for now */
1016         switch (type) {
1017         case ACCESS_INT:
1018             /* Integer load/store : only access allowed */
1019             break;
1020         case ACCESS_CODE:
1021             /* No code fetch is allowed in direct-store areas */
1022             return -4;
1023         case ACCESS_FLOAT:
1024             /* Floating point load/store */
1025             return -4;
1026         case ACCESS_RES:
1027             /* lwarx, ldarx or srwcx. */
1028             return -4;
1029         case ACCESS_CACHE:
1030             /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
1031             /* Should make the instruction do no-op.
1032              * As it already do no-op, it's quite easy :-)
1033              */
1034             ctx->raddr = eaddr;
1035             return 0;
1036         case ACCESS_EXT:
1037             /* eciwx or ecowx */
1038             return -4;
1039         default:
1040             qemu_log("ERROR: instruction should not need "
1041                         "address translation\n");
1042             return -4;
1043         }
1044         if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) {
1045             ctx->raddr = eaddr;
1046             ret = 2;
1047         } else {
1048             ret = -2;
1049         }
1050     }
1051
1052     return ret;
1053 }
1054
1055 /* Generic TLB check function for embedded PowerPC implementations */
1056 static inline int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb,
1057                                    target_phys_addr_t *raddrp,
1058                                    target_ulong address, uint32_t pid, int ext,
1059                                    int i)
1060 {
1061     target_ulong mask;
1062
1063     /* Check valid flag */
1064     if (!(tlb->prot & PAGE_VALID)) {
1065         qemu_log("%s: TLB %d not valid\n", __func__, i);
1066         return -1;
1067     }
1068     mask = ~(tlb->size - 1);
1069     LOG_SWTLB("%s: TLB %d address " ADDRX " PID %u <=> " ADDRX
1070                 " " ADDRX " %u\n",
1071                 __func__, i, address, pid, tlb->EPN, mask, (uint32_t)tlb->PID);
1072     /* Check PID */
1073     if (tlb->PID != 0 && tlb->PID != pid)
1074         return -1;
1075     /* Check effective address */
1076     if ((address & mask) != tlb->EPN)
1077         return -1;
1078     *raddrp = (tlb->RPN & mask) | (address & ~mask);
1079 #if (TARGET_PHYS_ADDR_BITS >= 36)
1080     if (ext) {
1081         /* Extend the physical address to 36 bits */
1082         *raddrp |= (target_phys_addr_t)(tlb->RPN & 0xF) << 32;
1083     }
1084 #endif
1085
1086     return 0;
1087 }
1088
1089 /* Generic TLB search function for PowerPC embedded implementations */
1090 int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid)
1091 {
1092     ppcemb_tlb_t *tlb;
1093     target_phys_addr_t raddr;
1094     int i, ret;
1095
1096     /* Default return value is no match */
1097     ret = -1;
1098     for (i = 0; i < env->nb_tlb; i++) {
1099         tlb = &env->tlb[i].tlbe;
1100         if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) {
1101             ret = i;
1102             break;
1103         }
1104     }
1105
1106     return ret;
1107 }
1108
1109 /* Helpers specific to PowerPC 40x implementations */
1110 static inline void ppc4xx_tlb_invalidate_all(CPUState *env)
1111 {
1112     ppcemb_tlb_t *tlb;
1113     int i;
1114
1115     for (i = 0; i < env->nb_tlb; i++) {
1116         tlb = &env->tlb[i].tlbe;
1117         tlb->prot &= ~PAGE_VALID;
1118     }
1119     tlb_flush(env, 1);
1120 }
1121
1122 static inline void ppc4xx_tlb_invalidate_virt(CPUState *env,
1123                                               target_ulong eaddr, uint32_t pid)
1124 {
1125 #if !defined(FLUSH_ALL_TLBS)
1126     ppcemb_tlb_t *tlb;
1127     target_phys_addr_t raddr;
1128     target_ulong page, end;
1129     int i;
1130
1131     for (i = 0; i < env->nb_tlb; i++) {
1132         tlb = &env->tlb[i].tlbe;
1133         if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {
1134             end = tlb->EPN + tlb->size;
1135             for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
1136                 tlb_flush_page(env, page);
1137             tlb->prot &= ~PAGE_VALID;
1138             break;
1139         }
1140     }
1141 #else
1142     ppc4xx_tlb_invalidate_all(env);
1143 #endif
1144 }
1145
1146 static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1147                                  target_ulong address, int rw, int access_type)
1148 {
1149     ppcemb_tlb_t *tlb;
1150     target_phys_addr_t raddr;
1151     int i, ret, zsel, zpr, pr;
1152
1153     ret = -1;
1154     raddr = (target_phys_addr_t)-1ULL;
1155     pr = msr_pr;
1156     for (i = 0; i < env->nb_tlb; i++) {
1157         tlb = &env->tlb[i].tlbe;
1158         if (ppcemb_tlb_check(env, tlb, &raddr, address,
1159                              env->spr[SPR_40x_PID], 0, i) < 0)
1160             continue;
1161         zsel = (tlb->attr >> 4) & 0xF;
1162         zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3;
1163         LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1164                     __func__, i, zsel, zpr, rw, tlb->attr);
1165         /* Check execute enable bit */
1166         switch (zpr) {
1167         case 0x2:
1168             if (pr != 0)
1169                 goto check_perms;
1170             /* No break here */
1171         case 0x3:
1172             /* All accesses granted */
1173             ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
1174             ret = 0;
1175             break;
1176         case 0x0:
1177             if (pr != 0) {
1178                 ctx->prot = 0;
1179                 ret = -2;
1180                 break;
1181             }
1182             /* No break here */
1183         case 0x1:
1184         check_perms:
1185             /* Check from TLB entry */
1186             /* XXX: there is a problem here or in the TLB fill code... */
1187             ctx->prot = tlb->prot;
1188             ctx->prot |= PAGE_EXEC;
1189             ret = check_prot(ctx->prot, rw, access_type);
1190             break;
1191         }
1192         if (ret >= 0) {
1193             ctx->raddr = raddr;
1194             LOG_SWTLB("%s: access granted " ADDRX " => " PADDRX
1195                         " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
1196                         ret);
1197             return 0;
1198         }
1199     }
1200     LOG_SWTLB("%s: access refused " ADDRX " => " PADDRX
1201                 " %d %d\n", __func__, address, raddr, ctx->prot,
1202                 ret);
1203
1204     return ret;
1205 }
1206
1207 void store_40x_sler (CPUPPCState *env, uint32_t val)
1208 {
1209     /* XXX: TO BE FIXED */
1210     if (val != 0x00000000) {
1211         cpu_abort(env, "Little-endian regions are not supported by now\n");
1212     }
1213     env->spr[SPR_405_SLER] = val;
1214 }
1215
1216 static int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1217                                           target_ulong address, int rw,
1218                                           int access_type)
1219 {
1220     ppcemb_tlb_t *tlb;
1221     target_phys_addr_t raddr;
1222     int i, prot, ret;
1223
1224     ret = -1;
1225     raddr = (target_phys_addr_t)-1ULL;
1226     for (i = 0; i < env->nb_tlb; i++) {
1227         tlb = &env->tlb[i].tlbe;
1228         if (ppcemb_tlb_check(env, tlb, &raddr, address,
1229                              env->spr[SPR_BOOKE_PID], 1, i) < 0)
1230             continue;
1231         if (msr_pr != 0)
1232             prot = tlb->prot & 0xF;
1233         else
1234             prot = (tlb->prot >> 4) & 0xF;
1235         /* Check the address space */
1236         if (access_type == ACCESS_CODE) {
1237             if (msr_ir != (tlb->attr & 1))
1238                 continue;
1239             ctx->prot = prot;
1240             if (prot & PAGE_EXEC) {
1241                 ret = 0;
1242                 break;
1243             }
1244             ret = -3;
1245         } else {
1246             if (msr_dr != (tlb->attr & 1))
1247                 continue;
1248             ctx->prot = prot;
1249             if ((!rw && prot & PAGE_READ) || (rw && (prot & PAGE_WRITE))) {
1250                 ret = 0;
1251                 break;
1252             }
1253             ret = -2;
1254         }
1255     }
1256     if (ret >= 0)
1257         ctx->raddr = raddr;
1258
1259     return ret;
1260 }
1261
1262 static inline int check_physical(CPUState *env, mmu_ctx_t *ctx,
1263                                  target_ulong eaddr, int rw)
1264 {
1265     int in_plb, ret;
1266
1267     ctx->raddr = eaddr;
1268     ctx->prot = PAGE_READ | PAGE_EXEC;
1269     ret = 0;
1270     switch (env->mmu_model) {
1271     case POWERPC_MMU_32B:
1272     case POWERPC_MMU_601:
1273     case POWERPC_MMU_SOFT_6xx:
1274     case POWERPC_MMU_SOFT_74xx:
1275     case POWERPC_MMU_SOFT_4xx:
1276     case POWERPC_MMU_REAL:
1277     case POWERPC_MMU_BOOKE:
1278         ctx->prot |= PAGE_WRITE;
1279         break;
1280 #if defined(TARGET_PPC64)
1281     case POWERPC_MMU_620:
1282     case POWERPC_MMU_64B:
1283         /* Real address are 60 bits long */
1284         ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL;
1285         ctx->prot |= PAGE_WRITE;
1286         break;
1287 #endif
1288     case POWERPC_MMU_SOFT_4xx_Z:
1289         if (unlikely(msr_pe != 0)) {
1290             /* 403 family add some particular protections,
1291              * using PBL/PBU registers for accesses with no translation.
1292              */
1293             in_plb =
1294                 /* Check PLB validity */
1295                 (env->pb[0] < env->pb[1] &&
1296                  /* and address in plb area */
1297                  eaddr >= env->pb[0] && eaddr < env->pb[1]) ||
1298                 (env->pb[2] < env->pb[3] &&
1299                  eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0;
1300             if (in_plb ^ msr_px) {
1301                 /* Access in protected area */
1302                 if (rw == 1) {
1303                     /* Access is not allowed */
1304                     ret = -2;
1305                 }
1306             } else {
1307                 /* Read-write access is allowed */
1308                 ctx->prot |= PAGE_WRITE;
1309             }
1310         }
1311         break;
1312     case POWERPC_MMU_MPC8xx:
1313         /* XXX: TODO */
1314         cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1315         break;
1316     case POWERPC_MMU_BOOKE_FSL:
1317         /* XXX: TODO */
1318         cpu_abort(env, "BookE FSL MMU model not implemented\n");
1319         break;
1320     default:
1321         cpu_abort(env, "Unknown or invalid MMU model\n");
1322         return -1;
1323     }
1324
1325     return ret;
1326 }
1327
1328 int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
1329                           int rw, int access_type)
1330 {
1331     int ret;
1332
1333 #if 0
1334     qemu_log("%s\n", __func__);
1335 #endif
1336     if ((access_type == ACCESS_CODE && msr_ir == 0) ||
1337         (access_type != ACCESS_CODE && msr_dr == 0)) {
1338         /* No address translation */
1339         ret = check_physical(env, ctx, eaddr, rw);
1340     } else {
1341         ret = -1;
1342         switch (env->mmu_model) {
1343         case POWERPC_MMU_32B:
1344         case POWERPC_MMU_601:
1345         case POWERPC_MMU_SOFT_6xx:
1346         case POWERPC_MMU_SOFT_74xx:
1347             /* Try to find a BAT */
1348             if (env->nb_BATs != 0)
1349                 ret = get_bat(env, ctx, eaddr, rw, access_type);
1350 #if defined(TARGET_PPC64)
1351         case POWERPC_MMU_620:
1352         case POWERPC_MMU_64B:
1353 #endif
1354             if (ret < 0) {
1355                 /* We didn't match any BAT entry or don't have BATs */
1356                 ret = get_segment(env, ctx, eaddr, rw, access_type);
1357             }
1358             break;
1359         case POWERPC_MMU_SOFT_4xx:
1360         case POWERPC_MMU_SOFT_4xx_Z:
1361             ret = mmu40x_get_physical_address(env, ctx, eaddr,
1362                                               rw, access_type);
1363             break;
1364         case POWERPC_MMU_BOOKE:
1365             ret = mmubooke_get_physical_address(env, ctx, eaddr,
1366                                                 rw, access_type);
1367             break;
1368         case POWERPC_MMU_MPC8xx:
1369             /* XXX: TODO */
1370             cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1371             break;
1372         case POWERPC_MMU_BOOKE_FSL:
1373             /* XXX: TODO */
1374             cpu_abort(env, "BookE FSL MMU model not implemented\n");
1375             return -1;
1376         case POWERPC_MMU_REAL:
1377             cpu_abort(env, "PowerPC in real mode do not do any translation\n");
1378             return -1;
1379         default:
1380             cpu_abort(env, "Unknown or invalid MMU model\n");
1381             return -1;
1382         }
1383     }
1384 #if 0
1385     qemu_log("%s address " ADDRX " => %d " PADDRX "\n",
1386                 __func__, eaddr, ret, ctx->raddr);
1387 #endif
1388
1389     return ret;
1390 }
1391
1392 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
1393 {
1394     mmu_ctx_t ctx;
1395
1396     if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0))
1397         return -1;
1398
1399     return ctx.raddr & TARGET_PAGE_MASK;
1400 }
1401
1402 /* Perform address translation */
1403 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1404                               int mmu_idx, int is_softmmu)
1405 {
1406     mmu_ctx_t ctx;
1407     int access_type;
1408     int ret = 0;
1409
1410     if (rw == 2) {
1411         /* code access */
1412         rw = 0;
1413         access_type = ACCESS_CODE;
1414     } else {
1415         /* data access */
1416         access_type = env->access_type;
1417     }
1418     ret = get_physical_address(env, &ctx, address, rw, access_type);
1419     if (ret == 0) {
1420         ret = tlb_set_page_exec(env, address & TARGET_PAGE_MASK,
1421                                 ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
1422                                 mmu_idx, is_softmmu);
1423     } else if (ret < 0) {
1424         LOG_MMU_STATE(env);
1425         if (access_type == ACCESS_CODE) {
1426             switch (ret) {
1427             case -1:
1428                 /* No matches in page tables or TLB */
1429                 switch (env->mmu_model) {
1430                 case POWERPC_MMU_SOFT_6xx:
1431                     env->exception_index = POWERPC_EXCP_IFTLB;
1432                     env->error_code = 1 << 18;
1433                     env->spr[SPR_IMISS] = address;
1434                     env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1435                     goto tlb_miss;
1436                 case POWERPC_MMU_SOFT_74xx:
1437                     env->exception_index = POWERPC_EXCP_IFTLB;
1438                     goto tlb_miss_74xx;
1439                 case POWERPC_MMU_SOFT_4xx:
1440                 case POWERPC_MMU_SOFT_4xx_Z:
1441                     env->exception_index = POWERPC_EXCP_ITLB;
1442                     env->error_code = 0;
1443                     env->spr[SPR_40x_DEAR] = address;
1444                     env->spr[SPR_40x_ESR] = 0x00000000;
1445                     break;
1446                 case POWERPC_MMU_32B:
1447                 case POWERPC_MMU_601:
1448 #if defined(TARGET_PPC64)
1449                 case POWERPC_MMU_620:
1450                 case POWERPC_MMU_64B:
1451 #endif
1452                     env->exception_index = POWERPC_EXCP_ISI;
1453                     env->error_code = 0x40000000;
1454                     break;
1455                 case POWERPC_MMU_BOOKE:
1456                     /* XXX: TODO */
1457                     cpu_abort(env, "BookE MMU model is not implemented\n");
1458                     return -1;
1459                 case POWERPC_MMU_BOOKE_FSL:
1460                     /* XXX: TODO */
1461                     cpu_abort(env, "BookE FSL MMU model is not implemented\n");
1462                     return -1;
1463                 case POWERPC_MMU_MPC8xx:
1464                     /* XXX: TODO */
1465                     cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1466                     break;
1467                 case POWERPC_MMU_REAL:
1468                     cpu_abort(env, "PowerPC in real mode should never raise "
1469                               "any MMU exceptions\n");
1470                     return -1;
1471                 default:
1472                     cpu_abort(env, "Unknown or invalid MMU model\n");
1473                     return -1;
1474                 }
1475                 break;
1476             case -2:
1477                 /* Access rights violation */
1478                 env->exception_index = POWERPC_EXCP_ISI;
1479                 env->error_code = 0x08000000;
1480                 break;
1481             case -3:
1482                 /* No execute protection violation */
1483                 env->exception_index = POWERPC_EXCP_ISI;
1484                 env->error_code = 0x10000000;
1485                 break;
1486             case -4:
1487                 /* Direct store exception */
1488                 /* No code fetch is allowed in direct-store areas */
1489                 env->exception_index = POWERPC_EXCP_ISI;
1490                 env->error_code = 0x10000000;
1491                 break;
1492 #if defined(TARGET_PPC64)
1493             case -5:
1494                 /* No match in segment table */
1495                 if (env->mmu_model == POWERPC_MMU_620) {
1496                     env->exception_index = POWERPC_EXCP_ISI;
1497                     /* XXX: this might be incorrect */
1498                     env->error_code = 0x40000000;
1499                 } else {
1500                     env->exception_index = POWERPC_EXCP_ISEG;
1501                     env->error_code = 0;
1502                 }
1503                 break;
1504 #endif
1505             }
1506         } else {
1507             switch (ret) {
1508             case -1:
1509                 /* No matches in page tables or TLB */
1510                 switch (env->mmu_model) {
1511                 case POWERPC_MMU_SOFT_6xx:
1512                     if (rw == 1) {
1513                         env->exception_index = POWERPC_EXCP_DSTLB;
1514                         env->error_code = 1 << 16;
1515                     } else {
1516                         env->exception_index = POWERPC_EXCP_DLTLB;
1517                         env->error_code = 0;
1518                     }
1519                     env->spr[SPR_DMISS] = address;
1520                     env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
1521                 tlb_miss:
1522                     env->error_code |= ctx.key << 19;
1523                     env->spr[SPR_HASH1] = ctx.pg_addr[0];
1524                     env->spr[SPR_HASH2] = ctx.pg_addr[1];
1525                     break;
1526                 case POWERPC_MMU_SOFT_74xx:
1527                     if (rw == 1) {
1528                         env->exception_index = POWERPC_EXCP_DSTLB;
1529                     } else {
1530                         env->exception_index = POWERPC_EXCP_DLTLB;
1531                     }
1532                 tlb_miss_74xx:
1533                     /* Implement LRU algorithm */
1534                     env->error_code = ctx.key << 19;
1535                     env->spr[SPR_TLBMISS] = (address & ~((target_ulong)0x3)) |
1536                         ((env->last_way + 1) & (env->nb_ways - 1));
1537                     env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem;
1538                     break;
1539                 case POWERPC_MMU_SOFT_4xx:
1540                 case POWERPC_MMU_SOFT_4xx_Z:
1541                     env->exception_index = POWERPC_EXCP_DTLB;
1542                     env->error_code = 0;
1543                     env->spr[SPR_40x_DEAR] = address;
1544                     if (rw)
1545                         env->spr[SPR_40x_ESR] = 0x00800000;
1546                     else
1547                         env->spr[SPR_40x_ESR] = 0x00000000;
1548                     break;
1549                 case POWERPC_MMU_32B:
1550                 case POWERPC_MMU_601:
1551 #if defined(TARGET_PPC64)
1552                 case POWERPC_MMU_620:
1553                 case POWERPC_MMU_64B:
1554 #endif
1555                     env->exception_index = POWERPC_EXCP_DSI;
1556                     env->error_code = 0;
1557                     env->spr[SPR_DAR] = address;
1558                     if (rw == 1)
1559                         env->spr[SPR_DSISR] = 0x42000000;
1560                     else
1561                         env->spr[SPR_DSISR] = 0x40000000;
1562                     break;
1563                 case POWERPC_MMU_MPC8xx:
1564                     /* XXX: TODO */
1565                     cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1566                     break;
1567                 case POWERPC_MMU_BOOKE:
1568                     /* XXX: TODO */
1569                     cpu_abort(env, "BookE MMU model is not implemented\n");
1570                     return -1;
1571                 case POWERPC_MMU_BOOKE_FSL:
1572                     /* XXX: TODO */
1573                     cpu_abort(env, "BookE FSL MMU model is not implemented\n");
1574                     return -1;
1575                 case POWERPC_MMU_REAL:
1576                     cpu_abort(env, "PowerPC in real mode should never raise "
1577                               "any MMU exceptions\n");
1578                     return -1;
1579                 default:
1580                     cpu_abort(env, "Unknown or invalid MMU model\n");
1581                     return -1;
1582                 }
1583                 break;
1584             case -2:
1585                 /* Access rights violation */
1586                 env->exception_index = POWERPC_EXCP_DSI;
1587                 env->error_code = 0;
1588                 env->spr[SPR_DAR] = address;
1589                 if (rw == 1)
1590                     env->spr[SPR_DSISR] = 0x0A000000;
1591                 else
1592                     env->spr[SPR_DSISR] = 0x08000000;
1593                 break;
1594             case -4:
1595                 /* Direct store exception */
1596                 switch (access_type) {
1597                 case ACCESS_FLOAT:
1598                     /* Floating point load/store */
1599                     env->exception_index = POWERPC_EXCP_ALIGN;
1600                     env->error_code = POWERPC_EXCP_ALIGN_FP;
1601                     env->spr[SPR_DAR] = address;
1602                     break;
1603                 case ACCESS_RES:
1604                     /* lwarx, ldarx or stwcx. */
1605                     env->exception_index = POWERPC_EXCP_DSI;
1606                     env->error_code = 0;
1607                     env->spr[SPR_DAR] = address;
1608                     if (rw == 1)
1609                         env->spr[SPR_DSISR] = 0x06000000;
1610                     else
1611                         env->spr[SPR_DSISR] = 0x04000000;
1612                     break;
1613                 case ACCESS_EXT:
1614                     /* eciwx or ecowx */
1615                     env->exception_index = POWERPC_EXCP_DSI;
1616                     env->error_code = 0;
1617                     env->spr[SPR_DAR] = address;
1618                     if (rw == 1)
1619                         env->spr[SPR_DSISR] = 0x06100000;
1620                     else
1621                         env->spr[SPR_DSISR] = 0x04100000;
1622                     break;
1623                 default:
1624                     printf("DSI: invalid exception (%d)\n", ret);
1625                     env->exception_index = POWERPC_EXCP_PROGRAM;
1626                     env->error_code =
1627                         POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
1628                     env->spr[SPR_DAR] = address;
1629                     break;
1630                 }
1631                 break;
1632 #if defined(TARGET_PPC64)
1633             case -5:
1634                 /* No match in segment table */
1635                 if (env->mmu_model == POWERPC_MMU_620) {
1636                     env->exception_index = POWERPC_EXCP_DSI;
1637                     env->error_code = 0;
1638                     env->spr[SPR_DAR] = address;
1639                     /* XXX: this might be incorrect */
1640                     if (rw == 1)
1641                         env->spr[SPR_DSISR] = 0x42000000;
1642                     else
1643                         env->spr[SPR_DSISR] = 0x40000000;
1644                 } else {
1645                     env->exception_index = POWERPC_EXCP_DSEG;
1646                     env->error_code = 0;
1647                     env->spr[SPR_DAR] = address;
1648                 }
1649                 break;
1650 #endif
1651             }
1652         }
1653 #if 0
1654         printf("%s: set exception to %d %02x\n", __func__,
1655                env->exception, env->error_code);
1656 #endif
1657         ret = 1;
1658     }
1659
1660     return ret;
1661 }
1662
1663 /*****************************************************************************/
1664 /* BATs management */
1665 #if !defined(FLUSH_ALL_TLBS)
1666 static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu,
1667                                      target_ulong mask)
1668 {
1669     target_ulong base, end, page;
1670
1671     base = BATu & ~0x0001FFFF;
1672     end = base + mask + 0x00020000;
1673     LOG_BATS("Flush BAT from " ADDRX " to " ADDRX " (" ADDRX ")\n",
1674                 base, end, mask);
1675     for (page = base; page != end; page += TARGET_PAGE_SIZE)
1676         tlb_flush_page(env, page);
1677     LOG_BATS("Flush done\n");
1678 }
1679 #endif
1680
1681 static inline void dump_store_bat(CPUPPCState *env, char ID, int ul, int nr,
1682                                   target_ulong value)
1683 {
1684     LOG_BATS("Set %cBAT%d%c to " ADDRX " (" ADDRX ")\n",
1685                 ID, nr, ul == 0 ? 'u' : 'l', value, env->nip);
1686 }
1687
1688 void ppc_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
1689 {
1690     target_ulong mask;
1691
1692     dump_store_bat(env, 'I', 0, nr, value);
1693     if (env->IBAT[0][nr] != value) {
1694         mask = (value << 15) & 0x0FFE0000UL;
1695 #if !defined(FLUSH_ALL_TLBS)
1696         do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1697 #endif
1698         /* When storing valid upper BAT, mask BEPI and BRPN
1699          * and invalidate all TLBs covered by this BAT
1700          */
1701         mask = (value << 15) & 0x0FFE0000UL;
1702         env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1703             (value & ~0x0001FFFFUL & ~mask);
1704         env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) |
1705             (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
1706 #if !defined(FLUSH_ALL_TLBS)
1707         do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1708 #else
1709         tlb_flush(env, 1);
1710 #endif
1711     }
1712 }
1713
1714 void ppc_store_ibatl (CPUPPCState *env, int nr, target_ulong value)
1715 {
1716     dump_store_bat(env, 'I', 1, nr, value);
1717     env->IBAT[1][nr] = value;
1718 }
1719
1720 void ppc_store_dbatu (CPUPPCState *env, int nr, target_ulong value)
1721 {
1722     target_ulong mask;
1723
1724     dump_store_bat(env, 'D', 0, nr, value);
1725     if (env->DBAT[0][nr] != value) {
1726         /* When storing valid upper BAT, mask BEPI and BRPN
1727          * and invalidate all TLBs covered by this BAT
1728          */
1729         mask = (value << 15) & 0x0FFE0000UL;
1730 #if !defined(FLUSH_ALL_TLBS)
1731         do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1732 #endif
1733         mask = (value << 15) & 0x0FFE0000UL;
1734         env->DBAT[0][nr] = (value & 0x00001FFFUL) |
1735             (value & ~0x0001FFFFUL & ~mask);
1736         env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) |
1737             (env->DBAT[1][nr] & ~0x0001FFFF & ~mask);
1738 #if !defined(FLUSH_ALL_TLBS)
1739         do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1740 #else
1741         tlb_flush(env, 1);
1742 #endif
1743     }
1744 }
1745
1746 void ppc_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
1747 {
1748     dump_store_bat(env, 'D', 1, nr, value);
1749     env->DBAT[1][nr] = value;
1750 }
1751
1752 void ppc_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value)
1753 {
1754     target_ulong mask;
1755     int do_inval;
1756
1757     dump_store_bat(env, 'I', 0, nr, value);
1758     if (env->IBAT[0][nr] != value) {
1759         do_inval = 0;
1760         mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
1761         if (env->IBAT[1][nr] & 0x40) {
1762             /* Invalidate BAT only if it is valid */
1763 #if !defined(FLUSH_ALL_TLBS)
1764             do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1765 #else
1766             do_inval = 1;
1767 #endif
1768         }
1769         /* When storing valid upper BAT, mask BEPI and BRPN
1770          * and invalidate all TLBs covered by this BAT
1771          */
1772         env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1773             (value & ~0x0001FFFFUL & ~mask);
1774         env->DBAT[0][nr] = env->IBAT[0][nr];
1775         if (env->IBAT[1][nr] & 0x40) {
1776 #if !defined(FLUSH_ALL_TLBS)
1777             do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1778 #else
1779             do_inval = 1;
1780 #endif
1781         }
1782 #if defined(FLUSH_ALL_TLBS)
1783         if (do_inval)
1784             tlb_flush(env, 1);
1785 #endif
1786     }
1787 }
1788
1789 void ppc_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value)
1790 {
1791     target_ulong mask;
1792     int do_inval;
1793
1794     dump_store_bat(env, 'I', 1, nr, value);
1795     if (env->IBAT[1][nr] != value) {
1796         do_inval = 0;
1797         if (env->IBAT[1][nr] & 0x40) {
1798 #if !defined(FLUSH_ALL_TLBS)
1799             mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
1800             do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1801 #else
1802             do_inval = 1;
1803 #endif
1804         }
1805         if (value & 0x40) {
1806 #if !defined(FLUSH_ALL_TLBS)
1807             mask = (value << 17) & 0x0FFE0000UL;
1808             do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1809 #else
1810             do_inval = 1;
1811 #endif
1812         }
1813         env->IBAT[1][nr] = value;
1814         env->DBAT[1][nr] = value;
1815 #if defined(FLUSH_ALL_TLBS)
1816         if (do_inval)
1817             tlb_flush(env, 1);
1818 #endif
1819     }
1820 }
1821
1822 /*****************************************************************************/
1823 /* TLB management */
1824 void ppc_tlb_invalidate_all (CPUPPCState *env)
1825 {
1826     switch (env->mmu_model) {
1827     case POWERPC_MMU_SOFT_6xx:
1828     case POWERPC_MMU_SOFT_74xx:
1829         ppc6xx_tlb_invalidate_all(env);
1830         break;
1831     case POWERPC_MMU_SOFT_4xx:
1832     case POWERPC_MMU_SOFT_4xx_Z:
1833         ppc4xx_tlb_invalidate_all(env);
1834         break;
1835     case POWERPC_MMU_REAL:
1836         cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
1837         break;
1838     case POWERPC_MMU_MPC8xx:
1839         /* XXX: TODO */
1840         cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1841         break;
1842     case POWERPC_MMU_BOOKE:
1843         /* XXX: TODO */
1844         cpu_abort(env, "BookE MMU model is not implemented\n");
1845         break;
1846     case POWERPC_MMU_BOOKE_FSL:
1847         /* XXX: TODO */
1848         if (!kvm_enabled())
1849             cpu_abort(env, "BookE MMU model is not implemented\n");
1850         break;
1851     case POWERPC_MMU_32B:
1852     case POWERPC_MMU_601:
1853 #if defined(TARGET_PPC64)
1854     case POWERPC_MMU_620:
1855     case POWERPC_MMU_64B:
1856 #endif /* defined(TARGET_PPC64) */
1857         tlb_flush(env, 1);
1858         break;
1859     default:
1860         /* XXX: TODO */
1861         cpu_abort(env, "Unknown MMU model\n");
1862         break;
1863     }
1864 }
1865
1866 void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
1867 {
1868 #if !defined(FLUSH_ALL_TLBS)
1869     addr &= TARGET_PAGE_MASK;
1870     switch (env->mmu_model) {
1871     case POWERPC_MMU_SOFT_6xx:
1872     case POWERPC_MMU_SOFT_74xx:
1873         ppc6xx_tlb_invalidate_virt(env, addr, 0);
1874         if (env->id_tlbs == 1)
1875             ppc6xx_tlb_invalidate_virt(env, addr, 1);
1876         break;
1877     case POWERPC_MMU_SOFT_4xx:
1878     case POWERPC_MMU_SOFT_4xx_Z:
1879         ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]);
1880         break;
1881     case POWERPC_MMU_REAL:
1882         cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
1883         break;
1884     case POWERPC_MMU_MPC8xx:
1885         /* XXX: TODO */
1886         cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1887         break;
1888     case POWERPC_MMU_BOOKE:
1889         /* XXX: TODO */
1890         cpu_abort(env, "BookE MMU model is not implemented\n");
1891         break;
1892     case POWERPC_MMU_BOOKE_FSL:
1893         /* XXX: TODO */
1894         cpu_abort(env, "BookE FSL MMU model is not implemented\n");
1895         break;
1896     case POWERPC_MMU_32B:
1897     case POWERPC_MMU_601:
1898         /* tlbie invalidate TLBs for all segments */
1899         addr &= ~((target_ulong)-1ULL << 28);
1900         /* XXX: this case should be optimized,
1901          * giving a mask to tlb_flush_page
1902          */
1903         tlb_flush_page(env, addr | (0x0 << 28));
1904         tlb_flush_page(env, addr | (0x1 << 28));
1905         tlb_flush_page(env, addr | (0x2 << 28));
1906         tlb_flush_page(env, addr | (0x3 << 28));
1907         tlb_flush_page(env, addr | (0x4 << 28));
1908         tlb_flush_page(env, addr | (0x5 << 28));
1909         tlb_flush_page(env, addr | (0x6 << 28));
1910         tlb_flush_page(env, addr | (0x7 << 28));
1911         tlb_flush_page(env, addr | (0x8 << 28));
1912         tlb_flush_page(env, addr | (0x9 << 28));
1913         tlb_flush_page(env, addr | (0xA << 28));
1914         tlb_flush_page(env, addr | (0xB << 28));
1915         tlb_flush_page(env, addr | (0xC << 28));
1916         tlb_flush_page(env, addr | (0xD << 28));
1917         tlb_flush_page(env, addr | (0xE << 28));
1918         tlb_flush_page(env, addr | (0xF << 28));
1919         break;
1920 #if defined(TARGET_PPC64)
1921     case POWERPC_MMU_620:
1922     case POWERPC_MMU_64B:
1923         /* tlbie invalidate TLBs for all segments */
1924         /* XXX: given the fact that there are too many segments to invalidate,
1925          *      and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
1926          *      we just invalidate all TLBs
1927          */
1928         tlb_flush(env, 1);
1929         break;
1930 #endif /* defined(TARGET_PPC64) */
1931     default:
1932         /* XXX: TODO */
1933         cpu_abort(env, "Unknown MMU model\n");
1934         break;
1935     }
1936 #else
1937     ppc_tlb_invalidate_all(env);
1938 #endif
1939 }
1940
1941 /*****************************************************************************/
1942 /* Special registers manipulation */
1943 #if defined(TARGET_PPC64)
1944 void ppc_store_asr (CPUPPCState *env, target_ulong value)
1945 {
1946     if (env->asr != value) {
1947         env->asr = value;
1948         tlb_flush(env, 1);
1949     }
1950 }
1951 #endif
1952
1953 void ppc_store_sdr1 (CPUPPCState *env, target_ulong value)
1954 {
1955     LOG_MMU("%s: " ADDRX "\n", __func__, value);
1956     if (env->sdr1 != value) {
1957         /* XXX: for PowerPC 64, should check that the HTABSIZE value
1958          *      is <= 28
1959          */
1960         env->sdr1 = value;
1961         tlb_flush(env, 1);
1962     }
1963 }
1964
1965 #if defined(TARGET_PPC64)
1966 target_ulong ppc_load_sr (CPUPPCState *env, int slb_nr)
1967 {
1968     // XXX
1969     return 0;
1970 }
1971 #endif
1972
1973 void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value)
1974 {
1975     LOG_MMU("%s: reg=%d " ADDRX " " ADDRX "\n",
1976                 __func__, srnum, value, env->sr[srnum]);
1977 #if defined(TARGET_PPC64)
1978     if (env->mmu_model & POWERPC_MMU_64) {
1979         uint64_t rb = 0, rs = 0;
1980
1981         /* ESID = srnum */
1982         rb |= ((uint32_t)srnum & 0xf) << 28;
1983         /* Set the valid bit */
1984         rb |= 1 << 27;
1985         /* Index = ESID */
1986         rb |= (uint32_t)srnum;
1987
1988         /* VSID = VSID */
1989         rs |= (value & 0xfffffff) << 12;
1990         /* flags = flags */
1991         rs |= ((value >> 27) & 0xf) << 9;
1992
1993         ppc_store_slb(env, rb, rs);
1994     } else
1995 #endif
1996     if (env->sr[srnum] != value) {
1997         env->sr[srnum] = value;
1998 /* Invalidating 256MB of virtual memory in 4kB pages is way longer than
1999    flusing the whole TLB. */
2000 #if !defined(FLUSH_ALL_TLBS) && 0
2001         {
2002             target_ulong page, end;
2003             /* Invalidate 256 MB of virtual memory */
2004             page = (16 << 20) * srnum;
2005             end = page + (16 << 20);
2006             for (; page != end; page += TARGET_PAGE_SIZE)
2007                 tlb_flush_page(env, page);
2008         }
2009 #else
2010         tlb_flush(env, 1);
2011 #endif
2012     }
2013 }
2014 #endif /* !defined (CONFIG_USER_ONLY) */
2015
2016 /* GDBstub can read and write MSR... */
2017 void ppc_store_msr (CPUPPCState *env, target_ulong value)
2018 {
2019     hreg_store_msr(env, value, 0);
2020 }
2021
2022 /*****************************************************************************/
2023 /* Exception processing */
2024 #if defined (CONFIG_USER_ONLY)
2025 void do_interrupt (CPUState *env)
2026 {
2027     env->exception_index = POWERPC_EXCP_NONE;
2028     env->error_code = 0;
2029 }
2030
2031 void ppc_hw_interrupt (CPUState *env)
2032 {
2033     env->exception_index = POWERPC_EXCP_NONE;
2034     env->error_code = 0;
2035 }
2036 #else /* defined (CONFIG_USER_ONLY) */
2037 static inline void dump_syscall(CPUState *env)
2038 {
2039     qemu_log_mask(CPU_LOG_INT, "syscall r0=" REGX " r3=" REGX " r4=" REGX
2040             " r5=" REGX " r6=" REGX " nip=" ADDRX "\n",
2041             ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4),
2042             ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6), env->nip);
2043 }
2044
2045 /* Note that this function should be greatly optimized
2046  * when called with a constant excp, from ppc_hw_interrupt
2047  */
2048 static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
2049 {
2050     target_ulong msr, new_msr, vector;
2051     int srr0, srr1, asrr0, asrr1;
2052     int lpes0, lpes1, lev;
2053
2054     if (0) {
2055         /* XXX: find a suitable condition to enable the hypervisor mode */
2056         lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;
2057         lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;
2058     } else {
2059         /* Those values ensure we won't enter the hypervisor mode */
2060         lpes0 = 0;
2061         lpes1 = 1;
2062     }
2063
2064     qemu_log_mask(CPU_LOG_INT, "Raise exception at " ADDRX " => %08x (%02x)\n",
2065                  env->nip, excp, env->error_code);
2066     msr = env->msr;
2067     new_msr = msr;
2068     srr0 = SPR_SRR0;
2069     srr1 = SPR_SRR1;
2070     asrr0 = -1;
2071     asrr1 = -1;
2072     msr &= ~((target_ulong)0x783F0000);
2073     switch (excp) {
2074     case POWERPC_EXCP_NONE:
2075         /* Should never happen */
2076         return;
2077     case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
2078         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2079         switch (excp_model) {
2080         case POWERPC_EXCP_40x:
2081             srr0 = SPR_40x_SRR2;
2082             srr1 = SPR_40x_SRR3;
2083             break;
2084         case POWERPC_EXCP_BOOKE:
2085             srr0 = SPR_BOOKE_CSRR0;
2086             srr1 = SPR_BOOKE_CSRR1;
2087             break;
2088         case POWERPC_EXCP_G2:
2089             break;
2090         default:
2091             goto excp_invalid;
2092         }
2093         goto store_next;
2094     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
2095         if (msr_me == 0) {
2096             /* Machine check exception is not enabled.
2097              * Enter checkstop state.
2098              */
2099             if (qemu_log_enabled()) {
2100                 qemu_log("Machine check while not allowed. "
2101                         "Entering checkstop state\n");
2102             } else {
2103                 fprintf(stderr, "Machine check while not allowed. "
2104                         "Entering checkstop state\n");
2105             }
2106             env->halted = 1;
2107             env->interrupt_request |= CPU_INTERRUPT_EXITTB;
2108         }
2109         new_msr &= ~((target_ulong)1 << MSR_RI);
2110         new_msr &= ~((target_ulong)1 << MSR_ME);
2111         if (0) {
2112             /* XXX: find a suitable condition to enable the hypervisor mode */
2113             new_msr |= (target_ulong)MSR_HVB;
2114         }
2115         /* XXX: should also have something loaded in DAR / DSISR */
2116         switch (excp_model) {
2117         case POWERPC_EXCP_40x:
2118             srr0 = SPR_40x_SRR2;
2119             srr1 = SPR_40x_SRR3;
2120             break;
2121         case POWERPC_EXCP_BOOKE:
2122             srr0 = SPR_BOOKE_MCSRR0;
2123             srr1 = SPR_BOOKE_MCSRR1;
2124             asrr0 = SPR_BOOKE_CSRR0;
2125             asrr1 = SPR_BOOKE_CSRR1;
2126             break;
2127         default:
2128             break;
2129         }
2130         goto store_next;
2131     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
2132         LOG_EXCP("DSI exception: DSISR=" ADDRX" DAR=" ADDRX "\n",
2133                     env->spr[SPR_DSISR], env->spr[SPR_DAR]);
2134         new_msr &= ~((target_ulong)1 << MSR_RI);
2135         if (lpes1 == 0)
2136             new_msr |= (target_ulong)MSR_HVB;
2137         goto store_next;
2138     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
2139         LOG_EXCP("ISI exception: msr=" ADDRX ", nip=" ADDRX "\n",
2140                     msr, env->nip);
2141         new_msr &= ~((target_ulong)1 << MSR_RI);
2142         if (lpes1 == 0)
2143             new_msr |= (target_ulong)MSR_HVB;
2144         msr |= env->error_code;
2145         goto store_next;
2146     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
2147         new_msr &= ~((target_ulong)1 << MSR_RI);
2148         if (lpes0 == 1)
2149             new_msr |= (target_ulong)MSR_HVB;
2150         goto store_next;
2151     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
2152         new_msr &= ~((target_ulong)1 << MSR_RI);
2153         if (lpes1 == 0)
2154             new_msr |= (target_ulong)MSR_HVB;
2155         /* XXX: this is false */
2156         /* Get rS/rD and rA from faulting opcode */
2157         env->spr[SPR_DSISR] |= (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
2158         goto store_current;
2159     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
2160         switch (env->error_code & ~0xF) {
2161         case POWERPC_EXCP_FP:
2162             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
2163                 LOG_EXCP("Ignore floating point exception\n");
2164                 env->exception_index = POWERPC_EXCP_NONE;
2165                 env->error_code = 0;
2166                 return;
2167             }
2168             new_msr &= ~((target_ulong)1 << MSR_RI);
2169             if (lpes1 == 0)
2170                 new_msr |= (target_ulong)MSR_HVB;
2171             msr |= 0x00100000;
2172             if (msr_fe0 == msr_fe1)
2173                 goto store_next;
2174             msr |= 0x00010000;
2175             break;
2176         case POWERPC_EXCP_INVAL:
2177             LOG_EXCP("Invalid instruction at " ADDRX "\n",
2178                         env->nip);
2179             new_msr &= ~((target_ulong)1 << MSR_RI);
2180             if (lpes1 == 0)
2181                 new_msr |= (target_ulong)MSR_HVB;
2182             msr |= 0x00080000;
2183             break;
2184         case POWERPC_EXCP_PRIV:
2185             new_msr &= ~((target_ulong)1 << MSR_RI);
2186             if (lpes1 == 0)
2187                 new_msr |= (target_ulong)MSR_HVB;
2188             msr |= 0x00040000;
2189             break;
2190         case POWERPC_EXCP_TRAP:
2191             new_msr &= ~((target_ulong)1 << MSR_RI);
2192             if (lpes1 == 0)
2193                 new_msr |= (target_ulong)MSR_HVB;
2194             msr |= 0x00020000;
2195             break;
2196         default:
2197             /* Should never occur */
2198             cpu_abort(env, "Invalid program exception %d. Aborting\n",
2199                       env->error_code);
2200             break;
2201         }
2202         goto store_current;
2203     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
2204         new_msr &= ~((target_ulong)1 << MSR_RI);
2205         if (lpes1 == 0)
2206             new_msr |= (target_ulong)MSR_HVB;
2207         goto store_current;
2208     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
2209         /* NOTE: this is a temporary hack to support graphics OSI
2210            calls from the MOL driver */
2211         /* XXX: To be removed */
2212         if (env->gpr[3] == 0x113724fa && env->gpr[4] == 0x77810f9b &&
2213             env->osi_call) {
2214             if (env->osi_call(env) != 0) {
2215                 env->exception_index = POWERPC_EXCP_NONE;
2216                 env->error_code = 0;
2217                 return;
2218             }
2219         }
2220         dump_syscall(env);
2221         new_msr &= ~((target_ulong)1 << MSR_RI);
2222         lev = env->error_code;
2223         if (lev == 1 || (lpes0 == 0 && lpes1 == 0))
2224             new_msr |= (target_ulong)MSR_HVB;
2225         goto store_next;
2226     case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
2227         new_msr &= ~((target_ulong)1 << MSR_RI);
2228         goto store_current;
2229     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
2230         new_msr &= ~((target_ulong)1 << MSR_RI);
2231         if (lpes1 == 0)
2232             new_msr |= (target_ulong)MSR_HVB;
2233         goto store_next;
2234     case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
2235         /* FIT on 4xx */
2236         LOG_EXCP("FIT exception\n");
2237         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2238         goto store_next;
2239     case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
2240         LOG_EXCP("WDT exception\n");
2241         switch (excp_model) {
2242         case POWERPC_EXCP_BOOKE:
2243             srr0 = SPR_BOOKE_CSRR0;
2244             srr1 = SPR_BOOKE_CSRR1;
2245             break;
2246         default:
2247             break;
2248         }
2249         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2250         goto store_next;
2251     case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
2252         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2253         goto store_next;
2254     case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
2255         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2256         goto store_next;
2257     case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
2258         switch (excp_model) {
2259         case POWERPC_EXCP_BOOKE:
2260             srr0 = SPR_BOOKE_DSRR0;
2261             srr1 = SPR_BOOKE_DSRR1;
2262             asrr0 = SPR_BOOKE_CSRR0;
2263             asrr1 = SPR_BOOKE_CSRR1;
2264             break;
2265         default:
2266             break;
2267         }
2268         /* XXX: TODO */
2269         cpu_abort(env, "Debug exception is not implemented yet !\n");
2270         goto store_next;
2271     case POWERPC_EXCP_SPEU:      /* SPE/embedded floating-point unavailable  */
2272         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2273         goto store_current;
2274     case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */
2275         /* XXX: TODO */
2276         cpu_abort(env, "Embedded floating point data exception "
2277                   "is not implemented yet !\n");
2278         goto store_next;
2279     case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */
2280         /* XXX: TODO */
2281         cpu_abort(env, "Embedded floating point round exception "
2282                   "is not implemented yet !\n");
2283         goto store_next;
2284     case POWERPC_EXCP_EPERFM:    /* Embedded performance monitor interrupt   */
2285         new_msr &= ~((target_ulong)1 << MSR_RI);
2286         /* XXX: TODO */
2287         cpu_abort(env,
2288                   "Performance counter exception is not implemented yet !\n");
2289         goto store_next;
2290     case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */
2291         /* XXX: TODO */
2292         cpu_abort(env,
2293                   "Embedded doorbell interrupt is not implemented yet !\n");
2294         goto store_next;
2295     case POWERPC_EXCP_DOORCI:    /* Embedded doorbell critical interrupt     */
2296         switch (excp_model) {
2297         case POWERPC_EXCP_BOOKE:
2298             srr0 = SPR_BOOKE_CSRR0;
2299             srr1 = SPR_BOOKE_CSRR1;
2300             break;
2301         default:
2302             break;
2303         }
2304         /* XXX: TODO */
2305         cpu_abort(env, "Embedded doorbell critical interrupt "
2306                   "is not implemented yet !\n");
2307         goto store_next;
2308     case POWERPC_EXCP_RESET:     /* System reset exception                   */
2309         new_msr &= ~((target_ulong)1 << MSR_RI);
2310         if (0) {
2311             /* XXX: find a suitable condition to enable the hypervisor mode */
2312             new_msr |= (target_ulong)MSR_HVB;
2313         }
2314         goto store_next;
2315     case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
2316         new_msr &= ~((target_ulong)1 << MSR_RI);
2317         if (lpes1 == 0)
2318             new_msr |= (target_ulong)MSR_HVB;
2319         goto store_next;
2320     case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
2321         new_msr &= ~((target_ulong)1 << MSR_RI);
2322         if (lpes1 == 0)
2323             new_msr |= (target_ulong)MSR_HVB;
2324         goto store_next;
2325     case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
2326         srr0 = SPR_HSRR0;
2327         srr1 = SPR_HSRR1;
2328         new_msr |= (target_ulong)MSR_HVB;
2329         goto store_next;
2330     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
2331         new_msr &= ~((target_ulong)1 << MSR_RI);
2332         if (lpes1 == 0)
2333             new_msr |= (target_ulong)MSR_HVB;
2334         goto store_next;
2335     case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
2336         srr0 = SPR_HSRR0;
2337         srr1 = SPR_HSRR1;
2338         new_msr |= (target_ulong)MSR_HVB;
2339         goto store_next;
2340     case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
2341         srr0 = SPR_HSRR0;
2342         srr1 = SPR_HSRR1;
2343         new_msr |= (target_ulong)MSR_HVB;
2344         goto store_next;
2345     case POWERPC_EXCP_HDSEG:     /* Hypervisor data segment exception        */
2346         srr0 = SPR_HSRR0;
2347         srr1 = SPR_HSRR1;
2348         new_msr |= (target_ulong)MSR_HVB;
2349         goto store_next;
2350     case POWERPC_EXCP_HISEG:     /* Hypervisor instruction segment exception */
2351         srr0 = SPR_HSRR0;
2352         srr1 = SPR_HSRR1;
2353         new_msr |= (target_ulong)MSR_HVB;
2354         goto store_next;
2355     case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
2356         new_msr &= ~((target_ulong)1 << MSR_RI);
2357         if (lpes1 == 0)
2358             new_msr |= (target_ulong)MSR_HVB;
2359         goto store_current;
2360     case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
2361         LOG_EXCP("PIT exception\n");
2362         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2363         goto store_next;
2364     case POWERPC_EXCP_IO:        /* IO error exception                       */
2365         /* XXX: TODO */
2366         cpu_abort(env, "601 IO error exception is not implemented yet !\n");
2367         goto store_next;
2368     case POWERPC_EXCP_RUNM:      /* Run mode exception                       */
2369         /* XXX: TODO */
2370         cpu_abort(env, "601 run mode exception is not implemented yet !\n");
2371         goto store_next;
2372     case POWERPC_EXCP_EMUL:      /* Emulation trap exception                 */
2373         /* XXX: TODO */
2374         cpu_abort(env, "602 emulation trap exception "
2375                   "is not implemented yet !\n");
2376         goto store_next;
2377     case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
2378         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2379         if (lpes1 == 0) /* XXX: check this */
2380             new_msr |= (target_ulong)MSR_HVB;
2381         switch (excp_model) {
2382         case POWERPC_EXCP_602:
2383         case POWERPC_EXCP_603:
2384         case POWERPC_EXCP_603E:
2385         case POWERPC_EXCP_G2:
2386             goto tlb_miss_tgpr;
2387         case POWERPC_EXCP_7x5:
2388             goto tlb_miss;
2389         case POWERPC_EXCP_74xx:
2390             goto tlb_miss_74xx;
2391         default:
2392             cpu_abort(env, "Invalid instruction TLB miss exception\n");
2393             break;
2394         }
2395         break;
2396     case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
2397         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2398         if (lpes1 == 0) /* XXX: check this */
2399             new_msr |= (target_ulong)MSR_HVB;
2400         switch (excp_model) {
2401         case POWERPC_EXCP_602:
2402         case POWERPC_EXCP_603:
2403         case POWERPC_EXCP_603E:
2404         case POWERPC_EXCP_G2:
2405             goto tlb_miss_tgpr;
2406         case POWERPC_EXCP_7x5:
2407             goto tlb_miss;
2408         case POWERPC_EXCP_74xx:
2409             goto tlb_miss_74xx;
2410         default:
2411             cpu_abort(env, "Invalid data load TLB miss exception\n");
2412             break;
2413         }
2414         break;
2415     case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
2416         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2417         if (lpes1 == 0) /* XXX: check this */
2418             new_msr |= (target_ulong)MSR_HVB;
2419         switch (excp_model) {
2420         case POWERPC_EXCP_602:
2421         case POWERPC_EXCP_603:
2422         case POWERPC_EXCP_603E:
2423         case POWERPC_EXCP_G2:
2424         tlb_miss_tgpr:
2425             /* Swap temporary saved registers with GPRs */
2426             if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
2427                 new_msr |= (target_ulong)1 << MSR_TGPR;
2428                 hreg_swap_gpr_tgpr(env);
2429             }
2430             goto tlb_miss;
2431         case POWERPC_EXCP_7x5:
2432         tlb_miss:
2433 #if defined (DEBUG_SOFTWARE_TLB)
2434             if (qemu_log_enabled()) {
2435                 const char *es;
2436                 target_ulong *miss, *cmp;
2437                 int en;
2438                 if (excp == POWERPC_EXCP_IFTLB) {
2439                     es = "I";
2440                     en = 'I';
2441                     miss = &env->spr[SPR_IMISS];
2442                     cmp = &env->spr[SPR_ICMP];
2443                 } else {
2444                     if (excp == POWERPC_EXCP_DLTLB)
2445                         es = "DL";
2446                     else
2447                         es = "DS";
2448                     en = 'D';
2449                     miss = &env->spr[SPR_DMISS];
2450                     cmp = &env->spr[SPR_DCMP];
2451                 }
2452                 qemu_log("6xx %sTLB miss: %cM " ADDRX " %cC " ADDRX
2453                         " H1 " ADDRX " H2 " ADDRX " %08x\n",
2454                         es, en, *miss, en, *cmp,
2455                         env->spr[SPR_HASH1], env->spr[SPR_HASH2],
2456                         env->error_code);
2457             }
2458 #endif
2459             msr |= env->crf[0] << 28;
2460             msr |= env->error_code; /* key, D/I, S/L bits */
2461             /* Set way using a LRU mechanism */
2462             msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
2463             break;
2464         case POWERPC_EXCP_74xx:
2465         tlb_miss_74xx:
2466 #if defined (DEBUG_SOFTWARE_TLB)
2467             if (qemu_log_enabled()) {
2468                 const char *es;
2469                 target_ulong *miss, *cmp;
2470                 int en;
2471                 if (excp == POWERPC_EXCP_IFTLB) {
2472                     es = "I";
2473                     en = 'I';
2474                     miss = &env->spr[SPR_TLBMISS];
2475                     cmp = &env->spr[SPR_PTEHI];
2476                 } else {
2477                     if (excp == POWERPC_EXCP_DLTLB)
2478                         es = "DL";
2479                     else
2480                         es = "DS";
2481                     en = 'D';
2482                     miss = &env->spr[SPR_TLBMISS];
2483                     cmp = &env->spr[SPR_PTEHI];
2484                 }
2485                 qemu_log("74xx %sTLB miss: %cM " ADDRX " %cC " ADDRX
2486                         " %08x\n",
2487                         es, en, *miss, en, *cmp, env->error_code);
2488             }
2489 #endif
2490             msr |= env->error_code; /* key bit */
2491             break;
2492         default:
2493             cpu_abort(env, "Invalid data store TLB miss exception\n");
2494             break;
2495         }
2496         goto store_next;
2497     case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */
2498         /* XXX: TODO */
2499         cpu_abort(env, "Floating point assist exception "
2500                   "is not implemented yet !\n");
2501         goto store_next;
2502     case POWERPC_EXCP_DABR:      /* Data address breakpoint                  */
2503         /* XXX: TODO */
2504         cpu_abort(env, "DABR exception is not implemented yet !\n");
2505         goto store_next;
2506     case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
2507         /* XXX: TODO */
2508         cpu_abort(env, "IABR exception is not implemented yet !\n");
2509         goto store_next;
2510     case POWERPC_EXCP_SMI:       /* System management interrupt              */
2511         /* XXX: TODO */
2512         cpu_abort(env, "SMI exception is not implemented yet !\n");
2513         goto store_next;
2514     case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
2515         /* XXX: TODO */
2516         cpu_abort(env, "Thermal management exception "
2517                   "is not implemented yet !\n");
2518         goto store_next;
2519     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
2520         new_msr &= ~((target_ulong)1 << MSR_RI);
2521         if (lpes1 == 0)
2522             new_msr |= (target_ulong)MSR_HVB;
2523         /* XXX: TODO */
2524         cpu_abort(env,
2525                   "Performance counter exception is not implemented yet !\n");
2526         goto store_next;
2527     case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
2528         /* XXX: TODO */
2529         cpu_abort(env, "VPU assist exception is not implemented yet !\n");
2530         goto store_next;
2531     case POWERPC_EXCP_SOFTP:     /* Soft patch exception                     */
2532         /* XXX: TODO */
2533         cpu_abort(env,
2534                   "970 soft-patch exception is not implemented yet !\n");
2535         goto store_next;
2536     case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */
2537         /* XXX: TODO */
2538         cpu_abort(env,
2539                   "970 maintenance exception is not implemented yet !\n");
2540         goto store_next;
2541     case POWERPC_EXCP_MEXTBR:    /* Maskable external breakpoint             */
2542         /* XXX: TODO */
2543         cpu_abort(env, "Maskable external exception "
2544                   "is not implemented yet !\n");
2545         goto store_next;
2546     case POWERPC_EXCP_NMEXTBR:   /* Non maskable external breakpoint         */
2547         /* XXX: TODO */
2548         cpu_abort(env, "Non maskable external exception "
2549                   "is not implemented yet !\n");
2550         goto store_next;
2551     default:
2552     excp_invalid:
2553         cpu_abort(env, "Invalid PowerPC exception %d. Aborting\n", excp);
2554         break;
2555     store_current:
2556         /* save current instruction location */
2557         env->spr[srr0] = env->nip - 4;
2558         break;
2559     store_next:
2560         /* save next instruction location */
2561         env->spr[srr0] = env->nip;
2562         break;
2563     }
2564     /* Save MSR */
2565     env->spr[srr1] = msr;
2566     /* If any alternate SRR register are defined, duplicate saved values */
2567     if (asrr0 != -1)
2568         env->spr[asrr0] = env->spr[srr0];
2569     if (asrr1 != -1)
2570         env->spr[asrr1] = env->spr[srr1];
2571     /* If we disactivated any translation, flush TLBs */
2572     if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR)))
2573         tlb_flush(env, 1);
2574     /* reload MSR with correct bits */
2575     new_msr &= ~((target_ulong)1 << MSR_EE);
2576     new_msr &= ~((target_ulong)1 << MSR_PR);
2577     new_msr &= ~((target_ulong)1 << MSR_FP);
2578     new_msr &= ~((target_ulong)1 << MSR_FE0);
2579     new_msr &= ~((target_ulong)1 << MSR_SE);
2580     new_msr &= ~((target_ulong)1 << MSR_BE);
2581     new_msr &= ~((target_ulong)1 << MSR_FE1);
2582     new_msr &= ~((target_ulong)1 << MSR_IR);
2583     new_msr &= ~((target_ulong)1 << MSR_DR);
2584 #if 0 /* Fix this: not on all targets */
2585     new_msr &= ~((target_ulong)1 << MSR_PMM);
2586 #endif
2587     new_msr &= ~((target_ulong)1 << MSR_LE);
2588     if (msr_ile)
2589         new_msr |= (target_ulong)1 << MSR_LE;
2590     else
2591         new_msr &= ~((target_ulong)1 << MSR_LE);
2592     /* Jump to handler */
2593     vector = env->excp_vectors[excp];
2594     if (vector == (target_ulong)-1ULL) {
2595         cpu_abort(env, "Raised an exception without defined vector %d\n",
2596                   excp);
2597     }
2598     vector |= env->excp_prefix;
2599 #if defined(TARGET_PPC64)
2600     if (excp_model == POWERPC_EXCP_BOOKE) {
2601         if (!msr_icm) {
2602             new_msr &= ~((target_ulong)1 << MSR_CM);
2603             vector = (uint32_t)vector;
2604         } else {
2605             new_msr |= (target_ulong)1 << MSR_CM;
2606         }
2607     } else {
2608         if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) {
2609             new_msr &= ~((target_ulong)1 << MSR_SF);
2610             vector = (uint32_t)vector;
2611         } else {
2612             new_msr |= (target_ulong)1 << MSR_SF;
2613         }
2614     }
2615 #endif
2616     /* XXX: we don't use hreg_store_msr here as already have treated
2617      *      any special case that could occur. Just store MSR and update hflags
2618      */
2619     env->msr = new_msr & env->msr_mask;
2620     hreg_compute_hflags(env);
2621     env->nip = vector;
2622     /* Reset exception state */
2623     env->exception_index = POWERPC_EXCP_NONE;
2624     env->error_code = 0;
2625 }
2626
2627 void do_interrupt (CPUState *env)
2628 {
2629     powerpc_excp(env, env->excp_model, env->exception_index);
2630 }
2631
2632 void ppc_hw_interrupt (CPUPPCState *env)
2633 {
2634     int hdice;
2635
2636 #if 0
2637     qemu_log_mask(CPU_LOG_INT, "%s: %p pending %08x req %08x me %d ee %d\n",
2638                 __func__, env, env->pending_interrupts,
2639                 env->interrupt_request, (int)msr_me, (int)msr_ee);
2640 #endif
2641     /* External reset */
2642     if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
2643         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
2644         powerpc_excp(env, env->excp_model, POWERPC_EXCP_RESET);
2645         return;
2646     }
2647     /* Machine check exception */
2648     if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
2649         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
2650         powerpc_excp(env, env->excp_model, POWERPC_EXCP_MCHECK);
2651         return;
2652     }
2653 #if 0 /* TODO */
2654     /* External debug exception */
2655     if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
2656         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
2657         powerpc_excp(env, env->excp_model, POWERPC_EXCP_DEBUG);
2658         return;
2659     }
2660 #endif
2661     if (0) {
2662         /* XXX: find a suitable condition to enable the hypervisor mode */
2663         hdice = env->spr[SPR_LPCR] & 1;
2664     } else {
2665         hdice = 0;
2666     }
2667     if ((msr_ee != 0 || msr_hv == 0 || msr_pr != 0) && hdice != 0) {
2668         /* Hypervisor decrementer exception */
2669         if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
2670             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
2671             powerpc_excp(env, env->excp_model, POWERPC_EXCP_HDECR);
2672             return;
2673         }
2674     }
2675     if (msr_ce != 0) {
2676         /* External critical interrupt */
2677         if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
2678             /* Taking a critical external interrupt does not clear the external
2679              * critical interrupt status
2680              */
2681 #if 0
2682             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CEXT);
2683 #endif
2684             powerpc_excp(env, env->excp_model, POWERPC_EXCP_CRITICAL);
2685             return;
2686         }
2687     }
2688     if (msr_ee != 0) {
2689         /* Watchdog timer on embedded PowerPC */
2690         if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
2691             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
2692             powerpc_excp(env, env->excp_model, POWERPC_EXCP_WDT);
2693             return;
2694         }
2695         if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
2696             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
2697             powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORCI);
2698             return;
2699         }
2700         /* Fixed interval timer on embedded PowerPC */
2701         if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
2702             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
2703             powerpc_excp(env, env->excp_model, POWERPC_EXCP_FIT);
2704             return;
2705         }
2706         /* Programmable interval timer on embedded PowerPC */
2707         if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
2708             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
2709             powerpc_excp(env, env->excp_model, POWERPC_EXCP_PIT);
2710             return;
2711         }
2712         /* Decrementer exception */
2713         if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
2714             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
2715             powerpc_excp(env, env->excp_model, POWERPC_EXCP_DECR);
2716             return;
2717         }
2718         /* External interrupt */
2719         if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
2720             /* Taking an external interrupt does not clear the external
2721              * interrupt status
2722              */
2723 #if 0
2724             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
2725 #endif
2726             powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL);
2727             return;
2728         }
2729         if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
2730             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
2731             powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORI);
2732             return;
2733         }
2734         if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
2735             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
2736             powerpc_excp(env, env->excp_model, POWERPC_EXCP_PERFM);
2737             return;
2738         }
2739         /* Thermal interrupt */
2740         if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
2741             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
2742             powerpc_excp(env, env->excp_model, POWERPC_EXCP_THERM);
2743             return;
2744         }
2745     }
2746 }
2747 #endif /* !CONFIG_USER_ONLY */
2748
2749 void cpu_dump_rfi (target_ulong RA, target_ulong msr)
2750 {
2751     qemu_log("Return from exception at " ADDRX " with flags " ADDRX "\n",
2752              RA, msr);
2753 }
2754
2755 void cpu_ppc_reset (void *opaque)
2756 {
2757     CPUPPCState *env = opaque;
2758     target_ulong msr;
2759
2760     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
2761         qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
2762         log_cpu_state(env, 0);
2763     }
2764
2765     msr = (target_ulong)0;
2766     if (0) {
2767         /* XXX: find a suitable condition to enable the hypervisor mode */
2768         msr |= (target_ulong)MSR_HVB;
2769     }
2770     msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
2771     msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
2772     msr |= (target_ulong)1 << MSR_EP;
2773 #if defined (DO_SINGLE_STEP) && 0
2774     /* Single step trace mode */
2775     msr |= (target_ulong)1 << MSR_SE;
2776     msr |= (target_ulong)1 << MSR_BE;
2777 #endif
2778 #if defined(CONFIG_USER_ONLY)
2779     msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
2780     msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
2781     msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
2782     msr |= (target_ulong)1 << MSR_PR;
2783 #else
2784     env->excp_prefix = env->hreset_excp_prefix;
2785     env->nip = env->hreset_vector | env->excp_prefix;
2786     if (env->mmu_model != POWERPC_MMU_REAL)
2787         ppc_tlb_invalidate_all(env);
2788 #endif
2789     env->msr = msr & env->msr_mask;
2790 #if defined(TARGET_PPC64)
2791     if (env->mmu_model & POWERPC_MMU_64)
2792         env->msr |= (1ULL << MSR_SF);
2793 #endif
2794     hreg_compute_hflags(env);
2795     env->reserve_addr = (target_ulong)-1ULL;
2796     /* Be sure no exception or interrupt is pending */
2797     env->pending_interrupts = 0;
2798     env->exception_index = POWERPC_EXCP_NONE;
2799     env->error_code = 0;
2800     /* Flush all TLBs */
2801     tlb_flush(env, 1);
2802 }
2803
2804 CPUPPCState *cpu_ppc_init (const char *cpu_model)
2805 {
2806     CPUPPCState *env;
2807     const ppc_def_t *def;
2808
2809     def = cpu_ppc_find_by_name(cpu_model);
2810     if (!def)
2811         return NULL;
2812
2813     env = qemu_mallocz(sizeof(CPUPPCState));
2814     cpu_exec_init(env);
2815     ppc_translate_init();
2816     env->cpu_model_str = cpu_model;
2817     cpu_ppc_register_internal(env, def);
2818     cpu_ppc_reset(env);
2819
2820     qemu_init_vcpu(env);
2821
2822     return env;
2823 }
2824
2825 void cpu_ppc_close (CPUPPCState *env)
2826 {
2827     /* Should also remove all opcode tables... */
2828     qemu_free(env);
2829 }