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