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