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