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