Coding style fixes in PowerPC related code (no functional change):
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #include <stdarg.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <inttypes.h>
25 #include <signal.h>
26 #include <assert.h>
27
28 #include "cpu.h"
29 #include "exec-all.h"
30
31 //#define DEBUG_MMU
32 //#define DEBUG_BATS
33 //#define DEBUG_SOFTWARE_TLB
34 //#define DEBUG_EXCEPTIONS
35 //#define FLUSH_ALL_TLBS
36
37 /*****************************************************************************/
38 /* PowerPC MMU emulation */
39
40 #if defined(CONFIG_USER_ONLY)
41 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
42                               int is_user, int is_softmmu)
43 {
44     int exception, error_code;
45
46     if (rw == 2) {
47         exception = EXCP_ISI;
48         error_code = 0;
49     } else {
50         exception = EXCP_DSI;
51         error_code = 0;
52         if (rw)
53             error_code |= 0x02000000;
54         env->spr[SPR_DAR] = address;
55         env->spr[SPR_DSISR] = error_code;
56     }
57     env->exception_index = exception;
58     env->error_code = error_code;
59
60     return 1;
61 }
62
63 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
64 {
65     return addr;
66 }
67
68 #else
69 /* Common routines used by software and hardware TLBs emulation */
70 static inline int pte_is_valid (target_ulong pte0)
71 {
72     return pte0 & 0x80000000 ? 1 : 0;
73 }
74
75 static inline void pte_invalidate (target_ulong *pte0)
76 {
77     *pte0 &= ~0x80000000;
78 }
79
80 #define PTE_PTEM_MASK 0x7FFFFFBF
81 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
82
83 static int pte_check (mmu_ctx_t *ctx,
84                       target_ulong pte0, target_ulong pte1, int h, int rw)
85 {
86     int access, ret;
87
88     access = 0;
89     ret = -1;
90     /* Check validity and table match */
91     if (pte_is_valid(pte0) && (h == ((pte0 >> 6) & 1))) {
92         /* Check vsid & api */
93         if ((pte0 & PTE_PTEM_MASK) == ctx->ptem) {
94             if (ctx->raddr != (target_ulong)-1) {
95                 /* all matches should have equal RPN, WIMG & PP */
96                 if ((ctx->raddr & PTE_CHECK_MASK) != (pte1 & PTE_CHECK_MASK)) {
97                     if (loglevel > 0)
98                         fprintf(logfile, "Bad RPN/WIMG/PP\n");
99                     return -3;
100                 }
101             }
102             /* Compute access rights */
103             if (ctx->key == 0) {
104                 access = PAGE_READ;
105                 if ((pte1 & 0x00000003) != 0x3)
106                     access |= PAGE_WRITE;
107             } else {
108                 switch (pte1 & 0x00000003) {
109                 case 0x0:
110                     access = 0;
111                     break;
112                 case 0x1:
113                 case 0x3:
114                     access = PAGE_READ;
115                     break;
116                 case 0x2:
117                     access = PAGE_READ | PAGE_WRITE;
118                     break;
119                 }
120             }
121             /* Keep the matching PTE informations */
122             ctx->raddr = pte1;
123             ctx->prot = access;
124             if ((rw == 0 && (access & PAGE_READ)) ||
125                 (rw == 1 && (access & PAGE_WRITE))) {
126                 /* Access granted */
127 #if defined (DEBUG_MMU)
128                 if (loglevel != 0)
129                     fprintf(logfile, "PTE access granted !\n");
130 #endif
131                 ret = 0;
132             } else {
133                 /* Access right violation */
134 #if defined (DEBUG_MMU)
135                 if (loglevel != 0)
136                     fprintf(logfile, "PTE access rejected\n");
137 #endif
138                 ret = -2;
139             }
140         }
141     }
142
143     return ret;
144 }
145
146 static int pte_update_flags (mmu_ctx_t *ctx, target_ulong *pte1p,
147                              int ret, int rw)
148 {
149     int store = 0;
150
151     /* Update page flags */
152     if (!(*pte1p & 0x00000100)) {
153         /* Update accessed flag */
154         *pte1p |= 0x00000100;
155         store = 1;
156     }
157     if (!(*pte1p & 0x00000080)) {
158         if (rw == 1 && ret == 0) {
159             /* Update changed flag */
160             *pte1p |= 0x00000080;
161             store = 1;
162         } else {
163             /* Force page fault for first write access */
164             ctx->prot &= ~PAGE_WRITE;
165         }
166     }
167
168     return store;
169 }
170
171 /* Software driven TLB helpers */
172 static int ppc6xx_tlb_getnum (CPUState *env, target_ulong eaddr,
173                               int way, int is_code)
174 {
175     int nr;
176
177     /* Select TLB num in a way from address */
178     nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1);
179     /* Select TLB way */
180     nr += env->tlb_per_way * way;
181     /* 6xx have separate TLBs for instructions and data */
182     if (is_code && env->id_tlbs == 1)
183         nr += env->nb_tlb;
184
185     return nr;
186 }
187
188 void ppc6xx_tlb_invalidate_all (CPUState *env)
189 {
190     ppc6xx_tlb_t *tlb;
191     int nr, max;
192
193 #if defined (DEBUG_SOFTWARE_TLB) && 0
194     if (loglevel != 0) {
195         fprintf(logfile, "Invalidate all TLBs\n");
196     }
197 #endif
198     /* Invalidate all defined software TLB */
199     max = env->nb_tlb;
200     if (env->id_tlbs == 1)
201         max *= 2;
202     for (nr = 0; nr < max; nr++) {
203         tlb = &env->tlb[nr].tlb6;
204 #if !defined(FLUSH_ALL_TLBS)
205         tlb_flush_page(env, tlb->EPN);
206 #endif
207         pte_invalidate(&tlb->pte0);
208     }
209 #if defined(FLUSH_ALL_TLBS)
210     tlb_flush(env, 1);
211 #endif
212 }
213
214 static inline void __ppc6xx_tlb_invalidate_virt (CPUState *env,
215                                                  target_ulong eaddr,
216                                                  int is_code, int match_epn)
217 {
218 #if !defined(FLUSH_ALL_TLBS)
219     ppc6xx_tlb_t *tlb;
220     int way, nr;
221
222     /* Invalidate ITLB + DTLB, all ways */
223     for (way = 0; way < env->nb_ways; way++) {
224         nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code);
225         tlb = &env->tlb[nr].tlb6;
226         if (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) {
227 #if defined (DEBUG_SOFTWARE_TLB)
228             if (loglevel != 0) {
229                 fprintf(logfile, "TLB invalidate %d/%d " ADDRX "\n",
230                         nr, env->nb_tlb, eaddr);
231             }
232 #endif
233             pte_invalidate(&tlb->pte0);
234             tlb_flush_page(env, tlb->EPN);
235         }
236     }
237 #else
238     /* XXX: PowerPC specification say this is valid as well */
239     ppc6xx_tlb_invalidate_all(env);
240 #endif
241 }
242
243 void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
244                                  int is_code)
245 {
246     __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
247 }
248
249 void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
250                        target_ulong pte0, target_ulong pte1)
251 {
252     ppc6xx_tlb_t *tlb;
253     int nr;
254
255     nr = ppc6xx_tlb_getnum(env, EPN, way, is_code);
256     tlb = &env->tlb[nr].tlb6;
257 #if defined (DEBUG_SOFTWARE_TLB)
258     if (loglevel != 0) {
259         fprintf(logfile, "Set TLB %d/%d EPN " ADDRX " PTE0 " ADDRX
260                 " PTE1 " ADDRX "\n", nr, env->nb_tlb, EPN, pte0, pte1);
261     }
262 #endif
263     /* Invalidate any pending reference in Qemu for this virtual address */
264     __ppc6xx_tlb_invalidate_virt(env, EPN, is_code, 1);
265     tlb->pte0 = pte0;
266     tlb->pte1 = pte1;
267     tlb->EPN = EPN;
268     /* Store last way for LRU mechanism */
269     env->last_way = way;
270 }
271
272 static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx,
273                              target_ulong eaddr, int rw, int access_type)
274 {
275     ppc6xx_tlb_t *tlb;
276     int nr, best, way;
277     int ret;
278
279     best = -1;
280     ret = -1; /* No TLB found */
281     for (way = 0; way < env->nb_ways; way++) {
282         nr = ppc6xx_tlb_getnum(env, eaddr, way,
283                                access_type == ACCESS_CODE ? 1 : 0);
284         tlb = &env->tlb[nr].tlb6;
285         /* This test "emulates" the PTE index match for hardware TLBs */
286         if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {
287 #if defined (DEBUG_SOFTWARE_TLB)
288             if (loglevel != 0) {
289                 fprintf(logfile, "TLB %d/%d %s [" ADDRX " " ADDRX
290                         "] <> " ADDRX "\n",
291                         nr, env->nb_tlb,
292                         pte_is_valid(tlb->pte0) ? "valid" : "inval",
293                         tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);
294             }
295 #endif
296             continue;
297         }
298 #if defined (DEBUG_SOFTWARE_TLB)
299         if (loglevel != 0) {
300             fprintf(logfile, "TLB %d/%d %s " ADDRX " <> " ADDRX " " ADDRX
301                     " %c %c\n",
302                     nr, env->nb_tlb,
303                     pte_is_valid(tlb->pte0) ? "valid" : "inval",
304                     tlb->EPN, eaddr, tlb->pte1,
305                     rw ? 'S' : 'L', access_type == ACCESS_CODE ? 'I' : 'D');
306         }
307 #endif
308         switch (pte_check(ctx, tlb->pte0, tlb->pte1, 0, rw)) {
309         case -3:
310             /* TLB inconsistency */
311             return -1;
312         case -2:
313             /* Access violation */
314             ret = -2;
315             best = nr;
316             break;
317         case -1:
318         default:
319             /* No match */
320             break;
321         case 0:
322             /* access granted */
323             /* XXX: we should go on looping to check all TLBs consistency
324              *      but we can speed-up the whole thing as the
325              *      result would be undefined if TLBs are not consistent.
326              */
327             ret = 0;
328             best = nr;
329             goto done;
330         }
331     }
332     if (best != -1) {
333     done:
334 #if defined (DEBUG_SOFTWARE_TLB)
335         if (loglevel != 0) {
336             fprintf(logfile, "found TLB at addr 0x%08lx prot=0x%01x ret=%d\n",
337                     ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
338         }
339 #endif
340         /* Update page flags */
341         pte_update_flags(ctx, &env->tlb[best].tlb6.pte1, ret, rw);
342     }
343
344     return ret;
345 }
346
347 /* Perform BAT hit & translation */
348 static int get_bat (CPUState *env, mmu_ctx_t *ctx,
349                     target_ulong virtual, int rw, int type)
350 {
351     target_ulong *BATlt, *BATut, *BATu, *BATl;
352     target_ulong base, BEPIl, BEPIu, bl;
353     int i;
354     int ret = -1;
355
356 #if defined (DEBUG_BATS)
357     if (loglevel != 0) {
358         fprintf(logfile, "%s: %cBAT v 0x" ADDRX "\n", __func__,
359                 type == ACCESS_CODE ? 'I' : 'D', virtual);
360     }
361 #endif
362     switch (type) {
363     case ACCESS_CODE:
364         BATlt = env->IBAT[1];
365         BATut = env->IBAT[0];
366         break;
367     default:
368         BATlt = env->DBAT[1];
369         BATut = env->DBAT[0];
370         break;
371     }
372 #if defined (DEBUG_BATS)
373     if (loglevel != 0) {
374         fprintf(logfile, "%s...: %cBAT v 0x" ADDRX "\n", __func__,
375                 type == ACCESS_CODE ? 'I' : 'D', virtual);
376     }
377 #endif
378     base = virtual & 0xFFFC0000;
379     for (i = 0; i < 4; i++) {
380         BATu = &BATut[i];
381         BATl = &BATlt[i];
382         BEPIu = *BATu & 0xF0000000;
383         BEPIl = *BATu & 0x0FFE0000;
384         bl = (*BATu & 0x00001FFC) << 15;
385 #if defined (DEBUG_BATS)
386         if (loglevel != 0) {
387             fprintf(logfile, "%s: %cBAT%d v 0x" ADDRX " BATu 0x" ADDRX
388                     " BATl 0x" ADDRX "\n",
389                     __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
390                     *BATu, *BATl);
391         }
392 #endif
393         if ((virtual & 0xF0000000) == BEPIu &&
394             ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
395             /* BAT matches */
396             if ((msr_pr == 0 && (*BATu & 0x00000002)) ||
397                 (msr_pr == 1 && (*BATu & 0x00000001))) {
398                 /* Get physical address */
399                 ctx->raddr = (*BATl & 0xF0000000) |
400                     ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
401                     (virtual & 0x0001F000);
402                 if (*BATl & 0x00000001)
403                     ctx->prot = PAGE_READ;
404                 if (*BATl & 0x00000002)
405                     ctx->prot = PAGE_WRITE | PAGE_READ;
406 #if defined (DEBUG_BATS)
407                 if (loglevel != 0) {
408                     fprintf(logfile, "BAT %d match: r 0x" PADDRX
409                             " prot=%c%c\n",
410                             i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-',
411                             ctx->prot & PAGE_WRITE ? 'W' : '-');
412                 }
413 #endif
414                 ret = 0;
415                 break;
416             }
417         }
418     }
419     if (ret < 0) {
420 #if defined (DEBUG_BATS)
421         if (loglevel != 0) {
422             fprintf(logfile, "no BAT match for 0x" ADDRX ":\n", virtual);
423             for (i = 0; i < 4; i++) {
424                 BATu = &BATut[i];
425                 BATl = &BATlt[i];
426                 BEPIu = *BATu & 0xF0000000;
427                 BEPIl = *BATu & 0x0FFE0000;
428                 bl = (*BATu & 0x00001FFC) << 15;
429                 fprintf(logfile, "%s: %cBAT%d v 0x" ADDRX " BATu 0x" ADDRX
430                         " BATl 0x" ADDRX " \n\t"
431                         "0x" ADDRX " 0x" ADDRX " 0x" ADDRX "\n",
432                         __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
433                         *BATu, *BATl, BEPIu, BEPIl, bl);
434             }
435         }
436 #endif
437     }
438     /* No hit */
439     return ret;
440 }
441
442 /* PTE table lookup */
443 static int find_pte (mmu_ctx_t *ctx, int h, int rw)
444 {
445     target_ulong base, pte0, pte1;
446     int i, good = -1;
447     int ret;
448
449     ret = -1; /* No entry found */
450     base = ctx->pg_addr[h];
451     for (i = 0; i < 8; i++) {
452         pte0 = ldl_phys(base + (i * 8));
453         pte1 =  ldl_phys(base + (i * 8) + 4);
454 #if defined (DEBUG_MMU)
455         if (loglevel > 0) {
456             fprintf(logfile, "Load pte from 0x" ADDRX " => 0x" ADDRX
457                     " 0x" ADDRX " %d %d %d 0x" ADDRX "\n",
458                     base + (i * 8), pte0, pte1,
459                     pte0 >> 31, h, (pte0 >> 6) & 1, ctx->ptem);
460         }
461 #endif
462         switch (pte_check(ctx, pte0, pte1, h, rw)) {
463         case -3:
464             /* PTE inconsistency */
465             return -1;
466         case -2:
467             /* Access violation */
468             ret = -2;
469             good = i;
470             break;
471         case -1:
472         default:
473             /* No PTE match */
474             break;
475         case 0:
476             /* access granted */
477             /* XXX: we should go on looping to check all PTEs consistency
478              *      but if we can speed-up the whole thing as the
479              *      result would be undefined if PTEs are not consistent.
480              */
481             ret = 0;
482             good = i;
483             goto done;
484         }
485     }
486     if (good != -1) {
487     done:
488 #if defined (DEBUG_MMU)
489         if (loglevel != 0) {
490             fprintf(logfile, "found PTE at addr 0x" PADDRX " prot=0x%01x "
491                     "ret=%d\n",
492                     ctx->raddr, ctx->prot, ret);
493         }
494 #endif
495         /* Update page flags */
496         pte1 = ctx->raddr;
497         if (pte_update_flags(ctx, &pte1, ret, rw) == 1)
498             stl_phys_notdirty(base + (good * 8) + 4, pte1);
499     }
500
501     return ret;
502 }
503
504 static inline target_phys_addr_t get_pgaddr (target_phys_addr_t sdr1,
505                                              target_phys_addr_t hash,
506                                              target_phys_addr_t mask)
507 {
508     return (sdr1 & 0xFFFF0000) | (hash & mask);
509 }
510
511 /* Perform segment based translation */
512 static int get_segment (CPUState *env, mmu_ctx_t *ctx,
513                         target_ulong eaddr, int rw, int type)
514 {
515     target_phys_addr_t sdr, hash, mask;
516     target_ulong sr, vsid, pgidx;
517     int ret = -1, ret2;
518
519     sr = env->sr[eaddr >> 28];
520 #if defined (DEBUG_MMU)
521     if (loglevel > 0) {
522         fprintf(logfile, "Check segment v=0x" ADDRX " %d 0x" ADDRX " nip=0x"
523                 ADDRX " lr=0x" ADDRX " ir=%d dr=%d pr=%d %d t=%d\n",
524                 eaddr, eaddr >> 28, sr, env->nip,
525                 env->lr, msr_ir, msr_dr, msr_pr, rw, type);
526     }
527 #endif
528     ctx->key = (((sr & 0x20000000) && msr_pr == 1) ||
529                 ((sr & 0x40000000) && msr_pr == 0)) ? 1 : 0;
530     if ((sr & 0x80000000) == 0) {
531 #if defined (DEBUG_MMU)
532         if (loglevel > 0)
533             fprintf(logfile, "pte segment: key=%d n=0x" ADDRX "\n",
534                     ctx->key, sr & 0x10000000);
535 #endif
536         /* Check if instruction fetch is allowed, if needed */
537         if (type != ACCESS_CODE || (sr & 0x10000000) == 0) {
538             /* Page address translation */
539             pgidx = (eaddr >> TARGET_PAGE_BITS) & 0xFFFF;
540             vsid = sr & 0x00FFFFFF;
541             hash = ((vsid ^ pgidx) & 0x0007FFFF) << 6;
542             /* Primary table address */
543             sdr = env->sdr1;
544             mask = ((sdr & 0x000001FF) << 16) | 0xFFC0;
545             ctx->pg_addr[0] = get_pgaddr(sdr, hash, mask);
546             /* Secondary table address */
547             hash = (~hash) & 0x01FFFFC0;
548             ctx->pg_addr[1] = get_pgaddr(sdr, hash, mask);
549             ctx->ptem = (vsid << 7) | (pgidx >> 10);
550             /* Initialize real address with an invalid value */
551             ctx->raddr = (target_ulong)-1;
552             if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
553                 /* Software TLB search */
554                 ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
555             } else {
556 #if defined (DEBUG_MMU)
557                 if (loglevel != 0) {
558                     fprintf(logfile, "0 sdr1=0x" PADDRX " vsid=0x%06x "
559                             "api=0x%04x hash=0x%07x pg_addr=0x" PADDRX "\n",
560                             sdr, (uint32_t)vsid, (uint32_t)pgidx,
561                             (uint32_t)hash, ctx->pg_addr[0]);
562                 }
563 #endif
564                 /* Primary table lookup */
565                 ret = find_pte(ctx, 0, rw);
566                 if (ret < 0) {
567                     /* Secondary table lookup */
568 #if defined (DEBUG_MMU)
569                     if (eaddr != 0xEFFFFFFF && loglevel != 0) {
570                         fprintf(logfile,
571                                 "1 sdr1=0x" PADDRX " vsid=0x%06x api=0x%04x "
572                                 "hash=0x%05x pg_addr=0x" PADDRX "\n",
573                                 sdr, (uint32_t)vsid, (uint32_t)pgidx,
574                                 (uint32_t)hash, ctx->pg_addr[1]);
575                     }
576 #endif
577                     ret2 = find_pte(ctx, 1, rw);
578                     if (ret2 != -1)
579                         ret = ret2;
580                 }
581             }
582         } else {
583 #if defined (DEBUG_MMU)
584             if (loglevel != 0)
585                 fprintf(logfile, "No access allowed\n");
586 #endif
587             ret = -3;
588         }
589     } else {
590 #if defined (DEBUG_MMU)
591         if (loglevel != 0)
592             fprintf(logfile, "direct store...\n");
593 #endif
594         /* Direct-store segment : absolutely *BUGGY* for now */
595         switch (type) {
596         case ACCESS_INT:
597             /* Integer load/store : only access allowed */
598             break;
599         case ACCESS_CODE:
600             /* No code fetch is allowed in direct-store areas */
601             return -4;
602         case ACCESS_FLOAT:
603             /* Floating point load/store */
604             return -4;
605         case ACCESS_RES:
606             /* lwarx, ldarx or srwcx. */
607             return -4;
608         case ACCESS_CACHE:
609             /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
610             /* Should make the instruction do no-op.
611              * As it already do no-op, it's quite easy :-)
612              */
613             ctx->raddr = eaddr;
614             return 0;
615         case ACCESS_EXT:
616             /* eciwx or ecowx */
617             return -4;
618         default:
619             if (logfile) {
620                 fprintf(logfile, "ERROR: instruction should not need "
621                         "address translation\n");
622             }
623             return -4;
624         }
625         if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) {
626             ctx->raddr = eaddr;
627             ret = 2;
628         } else {
629             ret = -2;
630         }
631     }
632
633     return ret;
634 }
635
636 /* Generic TLB check function for embedded PowerPC implementations */
637 static int ppcemb_tlb_check (CPUState *env, ppcemb_tlb_t *tlb,
638                              target_phys_addr_t *raddrp,
639                              target_ulong address,
640                              uint32_t pid, int ext, int i)
641 {
642     target_ulong mask;
643
644     /* Check valid flag */
645     if (!(tlb->prot & PAGE_VALID)) {
646         if (loglevel != 0)
647             fprintf(logfile, "%s: TLB %d not valid\n", __func__, i);
648         return -1;
649     }
650     mask = ~(tlb->size - 1);
651     if (loglevel != 0) {
652         fprintf(logfile, "%s: TLB %d address " ADDRX " PID %d <=> "
653                 ADDRX " " ADDRX " %d\n",
654                 __func__, i, address, pid, tlb->EPN, mask, (int)tlb->PID);
655     }
656     /* Check PID */
657     if (tlb->PID != 0 && tlb->PID != pid)
658         return -1;
659     /* Check effective address */
660     if ((address & mask) != tlb->EPN)
661         return -1;
662     *raddrp = (tlb->RPN & mask) | (address & ~mask);
663     if (ext) {
664         /* Extend the physical address to 36 bits */
665         *raddrp |= (target_phys_addr_t)(tlb->RPN & 0xF) << 32;
666     }
667
668     return 0;
669 }
670
671 /* Generic TLB search function for PowerPC embedded implementations */
672 int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid)
673 {
674     ppcemb_tlb_t *tlb;
675     target_phys_addr_t raddr;
676     int i, ret;
677
678     /* Default return value is no match */
679     ret = -1;
680     for (i = 0; i < 64; i++) {
681         tlb = &env->tlb[i].tlbe;
682         if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) {
683             ret = i;
684             break;
685         }
686     }
687
688     return ret;
689 }
690
691 /* Helpers specific to PowerPC 40x implementations */
692 void ppc4xx_tlb_invalidate_all (CPUState *env)
693 {
694     ppcemb_tlb_t *tlb;
695     int i;
696
697     for (i = 0; i < env->nb_tlb; i++) {
698         tlb = &env->tlb[i].tlbe;
699         if (tlb->prot & PAGE_VALID) {
700 #if 0 // XXX: TLB have variable sizes then we flush all Qemu TLB.
701             end = tlb->EPN + tlb->size;
702             for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
703                 tlb_flush_page(env, page);
704 #endif
705             tlb->prot &= ~PAGE_VALID;
706         }
707     }
708     tlb_flush(env, 1);
709 }
710
711 int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
712                                  target_ulong address, int rw, int access_type)
713 {
714     ppcemb_tlb_t *tlb;
715     target_phys_addr_t raddr;
716     int i, ret, zsel, zpr;
717
718     ret = -1;
719     raddr = -1;
720     for (i = 0; i < env->nb_tlb; i++) {
721         tlb = &env->tlb[i].tlbe;
722         if (ppcemb_tlb_check(env, tlb, &raddr, address,
723                              env->spr[SPR_40x_PID], 0, i) < 0)
724             continue;
725         zsel = (tlb->attr >> 4) & 0xF;
726         zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3;
727         if (loglevel != 0) {
728             fprintf(logfile, "%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
729                     __func__, i, zsel, zpr, rw, tlb->attr);
730         }
731         if (access_type == ACCESS_CODE) {
732             /* Check execute enable bit */
733             switch (zpr) {
734             case 0x2:
735                 if (msr_pr)
736                     goto check_exec_perm;
737                 goto exec_granted;
738             case 0x0:
739                 if (msr_pr) {
740                     ctx->prot = 0;
741                     ret = -3;
742                     break;
743                 }
744                 /* No break here */
745             case 0x1:
746             check_exec_perm:
747                 /* Check from TLB entry */
748                 if (!(tlb->prot & PAGE_EXEC)) {
749                     ret = -3;
750                 } else {
751                     if (tlb->prot & PAGE_WRITE) {
752                         ctx->prot = PAGE_READ | PAGE_WRITE;
753                     } else {
754                         ctx->prot = PAGE_READ;
755                     }
756                     ret = 0;
757                 }
758                 break;
759             case 0x3:
760             exec_granted:
761                 /* All accesses granted */
762                 ctx->prot = PAGE_READ | PAGE_WRITE;
763                 ret = 0;
764                 break;
765             }
766         } else {
767             switch (zpr) {
768             case 0x2:
769                 if (msr_pr)
770                     goto check_rw_perm;
771                 goto rw_granted;
772             case 0x0:
773                 if (msr_pr) {
774                     ctx->prot = 0;
775                     ret = -2;
776                     break;
777                 }
778                 /* No break here */
779             case 0x1:
780             check_rw_perm:
781                 /* Check from TLB entry */
782                 /* Check write protection bit */
783                 if (tlb->prot & PAGE_WRITE) {
784                     ctx->prot = PAGE_READ | PAGE_WRITE;
785                     ret = 0;
786                 } else {
787                     ctx->prot = PAGE_READ;
788                     if (rw)
789                         ret = -2;
790                     else
791                         ret = 0;
792                 }
793                 break;
794             case 0x3:
795             rw_granted:
796                 /* All accesses granted */
797                 ctx->prot = PAGE_READ | PAGE_WRITE;
798                 ret = 0;
799                 break;
800             }
801         }
802         if (ret >= 0) {
803             ctx->raddr = raddr;
804             if (loglevel != 0) {
805                 fprintf(logfile, "%s: access granted " ADDRX " => " REGX
806                         " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
807                         ret);
808             }
809             return 0;
810         }
811     }
812     if (loglevel != 0) {
813         fprintf(logfile, "%s: access refused " ADDRX " => " REGX
814                 " %d %d\n", __func__, address, raddr, ctx->prot,
815                 ret);
816     }
817
818     return ret;
819 }
820
821 void store_40x_sler (CPUPPCState *env, uint32_t val)
822 {
823     /* XXX: TO BE FIXED */
824     if (val != 0x00000000) {
825         cpu_abort(env, "Little-endian regions are not supported by now\n");
826     }
827     env->spr[SPR_405_SLER] = val;
828 }
829
830 static int check_physical (CPUState *env, mmu_ctx_t *ctx,
831                            target_ulong eaddr, int rw)
832 {
833     int in_plb, ret;
834
835     ctx->raddr = eaddr;
836     ctx->prot = PAGE_READ;
837     ret = 0;
838     if (unlikely(msr_pe != 0 && PPC_MMU(env) == PPC_FLAGS_MMU_403)) {
839         /* 403 family add some particular protections,
840          * using PBL/PBU registers for accesses with no translation.
841          */
842         in_plb =
843             /* Check PLB validity */
844             (env->pb[0] < env->pb[1] &&
845              /* and address in plb area */
846              eaddr >= env->pb[0] && eaddr < env->pb[1]) ||
847             (env->pb[2] < env->pb[3] &&
848              eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0;
849         if (in_plb ^ msr_px) {
850             /* Access in protected area */
851             if (rw == 1) {
852                 /* Access is not allowed */
853                 ret = -2;
854             }
855         } else {
856             /* Read-write access is allowed */
857             ctx->prot |= PAGE_WRITE;
858         }
859     } else {
860         ctx->prot |= PAGE_WRITE;
861     }
862
863     return ret;
864 }
865
866 int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
867                           int rw, int access_type, int check_BATs)
868 {
869     int ret;
870 #if 0
871     if (loglevel != 0) {
872         fprintf(logfile, "%s\n", __func__);
873     }
874 #endif
875     if ((access_type == ACCESS_CODE && msr_ir == 0) ||
876         (access_type != ACCESS_CODE && msr_dr == 0)) {
877         /* No address translation */
878         ret = check_physical(env, ctx, eaddr, rw);
879     } else {
880         ret = -1;
881         switch (PPC_MMU(env)) {
882         case PPC_FLAGS_MMU_32B:
883         case PPC_FLAGS_MMU_SOFT_6xx:
884             /* Try to find a BAT */
885             if (check_BATs)
886                 ret = get_bat(env, ctx, eaddr, rw, access_type);
887             /* No break here */
888 #if defined(TARGET_PPC64)
889         case PPC_FLAGS_MMU_64B:
890         case PPC_FLAGS_MMU_64BRIDGE:
891 #endif
892             if (ret < 0) {
893                 /* We didn't match any BAT entry or don't have BATs */
894                 ret = get_segment(env, ctx, eaddr, rw, access_type);
895             }
896             break;
897         case PPC_FLAGS_MMU_SOFT_4xx:
898         case PPC_FLAGS_MMU_403:
899             ret = mmu40x_get_physical_address(env, ctx, eaddr,
900                                               rw, access_type);
901             break;
902         case PPC_FLAGS_MMU_601:
903             /* XXX: TODO */
904             cpu_abort(env, "601 MMU model not implemented\n");
905             return -1;
906         case PPC_FLAGS_MMU_BOOKE:
907             /* XXX: TODO */
908             cpu_abort(env, "BookeE MMU model not implemented\n");
909             return -1;
910         case PPC_FLAGS_MMU_BOOKE_FSL:
911             /* XXX: TODO */
912             cpu_abort(env, "BookE FSL MMU model not implemented\n");
913             return -1;
914         default:
915             cpu_abort(env, "Unknown or invalid MMU model\n");
916             return -1;
917         }
918     }
919 #if 0
920     if (loglevel != 0) {
921         fprintf(logfile, "%s address " ADDRX " => %d " PADDRX "\n",
922                 __func__, eaddr, ret, ctx->raddr);
923     }
924 #endif
925
926     return ret;
927 }
928
929 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
930 {
931     mmu_ctx_t ctx;
932
933     if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT, 1) != 0))
934         return -1;
935
936     return ctx.raddr & TARGET_PAGE_MASK;
937 }
938
939 /* Perform address translation */
940 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
941                               int is_user, int is_softmmu)
942 {
943     mmu_ctx_t ctx;
944     int exception = 0, error_code = 0;
945     int access_type;
946     int ret = 0;
947
948     if (rw == 2) {
949         /* code access */
950         rw = 0;
951         access_type = ACCESS_CODE;
952     } else {
953         /* data access */
954         /* XXX: put correct access by using cpu_restore_state()
955            correctly */
956         access_type = ACCESS_INT;
957         //        access_type = env->access_type;
958     }
959     ret = get_physical_address(env, &ctx, address, rw, access_type, 1);
960     if (ret == 0) {
961         ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
962                            ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
963                            is_user, is_softmmu);
964     } else if (ret < 0) {
965 #if defined (DEBUG_MMU)
966         if (loglevel != 0)
967             cpu_dump_state(env, logfile, fprintf, 0);
968 #endif
969         if (access_type == ACCESS_CODE) {
970             exception = EXCP_ISI;
971             switch (ret) {
972             case -1:
973                 /* No matches in page tables or TLB */
974                 switch (PPC_MMU(env)) {
975                 case PPC_FLAGS_MMU_SOFT_6xx:
976                     exception = EXCP_I_TLBMISS;
977                     env->spr[SPR_IMISS] = address;
978                     env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
979                     error_code = 1 << 18;
980                     goto tlb_miss;
981                 case PPC_FLAGS_MMU_SOFT_4xx:
982                 case PPC_FLAGS_MMU_403:
983                     exception = EXCP_40x_ITLBMISS;
984                     error_code = 0;
985                     env->spr[SPR_40x_DEAR] = address;
986                     env->spr[SPR_40x_ESR] = 0x00000000;
987                     break;
988                 case PPC_FLAGS_MMU_32B:
989                     error_code = 0x40000000;
990                     break;
991 #if defined(TARGET_PPC64)
992                 case PPC_FLAGS_MMU_64B:
993                     /* XXX: TODO */
994                     cpu_abort(env, "MMU model not implemented\n");
995                     return -1;
996                 case PPC_FLAGS_MMU_64BRIDGE:
997                     /* XXX: TODO */
998                     cpu_abort(env, "MMU model not implemented\n");
999                     return -1;
1000 #endif
1001                 case PPC_FLAGS_MMU_601:
1002                     /* XXX: TODO */
1003                     cpu_abort(env, "MMU model not implemented\n");
1004                     return -1;
1005                 case PPC_FLAGS_MMU_BOOKE:
1006                     /* XXX: TODO */
1007                     cpu_abort(env, "MMU model not implemented\n");
1008                     return -1;
1009                 case PPC_FLAGS_MMU_BOOKE_FSL:
1010                     /* XXX: TODO */
1011                     cpu_abort(env, "MMU model not implemented\n");
1012                     return -1;
1013                 default:
1014                     cpu_abort(env, "Unknown or invalid MMU model\n");
1015                     return -1;
1016                 }
1017                 break;
1018             case -2:
1019                 /* Access rights violation */
1020                 error_code = 0x08000000;
1021                 break;
1022             case -3:
1023                 /* No execute protection violation */
1024                 error_code = 0x10000000;
1025                 break;
1026             case -4:
1027                 /* Direct store exception */
1028                 /* No code fetch is allowed in direct-store areas */
1029                 error_code = 0x10000000;
1030                 break;
1031             case -5:
1032                 /* No match in segment table */
1033                 exception = EXCP_ISEG;
1034                 error_code = 0;
1035                 break;
1036             }
1037         } else {
1038             exception = EXCP_DSI;
1039             switch (ret) {
1040             case -1:
1041                 /* No matches in page tables or TLB */
1042                 switch (PPC_MMU(env)) {
1043                 case PPC_FLAGS_MMU_SOFT_6xx:
1044                     if (rw == 1) {
1045                         exception = EXCP_DS_TLBMISS;
1046                         error_code = 1 << 16;
1047                     } else {
1048                         exception = EXCP_DL_TLBMISS;
1049                         error_code = 0;
1050                     }
1051                     env->spr[SPR_DMISS] = address;
1052                     env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
1053                 tlb_miss:
1054                     error_code |= ctx.key << 19;
1055                     env->spr[SPR_HASH1] = ctx.pg_addr[0];
1056                     env->spr[SPR_HASH2] = ctx.pg_addr[1];
1057                     /* Do not alter DAR nor DSISR */
1058                     goto out;
1059                 case PPC_FLAGS_MMU_SOFT_4xx:
1060                 case PPC_FLAGS_MMU_403:
1061                     exception = EXCP_40x_DTLBMISS;
1062                     error_code = 0;
1063                     env->spr[SPR_40x_DEAR] = address;
1064                     if (rw)
1065                         env->spr[SPR_40x_ESR] = 0x00800000;
1066                     else
1067                         env->spr[SPR_40x_ESR] = 0x00000000;
1068                     break;
1069                 case PPC_FLAGS_MMU_32B:
1070                     error_code = 0x40000000;
1071                     break;
1072 #if defined(TARGET_PPC64)
1073                 case PPC_FLAGS_MMU_64B:
1074                     /* XXX: TODO */
1075                     cpu_abort(env, "MMU model not implemented\n");
1076                     return -1;
1077                 case PPC_FLAGS_MMU_64BRIDGE:
1078                     /* XXX: TODO */
1079                     cpu_abort(env, "MMU model not implemented\n");
1080                     return -1;
1081 #endif
1082                 case PPC_FLAGS_MMU_601:
1083                     /* XXX: TODO */
1084                     cpu_abort(env, "MMU model not implemented\n");
1085                     return -1;
1086                 case PPC_FLAGS_MMU_BOOKE:
1087                     /* XXX: TODO */
1088                     cpu_abort(env, "MMU model not implemented\n");
1089                     return -1;
1090                 case PPC_FLAGS_MMU_BOOKE_FSL:
1091                     /* XXX: TODO */
1092                     cpu_abort(env, "MMU model not implemented\n");
1093                     return -1;
1094                 default:
1095                     cpu_abort(env, "Unknown or invalid MMU model\n");
1096                     return -1;
1097                 }
1098                 break;
1099             case -2:
1100                 /* Access rights violation */
1101                 error_code = 0x08000000;
1102                 break;
1103             case -4:
1104                 /* Direct store exception */
1105                 switch (access_type) {
1106                 case ACCESS_FLOAT:
1107                     /* Floating point load/store */
1108                     exception = EXCP_ALIGN;
1109                     error_code = EXCP_ALIGN_FP;
1110                     break;
1111                 case ACCESS_RES:
1112                     /* lwarx, ldarx or srwcx. */
1113                     error_code = 0x04000000;
1114                     break;
1115                 case ACCESS_EXT:
1116                     /* eciwx or ecowx */
1117                     error_code = 0x04100000;
1118                     break;
1119                 default:
1120                     printf("DSI: invalid exception (%d)\n", ret);
1121                     exception = EXCP_PROGRAM;
1122                     error_code = EXCP_INVAL | EXCP_INVAL_INVAL;
1123                     break;
1124                 }
1125                 break;
1126             case -5:
1127                 /* No match in segment table */
1128                 exception = EXCP_DSEG;
1129                 error_code = 0;
1130                 break;
1131             }
1132             if (exception == EXCP_DSI && rw == 1)
1133                 error_code |= 0x02000000;
1134             /* Store fault address */
1135             env->spr[SPR_DAR] = address;
1136             env->spr[SPR_DSISR] = error_code;
1137         }
1138     out:
1139 #if 0
1140         printf("%s: set exception to %d %02x\n",
1141                __func__, exception, error_code);
1142 #endif
1143         env->exception_index = exception;
1144         env->error_code = error_code;
1145         ret = 1;
1146     }
1147
1148     return ret;
1149 }
1150
1151 /*****************************************************************************/
1152 /* BATs management */
1153 #if !defined(FLUSH_ALL_TLBS)
1154 static inline void do_invalidate_BAT (CPUPPCState *env,
1155                                       target_ulong BATu, target_ulong mask)
1156 {
1157     target_ulong base, end, page;
1158
1159     base = BATu & ~0x0001FFFF;
1160     end = base + mask + 0x00020000;
1161 #if defined (DEBUG_BATS)
1162     if (loglevel != 0) {
1163         fprintf(logfile, "Flush BAT from " ADDRX " to " ADDRX " (" ADDRX ")\n",
1164                 base, end, mask);
1165     }
1166 #endif
1167     for (page = base; page != end; page += TARGET_PAGE_SIZE)
1168         tlb_flush_page(env, page);
1169 #if defined (DEBUG_BATS)
1170     if (loglevel != 0)
1171         fprintf(logfile, "Flush done\n");
1172 #endif
1173 }
1174 #endif
1175
1176 static inline void dump_store_bat (CPUPPCState *env, char ID, int ul, int nr,
1177                                    target_ulong value)
1178 {
1179 #if defined (DEBUG_BATS)
1180     if (loglevel != 0) {
1181         fprintf(logfile, "Set %cBAT%d%c to 0x" ADDRX " (0x" ADDRX ")\n",
1182                 ID, nr, ul == 0 ? 'u' : 'l', value, env->nip);
1183     }
1184 #endif
1185 }
1186
1187 target_ulong do_load_ibatu (CPUPPCState *env, int nr)
1188 {
1189     return env->IBAT[0][nr];
1190 }
1191
1192 target_ulong do_load_ibatl (CPUPPCState *env, int nr)
1193 {
1194     return env->IBAT[1][nr];
1195 }
1196
1197 void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
1198 {
1199     target_ulong mask;
1200
1201     dump_store_bat(env, 'I', 0, nr, value);
1202     if (env->IBAT[0][nr] != value) {
1203         mask = (value << 15) & 0x0FFE0000UL;
1204 #if !defined(FLUSH_ALL_TLBS)
1205         do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1206 #endif
1207         /* When storing valid upper BAT, mask BEPI and BRPN
1208          * and invalidate all TLBs covered by this BAT
1209          */
1210         mask = (value << 15) & 0x0FFE0000UL;
1211         env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1212             (value & ~0x0001FFFFUL & ~mask);
1213         env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) |
1214             (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
1215 #if !defined(FLUSH_ALL_TLBS)
1216         do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1217 #else
1218         tlb_flush(env, 1);
1219 #endif
1220     }
1221 }
1222
1223 void do_store_ibatl (CPUPPCState *env, int nr, target_ulong value)
1224 {
1225     dump_store_bat(env, 'I', 1, nr, value);
1226     env->IBAT[1][nr] = value;
1227 }
1228
1229 target_ulong do_load_dbatu (CPUPPCState *env, int nr)
1230 {
1231     return env->DBAT[0][nr];
1232 }
1233
1234 target_ulong do_load_dbatl (CPUPPCState *env, int nr)
1235 {
1236     return env->DBAT[1][nr];
1237 }
1238
1239 void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value)
1240 {
1241     target_ulong mask;
1242
1243     dump_store_bat(env, 'D', 0, nr, value);
1244     if (env->DBAT[0][nr] != value) {
1245         /* When storing valid upper BAT, mask BEPI and BRPN
1246          * and invalidate all TLBs covered by this BAT
1247          */
1248         mask = (value << 15) & 0x0FFE0000UL;
1249 #if !defined(FLUSH_ALL_TLBS)
1250         do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1251 #endif
1252         mask = (value << 15) & 0x0FFE0000UL;
1253         env->DBAT[0][nr] = (value & 0x00001FFFUL) |
1254             (value & ~0x0001FFFFUL & ~mask);
1255         env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) |
1256             (env->DBAT[1][nr] & ~0x0001FFFF & ~mask);
1257 #if !defined(FLUSH_ALL_TLBS)
1258         do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1259 #else
1260         tlb_flush(env, 1);
1261 #endif
1262     }
1263 }
1264
1265 void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
1266 {
1267     dump_store_bat(env, 'D', 1, nr, value);
1268     env->DBAT[1][nr] = value;
1269 }
1270
1271
1272 /*****************************************************************************/
1273 /* TLB management */
1274 void ppc_tlb_invalidate_all (CPUPPCState *env)
1275 {
1276     if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
1277         ppc6xx_tlb_invalidate_all(env);
1278     } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
1279         ppc4xx_tlb_invalidate_all(env);
1280     } else {
1281         tlb_flush(env, 1);
1282     }
1283 }
1284
1285 /*****************************************************************************/
1286 /* Special registers manipulation */
1287 #if defined(TARGET_PPC64)
1288 target_ulong ppc_load_asr (CPUPPCState *env)
1289 {
1290     return env->asr;
1291 }
1292
1293 void ppc_store_asr (CPUPPCState *env, target_ulong value)
1294 {
1295     if (env->asr != value) {
1296         env->asr = value;
1297         tlb_flush(env, 1);
1298     }
1299 }
1300 #endif
1301
1302 target_ulong do_load_sdr1 (CPUPPCState *env)
1303 {
1304     return env->sdr1;
1305 }
1306
1307 void do_store_sdr1 (CPUPPCState *env, target_ulong value)
1308 {
1309 #if defined (DEBUG_MMU)
1310     if (loglevel != 0) {
1311         fprintf(logfile, "%s: 0x" ADDRX "\n", __func__, value);
1312     }
1313 #endif
1314     if (env->sdr1 != value) {
1315         env->sdr1 = value;
1316         tlb_flush(env, 1);
1317     }
1318 }
1319
1320 target_ulong do_load_sr (CPUPPCState *env, int srnum)
1321 {
1322     return env->sr[srnum];
1323 }
1324
1325 void do_store_sr (CPUPPCState *env, int srnum, target_ulong value)
1326 {
1327 #if defined (DEBUG_MMU)
1328     if (loglevel != 0) {
1329         fprintf(logfile, "%s: reg=%d 0x" ADDRX " " ADDRX "\n",
1330                 __func__, srnum, value, env->sr[srnum]);
1331     }
1332 #endif
1333     if (env->sr[srnum] != value) {
1334         env->sr[srnum] = value;
1335 #if !defined(FLUSH_ALL_TLBS) && 0
1336         {
1337             target_ulong page, end;
1338             /* Invalidate 256 MB of virtual memory */
1339             page = (16 << 20) * srnum;
1340             end = page + (16 << 20);
1341             for (; page != end; page += TARGET_PAGE_SIZE)
1342                 tlb_flush_page(env, page);
1343         }
1344 #else
1345         tlb_flush(env, 1);
1346 #endif
1347     }
1348 }
1349 #endif /* !defined (CONFIG_USER_ONLY) */
1350
1351 uint32_t ppc_load_xer (CPUPPCState *env)
1352 {
1353     return (xer_so << XER_SO) |
1354         (xer_ov << XER_OV) |
1355         (xer_ca << XER_CA) |
1356         (xer_bc << XER_BC) |
1357         (xer_cmp << XER_CMP);
1358 }
1359
1360 void ppc_store_xer (CPUPPCState *env, uint32_t value)
1361 {
1362     xer_so = (value >> XER_SO) & 0x01;
1363     xer_ov = (value >> XER_OV) & 0x01;
1364     xer_ca = (value >> XER_CA) & 0x01;
1365     xer_cmp = (value >> XER_CMP) & 0xFF;
1366     xer_bc = (value >> XER_BC) & 0x7F;
1367 }
1368
1369 /* Swap temporary saved registers with GPRs */
1370 static inline void swap_gpr_tgpr (CPUPPCState *env)
1371 {
1372     ppc_gpr_t tmp;
1373
1374     tmp = env->gpr[0];
1375     env->gpr[0] = env->tgpr[0];
1376     env->tgpr[0] = tmp;
1377     tmp = env->gpr[1];
1378     env->gpr[1] = env->tgpr[1];
1379     env->tgpr[1] = tmp;
1380     tmp = env->gpr[2];
1381     env->gpr[2] = env->tgpr[2];
1382     env->tgpr[2] = tmp;
1383     tmp = env->gpr[3];
1384     env->gpr[3] = env->tgpr[3];
1385     env->tgpr[3] = tmp;
1386 }
1387
1388 /* GDBstub can read and write MSR... */
1389 target_ulong do_load_msr (CPUPPCState *env)
1390 {
1391     return
1392 #if defined (TARGET_PPC64)
1393         ((target_ulong)msr_sf   << MSR_SF)   |
1394         ((target_ulong)msr_isf  << MSR_ISF)  |
1395         ((target_ulong)msr_hv   << MSR_HV)   |
1396 #endif
1397         ((target_ulong)msr_ucle << MSR_UCLE) |
1398         ((target_ulong)msr_vr   << MSR_VR)   | /* VR / SPE */
1399         ((target_ulong)msr_ap   << MSR_AP)   |
1400         ((target_ulong)msr_sa   << MSR_SA)   |
1401         ((target_ulong)msr_key  << MSR_KEY)  |
1402         ((target_ulong)msr_pow  << MSR_POW)  | /* POW / WE */
1403         ((target_ulong)msr_tlb  << MSR_TLB)  | /* TLB / TGPE / CE */
1404         ((target_ulong)msr_ile  << MSR_ILE)  |
1405         ((target_ulong)msr_ee   << MSR_EE)   |
1406         ((target_ulong)msr_pr   << MSR_PR)   |
1407         ((target_ulong)msr_fp   << MSR_FP)   |
1408         ((target_ulong)msr_me   << MSR_ME)   |
1409         ((target_ulong)msr_fe0  << MSR_FE0)  |
1410         ((target_ulong)msr_se   << MSR_SE)   | /* SE / DWE / UBLE */
1411         ((target_ulong)msr_be   << MSR_BE)   | /* BE / DE */
1412         ((target_ulong)msr_fe1  << MSR_FE1)  |
1413         ((target_ulong)msr_al   << MSR_AL)   |
1414         ((target_ulong)msr_ip   << MSR_IP)   |
1415         ((target_ulong)msr_ir   << MSR_IR)   | /* IR / IS */
1416         ((target_ulong)msr_dr   << MSR_DR)   | /* DR / DS */
1417         ((target_ulong)msr_pe   << MSR_PE)   | /* PE / EP */
1418         ((target_ulong)msr_px   << MSR_PX)   | /* PX / PMM */
1419         ((target_ulong)msr_ri   << MSR_RI)   |
1420         ((target_ulong)msr_le   << MSR_LE);
1421 }
1422
1423 void do_store_msr (CPUPPCState *env, target_ulong value)
1424 {
1425     int enter_pm;
1426
1427     value &= env->msr_mask;
1428     if (((value >> MSR_IR) & 1) != msr_ir ||
1429         ((value >> MSR_DR) & 1) != msr_dr) {
1430         /* Flush all tlb when changing translation mode */
1431         tlb_flush(env, 1);
1432         env->interrupt_request |= CPU_INTERRUPT_EXITTB;
1433     }
1434 #if 0
1435     if (loglevel != 0) {
1436         fprintf(logfile, "%s: T0 %08lx\n", __func__, value);
1437     }
1438 #endif
1439     switch (PPC_EXCP(env)) {
1440     case PPC_FLAGS_EXCP_602:
1441     case PPC_FLAGS_EXCP_603:
1442         if (((value >> MSR_TGPR) & 1) != msr_tgpr) {
1443             /* Swap temporary saved registers with GPRs */
1444             swap_gpr_tgpr(env);
1445         }
1446         break;
1447     default:
1448         break;
1449     }
1450 #if defined (TARGET_PPC64)
1451     msr_sf   = (value >> MSR_SF)   & 1;
1452     msr_isf  = (value >> MSR_ISF)  & 1;
1453     msr_hv   = (value >> MSR_HV)   & 1;
1454 #endif
1455     msr_ucle = (value >> MSR_UCLE) & 1;
1456     msr_vr   = (value >> MSR_VR)   & 1; /* VR / SPE */
1457     msr_ap   = (value >> MSR_AP)   & 1;
1458     msr_sa   = (value >> MSR_SA)   & 1;
1459     msr_key  = (value >> MSR_KEY)  & 1;
1460     msr_pow  = (value >> MSR_POW)  & 1; /* POW / WE */
1461     msr_tlb  = (value >> MSR_TLB)  & 1; /* TLB / TGPR / CE */
1462     msr_ile  = (value >> MSR_ILE)  & 1;
1463     msr_ee   = (value >> MSR_EE)   & 1;
1464     msr_pr   = (value >> MSR_PR)   & 1;
1465     msr_fp   = (value >> MSR_FP)   & 1;
1466     msr_me   = (value >> MSR_ME)   & 1;
1467     msr_fe0  = (value >> MSR_FE0)  & 1;
1468     msr_se   = (value >> MSR_SE)   & 1; /* SE / DWE / UBLE */
1469     msr_be   = (value >> MSR_BE)   & 1; /* BE / DE */
1470     msr_fe1  = (value >> MSR_FE1)  & 1;
1471     msr_al   = (value >> MSR_AL)   & 1;
1472     msr_ip   = (value >> MSR_IP)   & 1;
1473     msr_ir   = (value >> MSR_IR)   & 1; /* IR / IS */
1474     msr_dr   = (value >> MSR_DR)   & 1; /* DR / DS */
1475     msr_pe   = (value >> MSR_PE)   & 1; /* PE / EP */
1476     msr_px   = (value >> MSR_PX)   & 1; /* PX / PMM */
1477     msr_ri   = (value >> MSR_RI)   & 1;
1478     msr_le   = (value >> MSR_LE)   & 1;
1479     do_compute_hflags(env);
1480
1481     enter_pm = 0;
1482     switch (PPC_EXCP(env)) {
1483     case PPC_FLAGS_EXCP_603:
1484         /* Don't handle SLEEP mode: we should disable all clocks...
1485          * No dynamic power-management.
1486          */
1487         if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00C00000) != 0)
1488             enter_pm = 1;
1489         break;
1490     case PPC_FLAGS_EXCP_604:
1491         if (msr_pow == 1)
1492             enter_pm = 1;
1493         break;
1494     case PPC_FLAGS_EXCP_7x0:
1495         if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00E00000) != 0)
1496             enter_pm = 1;
1497         break;
1498     default:
1499         break;
1500     }
1501     if (enter_pm) {
1502         if (likely(!env->halted)) {
1503             /* power save: exit cpu loop */
1504             env->halted = 1;
1505             env->exception_index = EXCP_HLT;
1506             cpu_loop_exit();
1507         }
1508     }
1509 }
1510
1511 #if defined(TARGET_PPC64)
1512 void ppc_store_msr_32 (CPUPPCState *env, uint32_t value)
1513 {
1514     do_store_msr(env,
1515                  (do_load_msr(env) & ~0xFFFFFFFFULL) | (value & 0xFFFFFFFF));
1516 }
1517 #endif
1518
1519 void do_compute_hflags (CPUPPCState *env)
1520 {
1521     /* Compute current hflags */
1522     env->hflags = (msr_cm << MSR_CM) | (msr_vr << MSR_VR) |
1523         (msr_ap << MSR_AP) | (msr_sa << MSR_SA) | (msr_pr << MSR_PR) |
1524         (msr_fp << MSR_FP) | (msr_fe0 << MSR_FE0) | (msr_se << MSR_SE) |
1525         (msr_be << MSR_BE) | (msr_fe1 << MSR_FE1) | (msr_le << MSR_LE);
1526 #if defined (TARGET_PPC64)
1527     /* No care here: PowerPC 64 MSR_SF means the same as MSR_CM for BookE */
1528     env->hflags |= (msr_sf << (MSR_SF - 32)) | (msr_hv << (MSR_HV - 32));
1529 #endif
1530 }
1531
1532 /*****************************************************************************/
1533 /* Exception processing */
1534 #if defined (CONFIG_USER_ONLY)
1535 void do_interrupt (CPUState *env)
1536 {
1537     env->exception_index = -1;
1538 }
1539
1540 void ppc_hw_interrupt (CPUState *env)
1541 {
1542     env->exception_index = -1;
1543 }
1544 #else /* defined (CONFIG_USER_ONLY) */
1545 static void dump_syscall (CPUState *env)
1546 {
1547     fprintf(logfile, "syscall r0=0x" REGX " r3=0x" REGX " r4=0x" REGX
1548             " r5=0x" REGX " r6=0x" REGX " nip=0x" ADDRX "\n",
1549             env->gpr[0], env->gpr[3], env->gpr[4],
1550             env->gpr[5], env->gpr[6], env->nip);
1551 }
1552
1553 void do_interrupt (CPUState *env)
1554 {
1555     target_ulong msr, *srr_0, *srr_1, *asrr_0, *asrr_1;
1556     int excp, idx;
1557
1558     excp = env->exception_index;
1559     msr = do_load_msr(env);
1560     /* The default is to use SRR0 & SRR1 to save the exception context */
1561     srr_0 = &env->spr[SPR_SRR0];
1562     srr_1 = &env->spr[SPR_SRR1];
1563     asrr_0 = NULL;
1564     asrr_1 = NULL;
1565 #if defined (DEBUG_EXCEPTIONS)
1566     if ((excp == EXCP_PROGRAM || excp == EXCP_DSI) && msr_pr == 1) {
1567         if (loglevel != 0) {
1568             fprintf(logfile,
1569                     "Raise exception at 0x" ADDRX " => 0x%08x (%02x)\n",
1570                     env->nip, excp, env->error_code);
1571             cpu_dump_state(env, logfile, fprintf, 0);
1572         }
1573     }
1574 #endif
1575     if (loglevel & CPU_LOG_INT) {
1576         fprintf(logfile, "Raise exception at 0x" ADDRX " => 0x%08x (%02x)\n",
1577                 env->nip, excp, env->error_code);
1578     }
1579     msr_pow = 0;
1580     idx = -1;
1581     /* Generate informations in save/restore registers */
1582     switch (excp) {
1583     /* Generic PowerPC exceptions */
1584     case EXCP_RESET: /* 0x0100 */
1585         switch (PPC_EXCP(env)) {
1586         case PPC_FLAGS_EXCP_40x:
1587             srr_0 = &env->spr[SPR_40x_SRR2];
1588             srr_1 = &env->spr[SPR_40x_SRR3];
1589             break;
1590         case PPC_FLAGS_EXCP_BOOKE:
1591             idx = 0;
1592             srr_0 = &env->spr[SPR_BOOKE_CSRR0];
1593             srr_1 = &env->spr[SPR_BOOKE_CSRR1];
1594             break;
1595         default:
1596             if (msr_ip)
1597                 excp += 0xFFC00;
1598             excp |= 0xFFC00000;
1599             break;
1600         }
1601         goto store_next;
1602     case EXCP_MACHINE_CHECK: /* 0x0200 */
1603         switch (PPC_EXCP(env)) {
1604         case PPC_FLAGS_EXCP_40x:
1605             srr_0 = &env->spr[SPR_40x_SRR2];
1606             srr_1 = &env->spr[SPR_40x_SRR3];
1607             break;
1608         case PPC_FLAGS_EXCP_BOOKE:
1609             idx = 1;
1610             srr_0 = &env->spr[SPR_BOOKE_MCSRR0];
1611             srr_1 = &env->spr[SPR_BOOKE_MCSRR1];
1612             asrr_0 = &env->spr[SPR_BOOKE_CSRR0];
1613             asrr_1 = &env->spr[SPR_BOOKE_CSRR1];
1614             msr_ce = 0;
1615             break;
1616         default:
1617             break;
1618         }
1619         msr_me = 0;
1620         break;
1621     case EXCP_DSI: /* 0x0300 */
1622         /* Store exception cause */
1623         /* data location address has been stored
1624          * when the fault has been detected
1625          */
1626         idx = 2;
1627         msr &= ~0xFFFF0000;
1628 #if defined (DEBUG_EXCEPTIONS)
1629         if (loglevel != 0) {
1630             fprintf(logfile, "DSI exception: DSISR=0x" ADDRX" DAR=0x" ADDRX
1631                     "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
1632         }
1633 #endif
1634         goto store_next;
1635     case EXCP_ISI: /* 0x0400 */
1636         /* Store exception cause */
1637         idx = 3;
1638         msr &= ~0xFFFF0000;
1639         msr |= env->error_code;
1640 #if defined (DEBUG_EXCEPTIONS)
1641         if (loglevel != 0) {
1642             fprintf(logfile, "ISI exception: msr=0x" ADDRX ", nip=0x" ADDRX
1643                     "\n", msr, env->nip);
1644         }
1645 #endif
1646         goto store_next;
1647     case EXCP_EXTERNAL: /* 0x0500 */
1648         idx = 4;
1649         goto store_next;
1650     case EXCP_ALIGN: /* 0x0600 */
1651         if (likely(PPC_EXCP(env) != PPC_FLAGS_EXCP_601)) {
1652             /* Store exception cause */
1653             idx = 5;
1654             /* Get rS/rD and rA from faulting opcode */
1655             env->spr[SPR_DSISR] |=
1656                 (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
1657             /* data location address has been stored
1658              * when the fault has been detected
1659              */
1660         } else {
1661             /* IO error exception on PowerPC 601 */
1662             /* XXX: TODO */
1663             cpu_abort(env,
1664                       "601 IO error exception is not implemented yet !\n");
1665         }
1666         goto store_current;
1667     case EXCP_PROGRAM: /* 0x0700 */
1668         idx = 6;
1669         msr &= ~0xFFFF0000;
1670         switch (env->error_code & ~0xF) {
1671         case EXCP_FP:
1672             if (msr_fe0 == 0 && msr_fe1 == 0) {
1673 #if defined (DEBUG_EXCEPTIONS)
1674                 if (loglevel != 0) {
1675                     fprintf(logfile, "Ignore floating point exception\n");
1676                 }
1677 #endif
1678                 return;
1679             }
1680             msr |= 0x00100000;
1681             /* Set FX */
1682             env->fpscr[7] |= 0x8;
1683             /* Finally, update FEX */
1684             if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) &
1685                 ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3)))
1686                 env->fpscr[7] |= 0x4;
1687             break;
1688         case EXCP_INVAL:
1689 #if defined (DEBUG_EXCEPTIONS)
1690             if (loglevel != 0) {
1691                 fprintf(logfile, "Invalid instruction at 0x" ADDRX "\n",
1692                         env->nip);
1693             }
1694 #endif
1695             msr |= 0x00080000;
1696             break;
1697         case EXCP_PRIV:
1698             msr |= 0x00040000;
1699             break;
1700         case EXCP_TRAP:
1701             idx = 15;
1702             msr |= 0x00020000;
1703             break;
1704         default:
1705             /* Should never occur */
1706             break;
1707         }
1708         msr |= 0x00010000;
1709         goto store_current;
1710     case EXCP_NO_FP: /* 0x0800 */
1711         idx = 7;
1712         msr &= ~0xFFFF0000;
1713         goto store_current;
1714     case EXCP_DECR:
1715         goto store_next;
1716     case EXCP_SYSCALL: /* 0x0C00 */
1717         idx = 8;
1718         /* NOTE: this is a temporary hack to support graphics OSI
1719            calls from the MOL driver */
1720         if (env->gpr[3] == 0x113724fa && env->gpr[4] == 0x77810f9b &&
1721             env->osi_call) {
1722             if (env->osi_call(env) != 0)
1723                 return;
1724         }
1725         if (loglevel & CPU_LOG_INT) {
1726             dump_syscall(env);
1727         }
1728         goto store_next;
1729     case EXCP_TRACE: /* 0x0D00 */
1730         goto store_next;
1731     case EXCP_PERF: /* 0x0F00 */
1732         /* XXX: TODO */
1733         cpu_abort(env,
1734                   "Performance counter exception is not implemented yet !\n");
1735         goto store_next;
1736     /* 32 bits PowerPC specific exceptions */
1737     case EXCP_FP_ASSIST: /* 0x0E00 */
1738         /* XXX: TODO */
1739         cpu_abort(env, "Floating point assist exception "
1740                   "is not implemented yet !\n");
1741         goto store_next;
1742         /* 64 bits PowerPC exceptions */
1743     case EXCP_DSEG: /* 0x0380 */
1744         /* XXX: TODO */
1745         cpu_abort(env, "Data segment exception is not implemented yet !\n");
1746         goto store_next;
1747     case EXCP_ISEG: /* 0x0480 */
1748         /* XXX: TODO */
1749         cpu_abort(env,
1750                   "Instruction segment exception is not implemented yet !\n");
1751         goto store_next;
1752     case EXCP_HDECR: /* 0x0980 */
1753         /* XXX: TODO */
1754         cpu_abort(env, "Hypervisor decrementer exception is not implemented "
1755                   "yet !\n");
1756         goto store_next;
1757     /* Implementation specific exceptions */
1758     case 0x0A00:
1759         if (likely(env->spr[SPR_PVR] == CPU_PPC_G2 ||
1760                    env->spr[SPR_PVR] == CPU_PPC_G2LE)) {
1761             /* Critical interrupt on G2 */
1762             /* XXX: TODO */
1763             cpu_abort(env, "G2 critical interrupt is not implemented yet !\n");
1764             goto store_next;
1765         } else {
1766             cpu_abort(env, "Invalid exception 0x0A00 !\n");
1767         }
1768         return;
1769     case 0x0F20:
1770         idx = 9;
1771         switch (PPC_EXCP(env)) {
1772         case PPC_FLAGS_EXCP_40x:
1773             /* APU unavailable on 405 */
1774             /* XXX: TODO */
1775             cpu_abort(env,
1776                       "APU unavailable exception is not implemented yet !\n");
1777             goto store_next;
1778         case PPC_FLAGS_EXCP_74xx:
1779             /* Altivec unavailable */
1780             /* XXX: TODO */
1781             cpu_abort(env, "Altivec unavailable exception "
1782                       "is not implemented yet !\n");
1783             goto store_next;
1784         default:
1785             cpu_abort(env, "Invalid exception 0x0F20 !\n");
1786             break;
1787         }
1788         return;
1789     case 0x1000:
1790         idx = 10;
1791         switch (PPC_EXCP(env)) {
1792         case PPC_FLAGS_EXCP_40x:
1793             /* PIT on 4xx */
1794             msr &= ~0xFFFF0000;
1795 #if defined (DEBUG_EXCEPTIONS)
1796             if (loglevel != 0)
1797                 fprintf(logfile, "PIT exception\n");
1798 #endif
1799             goto store_next;
1800         case PPC_FLAGS_EXCP_602:
1801         case PPC_FLAGS_EXCP_603:
1802             /* ITLBMISS on 602/603 */
1803             goto store_gprs;
1804         case PPC_FLAGS_EXCP_7x5:
1805             /* ITLBMISS on 745/755 */
1806             goto tlb_miss;
1807         default:
1808             cpu_abort(env, "Invalid exception 0x1000 !\n");
1809             break;
1810         }
1811         return;
1812     case 0x1010:
1813         idx = 11;
1814         switch (PPC_EXCP(env)) {
1815         case PPC_FLAGS_EXCP_40x:
1816             /* FIT on 4xx */
1817             msr &= ~0xFFFF0000;
1818 #if defined (DEBUG_EXCEPTIONS)
1819             if (loglevel != 0)
1820                 fprintf(logfile, "FIT exception\n");
1821 #endif
1822             goto store_next;
1823         default:
1824             cpu_abort(env, "Invalid exception 0x1010 !\n");
1825             break;
1826         }
1827         return;
1828     case 0x1020:
1829         idx = 12;
1830         switch (PPC_EXCP(env)) {
1831         case PPC_FLAGS_EXCP_40x:
1832             /* Watchdog on 4xx */
1833             msr &= ~0xFFFF0000;
1834 #if defined (DEBUG_EXCEPTIONS)
1835             if (loglevel != 0)
1836                 fprintf(logfile, "WDT exception\n");
1837 #endif
1838             goto store_next;
1839         case PPC_FLAGS_EXCP_BOOKE:
1840             srr_0 = &env->spr[SPR_BOOKE_CSRR0];
1841             srr_1 = &env->spr[SPR_BOOKE_CSRR1];
1842             break;
1843         default:
1844             cpu_abort(env, "Invalid exception 0x1020 !\n");
1845             break;
1846         }
1847         return;
1848     case 0x1100:
1849         idx = 13;
1850         switch (PPC_EXCP(env)) {
1851         case PPC_FLAGS_EXCP_40x:
1852             /* DTLBMISS on 4xx */
1853             msr &= ~0xFFFF0000;
1854             goto store_next;
1855         case PPC_FLAGS_EXCP_602:
1856         case PPC_FLAGS_EXCP_603:
1857             /* DLTLBMISS on 602/603 */
1858             goto store_gprs;
1859         case PPC_FLAGS_EXCP_7x5:
1860             /* DLTLBMISS on 745/755 */
1861             goto tlb_miss;
1862         default:
1863             cpu_abort(env, "Invalid exception 0x1100 !\n");
1864             break;
1865         }
1866         return;
1867     case 0x1200:
1868         idx = 14;
1869         switch (PPC_EXCP(env)) {
1870         case PPC_FLAGS_EXCP_40x:
1871             /* ITLBMISS on 4xx */
1872             msr &= ~0xFFFF0000;
1873             goto store_next;
1874         case PPC_FLAGS_EXCP_602:
1875         case PPC_FLAGS_EXCP_603:
1876             /* DSTLBMISS on 602/603 */
1877         store_gprs:
1878             /* Swap temporary saved registers with GPRs */
1879             swap_gpr_tgpr(env);
1880             msr_tgpr = 1;
1881 #if defined (DEBUG_SOFTWARE_TLB)
1882             if (loglevel != 0) {
1883                 const unsigned char *es;
1884                 target_ulong *miss, *cmp;
1885                 int en;
1886                 if (excp == 0x1000) {
1887                     es = "I";
1888                     en = 'I';
1889                     miss = &env->spr[SPR_IMISS];
1890                     cmp = &env->spr[SPR_ICMP];
1891                 } else {
1892                     if (excp == 0x1100)
1893                         es = "DL";
1894                     else
1895                         es = "DS";
1896                     en = 'D';
1897                     miss = &env->spr[SPR_DMISS];
1898                     cmp = &env->spr[SPR_DCMP];
1899                 }
1900                 fprintf(logfile, "6xx %sTLB miss: %cM " ADDRX " %cC " ADDRX
1901                         " H1 " ADDRX " H2 " ADDRX " %08x\n",
1902                         es, en, *miss, en, *cmp,
1903                         env->spr[SPR_HASH1], env->spr[SPR_HASH2],
1904                         env->error_code);
1905             }
1906 #endif
1907             goto tlb_miss;
1908         case PPC_FLAGS_EXCP_7x5:
1909             /* DSTLBMISS on 745/755 */
1910         tlb_miss:
1911             msr &= ~0xF83F0000;
1912             msr |= env->crf[0] << 28;
1913             msr |= env->error_code; /* key, D/I, S/L bits */
1914             /* Set way using a LRU mechanism */
1915             msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
1916             goto store_next;
1917         default:
1918             cpu_abort(env, "Invalid exception 0x1200 !\n");
1919             break;
1920         }
1921         return;
1922     case 0x1300:
1923         switch (PPC_EXCP(env)) {
1924         case PPC_FLAGS_EXCP_601:
1925         case PPC_FLAGS_EXCP_602:
1926         case PPC_FLAGS_EXCP_603:
1927         case PPC_FLAGS_EXCP_604:
1928         case PPC_FLAGS_EXCP_7x0:
1929         case PPC_FLAGS_EXCP_7x5:
1930             /* IABR on 6xx/7xx */
1931             /* XXX: TODO */
1932             cpu_abort(env, "IABR exception is not implemented yet !\n");
1933             goto store_next;
1934         default:
1935             cpu_abort(env, "Invalid exception 0x1300 !\n");
1936             break;
1937         }
1938         return;
1939     case 0x1400:
1940         switch (PPC_EXCP(env)) {
1941         case PPC_FLAGS_EXCP_601:
1942         case PPC_FLAGS_EXCP_602:
1943         case PPC_FLAGS_EXCP_603:
1944         case PPC_FLAGS_EXCP_604:
1945         case PPC_FLAGS_EXCP_7x0:
1946         case PPC_FLAGS_EXCP_7x5:
1947             /* SMI on 6xx/7xx */
1948             /* XXX: TODO */
1949             cpu_abort(env, "SMI exception is not implemented yet !\n");
1950             goto store_next;
1951         default:
1952             cpu_abort(env, "Invalid exception 0x1400 !\n");
1953             break;
1954         }
1955         return;
1956     case 0x1500:
1957         switch (PPC_EXCP(env)) {
1958         case PPC_FLAGS_EXCP_602:
1959             /* Watchdog on 602 */
1960             /* XXX: TODO */
1961             cpu_abort(env,
1962                       "602 watchdog exception is not implemented yet !\n");
1963             goto store_next;
1964         case PPC_FLAGS_EXCP_970:
1965             /* Soft patch exception on 970 */
1966             /* XXX: TODO */
1967             cpu_abort(env,
1968                       "970 soft-patch exception is not implemented yet !\n");
1969             goto store_next;
1970         case PPC_FLAGS_EXCP_74xx:
1971             /* VPU assist on 74xx */
1972             /* XXX: TODO */
1973             cpu_abort(env, "VPU assist exception is not implemented yet !\n");
1974             goto store_next;
1975         default:
1976             cpu_abort(env, "Invalid exception 0x1500 !\n");
1977             break;
1978         }
1979         return;
1980     case 0x1600:
1981         switch (PPC_EXCP(env)) {
1982         case PPC_FLAGS_EXCP_602:
1983             /* Emulation trap on 602 */
1984             /* XXX: TODO */
1985             cpu_abort(env, "602 emulation trap exception "
1986                       "is not implemented yet !\n");
1987             goto store_next;
1988         case PPC_FLAGS_EXCP_970:
1989             /* Maintenance exception on 970 */
1990             /* XXX: TODO */
1991             cpu_abort(env,
1992                       "970 maintenance exception is not implemented yet !\n");
1993             goto store_next;
1994         default:
1995             cpu_abort(env, "Invalid exception 0x1600 !\n");
1996             break;
1997         }
1998         return;
1999     case 0x1700:
2000         switch (PPC_EXCP(env)) {
2001         case PPC_FLAGS_EXCP_7x0:
2002         case PPC_FLAGS_EXCP_7x5:
2003             /* Thermal management interrupt on G3 */
2004             /* XXX: TODO */
2005             cpu_abort(env, "G3 thermal management exception "
2006                       "is not implemented yet !\n");
2007             goto store_next;
2008         case PPC_FLAGS_EXCP_970:
2009             /* VPU assist on 970 */
2010             /* XXX: TODO */
2011             cpu_abort(env,
2012                       "970 VPU assist exception is not implemented yet !\n");
2013             goto store_next;
2014         default:
2015             cpu_abort(env, "Invalid exception 0x1700 !\n");
2016             break;
2017         }
2018         return;
2019     case 0x1800:
2020         switch (PPC_EXCP(env)) {
2021         case PPC_FLAGS_EXCP_970:
2022             /* Thermal exception on 970 */
2023             /* XXX: TODO */
2024             cpu_abort(env, "970 thermal management exception "
2025                       "is not implemented yet !\n");
2026             goto store_next;
2027         default:
2028             cpu_abort(env, "Invalid exception 0x1800 !\n");
2029             break;
2030         }
2031         return;
2032     case 0x2000:
2033         switch (PPC_EXCP(env)) {
2034         case PPC_FLAGS_EXCP_40x:
2035             /* DEBUG on 4xx */
2036             /* XXX: TODO */
2037             cpu_abort(env, "40x debug exception is not implemented yet !\n");
2038             goto store_next;
2039         case PPC_FLAGS_EXCP_601:
2040             /* Run mode exception on 601 */
2041             /* XXX: TODO */
2042             cpu_abort(env,
2043                       "601 run mode exception is not implemented yet !\n");
2044             goto store_next;
2045         case PPC_FLAGS_EXCP_BOOKE:
2046             srr_0 = &env->spr[SPR_BOOKE_CSRR0];
2047             srr_1 = &env->spr[SPR_BOOKE_CSRR1];
2048             break;
2049         default:
2050             cpu_abort(env, "Invalid exception 0x1800 !\n");
2051             break;
2052         }
2053         return;
2054     /* Other exceptions */
2055     /* Qemu internal exceptions:
2056      * we should never come here with those values: abort execution
2057      */
2058     default:
2059         cpu_abort(env, "Invalid exception: code %d (%04x)\n", excp, excp);
2060         return;
2061     store_current:
2062         /* save current instruction location */
2063         *srr_0 = env->nip - 4;
2064         break;
2065     store_next:
2066         /* save next instruction location */
2067         *srr_0 = env->nip;
2068         break;
2069     }
2070     /* Save msr */
2071     *srr_1 = msr;
2072     if (asrr_0 != NULL)
2073         *asrr_0 = *srr_0;
2074     if (asrr_1 != NULL)
2075         *asrr_1 = *srr_1;
2076     /* If we disactivated any translation, flush TLBs */
2077     if (msr_ir || msr_dr) {
2078         tlb_flush(env, 1);
2079     }
2080     /* reload MSR with correct bits */
2081     msr_ee = 0;
2082     msr_pr = 0;
2083     msr_fp = 0;
2084     msr_fe0 = 0;
2085     msr_se = 0;
2086     msr_be = 0;
2087     msr_fe1 = 0;
2088     msr_ir = 0;
2089     msr_dr = 0;
2090     msr_ri = 0;
2091     msr_le = msr_ile;
2092     if (PPC_EXCP(env) == PPC_FLAGS_EXCP_BOOKE) {
2093         msr_cm = msr_icm;
2094         if (idx == -1 || (idx >= 16 && idx < 32)) {
2095             cpu_abort(env, "Invalid exception index for excp %d %08x idx %d\n",
2096                       excp, excp, idx);
2097         }
2098 #if defined(TARGET_PPC64)
2099         if (msr_cm)
2100             env->nip = (uint64_t)env->spr[SPR_BOOKE_IVPR];
2101         else
2102 #endif
2103             env->nip = (uint32_t)env->spr[SPR_BOOKE_IVPR];
2104         if (idx < 16)
2105             env->nip |= env->spr[SPR_BOOKE_IVOR0 + idx];
2106         else if (idx < 38)
2107             env->nip |= env->spr[SPR_BOOKE_IVOR32 + idx - 32];
2108     } else {
2109         msr_sf = msr_isf;
2110         env->nip = excp;
2111     }
2112     do_compute_hflags(env);
2113     /* Jump to handler */
2114     env->exception_index = EXCP_NONE;
2115 }
2116
2117 void ppc_hw_interrupt (CPUPPCState *env)
2118 {
2119     int raised = 0;
2120
2121 #if 1
2122     if (loglevel & CPU_LOG_INT) {
2123         fprintf(logfile, "%s: %p pending %08x req %08x me %d ee %d\n",
2124                 __func__, env, env->pending_interrupts,
2125                 env->interrupt_request, msr_me, msr_ee);
2126     }
2127 #endif
2128     /* Raise it */
2129     if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
2130         /* External reset / critical input */
2131         /* XXX: critical input should be handled another way.
2132          *      This code is not correct !
2133          */
2134         env->exception_index = EXCP_RESET;
2135         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
2136         raised = 1;
2137     }
2138     if (raised == 0 && msr_me != 0) {
2139         /* Machine check exception */
2140         if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
2141             env->exception_index = EXCP_MACHINE_CHECK;
2142             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
2143             raised = 1;
2144         }
2145     }
2146     if (raised == 0 && msr_ee != 0) {
2147 #if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
2148         /* Hypervisor decrementer exception */
2149         if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
2150             env->exception_index = EXCP_HDECR;
2151             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
2152             raised = 1;
2153         } else
2154 #endif
2155         /* Decrementer exception */
2156         if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
2157             env->exception_index = EXCP_DECR;
2158             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
2159             raised = 1;
2160         /* Programmable interval timer on embedded PowerPC */
2161         } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
2162             env->exception_index = EXCP_40x_PIT;
2163             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
2164             raised = 1;
2165         /* Fixed interval timer on embedded PowerPC */
2166         } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
2167             env->exception_index = EXCP_40x_FIT;
2168             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
2169             raised = 1;
2170         /* Watchdog timer on embedded PowerPC */
2171         } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
2172             env->exception_index = EXCP_40x_WATCHDOG;
2173             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
2174             raised = 1;
2175         /* External interrupt */
2176         } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
2177             env->exception_index = EXCP_EXTERNAL;
2178             /* Taking an external interrupt does not clear the external
2179              * interrupt status
2180              */
2181 #if 0
2182             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
2183 #endif
2184             raised = 1;
2185 #if 0 // TODO
2186         /* Thermal interrupt */
2187         } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
2188             env->exception_index = EXCP_970_THRM;
2189             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
2190             raised = 1;
2191 #endif
2192         }
2193 #if 0 // TODO
2194     /* External debug exception */
2195     } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
2196         env->exception_index = EXCP_xxx;
2197         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
2198         raised = 1;
2199 #endif
2200     }
2201     if (raised != 0) {
2202         env->error_code = 0;
2203         do_interrupt(env);
2204     }
2205 }
2206 #endif /* !CONFIG_USER_ONLY */
2207
2208 void cpu_dump_EA (target_ulong EA)
2209 {
2210     FILE *f;
2211
2212     if (logfile) {
2213         f = logfile;
2214     } else {
2215         f = stdout;
2216         return;
2217     }
2218     fprintf(f, "Memory access at address " ADDRX "\n", EA);
2219 }
2220
2221 void cpu_dump_rfi (target_ulong RA, target_ulong msr)
2222 {
2223     FILE *f;
2224
2225     if (logfile) {
2226         f = logfile;
2227     } else {
2228         f = stdout;
2229         return;
2230     }
2231     fprintf(f, "Return from exception at " ADDRX " with flags " ADDRX "\n",
2232             RA, msr);
2233 }
2234
2235 void cpu_ppc_reset (void *opaque)
2236 {
2237     CPUPPCState *env;
2238
2239     env = opaque;
2240 #if defined (DO_SINGLE_STEP) && 0
2241     /* Single step trace mode */
2242     msr_se = 1;
2243     msr_be = 1;
2244 #endif
2245     msr_fp = 1; /* Allow floating point exceptions */
2246     msr_me = 1; /* Allow machine check exceptions  */
2247 #if defined(TARGET_PPC64)
2248     msr_sf = 0; /* Boot in 32 bits mode */
2249     msr_cm = 0;
2250 #endif
2251 #if defined(CONFIG_USER_ONLY)
2252     msr_pr = 1;
2253     tlb_flush(env, 1);
2254 #else
2255     env->nip = 0xFFFFFFFC;
2256     ppc_tlb_invalidate_all(env);
2257 #endif
2258     do_compute_hflags(env);
2259     env->reserve = -1;
2260 }
2261
2262 CPUPPCState *cpu_ppc_init (void)
2263 {
2264     CPUPPCState *env;
2265
2266     env = qemu_mallocz(sizeof(CPUPPCState));
2267     if (!env)
2268         return NULL;
2269     cpu_exec_init(env);
2270     cpu_ppc_reset(env);
2271
2272     return env;
2273 }
2274
2275 void cpu_ppc_close (CPUPPCState *env)
2276 {
2277     /* Should also remove all opcode tables... */
2278     free(env);
2279 }