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 #include "mmu-booke.h" 37 38 /* #define DUMP_PAGE_TABLES */ 39 40 /* Context used internally during MMU translations */ 41 typedef struct { 42 hwaddr raddr; /* Real address */ 43 hwaddr eaddr; /* Effective address */ 44 int prot; /* Protection bits */ 45 hwaddr hash[2]; /* Pagetable hash values */ 46 target_ulong ptem; /* Virtual segment ID | API */ 47 int key; /* Access key */ 48 int nx; /* Non-execute area */ 49 } mmu_ctx_t; 50 51 void ppc_store_sdr1(CPUPPCState *env, target_ulong value) 52 { 53 PowerPCCPU *cpu = env_archcpu(env); 54 qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value); 55 assert(!cpu->env.has_hv_mode || !cpu->vhyp); 56 #if defined(TARGET_PPC64) 57 if (mmu_is_64bit(env->mmu_model)) { 58 target_ulong sdr_mask = SDR_64_HTABORG | SDR_64_HTABSIZE; 59 target_ulong htabsize = value & SDR_64_HTABSIZE; 60 61 if (value & ~sdr_mask) { 62 qemu_log_mask(LOG_GUEST_ERROR, "Invalid bits 0x"TARGET_FMT_lx 63 " set in SDR1", value & ~sdr_mask); 64 value &= sdr_mask; 65 } 66 if (htabsize > 28) { 67 qemu_log_mask(LOG_GUEST_ERROR, "Invalid HTABSIZE 0x" TARGET_FMT_lx 68 " stored in SDR1", htabsize); 69 return; 70 } 71 } 72 #endif /* defined(TARGET_PPC64) */ 73 /* FIXME: Should check for valid HTABMASK values in 32-bit case */ 74 env->spr[SPR_SDR1] = value; 75 } 76 77 /*****************************************************************************/ 78 /* PowerPC MMU emulation */ 79 80 static int pp_check(int key, int pp, int nx) 81 { 82 int access; 83 84 /* Compute access rights */ 85 access = 0; 86 if (key == 0) { 87 switch (pp) { 88 case 0x0: 89 case 0x1: 90 case 0x2: 91 access |= PAGE_WRITE; 92 /* fall through */ 93 case 0x3: 94 access |= PAGE_READ; 95 break; 96 } 97 } else { 98 switch (pp) { 99 case 0x0: 100 access = 0; 101 break; 102 case 0x1: 103 case 0x3: 104 access = PAGE_READ; 105 break; 106 case 0x2: 107 access = PAGE_READ | PAGE_WRITE; 108 break; 109 } 110 } 111 if (nx == 0) { 112 access |= PAGE_EXEC; 113 } 114 115 return access; 116 } 117 118 int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr, 119 int way, int is_code) 120 { 121 int nr; 122 123 /* Select TLB num in a way from address */ 124 nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1); 125 /* Select TLB way */ 126 nr += env->tlb_per_way * way; 127 /* 6xx has separate TLBs for instructions and data */ 128 if (is_code) { 129 nr += env->nb_tlb; 130 } 131 132 return nr; 133 } 134 135 static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0, 136 target_ulong pte1, int h, 137 MMUAccessType access_type) 138 { 139 target_ulong ptem, mmask; 140 int access, ret, pteh, ptev, pp; 141 142 ret = -1; 143 /* Check validity and table match */ 144 ptev = pte_is_valid(pte0); 145 pteh = (pte0 >> 6) & 1; 146 if (ptev && h == pteh) { 147 /* Check vsid & api */ 148 ptem = pte0 & PTE_PTEM_MASK; 149 mmask = PTE_CHECK_MASK; 150 pp = pte1 & 0x00000003; 151 if (ptem == ctx->ptem) { 152 if (ctx->raddr != (hwaddr)-1ULL) { 153 /* all matches should have equal RPN, WIMG & PP */ 154 if ((ctx->raddr & mmask) != (pte1 & mmask)) { 155 qemu_log_mask(CPU_LOG_MMU, "Bad RPN/WIMG/PP\n"); 156 return -3; 157 } 158 } 159 /* Compute access rights */ 160 access = pp_check(ctx->key, pp, ctx->nx); 161 /* Keep the matching PTE information */ 162 ctx->raddr = pte1; 163 ctx->prot = access; 164 if (check_prot_access_type(ctx->prot, access_type)) { 165 /* Access granted */ 166 qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n"); 167 ret = 0; 168 } else { 169 /* Access right violation */ 170 qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n"); 171 ret = -2; 172 } 173 } 174 } 175 176 return ret; 177 } 178 179 static int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p, 180 int ret, MMUAccessType access_type) 181 { 182 int store = 0; 183 184 /* Update page flags */ 185 if (!(*pte1p & 0x00000100)) { 186 /* Update accessed flag */ 187 *pte1p |= 0x00000100; 188 store = 1; 189 } 190 if (!(*pte1p & 0x00000080)) { 191 if (access_type == MMU_DATA_STORE && ret == 0) { 192 /* Update changed flag */ 193 *pte1p |= 0x00000080; 194 store = 1; 195 } else { 196 /* Force page fault for first write access */ 197 ctx->prot &= ~PAGE_WRITE; 198 } 199 } 200 201 return store; 202 } 203 204 /* Software driven TLB helpers */ 205 206 static int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx, 207 target_ulong eaddr, MMUAccessType access_type) 208 { 209 ppc6xx_tlb_t *tlb; 210 int nr, best, way; 211 int ret; 212 213 best = -1; 214 ret = -1; /* No TLB found */ 215 for (way = 0; way < env->nb_ways; way++) { 216 nr = ppc6xx_tlb_getnum(env, eaddr, way, access_type == MMU_INST_FETCH); 217 tlb = &env->tlb.tlb6[nr]; 218 /* This test "emulates" the PTE index match for hardware TLBs */ 219 if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) { 220 qemu_log_mask(CPU_LOG_MMU, "TLB %d/%d %s [" TARGET_FMT_lx 221 " " TARGET_FMT_lx "] <> " TARGET_FMT_lx "\n", 222 nr, env->nb_tlb, 223 pte_is_valid(tlb->pte0) ? "valid" : "inval", 224 tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr); 225 continue; 226 } 227 qemu_log_mask(CPU_LOG_MMU, "TLB %d/%d %s " TARGET_FMT_lx " <> " 228 TARGET_FMT_lx " " TARGET_FMT_lx " %c %c\n", 229 nr, env->nb_tlb, 230 pte_is_valid(tlb->pte0) ? "valid" : "inval", 231 tlb->EPN, eaddr, tlb->pte1, 232 access_type == MMU_DATA_STORE ? 'S' : 'L', 233 access_type == MMU_INST_FETCH ? 'I' : 'D'); 234 switch (ppc6xx_tlb_pte_check(ctx, tlb->pte0, tlb->pte1, 235 0, access_type)) { 236 case -2: 237 /* Access violation */ 238 ret = -2; 239 best = nr; 240 break; 241 case -1: /* No match */ 242 case -3: /* TLB inconsistency */ 243 default: 244 break; 245 case 0: 246 /* access granted */ 247 /* 248 * XXX: we should go on looping to check all TLBs 249 * consistency but we can speed-up the whole thing as 250 * the result would be undefined if TLBs are not 251 * consistent. 252 */ 253 ret = 0; 254 best = nr; 255 goto done; 256 } 257 } 258 if (best != -1) { 259 done: 260 qemu_log_mask(CPU_LOG_MMU, "found TLB at addr " HWADDR_FMT_plx 261 " prot=%01x ret=%d\n", 262 ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret); 263 /* Update page flags */ 264 pte_update_flags(ctx, &env->tlb.tlb6[best].pte1, ret, access_type); 265 } 266 #if defined(DUMP_PAGE_TABLES) 267 if (qemu_loglevel_mask(CPU_LOG_MMU)) { 268 CPUState *cs = env_cpu(env); 269 hwaddr base = ppc_hash32_hpt_base(env_archcpu(env)); 270 hwaddr len = ppc_hash32_hpt_mask(env_archcpu(env)) + 0x80; 271 uint32_t a0, a1, a2, a3; 272 273 qemu_log("Page table: " HWADDR_FMT_plx " len " HWADDR_FMT_plx "\n", 274 base, len); 275 for (hwaddr curaddr = base; curaddr < base + len; curaddr += 16) { 276 a0 = ldl_phys(cs->as, curaddr); 277 a1 = ldl_phys(cs->as, curaddr + 4); 278 a2 = ldl_phys(cs->as, curaddr + 8); 279 a3 = ldl_phys(cs->as, curaddr + 12); 280 if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) { 281 qemu_log(HWADDR_FMT_plx ": %08x %08x %08x %08x\n", 282 curaddr, a0, a1, a2, a3); 283 } 284 } 285 } 286 #endif 287 return ret; 288 } 289 290 /* Perform BAT hit & translation */ 291 static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp, 292 int *validp, int *protp, target_ulong *BATu, 293 target_ulong *BATl) 294 { 295 target_ulong bl; 296 int pp, valid, prot; 297 298 bl = (*BATu & 0x00001FFC) << 15; 299 valid = 0; 300 prot = 0; 301 if ((!FIELD_EX64(env->msr, MSR, PR) && (*BATu & 0x00000002)) || 302 (FIELD_EX64(env->msr, MSR, PR) && (*BATu & 0x00000001))) { 303 valid = 1; 304 pp = *BATl & 0x00000003; 305 if (pp != 0) { 306 prot = PAGE_READ | PAGE_EXEC; 307 if (pp == 0x2) { 308 prot |= PAGE_WRITE; 309 } 310 } 311 } 312 *blp = bl; 313 *validp = valid; 314 *protp = prot; 315 } 316 317 static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, 318 target_ulong virtual, MMUAccessType access_type) 319 { 320 target_ulong *BATlt, *BATut, *BATu, *BATl; 321 target_ulong BEPIl, BEPIu, bl; 322 int i, valid, prot; 323 int ret = -1; 324 bool ifetch = access_type == MMU_INST_FETCH; 325 326 qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT v " TARGET_FMT_lx "\n", __func__, 327 ifetch ? 'I' : 'D', virtual); 328 if (ifetch) { 329 BATlt = env->IBAT[1]; 330 BATut = env->IBAT[0]; 331 } else { 332 BATlt = env->DBAT[1]; 333 BATut = env->DBAT[0]; 334 } 335 for (i = 0; i < env->nb_BATs; i++) { 336 BATu = &BATut[i]; 337 BATl = &BATlt[i]; 338 BEPIu = *BATu & 0xF0000000; 339 BEPIl = *BATu & 0x0FFE0000; 340 bat_size_prot(env, &bl, &valid, &prot, BATu, BATl); 341 qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT%d v " TARGET_FMT_lx " BATu " 342 TARGET_FMT_lx " BATl " TARGET_FMT_lx "\n", __func__, 343 ifetch ? 'I' : 'D', i, virtual, *BATu, *BATl); 344 if ((virtual & 0xF0000000) == BEPIu && 345 ((virtual & 0x0FFE0000) & ~bl) == BEPIl) { 346 /* BAT matches */ 347 if (valid != 0) { 348 /* Get physical address */ 349 ctx->raddr = (*BATl & 0xF0000000) | 350 ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) | 351 (virtual & 0x0001F000); 352 /* Compute access rights */ 353 ctx->prot = prot; 354 if (check_prot_access_type(ctx->prot, access_type)) { 355 qemu_log_mask(CPU_LOG_MMU, "BAT %d match: r " HWADDR_FMT_plx 356 " prot=%c%c\n", i, ctx->raddr, 357 ctx->prot & PAGE_READ ? 'R' : '-', 358 ctx->prot & PAGE_WRITE ? 'W' : '-'); 359 ret = 0; 360 } else { 361 ret = -2; 362 } 363 break; 364 } 365 } 366 } 367 if (ret < 0) { 368 if (qemu_log_enabled()) { 369 qemu_log_mask(CPU_LOG_MMU, "no BAT match for " 370 TARGET_FMT_lx ":\n", virtual); 371 for (i = 0; i < 4; i++) { 372 BATu = &BATut[i]; 373 BATl = &BATlt[i]; 374 BEPIu = *BATu & 0xF0000000; 375 BEPIl = *BATu & 0x0FFE0000; 376 bl = (*BATu & 0x00001FFC) << 15; 377 qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT%d v " TARGET_FMT_lx 378 " BATu " TARGET_FMT_lx " BATl " TARGET_FMT_lx 379 "\n\t" TARGET_FMT_lx " " TARGET_FMT_lx " " 380 TARGET_FMT_lx "\n", __func__, ifetch ? 'I' : 'D', 381 i, virtual, *BATu, *BATl, BEPIu, BEPIl, bl); 382 } 383 } 384 } 385 /* No hit */ 386 return ret; 387 } 388 389 static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, 390 target_ulong eaddr, 391 MMUAccessType access_type, int type) 392 { 393 PowerPCCPU *cpu = env_archcpu(env); 394 hwaddr hash; 395 target_ulong vsid, sr, pgidx; 396 int ds, target_page_bits; 397 bool pr; 398 399 /* First try to find a BAT entry if there are any */ 400 if (env->nb_BATs && get_bat_6xx_tlb(env, ctx, eaddr, access_type) == 0) { 401 return 0; 402 } 403 404 /* Perform segment based translation when no BATs matched */ 405 pr = FIELD_EX64(env->msr, MSR, PR); 406 ctx->eaddr = eaddr; 407 408 sr = env->sr[eaddr >> 28]; 409 ctx->key = (((sr & 0x20000000) && pr) || 410 ((sr & 0x40000000) && !pr)) ? 1 : 0; 411 ds = sr & 0x80000000 ? 1 : 0; 412 ctx->nx = sr & 0x10000000 ? 1 : 0; 413 vsid = sr & 0x00FFFFFF; 414 target_page_bits = TARGET_PAGE_BITS; 415 qemu_log_mask(CPU_LOG_MMU, 416 "Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx 417 " nip=" TARGET_FMT_lx " lr=" TARGET_FMT_lx 418 " ir=%d dr=%d pr=%d %d t=%d\n", 419 eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, 420 (int)FIELD_EX64(env->msr, MSR, IR), 421 (int)FIELD_EX64(env->msr, MSR, DR), pr ? 1 : 0, 422 access_type == MMU_DATA_STORE, type); 423 pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits; 424 hash = vsid ^ pgidx; 425 ctx->ptem = (vsid << 7) | (pgidx >> 10); 426 427 qemu_log_mask(CPU_LOG_MMU, "pte segment: key=%d ds %d nx %d vsid " 428 TARGET_FMT_lx "\n", ctx->key, ds, ctx->nx, vsid); 429 if (!ds) { 430 /* Check if instruction fetch is allowed, if needed */ 431 if (type == ACCESS_CODE && ctx->nx) { 432 qemu_log_mask(CPU_LOG_MMU, "No access allowed\n"); 433 return -3; 434 } 435 /* Page address translation */ 436 qemu_log_mask(CPU_LOG_MMU, "htab_base " HWADDR_FMT_plx " htab_mask " 437 HWADDR_FMT_plx " hash " HWADDR_FMT_plx "\n", 438 ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash); 439 ctx->hash[0] = hash; 440 ctx->hash[1] = ~hash; 441 442 /* Initialize real address with an invalid value */ 443 ctx->raddr = (hwaddr)-1ULL; 444 /* Software TLB search */ 445 return ppc6xx_tlb_check(env, ctx, eaddr, access_type); 446 } 447 448 /* Direct-store segment : absolutely *BUGGY* for now */ 449 qemu_log_mask(CPU_LOG_MMU, "direct store...\n"); 450 switch (type) { 451 case ACCESS_INT: 452 /* Integer load/store : only access allowed */ 453 break; 454 case ACCESS_CODE: 455 /* No code fetch is allowed in direct-store areas */ 456 return -4; 457 case ACCESS_FLOAT: 458 /* Floating point load/store */ 459 return -4; 460 case ACCESS_RES: 461 /* lwarx, ldarx or srwcx. */ 462 return -4; 463 case ACCESS_CACHE: 464 /* 465 * dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi 466 * 467 * Should make the instruction do no-op. As it already do 468 * no-op, it's quite easy :-) 469 */ 470 ctx->raddr = eaddr; 471 return 0; 472 case ACCESS_EXT: 473 /* eciwx or ecowx */ 474 return -4; 475 default: 476 qemu_log_mask(CPU_LOG_MMU, "ERROR: instruction should not need address" 477 " translation\n"); 478 return -4; 479 } 480 if ((access_type == MMU_DATA_STORE || ctx->key != 1) && 481 (access_type == MMU_DATA_LOAD || ctx->key != 0)) { 482 ctx->raddr = eaddr; 483 return 2; 484 } 485 return -2; 486 } 487 488 static const char *book3e_tsize_to_str[32] = { 489 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", 490 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", 491 "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G", 492 "1T", "2T" 493 }; 494 495 static void mmubooke_dump_mmu(CPUPPCState *env) 496 { 497 ppcemb_tlb_t *entry; 498 int i; 499 500 #ifdef CONFIG_KVM 501 if (kvm_enabled() && !env->kvm_sw_tlb) { 502 qemu_printf("Cannot access KVM TLB\n"); 503 return; 504 } 505 #endif 506 507 qemu_printf("\nTLB:\n"); 508 qemu_printf("Effective Physical Size PID Prot " 509 "Attr\n"); 510 511 entry = &env->tlb.tlbe[0]; 512 for (i = 0; i < env->nb_tlb; i++, entry++) { 513 hwaddr ea, pa; 514 target_ulong mask; 515 uint64_t size = (uint64_t)entry->size; 516 char size_buf[20]; 517 518 /* Check valid flag */ 519 if (!(entry->prot & PAGE_VALID)) { 520 continue; 521 } 522 523 mask = ~(entry->size - 1); 524 ea = entry->EPN & mask; 525 pa = entry->RPN & mask; 526 /* Extend the physical address to 36 bits */ 527 pa |= (hwaddr)(entry->RPN & 0xF) << 32; 528 if (size >= 1 * MiB) { 529 snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "M", size / MiB); 530 } else { 531 snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "k", size / KiB); 532 } 533 qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %s %-5u %08x %08x\n", 534 (uint64_t)ea, (uint64_t)pa, size_buf, (uint32_t)entry->PID, 535 entry->prot, entry->attr); 536 } 537 538 } 539 540 static void mmubooke206_dump_one_tlb(CPUPPCState *env, int tlbn, int offset, 541 int tlbsize) 542 { 543 ppcmas_tlb_t *entry; 544 int i; 545 546 qemu_printf("\nTLB%d:\n", tlbn); 547 qemu_printf("Effective Physical Size TID TS SRWX" 548 " URWX WIMGE U0123\n"); 549 550 entry = &env->tlb.tlbm[offset]; 551 for (i = 0; i < tlbsize; i++, entry++) { 552 hwaddr ea, pa, size; 553 int tsize; 554 555 if (!(entry->mas1 & MAS1_VALID)) { 556 continue; 557 } 558 559 tsize = (entry->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT; 560 size = 1024ULL << tsize; 561 ea = entry->mas2 & ~(size - 1); 562 pa = entry->mas7_3 & ~(size - 1); 563 564 qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u S%c%c%c" 565 " U%c%c%c %c%c%c%c%c U%c%c%c%c\n", 566 (uint64_t)ea, (uint64_t)pa, 567 book3e_tsize_to_str[tsize], 568 (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT, 569 (entry->mas1 & MAS1_TS) >> MAS1_TS_SHIFT, 570 entry->mas7_3 & MAS3_SR ? 'R' : '-', 571 entry->mas7_3 & MAS3_SW ? 'W' : '-', 572 entry->mas7_3 & MAS3_SX ? 'X' : '-', 573 entry->mas7_3 & MAS3_UR ? 'R' : '-', 574 entry->mas7_3 & MAS3_UW ? 'W' : '-', 575 entry->mas7_3 & MAS3_UX ? 'X' : '-', 576 entry->mas2 & MAS2_W ? 'W' : '-', 577 entry->mas2 & MAS2_I ? 'I' : '-', 578 entry->mas2 & MAS2_M ? 'M' : '-', 579 entry->mas2 & MAS2_G ? 'G' : '-', 580 entry->mas2 & MAS2_E ? 'E' : '-', 581 entry->mas7_3 & MAS3_U0 ? '0' : '-', 582 entry->mas7_3 & MAS3_U1 ? '1' : '-', 583 entry->mas7_3 & MAS3_U2 ? '2' : '-', 584 entry->mas7_3 & MAS3_U3 ? '3' : '-'); 585 } 586 } 587 588 static void mmubooke206_dump_mmu(CPUPPCState *env) 589 { 590 int offset = 0; 591 int i; 592 593 #ifdef CONFIG_KVM 594 if (kvm_enabled() && !env->kvm_sw_tlb) { 595 qemu_printf("Cannot access KVM TLB\n"); 596 return; 597 } 598 #endif 599 600 for (i = 0; i < BOOKE206_MAX_TLBN; i++) { 601 int size = booke206_tlb_size(env, i); 602 603 if (size == 0) { 604 continue; 605 } 606 607 mmubooke206_dump_one_tlb(env, i, offset, size); 608 offset += size; 609 } 610 } 611 612 static void mmu6xx_dump_BATs(CPUPPCState *env, int type) 613 { 614 target_ulong *BATlt, *BATut, *BATu, *BATl; 615 target_ulong BEPIl, BEPIu, bl; 616 int i; 617 618 switch (type) { 619 case ACCESS_CODE: 620 BATlt = env->IBAT[1]; 621 BATut = env->IBAT[0]; 622 break; 623 default: 624 BATlt = env->DBAT[1]; 625 BATut = env->DBAT[0]; 626 break; 627 } 628 629 for (i = 0; i < env->nb_BATs; i++) { 630 BATu = &BATut[i]; 631 BATl = &BATlt[i]; 632 BEPIu = *BATu & 0xF0000000; 633 BEPIl = *BATu & 0x0FFE0000; 634 bl = (*BATu & 0x00001FFC) << 15; 635 qemu_printf("%s BAT%d BATu " TARGET_FMT_lx 636 " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " " 637 TARGET_FMT_lx " " TARGET_FMT_lx "\n", 638 type == ACCESS_CODE ? "code" : "data", i, 639 *BATu, *BATl, BEPIu, BEPIl, bl); 640 } 641 } 642 643 static void mmu6xx_dump_mmu(CPUPPCState *env) 644 { 645 PowerPCCPU *cpu = env_archcpu(env); 646 ppc6xx_tlb_t *tlb; 647 target_ulong sr; 648 int type, way, entry, i; 649 650 qemu_printf("HTAB base = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_base(cpu)); 651 qemu_printf("HTAB mask = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_mask(cpu)); 652 653 qemu_printf("\nSegment registers:\n"); 654 for (i = 0; i < 32; i++) { 655 sr = env->sr[i]; 656 if (sr & 0x80000000) { 657 qemu_printf("%02d T=%d Ks=%d Kp=%d BUID=0x%03x " 658 "CNTLR_SPEC=0x%05x\n", i, 659 sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0, 660 sr & 0x20000000 ? 1 : 0, (uint32_t)((sr >> 20) & 0x1FF), 661 (uint32_t)(sr & 0xFFFFF)); 662 } else { 663 qemu_printf("%02d T=%d Ks=%d Kp=%d N=%d VSID=0x%06x\n", i, 664 sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0, 665 sr & 0x20000000 ? 1 : 0, sr & 0x10000000 ? 1 : 0, 666 (uint32_t)(sr & 0x00FFFFFF)); 667 } 668 } 669 670 qemu_printf("\nBATs:\n"); 671 mmu6xx_dump_BATs(env, ACCESS_INT); 672 mmu6xx_dump_BATs(env, ACCESS_CODE); 673 674 qemu_printf("\nTLBs [EPN EPN + SIZE]\n"); 675 for (type = 0; type < 2; type++) { 676 for (way = 0; way < env->nb_ways; way++) { 677 for (entry = env->nb_tlb * type + env->tlb_per_way * way; 678 entry < (env->nb_tlb * type + env->tlb_per_way * (way + 1)); 679 entry++) { 680 681 tlb = &env->tlb.tlb6[entry]; 682 qemu_printf("%s TLB %02d/%02d way:%d %s [" 683 TARGET_FMT_lx " " TARGET_FMT_lx "]\n", 684 type ? "code" : "data", entry % env->nb_tlb, 685 env->nb_tlb, way, 686 pte_is_valid(tlb->pte0) ? "valid" : "inval", 687 tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE); 688 } 689 } 690 } 691 } 692 693 void dump_mmu(CPUPPCState *env) 694 { 695 switch (env->mmu_model) { 696 case POWERPC_MMU_BOOKE: 697 mmubooke_dump_mmu(env); 698 break; 699 case POWERPC_MMU_BOOKE206: 700 mmubooke206_dump_mmu(env); 701 break; 702 case POWERPC_MMU_SOFT_6xx: 703 mmu6xx_dump_mmu(env); 704 break; 705 #if defined(TARGET_PPC64) 706 case POWERPC_MMU_64B: 707 case POWERPC_MMU_2_03: 708 case POWERPC_MMU_2_06: 709 case POWERPC_MMU_2_07: 710 dump_slb(env_archcpu(env)); 711 break; 712 case POWERPC_MMU_3_00: 713 if (ppc64_v3_radix(env_archcpu(env))) { 714 qemu_log_mask(LOG_UNIMP, "%s: the PPC64 MMU is unsupported\n", 715 __func__); 716 } else { 717 dump_slb(env_archcpu(env)); 718 } 719 break; 720 #endif 721 default: 722 qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__); 723 } 724 } 725 726 727 static bool ppc_real_mode_xlate(PowerPCCPU *cpu, vaddr eaddr, 728 MMUAccessType access_type, 729 hwaddr *raddrp, int *psizep, int *protp) 730 { 731 CPUPPCState *env = &cpu->env; 732 733 if (access_type == MMU_INST_FETCH ? !FIELD_EX64(env->msr, MSR, IR) 734 : !FIELD_EX64(env->msr, MSR, DR)) { 735 *raddrp = eaddr; 736 *protp = PAGE_RWX; 737 *psizep = TARGET_PAGE_BITS; 738 return true; 739 } else if (env->mmu_model == POWERPC_MMU_REAL) { 740 cpu_abort(CPU(cpu), "PowerPC in real mode shold not do translation\n"); 741 } 742 return false; 743 } 744 745 static bool ppc_40x_xlate(PowerPCCPU *cpu, vaddr eaddr, 746 MMUAccessType access_type, 747 hwaddr *raddrp, int *psizep, int *protp, 748 int mmu_idx, bool guest_visible) 749 { 750 CPUState *cs = CPU(cpu); 751 CPUPPCState *env = &cpu->env; 752 int ret; 753 754 if (ppc_real_mode_xlate(cpu, eaddr, access_type, raddrp, psizep, protp)) { 755 return true; 756 } 757 758 ret = mmu40x_get_physical_address(env, raddrp, protp, eaddr, access_type); 759 if (ret == 0) { 760 *psizep = TARGET_PAGE_BITS; 761 return true; 762 } else if (!guest_visible) { 763 return false; 764 } 765 766 log_cpu_state_mask(CPU_LOG_MMU, cs, 0); 767 if (access_type == MMU_INST_FETCH) { 768 switch (ret) { 769 case -1: 770 /* No matches in page tables or TLB */ 771 cs->exception_index = POWERPC_EXCP_ITLB; 772 env->error_code = 0; 773 env->spr[SPR_40x_DEAR] = eaddr; 774 env->spr[SPR_40x_ESR] = 0x00000000; 775 break; 776 case -2: 777 /* Access rights violation */ 778 cs->exception_index = POWERPC_EXCP_ISI; 779 env->error_code = 0x08000000; 780 break; 781 default: 782 g_assert_not_reached(); 783 } 784 } else { 785 switch (ret) { 786 case -1: 787 /* No matches in page tables or TLB */ 788 cs->exception_index = POWERPC_EXCP_DTLB; 789 env->error_code = 0; 790 env->spr[SPR_40x_DEAR] = eaddr; 791 if (access_type == MMU_DATA_STORE) { 792 env->spr[SPR_40x_ESR] = 0x00800000; 793 } else { 794 env->spr[SPR_40x_ESR] = 0x00000000; 795 } 796 break; 797 case -2: 798 /* Access rights violation */ 799 cs->exception_index = POWERPC_EXCP_DSI; 800 env->error_code = 0; 801 env->spr[SPR_40x_DEAR] = eaddr; 802 if (access_type == MMU_DATA_STORE) { 803 env->spr[SPR_40x_ESR] |= 0x00800000; 804 } 805 break; 806 default: 807 g_assert_not_reached(); 808 } 809 } 810 return false; 811 } 812 813 static bool ppc_6xx_xlate(PowerPCCPU *cpu, vaddr eaddr, 814 MMUAccessType access_type, 815 hwaddr *raddrp, int *psizep, int *protp, 816 int mmu_idx, bool guest_visible) 817 { 818 CPUState *cs = CPU(cpu); 819 CPUPPCState *env = &cpu->env; 820 mmu_ctx_t ctx; 821 int type; 822 int ret; 823 824 if (ppc_real_mode_xlate(cpu, eaddr, access_type, raddrp, psizep, protp)) { 825 return true; 826 } 827 828 if (access_type == MMU_INST_FETCH) { 829 /* code access */ 830 type = ACCESS_CODE; 831 } else if (guest_visible) { 832 /* data access */ 833 type = env->access_type; 834 } else { 835 type = ACCESS_INT; 836 } 837 838 ctx.prot = 0; 839 ctx.hash[0] = 0; 840 ctx.hash[1] = 0; 841 ret = mmu6xx_get_physical_address(env, &ctx, eaddr, access_type, type); 842 if (ret == 0) { 843 *raddrp = ctx.raddr; 844 *protp = ctx.prot; 845 *psizep = TARGET_PAGE_BITS; 846 return true; 847 } else if (!guest_visible) { 848 return false; 849 } 850 851 log_cpu_state_mask(CPU_LOG_MMU, cs, 0); 852 if (type == ACCESS_CODE) { 853 switch (ret) { 854 case -1: 855 /* No matches in page tables or TLB */ 856 cs->exception_index = POWERPC_EXCP_IFTLB; 857 env->error_code = 1 << 18; 858 env->spr[SPR_IMISS] = eaddr; 859 env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem; 860 goto tlb_miss; 861 case -2: 862 /* Access rights violation */ 863 cs->exception_index = POWERPC_EXCP_ISI; 864 env->error_code = 0x08000000; 865 break; 866 case -3: 867 /* No execute protection violation */ 868 cs->exception_index = POWERPC_EXCP_ISI; 869 env->error_code = 0x10000000; 870 break; 871 case -4: 872 /* Direct store exception */ 873 /* No code fetch is allowed in direct-store areas */ 874 cs->exception_index = POWERPC_EXCP_ISI; 875 env->error_code = 0x10000000; 876 break; 877 } 878 } else { 879 switch (ret) { 880 case -1: 881 /* No matches in page tables or TLB */ 882 if (access_type == MMU_DATA_STORE) { 883 cs->exception_index = POWERPC_EXCP_DSTLB; 884 env->error_code = 1 << 16; 885 } else { 886 cs->exception_index = POWERPC_EXCP_DLTLB; 887 env->error_code = 0; 888 } 889 env->spr[SPR_DMISS] = eaddr; 890 env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem; 891 tlb_miss: 892 env->error_code |= ctx.key << 19; 893 env->spr[SPR_HASH1] = ppc_hash32_hpt_base(cpu) + 894 get_pteg_offset32(cpu, ctx.hash[0]); 895 env->spr[SPR_HASH2] = ppc_hash32_hpt_base(cpu) + 896 get_pteg_offset32(cpu, ctx.hash[1]); 897 break; 898 case -2: 899 /* Access rights violation */ 900 cs->exception_index = POWERPC_EXCP_DSI; 901 env->error_code = 0; 902 env->spr[SPR_DAR] = eaddr; 903 if (access_type == MMU_DATA_STORE) { 904 env->spr[SPR_DSISR] = 0x0A000000; 905 } else { 906 env->spr[SPR_DSISR] = 0x08000000; 907 } 908 break; 909 case -4: 910 /* Direct store exception */ 911 switch (type) { 912 case ACCESS_FLOAT: 913 /* Floating point load/store */ 914 cs->exception_index = POWERPC_EXCP_ALIGN; 915 env->error_code = POWERPC_EXCP_ALIGN_FP; 916 env->spr[SPR_DAR] = eaddr; 917 break; 918 case ACCESS_RES: 919 /* lwarx, ldarx or stwcx. */ 920 cs->exception_index = POWERPC_EXCP_DSI; 921 env->error_code = 0; 922 env->spr[SPR_DAR] = eaddr; 923 if (access_type == MMU_DATA_STORE) { 924 env->spr[SPR_DSISR] = 0x06000000; 925 } else { 926 env->spr[SPR_DSISR] = 0x04000000; 927 } 928 break; 929 case ACCESS_EXT: 930 /* eciwx or ecowx */ 931 cs->exception_index = POWERPC_EXCP_DSI; 932 env->error_code = 0; 933 env->spr[SPR_DAR] = eaddr; 934 if (access_type == MMU_DATA_STORE) { 935 env->spr[SPR_DSISR] = 0x06100000; 936 } else { 937 env->spr[SPR_DSISR] = 0x04100000; 938 } 939 break; 940 default: 941 printf("DSI: invalid exception (%d)\n", ret); 942 cs->exception_index = POWERPC_EXCP_PROGRAM; 943 env->error_code = POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL; 944 env->spr[SPR_DAR] = eaddr; 945 break; 946 } 947 break; 948 } 949 } 950 return false; 951 } 952 953 /*****************************************************************************/ 954 955 bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type, 956 hwaddr *raddrp, int *psizep, int *protp, 957 int mmu_idx, bool guest_visible) 958 { 959 switch (cpu->env.mmu_model) { 960 #if defined(TARGET_PPC64) 961 case POWERPC_MMU_3_00: 962 if (ppc64_v3_radix(cpu)) { 963 return ppc_radix64_xlate(cpu, eaddr, access_type, raddrp, 964 psizep, protp, mmu_idx, guest_visible); 965 } 966 /* fall through */ 967 case POWERPC_MMU_64B: 968 case POWERPC_MMU_2_03: 969 case POWERPC_MMU_2_06: 970 case POWERPC_MMU_2_07: 971 return ppc_hash64_xlate(cpu, eaddr, access_type, 972 raddrp, psizep, protp, mmu_idx, guest_visible); 973 #endif 974 975 case POWERPC_MMU_32B: 976 return ppc_hash32_xlate(cpu, eaddr, access_type, raddrp, 977 psizep, protp, mmu_idx, guest_visible); 978 case POWERPC_MMU_BOOKE: 979 case POWERPC_MMU_BOOKE206: 980 return ppc_booke_xlate(cpu, eaddr, access_type, raddrp, 981 psizep, protp, mmu_idx, guest_visible); 982 case POWERPC_MMU_SOFT_4xx: 983 return ppc_40x_xlate(cpu, eaddr, access_type, raddrp, 984 psizep, protp, mmu_idx, guest_visible); 985 case POWERPC_MMU_SOFT_6xx: 986 return ppc_6xx_xlate(cpu, eaddr, access_type, raddrp, 987 psizep, protp, mmu_idx, guest_visible); 988 case POWERPC_MMU_REAL: 989 return ppc_real_mode_xlate(cpu, eaddr, access_type, raddrp, psizep, 990 protp); 991 case POWERPC_MMU_MPC8xx: 992 cpu_abort(env_cpu(&cpu->env), "MPC8xx MMU model is not implemented\n"); 993 default: 994 cpu_abort(CPU(cpu), "Unknown or invalid MMU model\n"); 995 } 996 } 997 998 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) 999 { 1000 PowerPCCPU *cpu = POWERPC_CPU(cs); 1001 hwaddr raddr; 1002 int s, p; 1003 1004 /* 1005 * Some MMUs have separate TLBs for code and data. If we only 1006 * try an MMU_DATA_LOAD, we may not be able to read instructions 1007 * mapped by code TLBs, so we also try a MMU_INST_FETCH. 1008 */ 1009 if (ppc_xlate(cpu, addr, MMU_DATA_LOAD, &raddr, &s, &p, 1010 ppc_env_mmu_index(&cpu->env, false), false) || 1011 ppc_xlate(cpu, addr, MMU_INST_FETCH, &raddr, &s, &p, 1012 ppc_env_mmu_index(&cpu->env, true), false)) { 1013 return raddr & TARGET_PAGE_MASK; 1014 } 1015 return -1; 1016 } 1017