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