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