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