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