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