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