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