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