1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "qemu/osdep.h"
21#include "qemu/units.h"
22#include "cpu.h"
23#include "sysemu/kvm.h"
24#include "kvm_ppc.h"
25#include "mmu-hash64.h"
26#include "mmu-hash32.h"
27#include "exec/exec-all.h"
28#include "exec/log.h"
29#include "helper_regs.h"
30#include "qemu/error-report.h"
31#include "qemu/main-loop.h"
32#include "qemu/qemu-print.h"
33#include "internal.h"
34#include "mmu-book3s-v3.h"
35#include "mmu-radix64.h"
36
37
38
39void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
40{
41 PowerPCCPU *cpu = env_archcpu(env);
42 qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value);
43 assert(!cpu->env.has_hv_mode || !cpu->vhyp);
44#if defined(TARGET_PPC64)
45 if (mmu_is_64bit(env->mmu_model)) {
46 target_ulong sdr_mask = SDR_64_HTABORG | SDR_64_HTABSIZE;
47 target_ulong htabsize = value & SDR_64_HTABSIZE;
48
49 if (value & ~sdr_mask) {
50 qemu_log_mask(LOG_GUEST_ERROR, "Invalid bits 0x"TARGET_FMT_lx
51 " set in SDR1", value & ~sdr_mask);
52 value &= sdr_mask;
53 }
54 if (htabsize > 28) {
55 qemu_log_mask(LOG_GUEST_ERROR, "Invalid HTABSIZE 0x" TARGET_FMT_lx
56 " stored in SDR1", htabsize);
57 return;
58 }
59 }
60#endif
61
62 env->spr[SPR_SDR1] = value;
63}
64
65
66
67
68static int pp_check(int key, int pp, int nx)
69{
70 int access;
71
72
73 access = 0;
74 if (key == 0) {
75 switch (pp) {
76 case 0x0:
77 case 0x1:
78 case 0x2:
79 access |= PAGE_WRITE;
80
81 case 0x3:
82 access |= PAGE_READ;
83 break;
84 }
85 } else {
86 switch (pp) {
87 case 0x0:
88 access = 0;
89 break;
90 case 0x1:
91 case 0x3:
92 access = PAGE_READ;
93 break;
94 case 0x2:
95 access = PAGE_READ | PAGE_WRITE;
96 break;
97 }
98 }
99 if (nx == 0) {
100 access |= PAGE_EXEC;
101 }
102
103 return access;
104}
105
106static int check_prot(int prot, MMUAccessType access_type)
107{
108 return prot & prot_for_access_type(access_type) ? 0 : -2;
109}
110
111int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
112 int way, int is_code)
113{
114 int nr;
115
116
117 nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1);
118
119 nr += env->tlb_per_way * way;
120
121 if (is_code && env->id_tlbs == 1) {
122 nr += env->nb_tlb;
123 }
124
125 return nr;
126}
127
128static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0,
129 target_ulong pte1, int h,
130 MMUAccessType access_type)
131{
132 target_ulong ptem, mmask;
133 int access, ret, pteh, ptev, pp;
134
135 ret = -1;
136
137 ptev = pte_is_valid(pte0);
138 pteh = (pte0 >> 6) & 1;
139 if (ptev && h == pteh) {
140
141 ptem = pte0 & PTE_PTEM_MASK;
142 mmask = PTE_CHECK_MASK;
143 pp = pte1 & 0x00000003;
144 if (ptem == ctx->ptem) {
145 if (ctx->raddr != (hwaddr)-1ULL) {
146
147 if ((ctx->raddr & mmask) != (pte1 & mmask)) {
148 qemu_log_mask(CPU_LOG_MMU, "Bad RPN/WIMG/PP\n");
149 return -3;
150 }
151 }
152
153 access = pp_check(ctx->key, pp, ctx->nx);
154
155 ctx->raddr = pte1;
156 ctx->prot = access;
157 ret = check_prot(ctx->prot, access_type);
158 if (ret == 0) {
159
160 qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n");
161 } else {
162
163 qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
164 }
165 }
166 }
167
168 return ret;
169}
170
171static int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
172 int ret, MMUAccessType access_type)
173{
174 int store = 0;
175
176
177 if (!(*pte1p & 0x00000100)) {
178
179 *pte1p |= 0x00000100;
180 store = 1;
181 }
182 if (!(*pte1p & 0x00000080)) {
183 if (access_type == MMU_DATA_STORE && ret == 0) {
184
185 *pte1p |= 0x00000080;
186 store = 1;
187 } else {
188
189 ctx->prot &= ~PAGE_WRITE;
190 }
191 }
192
193 return store;
194}
195
196
197
198static int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx,
199 target_ulong eaddr, MMUAccessType access_type)
200{
201 ppc6xx_tlb_t *tlb;
202 int nr, best, way;
203 int ret;
204
205 best = -1;
206 ret = -1;
207 for (way = 0; way < env->nb_ways; way++) {
208 nr = ppc6xx_tlb_getnum(env, eaddr, way, access_type == MMU_INST_FETCH);
209 tlb = &env->tlb.tlb6[nr];
210
211 if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {
212 qemu_log_mask(CPU_LOG_MMU, "TLB %d/%d %s [" TARGET_FMT_lx
213 " " TARGET_FMT_lx "] <> " TARGET_FMT_lx "\n",
214 nr, env->nb_tlb,
215 pte_is_valid(tlb->pte0) ? "valid" : "inval",
216 tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);
217 continue;
218 }
219 qemu_log_mask(CPU_LOG_MMU, "TLB %d/%d %s " TARGET_FMT_lx " <> "
220 TARGET_FMT_lx " " TARGET_FMT_lx " %c %c\n",
221 nr, env->nb_tlb,
222 pte_is_valid(tlb->pte0) ? "valid" : "inval",
223 tlb->EPN, eaddr, tlb->pte1,
224 access_type == MMU_DATA_STORE ? 'S' : 'L',
225 access_type == MMU_INST_FETCH ? 'I' : 'D');
226 switch (ppc6xx_tlb_pte_check(ctx, tlb->pte0, tlb->pte1,
227 0, access_type)) {
228 case -3:
229
230 return -1;
231 case -2:
232
233 ret = -2;
234 best = nr;
235 break;
236 case -1:
237 default:
238
239 break;
240 case 0:
241
242
243
244
245
246
247
248 ret = 0;
249 best = nr;
250 goto done;
251 }
252 }
253 if (best != -1) {
254 done:
255 qemu_log_mask(CPU_LOG_MMU, "found TLB at addr " TARGET_FMT_plx
256 " prot=%01x ret=%d\n",
257 ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
258
259 pte_update_flags(ctx, &env->tlb.tlb6[best].pte1, ret, access_type);
260 }
261
262 return ret;
263}
264
265
266static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp,
267 int *validp, int *protp, target_ulong *BATu,
268 target_ulong *BATl)
269{
270 target_ulong bl;
271 int pp, valid, prot;
272
273 bl = (*BATu & 0x00001FFC) << 15;
274 valid = 0;
275 prot = 0;
276 if ((!FIELD_EX64(env->msr, MSR, PR) && (*BATu & 0x00000002)) ||
277 (FIELD_EX64(env->msr, MSR, PR) && (*BATu & 0x00000001))) {
278 valid = 1;
279 pp = *BATl & 0x00000003;
280 if (pp != 0) {
281 prot = PAGE_READ | PAGE_EXEC;
282 if (pp == 0x2) {
283 prot |= PAGE_WRITE;
284 }
285 }
286 }
287 *blp = bl;
288 *validp = valid;
289 *protp = prot;
290}
291
292static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
293 target_ulong virtual, MMUAccessType access_type)
294{
295 target_ulong *BATlt, *BATut, *BATu, *BATl;
296 target_ulong BEPIl, BEPIu, bl;
297 int i, valid, prot;
298 int ret = -1;
299 bool ifetch = access_type == MMU_INST_FETCH;
300
301 qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
302 ifetch ? 'I' : 'D', virtual);
303 if (ifetch) {
304 BATlt = env->IBAT[1];
305 BATut = env->IBAT[0];
306 } else {
307 BATlt = env->DBAT[1];
308 BATut = env->DBAT[0];
309 }
310 for (i = 0; i < env->nb_BATs; i++) {
311 BATu = &BATut[i];
312 BATl = &BATlt[i];
313 BEPIu = *BATu & 0xF0000000;
314 BEPIl = *BATu & 0x0FFE0000;
315 bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
316 qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT%d v " TARGET_FMT_lx " BATu "
317 TARGET_FMT_lx " BATl " TARGET_FMT_lx "\n", __func__,
318 ifetch ? 'I' : 'D', i, virtual, *BATu, *BATl);
319 if ((virtual & 0xF0000000) == BEPIu &&
320 ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
321
322 if (valid != 0) {
323
324 ctx->raddr = (*BATl & 0xF0000000) |
325 ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
326 (virtual & 0x0001F000);
327
328 ctx->prot = prot;
329 ret = check_prot(ctx->prot, access_type);
330 if (ret == 0) {
331 qemu_log_mask(CPU_LOG_MMU, "BAT %d match: r " TARGET_FMT_plx
332 " prot=%c%c\n", i, ctx->raddr,
333 ctx->prot & PAGE_READ ? 'R' : '-',
334 ctx->prot & PAGE_WRITE ? 'W' : '-');
335 }
336 break;
337 }
338 }
339 }
340 if (ret < 0) {
341 if (qemu_log_enabled()) {
342 qemu_log_mask(CPU_LOG_MMU, "no BAT match for "
343 TARGET_FMT_lx ":\n", virtual);
344 for (i = 0; i < 4; i++) {
345 BATu = &BATut[i];
346 BATl = &BATlt[i];
347 BEPIu = *BATu & 0xF0000000;
348 BEPIl = *BATu & 0x0FFE0000;
349 bl = (*BATu & 0x00001FFC) << 15;
350 qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT%d v "
351 TARGET_FMT_lx " BATu " TARGET_FMT_lx
352 " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
353 TARGET_FMT_lx " " TARGET_FMT_lx "\n",
354 __func__, ifetch ? 'I' : 'D', i, virtual,
355 *BATu, *BATl, BEPIu, BEPIl, bl);
356 }
357 }
358 }
359
360 return ret;
361}
362
363
364static int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
365 target_ulong eaddr, MMUAccessType access_type,
366 int type)
367{
368 PowerPCCPU *cpu = env_archcpu(env);
369 hwaddr hash;
370 target_ulong vsid;
371 int ds, target_page_bits;
372 bool pr;
373 int ret;
374 target_ulong sr, pgidx;
375
376 pr = FIELD_EX64(env->msr, MSR, PR);
377 ctx->eaddr = eaddr;
378
379 sr = env->sr[eaddr >> 28];
380 ctx->key = (((sr & 0x20000000) && pr) ||
381 ((sr & 0x40000000) && !pr)) ? 1 : 0;
382 ds = sr & 0x80000000 ? 1 : 0;
383 ctx->nx = sr & 0x10000000 ? 1 : 0;
384 vsid = sr & 0x00FFFFFF;
385 target_page_bits = TARGET_PAGE_BITS;
386 qemu_log_mask(CPU_LOG_MMU,
387 "Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx
388 " nip=" TARGET_FMT_lx " lr=" TARGET_FMT_lx
389 " ir=%d dr=%d pr=%d %d t=%d\n",
390 eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr,
391 (int)FIELD_EX64(env->msr, MSR, IR),
392 (int)FIELD_EX64(env->msr, MSR, DR), pr ? 1 : 0,
393 access_type == MMU_DATA_STORE, type);
394 pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits;
395 hash = vsid ^ pgidx;
396 ctx->ptem = (vsid << 7) | (pgidx >> 10);
397
398 qemu_log_mask(CPU_LOG_MMU,
399 "pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n",
400 ctx->key, ds, ctx->nx, vsid);
401 ret = -1;
402 if (!ds) {
403
404 if (type != ACCESS_CODE || ctx->nx == 0) {
405
406 qemu_log_mask(CPU_LOG_MMU, "htab_base " TARGET_FMT_plx
407 " htab_mask " TARGET_FMT_plx
408 " hash " TARGET_FMT_plx "\n",
409 ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash);
410 ctx->hash[0] = hash;
411 ctx->hash[1] = ~hash;
412
413
414 ctx->raddr = (hwaddr)-1ULL;
415
416 ret = ppc6xx_tlb_check(env, ctx, eaddr, access_type);
417#if defined(DUMP_PAGE_TABLES)
418 if (qemu_loglevel_mask(CPU_LOG_MMU)) {
419 CPUState *cs = env_cpu(env);
420 hwaddr curaddr;
421 uint32_t a0, a1, a2, a3;
422
423 qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx
424 "\n", ppc_hash32_hpt_base(cpu),
425 ppc_hash32_hpt_mask(cpu) + 0x80);
426 for (curaddr = ppc_hash32_hpt_base(cpu);
427 curaddr < (ppc_hash32_hpt_base(cpu)
428 + ppc_hash32_hpt_mask(cpu) + 0x80);
429 curaddr += 16) {
430 a0 = ldl_phys(cs->as, curaddr);
431 a1 = ldl_phys(cs->as, curaddr + 4);
432 a2 = ldl_phys(cs->as, curaddr + 8);
433 a3 = ldl_phys(cs->as, curaddr + 12);
434 if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
435 qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n",
436 curaddr, a0, a1, a2, a3);
437 }
438 }
439 }
440#endif
441 } else {
442 qemu_log_mask(CPU_LOG_MMU, "No access allowed\n");
443 ret = -3;
444 }
445 } else {
446 qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
447
448
449 switch (type) {
450 case ACCESS_INT:
451
452 break;
453 case ACCESS_CODE:
454
455 return -4;
456 case ACCESS_FLOAT:
457
458 return -4;
459 case ACCESS_RES:
460
461 return -4;
462 case ACCESS_CACHE:
463
464
465
466
467
468
469 ctx->raddr = eaddr;
470 return 0;
471 case ACCESS_EXT:
472
473 return -4;
474 default:
475 qemu_log_mask(CPU_LOG_MMU, "ERROR: instruction should not need "
476 "address translation\n");
477 return -4;
478 }
479 if ((access_type == MMU_DATA_STORE || ctx->key != 1) &&
480 (access_type == MMU_DATA_LOAD || ctx->key != 0)) {
481 ctx->raddr = eaddr;
482 ret = 2;
483 } else {
484 ret = -2;
485 }
486 }
487
488 return ret;
489}
490
491
492int ppcemb_tlb_check(CPUPPCState *env, ppcemb_tlb_t *tlb,
493 hwaddr *raddrp,
494 target_ulong address, uint32_t pid, int ext,
495 int i)
496{
497 target_ulong mask;
498
499
500 if (!(tlb->prot & PAGE_VALID)) {
501 return -1;
502 }
503 mask = ~(tlb->size - 1);
504 qemu_log_mask(CPU_LOG_MMU, "%s: TLB %d address " TARGET_FMT_lx
505 " PID %u <=> " TARGET_FMT_lx " " TARGET_FMT_lx " %u %x\n",
506 __func__, i, address, pid, tlb->EPN,
507 mask, (uint32_t)tlb->PID, tlb->prot);
508
509 if (tlb->PID != 0 && tlb->PID != pid) {
510 return -1;
511 }
512
513 if ((address & mask) != tlb->EPN) {
514 return -1;
515 }
516 *raddrp = (tlb->RPN & mask) | (address & ~mask);
517 if (ext) {
518
519 *raddrp |= (uint64_t)(tlb->RPN & 0xF) << 32;
520 }
521
522 return 0;
523}
524
525static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
526 target_ulong address,
527 MMUAccessType access_type)
528{
529 ppcemb_tlb_t *tlb;
530 hwaddr raddr;
531 int i, ret, zsel, zpr, pr;
532
533 ret = -1;
534 raddr = (hwaddr)-1ULL;
535 pr = FIELD_EX64(env->msr, MSR, PR);
536 for (i = 0; i < env->nb_tlb; i++) {
537 tlb = &env->tlb.tlbe[i];
538 if (ppcemb_tlb_check(env, tlb, &raddr, address,
539 env->spr[SPR_40x_PID], 0, i) < 0) {
540 continue;
541 }
542 zsel = (tlb->attr >> 4) & 0xF;
543 zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3;
544 qemu_log_mask(CPU_LOG_MMU,
545 "%s: TLB %d zsel %d zpr %d ty %d attr %08x\n",
546 __func__, i, zsel, zpr, access_type, tlb->attr);
547
548 switch (zpr) {
549 case 0x2:
550 if (pr != 0) {
551 goto check_perms;
552 }
553
554 case 0x3:
555
556 ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
557 ret = 0;
558 break;
559 case 0x0:
560 if (pr != 0) {
561
562 env->spr[SPR_40x_ESR] = 1 << 22;
563 ctx->prot = 0;
564 ret = -2;
565 break;
566 }
567
568 case 0x1:
569 check_perms:
570
571 ctx->prot = tlb->prot;
572 ret = check_prot(ctx->prot, access_type);
573 if (ret == -2) {
574 env->spr[SPR_40x_ESR] = 0;
575 }
576 break;
577 }
578 if (ret >= 0) {
579 ctx->raddr = raddr;
580 qemu_log_mask(CPU_LOG_MMU, "%s: access granted " TARGET_FMT_lx
581 " => " TARGET_FMT_plx
582 " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
583 ret);
584 return 0;
585 }
586 }
587 qemu_log_mask(CPU_LOG_MMU, "%s: access refused " TARGET_FMT_lx
588 " => " TARGET_FMT_plx
589 " %d %d\n", __func__, address, raddr, ctx->prot, ret);
590
591 return ret;
592}
593
594static int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb,
595 hwaddr *raddr, int *prot, target_ulong address,
596 MMUAccessType access_type, int i)
597{
598 int prot2;
599
600 if (ppcemb_tlb_check(env, tlb, raddr, address,
601 env->spr[SPR_BOOKE_PID],
602 !env->nb_pids, i) >= 0) {
603 goto found_tlb;
604 }
605
606 if (env->spr[SPR_BOOKE_PID1] &&
607 ppcemb_tlb_check(env, tlb, raddr, address,
608 env->spr[SPR_BOOKE_PID1], 0, i) >= 0) {
609 goto found_tlb;
610 }
611
612 if (env->spr[SPR_BOOKE_PID2] &&
613 ppcemb_tlb_check(env, tlb, raddr, address,
614 env->spr[SPR_BOOKE_PID2], 0, i) >= 0) {
615 goto found_tlb;
616 }
617
618 qemu_log_mask(CPU_LOG_MMU, "%s: TLB entry not found\n", __func__);
619 return -1;
620
621found_tlb:
622
623 if (FIELD_EX64(env->msr, MSR, PR)) {
624 prot2 = tlb->prot & 0xF;
625 } else {
626 prot2 = (tlb->prot >> 4) & 0xF;
627 }
628
629
630 if ((access_type == MMU_INST_FETCH ?
631 FIELD_EX64(env->msr, MSR, IR) :
632 FIELD_EX64(env->msr, MSR, DR)) != (tlb->attr & 1)) {
633 qemu_log_mask(CPU_LOG_MMU, "%s: AS doesn't match\n", __func__);
634 return -1;
635 }
636
637 *prot = prot2;
638 if (prot2 & prot_for_access_type(access_type)) {
639 qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
640 return 0;
641 }
642
643 qemu_log_mask(CPU_LOG_MMU, "%s: no prot match: %x\n", __func__, prot2);
644 return access_type == MMU_INST_FETCH ? -3 : -2;
645}
646
647static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
648 target_ulong address,
649 MMUAccessType access_type)
650{
651 ppcemb_tlb_t *tlb;
652 hwaddr raddr;
653 int i, ret;
654
655 ret = -1;
656 raddr = (hwaddr)-1ULL;
657 for (i = 0; i < env->nb_tlb; i++) {
658 tlb = &env->tlb.tlbe[i];
659 ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address,
660 access_type, i);
661 if (ret != -1) {
662 break;
663 }
664 }
665
666 if (ret >= 0) {
667 ctx->raddr = raddr;
668 qemu_log_mask(CPU_LOG_MMU, "%s: access granted " TARGET_FMT_lx
669 " => " TARGET_FMT_plx " %d %d\n", __func__,
670 address, ctx->raddr, ctx->prot, ret);
671 } else {
672 qemu_log_mask(CPU_LOG_MMU, "%s: access refused " TARGET_FMT_lx
673 " => " TARGET_FMT_plx " %d %d\n", __func__,
674 address, raddr, ctx->prot, ret);
675 }
676
677 return ret;
678}
679
680hwaddr booke206_tlb_to_page_size(CPUPPCState *env,
681 ppcmas_tlb_t *tlb)
682{
683 int tlbm_size;
684
685 tlbm_size = (tlb->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
686
687 return 1024ULL << tlbm_size;
688}
689
690
691int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb,
692 hwaddr *raddrp, target_ulong address,
693 uint32_t pid)
694{
695 hwaddr mask;
696 uint32_t tlb_pid;
697
698 if (!FIELD_EX64(env->msr, MSR, CM)) {
699
700 address = (uint32_t)address;
701 }
702
703
704 if (!(tlb->mas1 & MAS1_VALID)) {
705 return -1;
706 }
707
708 mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
709 qemu_log_mask(CPU_LOG_MMU, "%s: TLB ADDR=0x" TARGET_FMT_lx
710 " PID=0x%x MAS1=0x%x MAS2=0x%" PRIx64 " mask=0x%"
711 HWADDR_PRIx " MAS7_3=0x%" PRIx64 " MAS8=0x%" PRIx32 "\n",
712 __func__, address, pid, tlb->mas1, tlb->mas2, mask,
713 tlb->mas7_3, tlb->mas8);
714
715
716 tlb_pid = (tlb->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT;
717 if (tlb_pid != 0 && tlb_pid != pid) {
718 return -1;
719 }
720
721
722 if ((address & mask) != (tlb->mas2 & MAS2_EPN_MASK)) {
723 return -1;
724 }
725
726 if (raddrp) {
727 *raddrp = (tlb->mas7_3 & mask) | (address & ~mask);
728 }
729
730 return 0;
731}
732
733static bool is_epid_mmu(int mmu_idx)
734{
735 return mmu_idx == PPC_TLB_EPID_STORE || mmu_idx == PPC_TLB_EPID_LOAD;
736}
737
738static uint32_t mmubooke206_esr(int mmu_idx, MMUAccessType access_type)
739{
740 uint32_t esr = 0;
741 if (access_type == MMU_DATA_STORE) {
742 esr |= ESR_ST;
743 }
744 if (is_epid_mmu(mmu_idx)) {
745 esr |= ESR_EPID;
746 }
747 return esr;
748}
749
750
751
752
753
754
755
756
757
758static bool mmubooke206_get_as(CPUPPCState *env,
759 int mmu_idx, uint32_t *epid_out,
760 bool *as_out, bool *pr_out)
761{
762 if (is_epid_mmu(mmu_idx)) {
763 uint32_t epidr;
764 if (mmu_idx == PPC_TLB_EPID_STORE) {
765 epidr = env->spr[SPR_BOOKE_EPSC];
766 } else {
767 epidr = env->spr[SPR_BOOKE_EPLC];
768 }
769 *epid_out = (epidr & EPID_EPID) >> EPID_EPID_SHIFT;
770 *as_out = !!(epidr & EPID_EAS);
771 *pr_out = !!(epidr & EPID_EPR);
772 return true;
773 } else {
774 *as_out = FIELD_EX64(env->msr, MSR, DS);
775 *pr_out = FIELD_EX64(env->msr, MSR, PR);
776 return false;
777 }
778}
779
780
781static int mmubooke206_check_tlb(CPUPPCState *env, ppcmas_tlb_t *tlb,
782 hwaddr *raddr, int *prot,
783 target_ulong address,
784 MMUAccessType access_type, int mmu_idx)
785{
786 int prot2 = 0;
787 uint32_t epid;
788 bool as, pr;
789 bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr);
790
791 if (!use_epid) {
792 if (ppcmas_tlb_check(env, tlb, raddr, address,
793 env->spr[SPR_BOOKE_PID]) >= 0) {
794 goto found_tlb;
795 }
796
797 if (env->spr[SPR_BOOKE_PID1] &&
798 ppcmas_tlb_check(env, tlb, raddr, address,
799 env->spr[SPR_BOOKE_PID1]) >= 0) {
800 goto found_tlb;
801 }
802
803 if (env->spr[SPR_BOOKE_PID2] &&
804 ppcmas_tlb_check(env, tlb, raddr, address,
805 env->spr[SPR_BOOKE_PID2]) >= 0) {
806 goto found_tlb;
807 }
808 } else {
809 if (ppcmas_tlb_check(env, tlb, raddr, address, epid) >= 0) {
810 goto found_tlb;
811 }
812 }
813
814 qemu_log_mask(CPU_LOG_MMU, "%s: TLB entry not found\n", __func__);
815 return -1;
816
817found_tlb:
818
819 if (pr) {
820 if (tlb->mas7_3 & MAS3_UR) {
821 prot2 |= PAGE_READ;
822 }
823 if (tlb->mas7_3 & MAS3_UW) {
824 prot2 |= PAGE_WRITE;
825 }
826 if (tlb->mas7_3 & MAS3_UX) {
827 prot2 |= PAGE_EXEC;
828 }
829 } else {
830 if (tlb->mas7_3 & MAS3_SR) {
831 prot2 |= PAGE_READ;
832 }
833 if (tlb->mas7_3 & MAS3_SW) {
834 prot2 |= PAGE_WRITE;
835 }
836 if (tlb->mas7_3 & MAS3_SX) {
837 prot2 |= PAGE_EXEC;
838 }
839 }
840
841
842 if (access_type == MMU_INST_FETCH) {
843
844 assert(!use_epid);
845 as = FIELD_EX64(env->msr, MSR, IR);
846 }
847
848 if (as != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
849 qemu_log_mask(CPU_LOG_MMU, "%s: AS doesn't match\n", __func__);
850 return -1;
851 }
852
853 *prot = prot2;
854 if (prot2 & prot_for_access_type(access_type)) {
855 qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
856 return 0;
857 }
858
859 qemu_log_mask(CPU_LOG_MMU, "%s: no prot match: %x\n", __func__, prot2);
860 return access_type == MMU_INST_FETCH ? -3 : -2;
861}
862
863static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
864 target_ulong address,
865 MMUAccessType access_type,
866 int mmu_idx)
867{
868 ppcmas_tlb_t *tlb;
869 hwaddr raddr;
870 int i, j, ret;
871
872 ret = -1;
873 raddr = (hwaddr)-1ULL;
874
875 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
876 int ways = booke206_tlb_ways(env, i);
877
878 for (j = 0; j < ways; j++) {
879 tlb = booke206_get_tlbm(env, i, address, j);
880 if (!tlb) {
881 continue;
882 }
883 ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address,
884 access_type, mmu_idx);
885 if (ret != -1) {
886 goto found_tlb;
887 }
888 }
889 }
890
891found_tlb:
892
893 if (ret >= 0) {
894 ctx->raddr = raddr;
895 qemu_log_mask(CPU_LOG_MMU, "%s: access granted " TARGET_FMT_lx
896 " => " TARGET_FMT_plx " %d %d\n", __func__, address,
897 ctx->raddr, ctx->prot, ret);
898 } else {
899 qemu_log_mask(CPU_LOG_MMU, "%s: access refused " TARGET_FMT_lx
900 " => " TARGET_FMT_plx " %d %d\n", __func__, address,
901 raddr, ctx->prot, ret);
902 }
903
904 return ret;
905}
906
907static const char *book3e_tsize_to_str[32] = {
908 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
909 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
910 "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G",
911 "1T", "2T"
912};
913
914static void mmubooke_dump_mmu(CPUPPCState *env)
915{
916 ppcemb_tlb_t *entry;
917 int i;
918
919 if (kvm_enabled() && !env->kvm_sw_tlb) {
920 qemu_printf("Cannot access KVM TLB\n");
921 return;
922 }
923
924 qemu_printf("\nTLB:\n");
925 qemu_printf("Effective Physical Size PID Prot "
926 "Attr\n");
927
928 entry = &env->tlb.tlbe[0];
929 for (i = 0; i < env->nb_tlb; i++, entry++) {
930 hwaddr ea, pa;
931 target_ulong mask;
932 uint64_t size = (uint64_t)entry->size;
933 char size_buf[20];
934
935
936 if (!(entry->prot & PAGE_VALID)) {
937 continue;
938 }
939
940 mask = ~(entry->size - 1);
941 ea = entry->EPN & mask;
942 pa = entry->RPN & mask;
943
944 pa |= (hwaddr)(entry->RPN & 0xF) << 32;
945 if (size >= 1 * MiB) {
946 snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "M", size / MiB);
947 } else {
948 snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "k", size / KiB);
949 }
950 qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %s %-5u %08x %08x\n",
951 (uint64_t)ea, (uint64_t)pa, size_buf, (uint32_t)entry->PID,
952 entry->prot, entry->attr);
953 }
954
955}
956
957static void mmubooke206_dump_one_tlb(CPUPPCState *env, int tlbn, int offset,
958 int tlbsize)
959{
960 ppcmas_tlb_t *entry;
961 int i;
962
963 qemu_printf("\nTLB%d:\n", tlbn);
964 qemu_printf("Effective Physical Size TID TS SRWX"
965 " URWX WIMGE U0123\n");
966
967 entry = &env->tlb.tlbm[offset];
968 for (i = 0; i < tlbsize; i++, entry++) {
969 hwaddr ea, pa, size;
970 int tsize;
971
972 if (!(entry->mas1 & MAS1_VALID)) {
973 continue;
974 }
975
976 tsize = (entry->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
977 size = 1024ULL << tsize;
978 ea = entry->mas2 & ~(size - 1);
979 pa = entry->mas7_3 & ~(size - 1);
980
981 qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u S%c%c%c"
982 "U%c%c%c %c%c%c%c%c U%c%c%c%c\n",
983 (uint64_t)ea, (uint64_t)pa,
984 book3e_tsize_to_str[tsize],
985 (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT,
986 (entry->mas1 & MAS1_TS) >> MAS1_TS_SHIFT,
987 entry->mas7_3 & MAS3_SR ? 'R' : '-',
988 entry->mas7_3 & MAS3_SW ? 'W' : '-',
989 entry->mas7_3 & MAS3_SX ? 'X' : '-',
990 entry->mas7_3 & MAS3_UR ? 'R' : '-',
991 entry->mas7_3 & MAS3_UW ? 'W' : '-',
992 entry->mas7_3 & MAS3_UX ? 'X' : '-',
993 entry->mas2 & MAS2_W ? 'W' : '-',
994 entry->mas2 & MAS2_I ? 'I' : '-',
995 entry->mas2 & MAS2_M ? 'M' : '-',
996 entry->mas2 & MAS2_G ? 'G' : '-',
997 entry->mas2 & MAS2_E ? 'E' : '-',
998 entry->mas7_3 & MAS3_U0 ? '0' : '-',
999 entry->mas7_3 & MAS3_U1 ? '1' : '-',
1000 entry->mas7_3 & MAS3_U2 ? '2' : '-',
1001 entry->mas7_3 & MAS3_U3 ? '3' : '-');
1002 }
1003}
1004
1005static void mmubooke206_dump_mmu(CPUPPCState *env)
1006{
1007 int offset = 0;
1008 int i;
1009
1010 if (kvm_enabled() && !env->kvm_sw_tlb) {
1011 qemu_printf("Cannot access KVM TLB\n");
1012 return;
1013 }
1014
1015 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
1016 int size = booke206_tlb_size(env, i);
1017
1018 if (size == 0) {
1019 continue;
1020 }
1021
1022 mmubooke206_dump_one_tlb(env, i, offset, size);
1023 offset += size;
1024 }
1025}
1026
1027static void mmu6xx_dump_BATs(CPUPPCState *env, int type)
1028{
1029 target_ulong *BATlt, *BATut, *BATu, *BATl;
1030 target_ulong BEPIl, BEPIu, bl;
1031 int i;
1032
1033 switch (type) {
1034 case ACCESS_CODE:
1035 BATlt = env->IBAT[1];
1036 BATut = env->IBAT[0];
1037 break;
1038 default:
1039 BATlt = env->DBAT[1];
1040 BATut = env->DBAT[0];
1041 break;
1042 }
1043
1044 for (i = 0; i < env->nb_BATs; i++) {
1045 BATu = &BATut[i];
1046 BATl = &BATlt[i];
1047 BEPIu = *BATu & 0xF0000000;
1048 BEPIl = *BATu & 0x0FFE0000;
1049 bl = (*BATu & 0x00001FFC) << 15;
1050 qemu_printf("%s BAT%d BATu " TARGET_FMT_lx
1051 " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
1052 TARGET_FMT_lx " " TARGET_FMT_lx "\n",
1053 type == ACCESS_CODE ? "code" : "data", i,
1054 *BATu, *BATl, BEPIu, BEPIl, bl);
1055 }
1056}
1057
1058static void mmu6xx_dump_mmu(CPUPPCState *env)
1059{
1060 PowerPCCPU *cpu = env_archcpu(env);
1061 ppc6xx_tlb_t *tlb;
1062 target_ulong sr;
1063 int type, way, entry, i;
1064
1065 qemu_printf("HTAB base = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_base(cpu));
1066 qemu_printf("HTAB mask = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_mask(cpu));
1067
1068 qemu_printf("\nSegment registers:\n");
1069 for (i = 0; i < 32; i++) {
1070 sr = env->sr[i];
1071 if (sr & 0x80000000) {
1072 qemu_printf("%02d T=%d Ks=%d Kp=%d BUID=0x%03x "
1073 "CNTLR_SPEC=0x%05x\n", i,
1074 sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
1075 sr & 0x20000000 ? 1 : 0, (uint32_t)((sr >> 20) & 0x1FF),
1076 (uint32_t)(sr & 0xFFFFF));
1077 } else {
1078 qemu_printf("%02d T=%d Ks=%d Kp=%d N=%d VSID=0x%06x\n", i,
1079 sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
1080 sr & 0x20000000 ? 1 : 0, sr & 0x10000000 ? 1 : 0,
1081 (uint32_t)(sr & 0x00FFFFFF));
1082 }
1083 }
1084
1085 qemu_printf("\nBATs:\n");
1086 mmu6xx_dump_BATs(env, ACCESS_INT);
1087 mmu6xx_dump_BATs(env, ACCESS_CODE);
1088
1089 if (env->id_tlbs != 1) {
1090 qemu_printf("ERROR: 6xx MMU should have separated TLB"
1091 " for code and data\n");
1092 }
1093
1094 qemu_printf("\nTLBs [EPN EPN + SIZE]\n");
1095
1096 for (type = 0; type < 2; type++) {
1097 for (way = 0; way < env->nb_ways; way++) {
1098 for (entry = env->nb_tlb * type + env->tlb_per_way * way;
1099 entry < (env->nb_tlb * type + env->tlb_per_way * (way + 1));
1100 entry++) {
1101
1102 tlb = &env->tlb.tlb6[entry];
1103 qemu_printf("%s TLB %02d/%02d way:%d %s ["
1104 TARGET_FMT_lx " " TARGET_FMT_lx "]\n",
1105 type ? "code" : "data", entry % env->nb_tlb,
1106 env->nb_tlb, way,
1107 pte_is_valid(tlb->pte0) ? "valid" : "inval",
1108 tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE);
1109 }
1110 }
1111 }
1112}
1113
1114void dump_mmu(CPUPPCState *env)
1115{
1116 switch (env->mmu_model) {
1117 case POWERPC_MMU_BOOKE:
1118 mmubooke_dump_mmu(env);
1119 break;
1120 case POWERPC_MMU_BOOKE206:
1121 mmubooke206_dump_mmu(env);
1122 break;
1123 case POWERPC_MMU_SOFT_6xx:
1124 mmu6xx_dump_mmu(env);
1125 break;
1126#if defined(TARGET_PPC64)
1127 case POWERPC_MMU_64B:
1128 case POWERPC_MMU_2_03:
1129 case POWERPC_MMU_2_06:
1130 case POWERPC_MMU_2_07:
1131 dump_slb(env_archcpu(env));
1132 break;
1133 case POWERPC_MMU_3_00:
1134 if (ppc64_v3_radix(env_archcpu(env))) {
1135 qemu_log_mask(LOG_UNIMP, "%s: the PPC64 MMU is unsupported\n",
1136 __func__);
1137 } else {
1138 dump_slb(env_archcpu(env));
1139 }
1140 break;
1141#endif
1142 default:
1143 qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__);
1144 }
1145}
1146
1147static int check_physical(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr,
1148 MMUAccessType access_type)
1149{
1150 ctx->raddr = eaddr;
1151 ctx->prot = PAGE_READ | PAGE_EXEC;
1152
1153 switch (env->mmu_model) {
1154 case POWERPC_MMU_SOFT_6xx:
1155 case POWERPC_MMU_SOFT_4xx:
1156 case POWERPC_MMU_REAL:
1157 case POWERPC_MMU_BOOKE:
1158 ctx->prot |= PAGE_WRITE;
1159 break;
1160
1161 default:
1162
1163 g_assert_not_reached();
1164 }
1165
1166 return 0;
1167}
1168
1169int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
1170 target_ulong eaddr,
1171 MMUAccessType access_type, int type,
1172 int mmu_idx)
1173{
1174 int ret = -1;
1175 bool real_mode = (type == ACCESS_CODE && !FIELD_EX64(env->msr, MSR, IR)) ||
1176 (type != ACCESS_CODE && !FIELD_EX64(env->msr, MSR, DR));
1177
1178 switch (env->mmu_model) {
1179 case POWERPC_MMU_SOFT_6xx:
1180 if (real_mode) {
1181 ret = check_physical(env, ctx, eaddr, access_type);
1182 } else {
1183
1184 if (env->nb_BATs != 0) {
1185 ret = get_bat_6xx_tlb(env, ctx, eaddr, access_type);
1186 }
1187 if (ret < 0) {
1188
1189 ret = get_segment_6xx_tlb(env, ctx, eaddr, access_type, type);
1190 }
1191 }
1192 break;
1193
1194 case POWERPC_MMU_SOFT_4xx:
1195 if (real_mode) {
1196 ret = check_physical(env, ctx, eaddr, access_type);
1197 } else {
1198 ret = mmu40x_get_physical_address(env, ctx, eaddr, access_type);
1199 }
1200 break;
1201 case POWERPC_MMU_BOOKE:
1202 ret = mmubooke_get_physical_address(env, ctx, eaddr, access_type);
1203 break;
1204 case POWERPC_MMU_BOOKE206:
1205 ret = mmubooke206_get_physical_address(env, ctx, eaddr, access_type,
1206 mmu_idx);
1207 break;
1208 case POWERPC_MMU_MPC8xx:
1209
1210 cpu_abort(env_cpu(env), "MPC8xx MMU model is not implemented\n");
1211 break;
1212 case POWERPC_MMU_REAL:
1213 if (real_mode) {
1214 ret = check_physical(env, ctx, eaddr, access_type);
1215 } else {
1216 cpu_abort(env_cpu(env),
1217 "PowerPC in real mode do not do any translation\n");
1218 }
1219 return -1;
1220 default:
1221 cpu_abort(env_cpu(env), "Unknown or invalid MMU model\n");
1222 return -1;
1223 }
1224
1225 return ret;
1226}
1227
1228static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
1229 MMUAccessType access_type, int mmu_idx)
1230{
1231 uint32_t epid;
1232 bool as, pr;
1233 uint32_t missed_tid = 0;
1234 bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr);
1235
1236 if (access_type == MMU_INST_FETCH) {
1237 as = FIELD_EX64(env->msr, MSR, IR);
1238 }
1239 env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
1240 env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK;
1241 env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK;
1242 env->spr[SPR_BOOKE_MAS3] = 0;
1243 env->spr[SPR_BOOKE_MAS6] = 0;
1244 env->spr[SPR_BOOKE_MAS7] = 0;
1245
1246
1247 if (as) {
1248 env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
1249 env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS;
1250 }
1251
1252 env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID;
1253 env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK;
1254
1255 if (!use_epid) {
1256 switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) {
1257 case MAS4_TIDSELD_PID0:
1258 missed_tid = env->spr[SPR_BOOKE_PID];
1259 break;
1260 case MAS4_TIDSELD_PID1:
1261 missed_tid = env->spr[SPR_BOOKE_PID1];
1262 break;
1263 case MAS4_TIDSELD_PID2:
1264 missed_tid = env->spr[SPR_BOOKE_PID2];
1265 break;
1266 }
1267 env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16;
1268 } else {
1269 missed_tid = epid;
1270 env->spr[SPR_BOOKE_MAS6] |= missed_tid << 16;
1271 }
1272 env->spr[SPR_BOOKE_MAS1] |= (missed_tid << MAS1_TID_SHIFT);
1273
1274
1275
1276 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
1277 env->last_way++;
1278 env->last_way &= booke206_tlb_ways(env, 0) - 1;
1279 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
1280}
1281
1282
1283
1284static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
1285 MMUAccessType access_type,
1286 hwaddr *raddrp, int *psizep, int *protp,
1287 int mmu_idx, bool guest_visible)
1288{
1289 CPUState *cs = CPU(cpu);
1290 CPUPPCState *env = &cpu->env;
1291 mmu_ctx_t ctx;
1292 int type;
1293 int ret;
1294
1295 if (access_type == MMU_INST_FETCH) {
1296
1297 type = ACCESS_CODE;
1298 } else if (guest_visible) {
1299
1300 type = env->access_type;
1301 } else {
1302 type = ACCESS_INT;
1303 }
1304
1305 ret = get_physical_address_wtlb(env, &ctx, eaddr, access_type,
1306 type, mmu_idx);
1307 if (ret == 0) {
1308 *raddrp = ctx.raddr;
1309 *protp = ctx.prot;
1310 *psizep = TARGET_PAGE_BITS;
1311 return true;
1312 }
1313
1314 if (guest_visible) {
1315 log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
1316 if (type == ACCESS_CODE) {
1317 switch (ret) {
1318 case -1:
1319
1320 switch (env->mmu_model) {
1321 case POWERPC_MMU_SOFT_6xx:
1322 cs->exception_index = POWERPC_EXCP_IFTLB;
1323 env->error_code = 1 << 18;
1324 env->spr[SPR_IMISS] = eaddr;
1325 env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1326 goto tlb_miss;
1327 case POWERPC_MMU_SOFT_4xx:
1328 cs->exception_index = POWERPC_EXCP_ITLB;
1329 env->error_code = 0;
1330 env->spr[SPR_40x_DEAR] = eaddr;
1331 env->spr[SPR_40x_ESR] = 0x00000000;
1332 break;
1333 case POWERPC_MMU_BOOKE206:
1334 booke206_update_mas_tlb_miss(env, eaddr, 2, mmu_idx);
1335
1336 case POWERPC_MMU_BOOKE:
1337 cs->exception_index = POWERPC_EXCP_ITLB;
1338 env->error_code = 0;
1339 env->spr[SPR_BOOKE_DEAR] = eaddr;
1340 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, MMU_DATA_LOAD);
1341 break;
1342 case POWERPC_MMU_MPC8xx:
1343 cpu_abort(cs, "MPC8xx MMU model is not implemented\n");
1344 case POWERPC_MMU_REAL:
1345 cpu_abort(cs, "PowerPC in real mode should never raise "
1346 "any MMU exceptions\n");
1347 default:
1348 cpu_abort(cs, "Unknown or invalid MMU model\n");
1349 }
1350 break;
1351 case -2:
1352
1353 cs->exception_index = POWERPC_EXCP_ISI;
1354 if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1355 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1356 env->error_code = 0;
1357 } else {
1358 env->error_code = 0x08000000;
1359 }
1360 break;
1361 case -3:
1362
1363 if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1364 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1365 env->spr[SPR_BOOKE_ESR] = 0x00000000;
1366 env->error_code = 0;
1367 } else {
1368 env->error_code = 0x10000000;
1369 }
1370 cs->exception_index = POWERPC_EXCP_ISI;
1371 break;
1372 case -4:
1373
1374
1375 cs->exception_index = POWERPC_EXCP_ISI;
1376 if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1377 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1378 env->error_code = 0;
1379 } else {
1380 env->error_code = 0x10000000;
1381 }
1382 break;
1383 }
1384 } else {
1385 switch (ret) {
1386 case -1:
1387
1388 switch (env->mmu_model) {
1389 case POWERPC_MMU_SOFT_6xx:
1390 if (access_type == MMU_DATA_STORE) {
1391 cs->exception_index = POWERPC_EXCP_DSTLB;
1392 env->error_code = 1 << 16;
1393 } else {
1394 cs->exception_index = POWERPC_EXCP_DLTLB;
1395 env->error_code = 0;
1396 }
1397 env->spr[SPR_DMISS] = eaddr;
1398 env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
1399 tlb_miss:
1400 env->error_code |= ctx.key << 19;
1401 env->spr[SPR_HASH1] = ppc_hash32_hpt_base(cpu) +
1402 get_pteg_offset32(cpu, ctx.hash[0]);
1403 env->spr[SPR_HASH2] = ppc_hash32_hpt_base(cpu) +
1404 get_pteg_offset32(cpu, ctx.hash[1]);
1405 break;
1406 case POWERPC_MMU_SOFT_4xx:
1407 cs->exception_index = POWERPC_EXCP_DTLB;
1408 env->error_code = 0;
1409 env->spr[SPR_40x_DEAR] = eaddr;
1410 if (access_type == MMU_DATA_STORE) {
1411 env->spr[SPR_40x_ESR] = 0x00800000;
1412 } else {
1413 env->spr[SPR_40x_ESR] = 0x00000000;
1414 }
1415 break;
1416 case POWERPC_MMU_MPC8xx:
1417
1418 cpu_abort(cs, "MPC8xx MMU model is not implemented\n");
1419 case POWERPC_MMU_BOOKE206:
1420 booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
1421
1422 case POWERPC_MMU_BOOKE:
1423 cs->exception_index = POWERPC_EXCP_DTLB;
1424 env->error_code = 0;
1425 env->spr[SPR_BOOKE_DEAR] = eaddr;
1426 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1427 break;
1428 case POWERPC_MMU_REAL:
1429 cpu_abort(cs, "PowerPC in real mode should never raise "
1430 "any MMU exceptions\n");
1431 default:
1432 cpu_abort(cs, "Unknown or invalid MMU model\n");
1433 }
1434 break;
1435 case -2:
1436
1437 cs->exception_index = POWERPC_EXCP_DSI;
1438 env->error_code = 0;
1439 if (env->mmu_model == POWERPC_MMU_SOFT_4xx) {
1440 env->spr[SPR_40x_DEAR] = eaddr;
1441 if (access_type == MMU_DATA_STORE) {
1442 env->spr[SPR_40x_ESR] |= 0x00800000;
1443 }
1444 } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1445 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1446 env->spr[SPR_BOOKE_DEAR] = eaddr;
1447 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1448 } else {
1449 env->spr[SPR_DAR] = eaddr;
1450 if (access_type == MMU_DATA_STORE) {
1451 env->spr[SPR_DSISR] = 0x0A000000;
1452 } else {
1453 env->spr[SPR_DSISR] = 0x08000000;
1454 }
1455 }
1456 break;
1457 case -4:
1458
1459 switch (type) {
1460 case ACCESS_FLOAT:
1461
1462 cs->exception_index = POWERPC_EXCP_ALIGN;
1463 env->error_code = POWERPC_EXCP_ALIGN_FP;
1464 env->spr[SPR_DAR] = eaddr;
1465 break;
1466 case ACCESS_RES:
1467
1468 cs->exception_index = POWERPC_EXCP_DSI;
1469 env->error_code = 0;
1470 env->spr[SPR_DAR] = eaddr;
1471 if (access_type == MMU_DATA_STORE) {
1472 env->spr[SPR_DSISR] = 0x06000000;
1473 } else {
1474 env->spr[SPR_DSISR] = 0x04000000;
1475 }
1476 break;
1477 case ACCESS_EXT:
1478
1479 cs->exception_index = POWERPC_EXCP_DSI;
1480 env->error_code = 0;
1481 env->spr[SPR_DAR] = eaddr;
1482 if (access_type == MMU_DATA_STORE) {
1483 env->spr[SPR_DSISR] = 0x06100000;
1484 } else {
1485 env->spr[SPR_DSISR] = 0x04100000;
1486 }
1487 break;
1488 default:
1489 printf("DSI: invalid exception (%d)\n", ret);
1490 cs->exception_index = POWERPC_EXCP_PROGRAM;
1491 env->error_code =
1492 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
1493 env->spr[SPR_DAR] = eaddr;
1494 break;
1495 }
1496 break;
1497 }
1498 }
1499 }
1500 return false;
1501}
1502
1503
1504
1505bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
1506 hwaddr *raddrp, int *psizep, int *protp,
1507 int mmu_idx, bool guest_visible)
1508{
1509 switch (cpu->env.mmu_model) {
1510#if defined(TARGET_PPC64)
1511 case POWERPC_MMU_3_00:
1512 if (ppc64_v3_radix(cpu)) {
1513 return ppc_radix64_xlate(cpu, eaddr, access_type, raddrp,
1514 psizep, protp, mmu_idx, guest_visible);
1515 }
1516
1517 case POWERPC_MMU_64B:
1518 case POWERPC_MMU_2_03:
1519 case POWERPC_MMU_2_06:
1520 case POWERPC_MMU_2_07:
1521 return ppc_hash64_xlate(cpu, eaddr, access_type,
1522 raddrp, psizep, protp, mmu_idx, guest_visible);
1523#endif
1524
1525 case POWERPC_MMU_32B:
1526 return ppc_hash32_xlate(cpu, eaddr, access_type, raddrp,
1527 psizep, protp, mmu_idx, guest_visible);
1528
1529 default:
1530 return ppc_jumbo_xlate(cpu, eaddr, access_type, raddrp,
1531 psizep, protp, mmu_idx, guest_visible);
1532 }
1533}
1534
1535hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
1536{
1537 PowerPCCPU *cpu = POWERPC_CPU(cs);
1538 hwaddr raddr;
1539 int s, p;
1540
1541
1542
1543
1544
1545
1546 if (ppc_xlate(cpu, addr, MMU_DATA_LOAD, &raddr, &s, &p,
1547 cpu_mmu_index(&cpu->env, false), false) ||
1548 ppc_xlate(cpu, addr, MMU_INST_FETCH, &raddr, &s, &p,
1549 cpu_mmu_index(&cpu->env, true), false)) {
1550 return raddr & TARGET_PAGE_MASK;
1551 }
1552 return -1;
1553}
1554