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 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 #include "qemu/osdep.h" 20 #include "qemu/units.h" 21 #include "cpu.h" 22 #include "exec/helper-proto.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/cpu_ldst.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 "mmu-book3s-v3.h" 34 #include "mmu-radix64.h" 35 36 //#define DEBUG_MMU 37 //#define DEBUG_BATS 38 //#define DEBUG_SOFTWARE_TLB 39 //#define DUMP_PAGE_TABLES 40 //#define FLUSH_ALL_TLBS 41 42 #ifdef DEBUG_MMU 43 # define LOG_MMU_STATE(cpu) log_cpu_state_mask(CPU_LOG_MMU, (cpu), 0) 44 #else 45 # define LOG_MMU_STATE(cpu) do { } while (0) 46 #endif 47 48 #ifdef DEBUG_SOFTWARE_TLB 49 # define LOG_SWTLB(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__) 50 #else 51 # define LOG_SWTLB(...) do { } while (0) 52 #endif 53 54 #ifdef DEBUG_BATS 55 # define LOG_BATS(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__) 56 #else 57 # define LOG_BATS(...) do { } while (0) 58 #endif 59 60 /*****************************************************************************/ 61 /* PowerPC MMU emulation */ 62 63 /* Context used internally during MMU translations */ 64 typedef struct mmu_ctx_t mmu_ctx_t; 65 struct mmu_ctx_t { 66 hwaddr raddr; /* Real address */ 67 hwaddr eaddr; /* Effective address */ 68 int prot; /* Protection bits */ 69 hwaddr hash[2]; /* Pagetable hash values */ 70 target_ulong ptem; /* Virtual segment ID | API */ 71 int key; /* Access key */ 72 int nx; /* Non-execute area */ 73 }; 74 75 /* Common routines used by software and hardware TLBs emulation */ 76 static inline int pte_is_valid(target_ulong pte0) 77 { 78 return pte0 & 0x80000000 ? 1 : 0; 79 } 80 81 static inline void pte_invalidate(target_ulong *pte0) 82 { 83 *pte0 &= ~0x80000000; 84 } 85 86 #define PTE_PTEM_MASK 0x7FFFFFBF 87 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B) 88 89 static int pp_check(int key, int pp, int nx) 90 { 91 int access; 92 93 /* Compute access rights */ 94 access = 0; 95 if (key == 0) { 96 switch (pp) { 97 case 0x0: 98 case 0x1: 99 case 0x2: 100 access |= PAGE_WRITE; 101 /* No break here */ 102 case 0x3: 103 access |= PAGE_READ; 104 break; 105 } 106 } else { 107 switch (pp) { 108 case 0x0: 109 access = 0; 110 break; 111 case 0x1: 112 case 0x3: 113 access = PAGE_READ; 114 break; 115 case 0x2: 116 access = PAGE_READ | PAGE_WRITE; 117 break; 118 } 119 } 120 if (nx == 0) { 121 access |= PAGE_EXEC; 122 } 123 124 return access; 125 } 126 127 static int check_prot(int prot, int rw, int access_type) 128 { 129 int ret; 130 131 if (access_type == ACCESS_CODE) { 132 if (prot & PAGE_EXEC) { 133 ret = 0; 134 } else { 135 ret = -2; 136 } 137 } else if (rw) { 138 if (prot & PAGE_WRITE) { 139 ret = 0; 140 } else { 141 ret = -2; 142 } 143 } else { 144 if (prot & PAGE_READ) { 145 ret = 0; 146 } else { 147 ret = -2; 148 } 149 } 150 151 return ret; 152 } 153 154 static inline int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0, 155 target_ulong pte1, int h, int rw, int type) 156 { 157 target_ulong ptem, mmask; 158 int access, ret, pteh, ptev, pp; 159 160 ret = -1; 161 /* Check validity and table match */ 162 ptev = pte_is_valid(pte0); 163 pteh = (pte0 >> 6) & 1; 164 if (ptev && h == pteh) { 165 /* Check vsid & api */ 166 ptem = pte0 & PTE_PTEM_MASK; 167 mmask = PTE_CHECK_MASK; 168 pp = pte1 & 0x00000003; 169 if (ptem == ctx->ptem) { 170 if (ctx->raddr != (hwaddr)-1ULL) { 171 /* all matches should have equal RPN, WIMG & PP */ 172 if ((ctx->raddr & mmask) != (pte1 & mmask)) { 173 qemu_log_mask(CPU_LOG_MMU, "Bad RPN/WIMG/PP\n"); 174 return -3; 175 } 176 } 177 /* Compute access rights */ 178 access = pp_check(ctx->key, pp, ctx->nx); 179 /* Keep the matching PTE informations */ 180 ctx->raddr = pte1; 181 ctx->prot = access; 182 ret = check_prot(ctx->prot, rw, type); 183 if (ret == 0) { 184 /* Access granted */ 185 qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n"); 186 } else { 187 /* Access right violation */ 188 qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n"); 189 } 190 } 191 } 192 193 return ret; 194 } 195 196 static int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p, 197 int ret, int rw) 198 { 199 int store = 0; 200 201 /* Update page flags */ 202 if (!(*pte1p & 0x00000100)) { 203 /* Update accessed flag */ 204 *pte1p |= 0x00000100; 205 store = 1; 206 } 207 if (!(*pte1p & 0x00000080)) { 208 if (rw == 1 && ret == 0) { 209 /* Update changed flag */ 210 *pte1p |= 0x00000080; 211 store = 1; 212 } else { 213 /* Force page fault for first write access */ 214 ctx->prot &= ~PAGE_WRITE; 215 } 216 } 217 218 return store; 219 } 220 221 /* Software driven TLB helpers */ 222 static inline int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr, 223 int way, int is_code) 224 { 225 int nr; 226 227 /* Select TLB num in a way from address */ 228 nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1); 229 /* Select TLB way */ 230 nr += env->tlb_per_way * way; 231 /* 6xx have separate TLBs for instructions and data */ 232 if (is_code && env->id_tlbs == 1) { 233 nr += env->nb_tlb; 234 } 235 236 return nr; 237 } 238 239 static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env) 240 { 241 PowerPCCPU *cpu = ppc_env_get_cpu(env); 242 ppc6xx_tlb_t *tlb; 243 int nr, max; 244 245 /* LOG_SWTLB("Invalidate all TLBs\n"); */ 246 /* Invalidate all defined software TLB */ 247 max = env->nb_tlb; 248 if (env->id_tlbs == 1) { 249 max *= 2; 250 } 251 for (nr = 0; nr < max; nr++) { 252 tlb = &env->tlb.tlb6[nr]; 253 pte_invalidate(&tlb->pte0); 254 } 255 tlb_flush(CPU(cpu)); 256 } 257 258 static inline void ppc6xx_tlb_invalidate_virt2(CPUPPCState *env, 259 target_ulong eaddr, 260 int is_code, int match_epn) 261 { 262 #if !defined(FLUSH_ALL_TLBS) 263 CPUState *cs = CPU(ppc_env_get_cpu(env)); 264 ppc6xx_tlb_t *tlb; 265 int way, nr; 266 267 /* Invalidate ITLB + DTLB, all ways */ 268 for (way = 0; way < env->nb_ways; way++) { 269 nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code); 270 tlb = &env->tlb.tlb6[nr]; 271 if (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) { 272 LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx "\n", nr, 273 env->nb_tlb, eaddr); 274 pte_invalidate(&tlb->pte0); 275 tlb_flush_page(cs, tlb->EPN); 276 } 277 } 278 #else 279 /* XXX: PowerPC specification say this is valid as well */ 280 ppc6xx_tlb_invalidate_all(env); 281 #endif 282 } 283 284 static inline void ppc6xx_tlb_invalidate_virt(CPUPPCState *env, 285 target_ulong eaddr, int is_code) 286 { 287 ppc6xx_tlb_invalidate_virt2(env, eaddr, is_code, 0); 288 } 289 290 static void ppc6xx_tlb_store(CPUPPCState *env, target_ulong EPN, int way, 291 int is_code, target_ulong pte0, target_ulong pte1) 292 { 293 ppc6xx_tlb_t *tlb; 294 int nr; 295 296 nr = ppc6xx_tlb_getnum(env, EPN, way, is_code); 297 tlb = &env->tlb.tlb6[nr]; 298 LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx 299 " PTE1 " TARGET_FMT_lx "\n", nr, env->nb_tlb, EPN, pte0, pte1); 300 /* Invalidate any pending reference in QEMU for this virtual address */ 301 ppc6xx_tlb_invalidate_virt2(env, EPN, is_code, 1); 302 tlb->pte0 = pte0; 303 tlb->pte1 = pte1; 304 tlb->EPN = EPN; 305 /* Store last way for LRU mechanism */ 306 env->last_way = way; 307 } 308 309 static inline int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx, 310 target_ulong eaddr, int rw, int access_type) 311 { 312 ppc6xx_tlb_t *tlb; 313 int nr, best, way; 314 int ret; 315 316 best = -1; 317 ret = -1; /* No TLB found */ 318 for (way = 0; way < env->nb_ways; way++) { 319 nr = ppc6xx_tlb_getnum(env, eaddr, way, 320 access_type == ACCESS_CODE ? 1 : 0); 321 tlb = &env->tlb.tlb6[nr]; 322 /* This test "emulates" the PTE index match for hardware TLBs */ 323 if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) { 324 LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx " " TARGET_FMT_lx 325 "] <> " TARGET_FMT_lx "\n", nr, env->nb_tlb, 326 pte_is_valid(tlb->pte0) ? "valid" : "inval", 327 tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr); 328 continue; 329 } 330 LOG_SWTLB("TLB %d/%d %s " TARGET_FMT_lx " <> " TARGET_FMT_lx " " 331 TARGET_FMT_lx " %c %c\n", nr, env->nb_tlb, 332 pte_is_valid(tlb->pte0) ? "valid" : "inval", 333 tlb->EPN, eaddr, tlb->pte1, 334 rw ? 'S' : 'L', access_type == ACCESS_CODE ? 'I' : 'D'); 335 switch (ppc6xx_tlb_pte_check(ctx, tlb->pte0, tlb->pte1, 0, rw, access_type)) { 336 case -3: 337 /* TLB inconsistency */ 338 return -1; 339 case -2: 340 /* Access violation */ 341 ret = -2; 342 best = nr; 343 break; 344 case -1: 345 default: 346 /* No match */ 347 break; 348 case 0: 349 /* access granted */ 350 /* XXX: we should go on looping to check all TLBs consistency 351 * but we can speed-up the whole thing as the 352 * result would be undefined if TLBs are not consistent. 353 */ 354 ret = 0; 355 best = nr; 356 goto done; 357 } 358 } 359 if (best != -1) { 360 done: 361 LOG_SWTLB("found TLB at addr " TARGET_FMT_plx " prot=%01x ret=%d\n", 362 ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret); 363 /* Update page flags */ 364 pte_update_flags(ctx, &env->tlb.tlb6[best].pte1, ret, rw); 365 } 366 367 return ret; 368 } 369 370 /* Perform BAT hit & translation */ 371 static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp, 372 int *validp, int *protp, target_ulong *BATu, 373 target_ulong *BATl) 374 { 375 target_ulong bl; 376 int pp, valid, prot; 377 378 bl = (*BATu & 0x00001FFC) << 15; 379 valid = 0; 380 prot = 0; 381 if (((msr_pr == 0) && (*BATu & 0x00000002)) || 382 ((msr_pr != 0) && (*BATu & 0x00000001))) { 383 valid = 1; 384 pp = *BATl & 0x00000003; 385 if (pp != 0) { 386 prot = PAGE_READ | PAGE_EXEC; 387 if (pp == 0x2) { 388 prot |= PAGE_WRITE; 389 } 390 } 391 } 392 *blp = bl; 393 *validp = valid; 394 *protp = prot; 395 } 396 397 static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, 398 target_ulong virtual, int rw, int type) 399 { 400 target_ulong *BATlt, *BATut, *BATu, *BATl; 401 target_ulong BEPIl, BEPIu, bl; 402 int i, valid, prot; 403 int ret = -1; 404 405 LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__, 406 type == ACCESS_CODE ? 'I' : 'D', virtual); 407 switch (type) { 408 case ACCESS_CODE: 409 BATlt = env->IBAT[1]; 410 BATut = env->IBAT[0]; 411 break; 412 default: 413 BATlt = env->DBAT[1]; 414 BATut = env->DBAT[0]; 415 break; 416 } 417 for (i = 0; i < env->nb_BATs; i++) { 418 BATu = &BATut[i]; 419 BATl = &BATlt[i]; 420 BEPIu = *BATu & 0xF0000000; 421 BEPIl = *BATu & 0x0FFE0000; 422 bat_size_prot(env, &bl, &valid, &prot, BATu, BATl); 423 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx 424 " BATl " TARGET_FMT_lx "\n", __func__, 425 type == ACCESS_CODE ? 'I' : 'D', i, virtual, *BATu, *BATl); 426 if ((virtual & 0xF0000000) == BEPIu && 427 ((virtual & 0x0FFE0000) & ~bl) == BEPIl) { 428 /* BAT matches */ 429 if (valid != 0) { 430 /* Get physical address */ 431 ctx->raddr = (*BATl & 0xF0000000) | 432 ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) | 433 (virtual & 0x0001F000); 434 /* Compute access rights */ 435 ctx->prot = prot; 436 ret = check_prot(ctx->prot, rw, type); 437 if (ret == 0) { 438 LOG_BATS("BAT %d match: r " TARGET_FMT_plx " prot=%c%c\n", 439 i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-', 440 ctx->prot & PAGE_WRITE ? 'W' : '-'); 441 } 442 break; 443 } 444 } 445 } 446 if (ret < 0) { 447 #if defined(DEBUG_BATS) 448 if (qemu_log_enabled()) { 449 LOG_BATS("no BAT match for " TARGET_FMT_lx ":\n", virtual); 450 for (i = 0; i < 4; i++) { 451 BATu = &BATut[i]; 452 BATl = &BATlt[i]; 453 BEPIu = *BATu & 0xF0000000; 454 BEPIl = *BATu & 0x0FFE0000; 455 bl = (*BATu & 0x00001FFC) << 15; 456 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx 457 " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " " 458 TARGET_FMT_lx " " TARGET_FMT_lx "\n", 459 __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual, 460 *BATu, *BATl, BEPIu, BEPIl, bl); 461 } 462 } 463 #endif 464 } 465 /* No hit */ 466 return ret; 467 } 468 469 /* Perform segment based translation */ 470 static inline int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, 471 target_ulong eaddr, int rw, int type) 472 { 473 PowerPCCPU *cpu = ppc_env_get_cpu(env); 474 hwaddr hash; 475 target_ulong vsid; 476 int ds, pr, target_page_bits; 477 int ret; 478 target_ulong sr, pgidx; 479 480 pr = msr_pr; 481 ctx->eaddr = eaddr; 482 483 sr = env->sr[eaddr >> 28]; 484 ctx->key = (((sr & 0x20000000) && (pr != 0)) || 485 ((sr & 0x40000000) && (pr == 0))) ? 1 : 0; 486 ds = sr & 0x80000000 ? 1 : 0; 487 ctx->nx = sr & 0x10000000 ? 1 : 0; 488 vsid = sr & 0x00FFFFFF; 489 target_page_bits = TARGET_PAGE_BITS; 490 qemu_log_mask(CPU_LOG_MMU, 491 "Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx 492 " nip=" TARGET_FMT_lx " lr=" TARGET_FMT_lx 493 " ir=%d dr=%d pr=%d %d t=%d\n", 494 eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir, 495 (int)msr_dr, pr != 0 ? 1 : 0, rw, type); 496 pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits; 497 hash = vsid ^ pgidx; 498 ctx->ptem = (vsid << 7) | (pgidx >> 10); 499 500 qemu_log_mask(CPU_LOG_MMU, 501 "pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n", 502 ctx->key, ds, ctx->nx, vsid); 503 ret = -1; 504 if (!ds) { 505 /* Check if instruction fetch is allowed, if needed */ 506 if (type != ACCESS_CODE || ctx->nx == 0) { 507 /* Page address translation */ 508 qemu_log_mask(CPU_LOG_MMU, "htab_base " TARGET_FMT_plx 509 " htab_mask " TARGET_FMT_plx 510 " hash " TARGET_FMT_plx "\n", 511 ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash); 512 ctx->hash[0] = hash; 513 ctx->hash[1] = ~hash; 514 515 /* Initialize real address with an invalid value */ 516 ctx->raddr = (hwaddr)-1ULL; 517 /* Software TLB search */ 518 ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type); 519 #if defined(DUMP_PAGE_TABLES) 520 if (qemu_loglevel_mask(CPU_LOG_MMU)) { 521 CPUState *cs = ENV_GET_CPU(env); 522 hwaddr curaddr; 523 uint32_t a0, a1, a2, a3; 524 525 qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx 526 "\n", ppc_hash32_hpt_base(cpu), 527 ppc_hash32_hpt_mask(env) + 0x80); 528 for (curaddr = ppc_hash32_hpt_base(cpu); 529 curaddr < (ppc_hash32_hpt_base(cpu) 530 + ppc_hash32_hpt_mask(cpu) + 0x80); 531 curaddr += 16) { 532 a0 = ldl_phys(cs->as, curaddr); 533 a1 = ldl_phys(cs->as, curaddr + 4); 534 a2 = ldl_phys(cs->as, curaddr + 8); 535 a3 = ldl_phys(cs->as, curaddr + 12); 536 if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) { 537 qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n", 538 curaddr, a0, a1, a2, a3); 539 } 540 } 541 } 542 #endif 543 } else { 544 qemu_log_mask(CPU_LOG_MMU, "No access allowed\n"); 545 ret = -3; 546 } 547 } else { 548 target_ulong sr; 549 550 qemu_log_mask(CPU_LOG_MMU, "direct store...\n"); 551 /* Direct-store segment : absolutely *BUGGY* for now */ 552 553 /* Direct-store implies a 32-bit MMU. 554 * Check the Segment Register's bus unit ID (BUID). 555 */ 556 sr = env->sr[eaddr >> 28]; 557 if ((sr & 0x1FF00000) >> 20 == 0x07f) { 558 /* Memory-forced I/O controller interface access */ 559 /* If T=1 and BUID=x'07F', the 601 performs a memory access 560 * to SR[28-31] LA[4-31], bypassing all protection mechanisms. 561 */ 562 ctx->raddr = ((sr & 0xF) << 28) | (eaddr & 0x0FFFFFFF); 563 ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 564 return 0; 565 } 566 567 switch (type) { 568 case ACCESS_INT: 569 /* Integer load/store : only access allowed */ 570 break; 571 case ACCESS_CODE: 572 /* No code fetch is allowed in direct-store areas */ 573 return -4; 574 case ACCESS_FLOAT: 575 /* Floating point load/store */ 576 return -4; 577 case ACCESS_RES: 578 /* lwarx, ldarx or srwcx. */ 579 return -4; 580 case ACCESS_CACHE: 581 /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */ 582 /* Should make the instruction do no-op. 583 * As it already do no-op, it's quite easy :-) 584 */ 585 ctx->raddr = eaddr; 586 return 0; 587 case ACCESS_EXT: 588 /* eciwx or ecowx */ 589 return -4; 590 default: 591 qemu_log_mask(CPU_LOG_MMU, "ERROR: instruction should not need " 592 "address translation\n"); 593 return -4; 594 } 595 if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) { 596 ctx->raddr = eaddr; 597 ret = 2; 598 } else { 599 ret = -2; 600 } 601 } 602 603 return ret; 604 } 605 606 /* Generic TLB check function for embedded PowerPC implementations */ 607 static int ppcemb_tlb_check(CPUPPCState *env, ppcemb_tlb_t *tlb, 608 hwaddr *raddrp, 609 target_ulong address, uint32_t pid, int ext, 610 int i) 611 { 612 target_ulong mask; 613 614 /* Check valid flag */ 615 if (!(tlb->prot & PAGE_VALID)) { 616 return -1; 617 } 618 mask = ~(tlb->size - 1); 619 LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx " PID %u <=> " TARGET_FMT_lx 620 " " TARGET_FMT_lx " %u %x\n", __func__, i, address, pid, tlb->EPN, 621 mask, (uint32_t)tlb->PID, tlb->prot); 622 /* Check PID */ 623 if (tlb->PID != 0 && tlb->PID != pid) { 624 return -1; 625 } 626 /* Check effective address */ 627 if ((address & mask) != tlb->EPN) { 628 return -1; 629 } 630 *raddrp = (tlb->RPN & mask) | (address & ~mask); 631 if (ext) { 632 /* Extend the physical address to 36 bits */ 633 *raddrp |= (uint64_t)(tlb->RPN & 0xF) << 32; 634 } 635 636 return 0; 637 } 638 639 /* Generic TLB search function for PowerPC embedded implementations */ 640 static int ppcemb_tlb_search(CPUPPCState *env, target_ulong address, 641 uint32_t pid) 642 { 643 ppcemb_tlb_t *tlb; 644 hwaddr raddr; 645 int i, ret; 646 647 /* Default return value is no match */ 648 ret = -1; 649 for (i = 0; i < env->nb_tlb; i++) { 650 tlb = &env->tlb.tlbe[i]; 651 if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) { 652 ret = i; 653 break; 654 } 655 } 656 657 return ret; 658 } 659 660 /* Helpers specific to PowerPC 40x implementations */ 661 static inline void ppc4xx_tlb_invalidate_all(CPUPPCState *env) 662 { 663 PowerPCCPU *cpu = ppc_env_get_cpu(env); 664 ppcemb_tlb_t *tlb; 665 int i; 666 667 for (i = 0; i < env->nb_tlb; i++) { 668 tlb = &env->tlb.tlbe[i]; 669 tlb->prot &= ~PAGE_VALID; 670 } 671 tlb_flush(CPU(cpu)); 672 } 673 674 static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, 675 target_ulong address, int rw, 676 int access_type) 677 { 678 ppcemb_tlb_t *tlb; 679 hwaddr raddr; 680 int i, ret, zsel, zpr, pr; 681 682 ret = -1; 683 raddr = (hwaddr)-1ULL; 684 pr = msr_pr; 685 for (i = 0; i < env->nb_tlb; i++) { 686 tlb = &env->tlb.tlbe[i]; 687 if (ppcemb_tlb_check(env, tlb, &raddr, address, 688 env->spr[SPR_40x_PID], 0, i) < 0) { 689 continue; 690 } 691 zsel = (tlb->attr >> 4) & 0xF; 692 zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3; 693 LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n", 694 __func__, i, zsel, zpr, rw, tlb->attr); 695 /* Check execute enable bit */ 696 switch (zpr) { 697 case 0x2: 698 if (pr != 0) { 699 goto check_perms; 700 } 701 /* No break here */ 702 case 0x3: 703 /* All accesses granted */ 704 ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 705 ret = 0; 706 break; 707 case 0x0: 708 if (pr != 0) { 709 /* Raise Zone protection fault. */ 710 env->spr[SPR_40x_ESR] = 1 << 22; 711 ctx->prot = 0; 712 ret = -2; 713 break; 714 } 715 /* No break here */ 716 case 0x1: 717 check_perms: 718 /* Check from TLB entry */ 719 ctx->prot = tlb->prot; 720 ret = check_prot(ctx->prot, rw, access_type); 721 if (ret == -2) { 722 env->spr[SPR_40x_ESR] = 0; 723 } 724 break; 725 } 726 if (ret >= 0) { 727 ctx->raddr = raddr; 728 LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx 729 " %d %d\n", __func__, address, ctx->raddr, ctx->prot, 730 ret); 731 return 0; 732 } 733 } 734 LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx 735 " %d %d\n", __func__, address, raddr, ctx->prot, ret); 736 737 return ret; 738 } 739 740 void store_40x_sler(CPUPPCState *env, uint32_t val) 741 { 742 PowerPCCPU *cpu = ppc_env_get_cpu(env); 743 744 /* XXX: TO BE FIXED */ 745 if (val != 0x00000000) { 746 cpu_abort(CPU(cpu), "Little-endian regions are not supported by now\n"); 747 } 748 env->spr[SPR_405_SLER] = val; 749 } 750 751 static inline int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb, 752 hwaddr *raddr, int *prot, 753 target_ulong address, int rw, 754 int access_type, int i) 755 { 756 int ret, prot2; 757 758 if (ppcemb_tlb_check(env, tlb, raddr, address, 759 env->spr[SPR_BOOKE_PID], 760 !env->nb_pids, i) >= 0) { 761 goto found_tlb; 762 } 763 764 if (env->spr[SPR_BOOKE_PID1] && 765 ppcemb_tlb_check(env, tlb, raddr, address, 766 env->spr[SPR_BOOKE_PID1], 0, i) >= 0) { 767 goto found_tlb; 768 } 769 770 if (env->spr[SPR_BOOKE_PID2] && 771 ppcemb_tlb_check(env, tlb, raddr, address, 772 env->spr[SPR_BOOKE_PID2], 0, i) >= 0) { 773 goto found_tlb; 774 } 775 776 LOG_SWTLB("%s: TLB entry not found\n", __func__); 777 return -1; 778 779 found_tlb: 780 781 if (msr_pr != 0) { 782 prot2 = tlb->prot & 0xF; 783 } else { 784 prot2 = (tlb->prot >> 4) & 0xF; 785 } 786 787 /* Check the address space */ 788 if (access_type == ACCESS_CODE) { 789 if (msr_ir != (tlb->attr & 1)) { 790 LOG_SWTLB("%s: AS doesn't match\n", __func__); 791 return -1; 792 } 793 794 *prot = prot2; 795 if (prot2 & PAGE_EXEC) { 796 LOG_SWTLB("%s: good TLB!\n", __func__); 797 return 0; 798 } 799 800 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, prot2); 801 ret = -3; 802 } else { 803 if (msr_dr != (tlb->attr & 1)) { 804 LOG_SWTLB("%s: AS doesn't match\n", __func__); 805 return -1; 806 } 807 808 *prot = prot2; 809 if ((!rw && prot2 & PAGE_READ) || (rw && (prot2 & PAGE_WRITE))) { 810 LOG_SWTLB("%s: found TLB!\n", __func__); 811 return 0; 812 } 813 814 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, prot2); 815 ret = -2; 816 } 817 818 return ret; 819 } 820 821 static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, 822 target_ulong address, int rw, 823 int access_type) 824 { 825 ppcemb_tlb_t *tlb; 826 hwaddr raddr; 827 int i, ret; 828 829 ret = -1; 830 raddr = (hwaddr)-1ULL; 831 for (i = 0; i < env->nb_tlb; i++) { 832 tlb = &env->tlb.tlbe[i]; 833 ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address, rw, 834 access_type, i); 835 if (ret != -1) { 836 break; 837 } 838 } 839 840 if (ret >= 0) { 841 ctx->raddr = raddr; 842 LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx 843 " %d %d\n", __func__, address, ctx->raddr, ctx->prot, 844 ret); 845 } else { 846 LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx 847 " %d %d\n", __func__, address, raddr, ctx->prot, ret); 848 } 849 850 return ret; 851 } 852 853 static void booke206_flush_tlb(CPUPPCState *env, int flags, 854 const int check_iprot) 855 { 856 PowerPCCPU *cpu = ppc_env_get_cpu(env); 857 int tlb_size; 858 int i, j; 859 ppcmas_tlb_t *tlb = env->tlb.tlbm; 860 861 for (i = 0; i < BOOKE206_MAX_TLBN; i++) { 862 if (flags & (1 << i)) { 863 tlb_size = booke206_tlb_size(env, i); 864 for (j = 0; j < tlb_size; j++) { 865 if (!check_iprot || !(tlb[j].mas1 & MAS1_IPROT)) { 866 tlb[j].mas1 &= ~MAS1_VALID; 867 } 868 } 869 } 870 tlb += booke206_tlb_size(env, i); 871 } 872 873 tlb_flush(CPU(cpu)); 874 } 875 876 static hwaddr booke206_tlb_to_page_size(CPUPPCState *env, 877 ppcmas_tlb_t *tlb) 878 { 879 int tlbm_size; 880 881 tlbm_size = (tlb->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT; 882 883 return 1024ULL << tlbm_size; 884 } 885 886 /* TLB check function for MAS based SoftTLBs */ 887 static int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb, 888 hwaddr *raddrp, target_ulong address, 889 uint32_t pid) 890 { 891 hwaddr mask; 892 uint32_t tlb_pid; 893 894 if (!msr_cm) { 895 /* In 32bit mode we can only address 32bit EAs */ 896 address = (uint32_t)address; 897 } 898 899 /* Check valid flag */ 900 if (!(tlb->mas1 & MAS1_VALID)) { 901 return -1; 902 } 903 904 mask = ~(booke206_tlb_to_page_size(env, tlb) - 1); 905 LOG_SWTLB("%s: TLB ADDR=0x" TARGET_FMT_lx " PID=0x%x MAS1=0x%x MAS2=0x%" 906 PRIx64 " mask=0x%" HWADDR_PRIx " MAS7_3=0x%" PRIx64 " MAS8=0x%" 907 PRIx32 "\n", __func__, address, pid, tlb->mas1, tlb->mas2, mask, 908 tlb->mas7_3, tlb->mas8); 909 910 /* Check PID */ 911 tlb_pid = (tlb->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT; 912 if (tlb_pid != 0 && tlb_pid != pid) { 913 return -1; 914 } 915 916 /* Check effective address */ 917 if ((address & mask) != (tlb->mas2 & MAS2_EPN_MASK)) { 918 return -1; 919 } 920 921 if (raddrp) { 922 *raddrp = (tlb->mas7_3 & mask) | (address & ~mask); 923 } 924 925 return 0; 926 } 927 928 static bool is_epid_mmu(int mmu_idx) 929 { 930 return mmu_idx == PPC_TLB_EPID_STORE || mmu_idx == PPC_TLB_EPID_LOAD; 931 } 932 933 static uint32_t mmubooke206_esr(int mmu_idx, bool rw) 934 { 935 uint32_t esr = 0; 936 if (rw) { 937 esr |= ESR_ST; 938 } 939 if (is_epid_mmu(mmu_idx)) { 940 esr |= ESR_EPID; 941 } 942 return esr; 943 } 944 945 /* Get EPID register given the mmu_idx. If this is regular load, 946 * construct the EPID access bits from current processor state */ 947 948 /* Get the effective AS and PR bits and the PID. The PID is returned only if 949 * EPID load is requested, otherwise the caller must detect the correct EPID. 950 * Return true if valid EPID is returned. */ 951 static bool mmubooke206_get_as(CPUPPCState *env, 952 int mmu_idx, uint32_t *epid_out, 953 bool *as_out, bool *pr_out) 954 { 955 if (is_epid_mmu(mmu_idx)) { 956 uint32_t epidr; 957 if (mmu_idx == PPC_TLB_EPID_STORE) { 958 epidr = env->spr[SPR_BOOKE_EPSC]; 959 } else { 960 epidr = env->spr[SPR_BOOKE_EPLC]; 961 } 962 *epid_out = (epidr & EPID_EPID) >> EPID_EPID_SHIFT; 963 *as_out = !!(epidr & EPID_EAS); 964 *pr_out = !!(epidr & EPID_EPR); 965 return true; 966 } else { 967 *as_out = msr_ds; 968 *pr_out = msr_pr; 969 return false; 970 } 971 } 972 973 /* Check if the tlb found by hashing really matches */ 974 static int mmubooke206_check_tlb(CPUPPCState *env, ppcmas_tlb_t *tlb, 975 hwaddr *raddr, int *prot, 976 target_ulong address, int rw, 977 int access_type, int mmu_idx) 978 { 979 int ret; 980 int prot2 = 0; 981 uint32_t epid; 982 bool as, pr; 983 bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr); 984 985 if (!use_epid) { 986 if (ppcmas_tlb_check(env, tlb, raddr, address, 987 env->spr[SPR_BOOKE_PID]) >= 0) { 988 goto found_tlb; 989 } 990 991 if (env->spr[SPR_BOOKE_PID1] && 992 ppcmas_tlb_check(env, tlb, raddr, address, 993 env->spr[SPR_BOOKE_PID1]) >= 0) { 994 goto found_tlb; 995 } 996 997 if (env->spr[SPR_BOOKE_PID2] && 998 ppcmas_tlb_check(env, tlb, raddr, address, 999 env->spr[SPR_BOOKE_PID2]) >= 0) { 1000 goto found_tlb; 1001 } 1002 } else { 1003 if (ppcmas_tlb_check(env, tlb, raddr, address, epid) >= 0) { 1004 goto found_tlb; 1005 } 1006 } 1007 1008 LOG_SWTLB("%s: TLB entry not found\n", __func__); 1009 return -1; 1010 1011 found_tlb: 1012 1013 if (pr) { 1014 if (tlb->mas7_3 & MAS3_UR) { 1015 prot2 |= PAGE_READ; 1016 } 1017 if (tlb->mas7_3 & MAS3_UW) { 1018 prot2 |= PAGE_WRITE; 1019 } 1020 if (tlb->mas7_3 & MAS3_UX) { 1021 prot2 |= PAGE_EXEC; 1022 } 1023 } else { 1024 if (tlb->mas7_3 & MAS3_SR) { 1025 prot2 |= PAGE_READ; 1026 } 1027 if (tlb->mas7_3 & MAS3_SW) { 1028 prot2 |= PAGE_WRITE; 1029 } 1030 if (tlb->mas7_3 & MAS3_SX) { 1031 prot2 |= PAGE_EXEC; 1032 } 1033 } 1034 1035 /* Check the address space and permissions */ 1036 if (access_type == ACCESS_CODE) { 1037 /* There is no way to fetch code using epid load */ 1038 assert(!use_epid); 1039 if (msr_ir != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) { 1040 LOG_SWTLB("%s: AS doesn't match\n", __func__); 1041 return -1; 1042 } 1043 1044 *prot = prot2; 1045 if (prot2 & PAGE_EXEC) { 1046 LOG_SWTLB("%s: good TLB!\n", __func__); 1047 return 0; 1048 } 1049 1050 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, prot2); 1051 ret = -3; 1052 } else { 1053 if (as != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) { 1054 LOG_SWTLB("%s: AS doesn't match\n", __func__); 1055 return -1; 1056 } 1057 1058 *prot = prot2; 1059 if ((!rw && prot2 & PAGE_READ) || (rw && (prot2 & PAGE_WRITE))) { 1060 LOG_SWTLB("%s: found TLB!\n", __func__); 1061 return 0; 1062 } 1063 1064 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, prot2); 1065 ret = -2; 1066 } 1067 1068 return ret; 1069 } 1070 1071 static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, 1072 target_ulong address, int rw, 1073 int access_type, int mmu_idx) 1074 { 1075 ppcmas_tlb_t *tlb; 1076 hwaddr raddr; 1077 int i, j, ret; 1078 1079 ret = -1; 1080 raddr = (hwaddr)-1ULL; 1081 1082 for (i = 0; i < BOOKE206_MAX_TLBN; i++) { 1083 int ways = booke206_tlb_ways(env, i); 1084 1085 for (j = 0; j < ways; j++) { 1086 tlb = booke206_get_tlbm(env, i, address, j); 1087 if (!tlb) { 1088 continue; 1089 } 1090 ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address, 1091 rw, access_type, mmu_idx); 1092 if (ret != -1) { 1093 goto found_tlb; 1094 } 1095 } 1096 } 1097 1098 found_tlb: 1099 1100 if (ret >= 0) { 1101 ctx->raddr = raddr; 1102 LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx 1103 " %d %d\n", __func__, address, ctx->raddr, ctx->prot, 1104 ret); 1105 } else { 1106 LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx 1107 " %d %d\n", __func__, address, raddr, ctx->prot, ret); 1108 } 1109 1110 return ret; 1111 } 1112 1113 static const char *book3e_tsize_to_str[32] = { 1114 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", 1115 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", 1116 "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G", 1117 "1T", "2T" 1118 }; 1119 1120 static void mmubooke_dump_mmu(CPUPPCState *env) 1121 { 1122 ppcemb_tlb_t *entry; 1123 int i; 1124 1125 if (kvm_enabled() && !env->kvm_sw_tlb) { 1126 qemu_printf("Cannot access KVM TLB\n"); 1127 return; 1128 } 1129 1130 qemu_printf("\nTLB:\n"); 1131 qemu_printf("Effective Physical Size PID Prot " 1132 "Attr\n"); 1133 1134 entry = &env->tlb.tlbe[0]; 1135 for (i = 0; i < env->nb_tlb; i++, entry++) { 1136 hwaddr ea, pa; 1137 target_ulong mask; 1138 uint64_t size = (uint64_t)entry->size; 1139 char size_buf[20]; 1140 1141 /* Check valid flag */ 1142 if (!(entry->prot & PAGE_VALID)) { 1143 continue; 1144 } 1145 1146 mask = ~(entry->size - 1); 1147 ea = entry->EPN & mask; 1148 pa = entry->RPN & mask; 1149 /* Extend the physical address to 36 bits */ 1150 pa |= (hwaddr)(entry->RPN & 0xF) << 32; 1151 if (size >= 1 * MiB) { 1152 snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "M", size / MiB); 1153 } else { 1154 snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "k", size / KiB); 1155 } 1156 qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %s %-5u %08x %08x\n", 1157 (uint64_t)ea, (uint64_t)pa, size_buf, (uint32_t)entry->PID, 1158 entry->prot, entry->attr); 1159 } 1160 1161 } 1162 1163 static void mmubooke206_dump_one_tlb(CPUPPCState *env, int tlbn, int offset, 1164 int tlbsize) 1165 { 1166 ppcmas_tlb_t *entry; 1167 int i; 1168 1169 qemu_printf("\nTLB%d:\n", tlbn); 1170 qemu_printf("Effective Physical Size TID TS SRWX" 1171 " URWX WIMGE U0123\n"); 1172 1173 entry = &env->tlb.tlbm[offset]; 1174 for (i = 0; i < tlbsize; i++, entry++) { 1175 hwaddr ea, pa, size; 1176 int tsize; 1177 1178 if (!(entry->mas1 & MAS1_VALID)) { 1179 continue; 1180 } 1181 1182 tsize = (entry->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT; 1183 size = 1024ULL << tsize; 1184 ea = entry->mas2 & ~(size - 1); 1185 pa = entry->mas7_3 & ~(size - 1); 1186 1187 qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u S%c%c%c" 1188 "U%c%c%c %c%c%c%c%c U%c%c%c%c\n", 1189 (uint64_t)ea, (uint64_t)pa, 1190 book3e_tsize_to_str[tsize], 1191 (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT, 1192 (entry->mas1 & MAS1_TS) >> MAS1_TS_SHIFT, 1193 entry->mas7_3 & MAS3_SR ? 'R' : '-', 1194 entry->mas7_3 & MAS3_SW ? 'W' : '-', 1195 entry->mas7_3 & MAS3_SX ? 'X' : '-', 1196 entry->mas7_3 & MAS3_UR ? 'R' : '-', 1197 entry->mas7_3 & MAS3_UW ? 'W' : '-', 1198 entry->mas7_3 & MAS3_UX ? 'X' : '-', 1199 entry->mas2 & MAS2_W ? 'W' : '-', 1200 entry->mas2 & MAS2_I ? 'I' : '-', 1201 entry->mas2 & MAS2_M ? 'M' : '-', 1202 entry->mas2 & MAS2_G ? 'G' : '-', 1203 entry->mas2 & MAS2_E ? 'E' : '-', 1204 entry->mas7_3 & MAS3_U0 ? '0' : '-', 1205 entry->mas7_3 & MAS3_U1 ? '1' : '-', 1206 entry->mas7_3 & MAS3_U2 ? '2' : '-', 1207 entry->mas7_3 & MAS3_U3 ? '3' : '-'); 1208 } 1209 } 1210 1211 static void mmubooke206_dump_mmu(CPUPPCState *env) 1212 { 1213 int offset = 0; 1214 int i; 1215 1216 if (kvm_enabled() && !env->kvm_sw_tlb) { 1217 qemu_printf("Cannot access KVM TLB\n"); 1218 return; 1219 } 1220 1221 for (i = 0; i < BOOKE206_MAX_TLBN; i++) { 1222 int size = booke206_tlb_size(env, i); 1223 1224 if (size == 0) { 1225 continue; 1226 } 1227 1228 mmubooke206_dump_one_tlb(env, i, offset, size); 1229 offset += size; 1230 } 1231 } 1232 1233 static void mmu6xx_dump_BATs(CPUPPCState *env, int type) 1234 { 1235 target_ulong *BATlt, *BATut, *BATu, *BATl; 1236 target_ulong BEPIl, BEPIu, bl; 1237 int i; 1238 1239 switch (type) { 1240 case ACCESS_CODE: 1241 BATlt = env->IBAT[1]; 1242 BATut = env->IBAT[0]; 1243 break; 1244 default: 1245 BATlt = env->DBAT[1]; 1246 BATut = env->DBAT[0]; 1247 break; 1248 } 1249 1250 for (i = 0; i < env->nb_BATs; i++) { 1251 BATu = &BATut[i]; 1252 BATl = &BATlt[i]; 1253 BEPIu = *BATu & 0xF0000000; 1254 BEPIl = *BATu & 0x0FFE0000; 1255 bl = (*BATu & 0x00001FFC) << 15; 1256 qemu_printf("%s BAT%d BATu " TARGET_FMT_lx 1257 " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " " 1258 TARGET_FMT_lx " " TARGET_FMT_lx "\n", 1259 type == ACCESS_CODE ? "code" : "data", i, 1260 *BATu, *BATl, BEPIu, BEPIl, bl); 1261 } 1262 } 1263 1264 static void mmu6xx_dump_mmu(CPUPPCState *env) 1265 { 1266 PowerPCCPU *cpu = ppc_env_get_cpu(env); 1267 ppc6xx_tlb_t *tlb; 1268 target_ulong sr; 1269 int type, way, entry, i; 1270 1271 qemu_printf("HTAB base = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_base(cpu)); 1272 qemu_printf("HTAB mask = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_mask(cpu)); 1273 1274 qemu_printf("\nSegment registers:\n"); 1275 for (i = 0; i < 32; i++) { 1276 sr = env->sr[i]; 1277 if (sr & 0x80000000) { 1278 qemu_printf("%02d T=%d Ks=%d Kp=%d BUID=0x%03x " 1279 "CNTLR_SPEC=0x%05x\n", i, 1280 sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0, 1281 sr & 0x20000000 ? 1 : 0, (uint32_t)((sr >> 20) & 0x1FF), 1282 (uint32_t)(sr & 0xFFFFF)); 1283 } else { 1284 qemu_printf("%02d T=%d Ks=%d Kp=%d N=%d VSID=0x%06x\n", i, 1285 sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0, 1286 sr & 0x20000000 ? 1 : 0, sr & 0x10000000 ? 1 : 0, 1287 (uint32_t)(sr & 0x00FFFFFF)); 1288 } 1289 } 1290 1291 qemu_printf("\nBATs:\n"); 1292 mmu6xx_dump_BATs(env, ACCESS_INT); 1293 mmu6xx_dump_BATs(env, ACCESS_CODE); 1294 1295 if (env->id_tlbs != 1) { 1296 qemu_printf("ERROR: 6xx MMU should have separated TLB" 1297 " for code and data\n"); 1298 } 1299 1300 qemu_printf("\nTLBs [EPN EPN + SIZE]\n"); 1301 1302 for (type = 0; type < 2; type++) { 1303 for (way = 0; way < env->nb_ways; way++) { 1304 for (entry = env->nb_tlb * type + env->tlb_per_way * way; 1305 entry < (env->nb_tlb * type + env->tlb_per_way * (way + 1)); 1306 entry++) { 1307 1308 tlb = &env->tlb.tlb6[entry]; 1309 qemu_printf("%s TLB %02d/%02d way:%d %s [" 1310 TARGET_FMT_lx " " TARGET_FMT_lx "]\n", 1311 type ? "code" : "data", entry % env->nb_tlb, 1312 env->nb_tlb, way, 1313 pte_is_valid(tlb->pte0) ? "valid" : "inval", 1314 tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE); 1315 } 1316 } 1317 } 1318 } 1319 1320 void dump_mmu(CPUPPCState *env) 1321 { 1322 switch (env->mmu_model) { 1323 case POWERPC_MMU_BOOKE: 1324 mmubooke_dump_mmu(env); 1325 break; 1326 case POWERPC_MMU_BOOKE206: 1327 mmubooke206_dump_mmu(env); 1328 break; 1329 case POWERPC_MMU_SOFT_6xx: 1330 case POWERPC_MMU_SOFT_74xx: 1331 mmu6xx_dump_mmu(env); 1332 break; 1333 #if defined(TARGET_PPC64) 1334 case POWERPC_MMU_64B: 1335 case POWERPC_MMU_2_03: 1336 case POWERPC_MMU_2_06: 1337 case POWERPC_MMU_2_07: 1338 dump_slb(ppc_env_get_cpu(env)); 1339 break; 1340 case POWERPC_MMU_3_00: 1341 if (ppc64_v3_radix(ppc_env_get_cpu(env))) { 1342 /* TODO - Unsupported */ 1343 } else { 1344 dump_slb(ppc_env_get_cpu(env)); 1345 break; 1346 } 1347 #endif 1348 default: 1349 qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__); 1350 } 1351 } 1352 1353 static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx, 1354 target_ulong eaddr, int rw) 1355 { 1356 int in_plb, ret; 1357 1358 ctx->raddr = eaddr; 1359 ctx->prot = PAGE_READ | PAGE_EXEC; 1360 ret = 0; 1361 switch (env->mmu_model) { 1362 case POWERPC_MMU_SOFT_6xx: 1363 case POWERPC_MMU_SOFT_74xx: 1364 case POWERPC_MMU_SOFT_4xx: 1365 case POWERPC_MMU_REAL: 1366 case POWERPC_MMU_BOOKE: 1367 ctx->prot |= PAGE_WRITE; 1368 break; 1369 1370 case POWERPC_MMU_SOFT_4xx_Z: 1371 if (unlikely(msr_pe != 0)) { 1372 /* 403 family add some particular protections, 1373 * using PBL/PBU registers for accesses with no translation. 1374 */ 1375 in_plb = 1376 /* Check PLB validity */ 1377 (env->pb[0] < env->pb[1] && 1378 /* and address in plb area */ 1379 eaddr >= env->pb[0] && eaddr < env->pb[1]) || 1380 (env->pb[2] < env->pb[3] && 1381 eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0; 1382 if (in_plb ^ msr_px) { 1383 /* Access in protected area */ 1384 if (rw == 1) { 1385 /* Access is not allowed */ 1386 ret = -2; 1387 } 1388 } else { 1389 /* Read-write access is allowed */ 1390 ctx->prot |= PAGE_WRITE; 1391 } 1392 } 1393 break; 1394 1395 default: 1396 /* Caller's checks mean we should never get here for other models */ 1397 abort(); 1398 return -1; 1399 } 1400 1401 return ret; 1402 } 1403 1404 static int get_physical_address_wtlb( 1405 CPUPPCState *env, mmu_ctx_t *ctx, 1406 target_ulong eaddr, int rw, int access_type, 1407 int mmu_idx) 1408 { 1409 PowerPCCPU *cpu = ppc_env_get_cpu(env); 1410 int ret = -1; 1411 bool real_mode = (access_type == ACCESS_CODE && msr_ir == 0) 1412 || (access_type != ACCESS_CODE && msr_dr == 0); 1413 1414 switch (env->mmu_model) { 1415 case POWERPC_MMU_SOFT_6xx: 1416 case POWERPC_MMU_SOFT_74xx: 1417 if (real_mode) { 1418 ret = check_physical(env, ctx, eaddr, rw); 1419 } else { 1420 /* Try to find a BAT */ 1421 if (env->nb_BATs != 0) { 1422 ret = get_bat_6xx_tlb(env, ctx, eaddr, rw, access_type); 1423 } 1424 if (ret < 0) { 1425 /* We didn't match any BAT entry or don't have BATs */ 1426 ret = get_segment_6xx_tlb(env, ctx, eaddr, rw, access_type); 1427 } 1428 } 1429 break; 1430 1431 case POWERPC_MMU_SOFT_4xx: 1432 case POWERPC_MMU_SOFT_4xx_Z: 1433 if (real_mode) { 1434 ret = check_physical(env, ctx, eaddr, rw); 1435 } else { 1436 ret = mmu40x_get_physical_address(env, ctx, eaddr, 1437 rw, access_type); 1438 } 1439 break; 1440 case POWERPC_MMU_BOOKE: 1441 ret = mmubooke_get_physical_address(env, ctx, eaddr, 1442 rw, access_type); 1443 break; 1444 case POWERPC_MMU_BOOKE206: 1445 ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw, 1446 access_type, mmu_idx); 1447 break; 1448 case POWERPC_MMU_MPC8xx: 1449 /* XXX: TODO */ 1450 cpu_abort(CPU(cpu), "MPC8xx MMU model is not implemented\n"); 1451 break; 1452 case POWERPC_MMU_REAL: 1453 if (real_mode) { 1454 ret = check_physical(env, ctx, eaddr, rw); 1455 } else { 1456 cpu_abort(CPU(cpu), "PowerPC in real mode do not do any translation\n"); 1457 } 1458 return -1; 1459 default: 1460 cpu_abort(CPU(cpu), "Unknown or invalid MMU model\n"); 1461 return -1; 1462 } 1463 1464 return ret; 1465 } 1466 1467 static int get_physical_address( 1468 CPUPPCState *env, mmu_ctx_t *ctx, 1469 target_ulong eaddr, int rw, int access_type) 1470 { 1471 return get_physical_address_wtlb(env, ctx, eaddr, rw, access_type, 0); 1472 } 1473 1474 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) 1475 { 1476 PowerPCCPU *cpu = POWERPC_CPU(cs); 1477 CPUPPCState *env = &cpu->env; 1478 mmu_ctx_t ctx; 1479 1480 switch (env->mmu_model) { 1481 #if defined(TARGET_PPC64) 1482 case POWERPC_MMU_64B: 1483 case POWERPC_MMU_2_03: 1484 case POWERPC_MMU_2_06: 1485 case POWERPC_MMU_2_07: 1486 return ppc_hash64_get_phys_page_debug(cpu, addr); 1487 case POWERPC_MMU_3_00: 1488 return ppc64_v3_get_phys_page_debug(cpu, addr); 1489 #endif 1490 1491 case POWERPC_MMU_32B: 1492 case POWERPC_MMU_601: 1493 return ppc_hash32_get_phys_page_debug(cpu, addr); 1494 1495 default: 1496 ; 1497 } 1498 1499 if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0)) { 1500 1501 /* Some MMUs have separate TLBs for code and data. If we only try an 1502 * ACCESS_INT, we may not be able to read instructions mapped by code 1503 * TLBs, so we also try a ACCESS_CODE. 1504 */ 1505 if (unlikely(get_physical_address(env, &ctx, addr, 0, 1506 ACCESS_CODE) != 0)) { 1507 return -1; 1508 } 1509 } 1510 1511 return ctx.raddr & TARGET_PAGE_MASK; 1512 } 1513 1514 static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address, 1515 int rw, int mmu_idx) 1516 { 1517 uint32_t epid; 1518 bool as, pr; 1519 uint32_t missed_tid = 0; 1520 bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr); 1521 if (rw == 2) { 1522 as = msr_ir; 1523 } 1524 env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK; 1525 env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK; 1526 env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK; 1527 env->spr[SPR_BOOKE_MAS3] = 0; 1528 env->spr[SPR_BOOKE_MAS6] = 0; 1529 env->spr[SPR_BOOKE_MAS7] = 0; 1530 1531 /* AS */ 1532 if (as) { 1533 env->spr[SPR_BOOKE_MAS1] |= MAS1_TS; 1534 env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS; 1535 } 1536 1537 env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID; 1538 env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK; 1539 1540 if (!use_epid) { 1541 switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) { 1542 case MAS4_TIDSELD_PID0: 1543 missed_tid = env->spr[SPR_BOOKE_PID]; 1544 break; 1545 case MAS4_TIDSELD_PID1: 1546 missed_tid = env->spr[SPR_BOOKE_PID1]; 1547 break; 1548 case MAS4_TIDSELD_PID2: 1549 missed_tid = env->spr[SPR_BOOKE_PID2]; 1550 break; 1551 } 1552 env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16; 1553 } else { 1554 missed_tid = epid; 1555 env->spr[SPR_BOOKE_MAS6] |= missed_tid << 16; 1556 } 1557 env->spr[SPR_BOOKE_MAS1] |= (missed_tid << MAS1_TID_SHIFT); 1558 1559 1560 /* next victim logic */ 1561 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT; 1562 env->last_way++; 1563 env->last_way &= booke206_tlb_ways(env, 0) - 1; 1564 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT; 1565 } 1566 1567 /* Perform address translation */ 1568 static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, 1569 int rw, int mmu_idx) 1570 { 1571 CPUState *cs = CPU(ppc_env_get_cpu(env)); 1572 PowerPCCPU *cpu = POWERPC_CPU(cs); 1573 mmu_ctx_t ctx; 1574 int access_type; 1575 int ret = 0; 1576 1577 if (rw == 2) { 1578 /* code access */ 1579 rw = 0; 1580 access_type = ACCESS_CODE; 1581 } else { 1582 /* data access */ 1583 access_type = env->access_type; 1584 } 1585 ret = get_physical_address_wtlb(env, &ctx, address, rw, 1586 access_type, mmu_idx); 1587 if (ret == 0) { 1588 tlb_set_page(cs, address & TARGET_PAGE_MASK, 1589 ctx.raddr & TARGET_PAGE_MASK, ctx.prot, 1590 mmu_idx, TARGET_PAGE_SIZE); 1591 ret = 0; 1592 } else if (ret < 0) { 1593 LOG_MMU_STATE(cs); 1594 if (access_type == ACCESS_CODE) { 1595 switch (ret) { 1596 case -1: 1597 /* No matches in page tables or TLB */ 1598 switch (env->mmu_model) { 1599 case POWERPC_MMU_SOFT_6xx: 1600 cs->exception_index = POWERPC_EXCP_IFTLB; 1601 env->error_code = 1 << 18; 1602 env->spr[SPR_IMISS] = address; 1603 env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem; 1604 goto tlb_miss; 1605 case POWERPC_MMU_SOFT_74xx: 1606 cs->exception_index = POWERPC_EXCP_IFTLB; 1607 goto tlb_miss_74xx; 1608 case POWERPC_MMU_SOFT_4xx: 1609 case POWERPC_MMU_SOFT_4xx_Z: 1610 cs->exception_index = POWERPC_EXCP_ITLB; 1611 env->error_code = 0; 1612 env->spr[SPR_40x_DEAR] = address; 1613 env->spr[SPR_40x_ESR] = 0x00000000; 1614 break; 1615 case POWERPC_MMU_BOOKE206: 1616 booke206_update_mas_tlb_miss(env, address, 2, mmu_idx); 1617 /* fall through */ 1618 case POWERPC_MMU_BOOKE: 1619 cs->exception_index = POWERPC_EXCP_ITLB; 1620 env->error_code = 0; 1621 env->spr[SPR_BOOKE_DEAR] = address; 1622 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, 0); 1623 return -1; 1624 case POWERPC_MMU_MPC8xx: 1625 /* XXX: TODO */ 1626 cpu_abort(cs, "MPC8xx MMU model is not implemented\n"); 1627 break; 1628 case POWERPC_MMU_REAL: 1629 cpu_abort(cs, "PowerPC in real mode should never raise " 1630 "any MMU exceptions\n"); 1631 return -1; 1632 default: 1633 cpu_abort(cs, "Unknown or invalid MMU model\n"); 1634 return -1; 1635 } 1636 break; 1637 case -2: 1638 /* Access rights violation */ 1639 cs->exception_index = POWERPC_EXCP_ISI; 1640 env->error_code = 0x08000000; 1641 break; 1642 case -3: 1643 /* No execute protection violation */ 1644 if ((env->mmu_model == POWERPC_MMU_BOOKE) || 1645 (env->mmu_model == POWERPC_MMU_BOOKE206)) { 1646 env->spr[SPR_BOOKE_ESR] = 0x00000000; 1647 } 1648 cs->exception_index = POWERPC_EXCP_ISI; 1649 env->error_code = 0x10000000; 1650 break; 1651 case -4: 1652 /* Direct store exception */ 1653 /* No code fetch is allowed in direct-store areas */ 1654 cs->exception_index = POWERPC_EXCP_ISI; 1655 env->error_code = 0x10000000; 1656 break; 1657 } 1658 } else { 1659 switch (ret) { 1660 case -1: 1661 /* No matches in page tables or TLB */ 1662 switch (env->mmu_model) { 1663 case POWERPC_MMU_SOFT_6xx: 1664 if (rw == 1) { 1665 cs->exception_index = POWERPC_EXCP_DSTLB; 1666 env->error_code = 1 << 16; 1667 } else { 1668 cs->exception_index = POWERPC_EXCP_DLTLB; 1669 env->error_code = 0; 1670 } 1671 env->spr[SPR_DMISS] = address; 1672 env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem; 1673 tlb_miss: 1674 env->error_code |= ctx.key << 19; 1675 env->spr[SPR_HASH1] = ppc_hash32_hpt_base(cpu) + 1676 get_pteg_offset32(cpu, ctx.hash[0]); 1677 env->spr[SPR_HASH2] = ppc_hash32_hpt_base(cpu) + 1678 get_pteg_offset32(cpu, ctx.hash[1]); 1679 break; 1680 case POWERPC_MMU_SOFT_74xx: 1681 if (rw == 1) { 1682 cs->exception_index = POWERPC_EXCP_DSTLB; 1683 } else { 1684 cs->exception_index = POWERPC_EXCP_DLTLB; 1685 } 1686 tlb_miss_74xx: 1687 /* Implement LRU algorithm */ 1688 env->error_code = ctx.key << 19; 1689 env->spr[SPR_TLBMISS] = (address & ~((target_ulong)0x3)) | 1690 ((env->last_way + 1) & (env->nb_ways - 1)); 1691 env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem; 1692 break; 1693 case POWERPC_MMU_SOFT_4xx: 1694 case POWERPC_MMU_SOFT_4xx_Z: 1695 cs->exception_index = POWERPC_EXCP_DTLB; 1696 env->error_code = 0; 1697 env->spr[SPR_40x_DEAR] = address; 1698 if (rw) { 1699 env->spr[SPR_40x_ESR] = 0x00800000; 1700 } else { 1701 env->spr[SPR_40x_ESR] = 0x00000000; 1702 } 1703 break; 1704 case POWERPC_MMU_MPC8xx: 1705 /* XXX: TODO */ 1706 cpu_abort(cs, "MPC8xx MMU model is not implemented\n"); 1707 break; 1708 case POWERPC_MMU_BOOKE206: 1709 booke206_update_mas_tlb_miss(env, address, rw, mmu_idx); 1710 /* fall through */ 1711 case POWERPC_MMU_BOOKE: 1712 cs->exception_index = POWERPC_EXCP_DTLB; 1713 env->error_code = 0; 1714 env->spr[SPR_BOOKE_DEAR] = address; 1715 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, rw); 1716 return -1; 1717 case POWERPC_MMU_REAL: 1718 cpu_abort(cs, "PowerPC in real mode should never raise " 1719 "any MMU exceptions\n"); 1720 return -1; 1721 default: 1722 cpu_abort(cs, "Unknown or invalid MMU model\n"); 1723 return -1; 1724 } 1725 break; 1726 case -2: 1727 /* Access rights violation */ 1728 cs->exception_index = POWERPC_EXCP_DSI; 1729 env->error_code = 0; 1730 if (env->mmu_model == POWERPC_MMU_SOFT_4xx 1731 || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) { 1732 env->spr[SPR_40x_DEAR] = address; 1733 if (rw) { 1734 env->spr[SPR_40x_ESR] |= 0x00800000; 1735 } 1736 } else if ((env->mmu_model == POWERPC_MMU_BOOKE) || 1737 (env->mmu_model == POWERPC_MMU_BOOKE206)) { 1738 env->spr[SPR_BOOKE_DEAR] = address; 1739 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, rw); 1740 } else { 1741 env->spr[SPR_DAR] = address; 1742 if (rw == 1) { 1743 env->spr[SPR_DSISR] = 0x0A000000; 1744 } else { 1745 env->spr[SPR_DSISR] = 0x08000000; 1746 } 1747 } 1748 break; 1749 case -4: 1750 /* Direct store exception */ 1751 switch (access_type) { 1752 case ACCESS_FLOAT: 1753 /* Floating point load/store */ 1754 cs->exception_index = POWERPC_EXCP_ALIGN; 1755 env->error_code = POWERPC_EXCP_ALIGN_FP; 1756 env->spr[SPR_DAR] = address; 1757 break; 1758 case ACCESS_RES: 1759 /* lwarx, ldarx or stwcx. */ 1760 cs->exception_index = POWERPC_EXCP_DSI; 1761 env->error_code = 0; 1762 env->spr[SPR_DAR] = address; 1763 if (rw == 1) { 1764 env->spr[SPR_DSISR] = 0x06000000; 1765 } else { 1766 env->spr[SPR_DSISR] = 0x04000000; 1767 } 1768 break; 1769 case ACCESS_EXT: 1770 /* eciwx or ecowx */ 1771 cs->exception_index = POWERPC_EXCP_DSI; 1772 env->error_code = 0; 1773 env->spr[SPR_DAR] = address; 1774 if (rw == 1) { 1775 env->spr[SPR_DSISR] = 0x06100000; 1776 } else { 1777 env->spr[SPR_DSISR] = 0x04100000; 1778 } 1779 break; 1780 default: 1781 printf("DSI: invalid exception (%d)\n", ret); 1782 cs->exception_index = POWERPC_EXCP_PROGRAM; 1783 env->error_code = 1784 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL; 1785 env->spr[SPR_DAR] = address; 1786 break; 1787 } 1788 break; 1789 } 1790 } 1791 ret = 1; 1792 } 1793 1794 return ret; 1795 } 1796 1797 /*****************************************************************************/ 1798 /* BATs management */ 1799 #if !defined(FLUSH_ALL_TLBS) 1800 static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu, 1801 target_ulong mask) 1802 { 1803 CPUState *cs = CPU(ppc_env_get_cpu(env)); 1804 target_ulong base, end, page; 1805 1806 base = BATu & ~0x0001FFFF; 1807 end = base + mask + 0x00020000; 1808 LOG_BATS("Flush BAT from " TARGET_FMT_lx " to " TARGET_FMT_lx " (" 1809 TARGET_FMT_lx ")\n", base, end, mask); 1810 for (page = base; page != end; page += TARGET_PAGE_SIZE) { 1811 tlb_flush_page(cs, page); 1812 } 1813 LOG_BATS("Flush done\n"); 1814 } 1815 #endif 1816 1817 static inline void dump_store_bat(CPUPPCState *env, char ID, int ul, int nr, 1818 target_ulong value) 1819 { 1820 LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n", ID, 1821 nr, ul == 0 ? 'u' : 'l', value, env->nip); 1822 } 1823 1824 void helper_store_ibatu(CPUPPCState *env, uint32_t nr, target_ulong value) 1825 { 1826 target_ulong mask; 1827 #if defined(FLUSH_ALL_TLBS) 1828 PowerPCCPU *cpu = ppc_env_get_cpu(env); 1829 #endif 1830 1831 dump_store_bat(env, 'I', 0, nr, value); 1832 if (env->IBAT[0][nr] != value) { 1833 mask = (value << 15) & 0x0FFE0000UL; 1834 #if !defined(FLUSH_ALL_TLBS) 1835 do_invalidate_BAT(env, env->IBAT[0][nr], mask); 1836 #endif 1837 /* When storing valid upper BAT, mask BEPI and BRPN 1838 * and invalidate all TLBs covered by this BAT 1839 */ 1840 mask = (value << 15) & 0x0FFE0000UL; 1841 env->IBAT[0][nr] = (value & 0x00001FFFUL) | 1842 (value & ~0x0001FFFFUL & ~mask); 1843 env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) | 1844 (env->IBAT[1][nr] & ~0x0001FFFF & ~mask); 1845 #if !defined(FLUSH_ALL_TLBS) 1846 do_invalidate_BAT(env, env->IBAT[0][nr], mask); 1847 #else 1848 tlb_flush(CPU(cpu)); 1849 #endif 1850 } 1851 } 1852 1853 void helper_store_ibatl(CPUPPCState *env, uint32_t nr, target_ulong value) 1854 { 1855 dump_store_bat(env, 'I', 1, nr, value); 1856 env->IBAT[1][nr] = value; 1857 } 1858 1859 void helper_store_dbatu(CPUPPCState *env, uint32_t nr, target_ulong value) 1860 { 1861 target_ulong mask; 1862 #if defined(FLUSH_ALL_TLBS) 1863 PowerPCCPU *cpu = ppc_env_get_cpu(env); 1864 #endif 1865 1866 dump_store_bat(env, 'D', 0, nr, value); 1867 if (env->DBAT[0][nr] != value) { 1868 /* When storing valid upper BAT, mask BEPI and BRPN 1869 * and invalidate all TLBs covered by this BAT 1870 */ 1871 mask = (value << 15) & 0x0FFE0000UL; 1872 #if !defined(FLUSH_ALL_TLBS) 1873 do_invalidate_BAT(env, env->DBAT[0][nr], mask); 1874 #endif 1875 mask = (value << 15) & 0x0FFE0000UL; 1876 env->DBAT[0][nr] = (value & 0x00001FFFUL) | 1877 (value & ~0x0001FFFFUL & ~mask); 1878 env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) | 1879 (env->DBAT[1][nr] & ~0x0001FFFF & ~mask); 1880 #if !defined(FLUSH_ALL_TLBS) 1881 do_invalidate_BAT(env, env->DBAT[0][nr], mask); 1882 #else 1883 tlb_flush(CPU(cpu)); 1884 #endif 1885 } 1886 } 1887 1888 void helper_store_dbatl(CPUPPCState *env, uint32_t nr, target_ulong value) 1889 { 1890 dump_store_bat(env, 'D', 1, nr, value); 1891 env->DBAT[1][nr] = value; 1892 } 1893 1894 void helper_store_601_batu(CPUPPCState *env, uint32_t nr, target_ulong value) 1895 { 1896 target_ulong mask; 1897 #if defined(FLUSH_ALL_TLBS) 1898 PowerPCCPU *cpu = ppc_env_get_cpu(env); 1899 int do_inval; 1900 #endif 1901 1902 dump_store_bat(env, 'I', 0, nr, value); 1903 if (env->IBAT[0][nr] != value) { 1904 #if defined(FLUSH_ALL_TLBS) 1905 do_inval = 0; 1906 #endif 1907 mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL; 1908 if (env->IBAT[1][nr] & 0x40) { 1909 /* Invalidate BAT only if it is valid */ 1910 #if !defined(FLUSH_ALL_TLBS) 1911 do_invalidate_BAT(env, env->IBAT[0][nr], mask); 1912 #else 1913 do_inval = 1; 1914 #endif 1915 } 1916 /* When storing valid upper BAT, mask BEPI and BRPN 1917 * and invalidate all TLBs covered by this BAT 1918 */ 1919 env->IBAT[0][nr] = (value & 0x00001FFFUL) | 1920 (value & ~0x0001FFFFUL & ~mask); 1921 env->DBAT[0][nr] = env->IBAT[0][nr]; 1922 if (env->IBAT[1][nr] & 0x40) { 1923 #if !defined(FLUSH_ALL_TLBS) 1924 do_invalidate_BAT(env, env->IBAT[0][nr], mask); 1925 #else 1926 do_inval = 1; 1927 #endif 1928 } 1929 #if defined(FLUSH_ALL_TLBS) 1930 if (do_inval) { 1931 tlb_flush(CPU(cpu)); 1932 } 1933 #endif 1934 } 1935 } 1936 1937 void helper_store_601_batl(CPUPPCState *env, uint32_t nr, target_ulong value) 1938 { 1939 #if !defined(FLUSH_ALL_TLBS) 1940 target_ulong mask; 1941 #else 1942 PowerPCCPU *cpu = ppc_env_get_cpu(env); 1943 int do_inval; 1944 #endif 1945 1946 dump_store_bat(env, 'I', 1, nr, value); 1947 if (env->IBAT[1][nr] != value) { 1948 #if defined(FLUSH_ALL_TLBS) 1949 do_inval = 0; 1950 #endif 1951 if (env->IBAT[1][nr] & 0x40) { 1952 #if !defined(FLUSH_ALL_TLBS) 1953 mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL; 1954 do_invalidate_BAT(env, env->IBAT[0][nr], mask); 1955 #else 1956 do_inval = 1; 1957 #endif 1958 } 1959 if (value & 0x40) { 1960 #if !defined(FLUSH_ALL_TLBS) 1961 mask = (value << 17) & 0x0FFE0000UL; 1962 do_invalidate_BAT(env, env->IBAT[0][nr], mask); 1963 #else 1964 do_inval = 1; 1965 #endif 1966 } 1967 env->IBAT[1][nr] = value; 1968 env->DBAT[1][nr] = value; 1969 #if defined(FLUSH_ALL_TLBS) 1970 if (do_inval) { 1971 tlb_flush(CPU(cpu)); 1972 } 1973 #endif 1974 } 1975 } 1976 1977 /*****************************************************************************/ 1978 /* TLB management */ 1979 void ppc_tlb_invalidate_all(CPUPPCState *env) 1980 { 1981 PowerPCCPU *cpu = ppc_env_get_cpu(env); 1982 1983 #if defined(TARGET_PPC64) 1984 if (env->mmu_model & POWERPC_MMU_64) { 1985 env->tlb_need_flush = 0; 1986 tlb_flush(CPU(cpu)); 1987 } else 1988 #endif /* defined(TARGET_PPC64) */ 1989 switch (env->mmu_model) { 1990 case POWERPC_MMU_SOFT_6xx: 1991 case POWERPC_MMU_SOFT_74xx: 1992 ppc6xx_tlb_invalidate_all(env); 1993 break; 1994 case POWERPC_MMU_SOFT_4xx: 1995 case POWERPC_MMU_SOFT_4xx_Z: 1996 ppc4xx_tlb_invalidate_all(env); 1997 break; 1998 case POWERPC_MMU_REAL: 1999 cpu_abort(CPU(cpu), "No TLB for PowerPC 4xx in real mode\n"); 2000 break; 2001 case POWERPC_MMU_MPC8xx: 2002 /* XXX: TODO */ 2003 cpu_abort(CPU(cpu), "MPC8xx MMU model is not implemented\n"); 2004 break; 2005 case POWERPC_MMU_BOOKE: 2006 tlb_flush(CPU(cpu)); 2007 break; 2008 case POWERPC_MMU_BOOKE206: 2009 booke206_flush_tlb(env, -1, 0); 2010 break; 2011 case POWERPC_MMU_32B: 2012 case POWERPC_MMU_601: 2013 env->tlb_need_flush = 0; 2014 tlb_flush(CPU(cpu)); 2015 break; 2016 default: 2017 /* XXX: TODO */ 2018 cpu_abort(CPU(cpu), "Unknown MMU model %x\n", env->mmu_model); 2019 break; 2020 } 2021 } 2022 2023 void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr) 2024 { 2025 #if !defined(FLUSH_ALL_TLBS) 2026 addr &= TARGET_PAGE_MASK; 2027 #if defined(TARGET_PPC64) 2028 if (env->mmu_model & POWERPC_MMU_64) { 2029 /* tlbie invalidate TLBs for all segments */ 2030 /* XXX: given the fact that there are too many segments to invalidate, 2031 * and we still don't have a tlb_flush_mask(env, n, mask) in QEMU, 2032 * we just invalidate all TLBs 2033 */ 2034 env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH; 2035 } else 2036 #endif /* defined(TARGET_PPC64) */ 2037 switch (env->mmu_model) { 2038 case POWERPC_MMU_SOFT_6xx: 2039 case POWERPC_MMU_SOFT_74xx: 2040 ppc6xx_tlb_invalidate_virt(env, addr, 0); 2041 if (env->id_tlbs == 1) { 2042 ppc6xx_tlb_invalidate_virt(env, addr, 1); 2043 } 2044 break; 2045 case POWERPC_MMU_32B: 2046 case POWERPC_MMU_601: 2047 /* Actual CPUs invalidate entire congruence classes based on the 2048 * geometry of their TLBs and some OSes take that into account, 2049 * we just mark the TLB to be flushed later (context synchronizing 2050 * event or sync instruction on 32-bit). 2051 */ 2052 env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH; 2053 break; 2054 default: 2055 /* Should never reach here with other MMU models */ 2056 assert(0); 2057 } 2058 #else 2059 ppc_tlb_invalidate_all(env); 2060 #endif 2061 } 2062 2063 /*****************************************************************************/ 2064 /* Special registers manipulation */ 2065 void ppc_store_sdr1(CPUPPCState *env, target_ulong value) 2066 { 2067 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2068 qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value); 2069 assert(!cpu->vhyp); 2070 #if defined(TARGET_PPC64) 2071 if (env->mmu_model & POWERPC_MMU_64) { 2072 target_ulong sdr_mask = SDR_64_HTABORG | SDR_64_HTABSIZE; 2073 target_ulong htabsize = value & SDR_64_HTABSIZE; 2074 2075 if (value & ~sdr_mask) { 2076 error_report("Invalid bits 0x"TARGET_FMT_lx" set in SDR1", 2077 value & ~sdr_mask); 2078 value &= sdr_mask; 2079 } 2080 if (htabsize > 28) { 2081 error_report("Invalid HTABSIZE 0x" TARGET_FMT_lx" stored in SDR1", 2082 htabsize); 2083 return; 2084 } 2085 } 2086 #endif /* defined(TARGET_PPC64) */ 2087 /* FIXME: Should check for valid HTABMASK values in 32-bit case */ 2088 env->spr[SPR_SDR1] = value; 2089 } 2090 2091 #if defined(TARGET_PPC64) 2092 void ppc_store_ptcr(CPUPPCState *env, target_ulong value) 2093 { 2094 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2095 target_ulong ptcr_mask = PTCR_PATB | PTCR_PATS; 2096 target_ulong patbsize = value & PTCR_PATS; 2097 2098 qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value); 2099 2100 assert(!cpu->vhyp); 2101 assert(env->mmu_model & POWERPC_MMU_3_00); 2102 2103 if (value & ~ptcr_mask) { 2104 error_report("Invalid bits 0x"TARGET_FMT_lx" set in PTCR", 2105 value & ~ptcr_mask); 2106 value &= ptcr_mask; 2107 } 2108 2109 if (patbsize > 24) { 2110 error_report("Invalid Partition Table size 0x" TARGET_FMT_lx 2111 " stored in PTCR", patbsize); 2112 return; 2113 } 2114 2115 env->spr[SPR_PTCR] = value; 2116 } 2117 2118 #endif /* defined(TARGET_PPC64) */ 2119 2120 /* Segment registers load and store */ 2121 target_ulong helper_load_sr(CPUPPCState *env, target_ulong sr_num) 2122 { 2123 #if defined(TARGET_PPC64) 2124 if (env->mmu_model & POWERPC_MMU_64) { 2125 /* XXX */ 2126 return 0; 2127 } 2128 #endif 2129 return env->sr[sr_num]; 2130 } 2131 2132 void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value) 2133 { 2134 qemu_log_mask(CPU_LOG_MMU, 2135 "%s: reg=%d " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__, 2136 (int)srnum, value, env->sr[srnum]); 2137 #if defined(TARGET_PPC64) 2138 if (env->mmu_model & POWERPC_MMU_64) { 2139 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2140 uint64_t esid, vsid; 2141 2142 /* ESID = srnum */ 2143 esid = ((uint64_t)(srnum & 0xf) << 28) | SLB_ESID_V; 2144 2145 /* VSID = VSID */ 2146 vsid = (value & 0xfffffff) << 12; 2147 /* flags = flags */ 2148 vsid |= ((value >> 27) & 0xf) << 8; 2149 2150 ppc_store_slb(cpu, srnum, esid, vsid); 2151 } else 2152 #endif 2153 if (env->sr[srnum] != value) { 2154 env->sr[srnum] = value; 2155 /* Invalidating 256MB of virtual memory in 4kB pages is way longer than 2156 flusing the whole TLB. */ 2157 #if !defined(FLUSH_ALL_TLBS) && 0 2158 { 2159 target_ulong page, end; 2160 /* Invalidate 256 MB of virtual memory */ 2161 page = (16 << 20) * srnum; 2162 end = page + (16 << 20); 2163 for (; page != end; page += TARGET_PAGE_SIZE) { 2164 tlb_flush_page(CPU(cpu), page); 2165 } 2166 } 2167 #else 2168 env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH; 2169 #endif 2170 } 2171 } 2172 2173 /* TLB management */ 2174 void helper_tlbia(CPUPPCState *env) 2175 { 2176 ppc_tlb_invalidate_all(env); 2177 } 2178 2179 void helper_tlbie(CPUPPCState *env, target_ulong addr) 2180 { 2181 ppc_tlb_invalidate_one(env, addr); 2182 } 2183 2184 void helper_tlbiva(CPUPPCState *env, target_ulong addr) 2185 { 2186 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2187 2188 /* tlbiva instruction only exists on BookE */ 2189 assert(env->mmu_model == POWERPC_MMU_BOOKE); 2190 /* XXX: TODO */ 2191 cpu_abort(CPU(cpu), "BookE MMU model is not implemented\n"); 2192 } 2193 2194 /* Software driven TLBs management */ 2195 /* PowerPC 602/603 software TLB load instructions helpers */ 2196 static void do_6xx_tlb(CPUPPCState *env, target_ulong new_EPN, int is_code) 2197 { 2198 target_ulong RPN, CMP, EPN; 2199 int way; 2200 2201 RPN = env->spr[SPR_RPA]; 2202 if (is_code) { 2203 CMP = env->spr[SPR_ICMP]; 2204 EPN = env->spr[SPR_IMISS]; 2205 } else { 2206 CMP = env->spr[SPR_DCMP]; 2207 EPN = env->spr[SPR_DMISS]; 2208 } 2209 way = (env->spr[SPR_SRR1] >> 17) & 1; 2210 (void)EPN; /* avoid a compiler warning */ 2211 LOG_SWTLB("%s: EPN " TARGET_FMT_lx " " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx 2212 " PTE1 " TARGET_FMT_lx " way %d\n", __func__, new_EPN, EPN, CMP, 2213 RPN, way); 2214 /* Store this TLB */ 2215 ppc6xx_tlb_store(env, (uint32_t)(new_EPN & TARGET_PAGE_MASK), 2216 way, is_code, CMP, RPN); 2217 } 2218 2219 void helper_6xx_tlbd(CPUPPCState *env, target_ulong EPN) 2220 { 2221 do_6xx_tlb(env, EPN, 0); 2222 } 2223 2224 void helper_6xx_tlbi(CPUPPCState *env, target_ulong EPN) 2225 { 2226 do_6xx_tlb(env, EPN, 1); 2227 } 2228 2229 /* PowerPC 74xx software TLB load instructions helpers */ 2230 static void do_74xx_tlb(CPUPPCState *env, target_ulong new_EPN, int is_code) 2231 { 2232 target_ulong RPN, CMP, EPN; 2233 int way; 2234 2235 RPN = env->spr[SPR_PTELO]; 2236 CMP = env->spr[SPR_PTEHI]; 2237 EPN = env->spr[SPR_TLBMISS] & ~0x3; 2238 way = env->spr[SPR_TLBMISS] & 0x3; 2239 (void)EPN; /* avoid a compiler warning */ 2240 LOG_SWTLB("%s: EPN " TARGET_FMT_lx " " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx 2241 " PTE1 " TARGET_FMT_lx " way %d\n", __func__, new_EPN, EPN, CMP, 2242 RPN, way); 2243 /* Store this TLB */ 2244 ppc6xx_tlb_store(env, (uint32_t)(new_EPN & TARGET_PAGE_MASK), 2245 way, is_code, CMP, RPN); 2246 } 2247 2248 void helper_74xx_tlbd(CPUPPCState *env, target_ulong EPN) 2249 { 2250 do_74xx_tlb(env, EPN, 0); 2251 } 2252 2253 void helper_74xx_tlbi(CPUPPCState *env, target_ulong EPN) 2254 { 2255 do_74xx_tlb(env, EPN, 1); 2256 } 2257 2258 /*****************************************************************************/ 2259 /* PowerPC 601 specific instructions (POWER bridge) */ 2260 2261 target_ulong helper_rac(CPUPPCState *env, target_ulong addr) 2262 { 2263 mmu_ctx_t ctx; 2264 int nb_BATs; 2265 target_ulong ret = 0; 2266 2267 /* We don't have to generate many instances of this instruction, 2268 * as rac is supervisor only. 2269 */ 2270 /* XXX: FIX THIS: Pretend we have no BAT */ 2271 nb_BATs = env->nb_BATs; 2272 env->nb_BATs = 0; 2273 if (get_physical_address(env, &ctx, addr, 0, ACCESS_INT) == 0) { 2274 ret = ctx.raddr; 2275 } 2276 env->nb_BATs = nb_BATs; 2277 return ret; 2278 } 2279 2280 static inline target_ulong booke_tlb_to_page_size(int size) 2281 { 2282 return 1024 << (2 * size); 2283 } 2284 2285 static inline int booke_page_size_to_tlb(target_ulong page_size) 2286 { 2287 int size; 2288 2289 switch (page_size) { 2290 case 0x00000400UL: 2291 size = 0x0; 2292 break; 2293 case 0x00001000UL: 2294 size = 0x1; 2295 break; 2296 case 0x00004000UL: 2297 size = 0x2; 2298 break; 2299 case 0x00010000UL: 2300 size = 0x3; 2301 break; 2302 case 0x00040000UL: 2303 size = 0x4; 2304 break; 2305 case 0x00100000UL: 2306 size = 0x5; 2307 break; 2308 case 0x00400000UL: 2309 size = 0x6; 2310 break; 2311 case 0x01000000UL: 2312 size = 0x7; 2313 break; 2314 case 0x04000000UL: 2315 size = 0x8; 2316 break; 2317 case 0x10000000UL: 2318 size = 0x9; 2319 break; 2320 case 0x40000000UL: 2321 size = 0xA; 2322 break; 2323 #if defined(TARGET_PPC64) 2324 case 0x000100000000ULL: 2325 size = 0xB; 2326 break; 2327 case 0x000400000000ULL: 2328 size = 0xC; 2329 break; 2330 case 0x001000000000ULL: 2331 size = 0xD; 2332 break; 2333 case 0x004000000000ULL: 2334 size = 0xE; 2335 break; 2336 case 0x010000000000ULL: 2337 size = 0xF; 2338 break; 2339 #endif 2340 default: 2341 size = -1; 2342 break; 2343 } 2344 2345 return size; 2346 } 2347 2348 /* Helpers for 4xx TLB management */ 2349 #define PPC4XX_TLB_ENTRY_MASK 0x0000003f /* Mask for 64 TLB entries */ 2350 2351 #define PPC4XX_TLBHI_V 0x00000040 2352 #define PPC4XX_TLBHI_E 0x00000020 2353 #define PPC4XX_TLBHI_SIZE_MIN 0 2354 #define PPC4XX_TLBHI_SIZE_MAX 7 2355 #define PPC4XX_TLBHI_SIZE_DEFAULT 1 2356 #define PPC4XX_TLBHI_SIZE_SHIFT 7 2357 #define PPC4XX_TLBHI_SIZE_MASK 0x00000007 2358 2359 #define PPC4XX_TLBLO_EX 0x00000200 2360 #define PPC4XX_TLBLO_WR 0x00000100 2361 #define PPC4XX_TLBLO_ATTR_MASK 0x000000FF 2362 #define PPC4XX_TLBLO_RPN_MASK 0xFFFFFC00 2363 2364 target_ulong helper_4xx_tlbre_hi(CPUPPCState *env, target_ulong entry) 2365 { 2366 ppcemb_tlb_t *tlb; 2367 target_ulong ret; 2368 int size; 2369 2370 entry &= PPC4XX_TLB_ENTRY_MASK; 2371 tlb = &env->tlb.tlbe[entry]; 2372 ret = tlb->EPN; 2373 if (tlb->prot & PAGE_VALID) { 2374 ret |= PPC4XX_TLBHI_V; 2375 } 2376 size = booke_page_size_to_tlb(tlb->size); 2377 if (size < PPC4XX_TLBHI_SIZE_MIN || size > PPC4XX_TLBHI_SIZE_MAX) { 2378 size = PPC4XX_TLBHI_SIZE_DEFAULT; 2379 } 2380 ret |= size << PPC4XX_TLBHI_SIZE_SHIFT; 2381 env->spr[SPR_40x_PID] = tlb->PID; 2382 return ret; 2383 } 2384 2385 target_ulong helper_4xx_tlbre_lo(CPUPPCState *env, target_ulong entry) 2386 { 2387 ppcemb_tlb_t *tlb; 2388 target_ulong ret; 2389 2390 entry &= PPC4XX_TLB_ENTRY_MASK; 2391 tlb = &env->tlb.tlbe[entry]; 2392 ret = tlb->RPN; 2393 if (tlb->prot & PAGE_EXEC) { 2394 ret |= PPC4XX_TLBLO_EX; 2395 } 2396 if (tlb->prot & PAGE_WRITE) { 2397 ret |= PPC4XX_TLBLO_WR; 2398 } 2399 return ret; 2400 } 2401 2402 void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry, 2403 target_ulong val) 2404 { 2405 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2406 CPUState *cs = CPU(cpu); 2407 ppcemb_tlb_t *tlb; 2408 target_ulong page, end; 2409 2410 LOG_SWTLB("%s entry %d val " TARGET_FMT_lx "\n", __func__, (int)entry, 2411 val); 2412 entry &= PPC4XX_TLB_ENTRY_MASK; 2413 tlb = &env->tlb.tlbe[entry]; 2414 /* Invalidate previous TLB (if it's valid) */ 2415 if (tlb->prot & PAGE_VALID) { 2416 end = tlb->EPN + tlb->size; 2417 LOG_SWTLB("%s: invalidate old TLB %d start " TARGET_FMT_lx " end " 2418 TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end); 2419 for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) { 2420 tlb_flush_page(cs, page); 2421 } 2422 } 2423 tlb->size = booke_tlb_to_page_size((val >> PPC4XX_TLBHI_SIZE_SHIFT) 2424 & PPC4XX_TLBHI_SIZE_MASK); 2425 /* We cannot handle TLB size < TARGET_PAGE_SIZE. 2426 * If this ever occurs, we should implement TARGET_PAGE_BITS_VARY 2427 */ 2428 if ((val & PPC4XX_TLBHI_V) && tlb->size < TARGET_PAGE_SIZE) { 2429 cpu_abort(cs, "TLB size " TARGET_FMT_lu " < %u " 2430 "are not supported (%d)\n" 2431 "Please implement TARGET_PAGE_BITS_VARY\n", 2432 tlb->size, TARGET_PAGE_SIZE, (int)((val >> 7) & 0x7)); 2433 } 2434 tlb->EPN = val & ~(tlb->size - 1); 2435 if (val & PPC4XX_TLBHI_V) { 2436 tlb->prot |= PAGE_VALID; 2437 if (val & PPC4XX_TLBHI_E) { 2438 /* XXX: TO BE FIXED */ 2439 cpu_abort(cs, 2440 "Little-endian TLB entries are not supported by now\n"); 2441 } 2442 } else { 2443 tlb->prot &= ~PAGE_VALID; 2444 } 2445 tlb->PID = env->spr[SPR_40x_PID]; /* PID */ 2446 LOG_SWTLB("%s: set up TLB %d RPN " TARGET_FMT_plx " EPN " TARGET_FMT_lx 2447 " size " TARGET_FMT_lx " prot %c%c%c%c PID %d\n", __func__, 2448 (int)entry, tlb->RPN, tlb->EPN, tlb->size, 2449 tlb->prot & PAGE_READ ? 'r' : '-', 2450 tlb->prot & PAGE_WRITE ? 'w' : '-', 2451 tlb->prot & PAGE_EXEC ? 'x' : '-', 2452 tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID); 2453 /* Invalidate new TLB (if valid) */ 2454 if (tlb->prot & PAGE_VALID) { 2455 end = tlb->EPN + tlb->size; 2456 LOG_SWTLB("%s: invalidate TLB %d start " TARGET_FMT_lx " end " 2457 TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end); 2458 for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) { 2459 tlb_flush_page(cs, page); 2460 } 2461 } 2462 } 2463 2464 void helper_4xx_tlbwe_lo(CPUPPCState *env, target_ulong entry, 2465 target_ulong val) 2466 { 2467 ppcemb_tlb_t *tlb; 2468 2469 LOG_SWTLB("%s entry %i val " TARGET_FMT_lx "\n", __func__, (int)entry, 2470 val); 2471 entry &= PPC4XX_TLB_ENTRY_MASK; 2472 tlb = &env->tlb.tlbe[entry]; 2473 tlb->attr = val & PPC4XX_TLBLO_ATTR_MASK; 2474 tlb->RPN = val & PPC4XX_TLBLO_RPN_MASK; 2475 tlb->prot = PAGE_READ; 2476 if (val & PPC4XX_TLBLO_EX) { 2477 tlb->prot |= PAGE_EXEC; 2478 } 2479 if (val & PPC4XX_TLBLO_WR) { 2480 tlb->prot |= PAGE_WRITE; 2481 } 2482 LOG_SWTLB("%s: set up TLB %d RPN " TARGET_FMT_plx " EPN " TARGET_FMT_lx 2483 " size " TARGET_FMT_lx " prot %c%c%c%c PID %d\n", __func__, 2484 (int)entry, tlb->RPN, tlb->EPN, tlb->size, 2485 tlb->prot & PAGE_READ ? 'r' : '-', 2486 tlb->prot & PAGE_WRITE ? 'w' : '-', 2487 tlb->prot & PAGE_EXEC ? 'x' : '-', 2488 tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID); 2489 } 2490 2491 target_ulong helper_4xx_tlbsx(CPUPPCState *env, target_ulong address) 2492 { 2493 return ppcemb_tlb_search(env, address, env->spr[SPR_40x_PID]); 2494 } 2495 2496 /* PowerPC 440 TLB management */ 2497 void helper_440_tlbwe(CPUPPCState *env, uint32_t word, target_ulong entry, 2498 target_ulong value) 2499 { 2500 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2501 ppcemb_tlb_t *tlb; 2502 target_ulong EPN, RPN, size; 2503 int do_flush_tlbs; 2504 2505 LOG_SWTLB("%s word %d entry %d value " TARGET_FMT_lx "\n", 2506 __func__, word, (int)entry, value); 2507 do_flush_tlbs = 0; 2508 entry &= 0x3F; 2509 tlb = &env->tlb.tlbe[entry]; 2510 switch (word) { 2511 default: 2512 /* Just here to please gcc */ 2513 case 0: 2514 EPN = value & 0xFFFFFC00; 2515 if ((tlb->prot & PAGE_VALID) && EPN != tlb->EPN) { 2516 do_flush_tlbs = 1; 2517 } 2518 tlb->EPN = EPN; 2519 size = booke_tlb_to_page_size((value >> 4) & 0xF); 2520 if ((tlb->prot & PAGE_VALID) && tlb->size < size) { 2521 do_flush_tlbs = 1; 2522 } 2523 tlb->size = size; 2524 tlb->attr &= ~0x1; 2525 tlb->attr |= (value >> 8) & 1; 2526 if (value & 0x200) { 2527 tlb->prot |= PAGE_VALID; 2528 } else { 2529 if (tlb->prot & PAGE_VALID) { 2530 tlb->prot &= ~PAGE_VALID; 2531 do_flush_tlbs = 1; 2532 } 2533 } 2534 tlb->PID = env->spr[SPR_440_MMUCR] & 0x000000FF; 2535 if (do_flush_tlbs) { 2536 tlb_flush(CPU(cpu)); 2537 } 2538 break; 2539 case 1: 2540 RPN = value & 0xFFFFFC0F; 2541 if ((tlb->prot & PAGE_VALID) && tlb->RPN != RPN) { 2542 tlb_flush(CPU(cpu)); 2543 } 2544 tlb->RPN = RPN; 2545 break; 2546 case 2: 2547 tlb->attr = (tlb->attr & 0x1) | (value & 0x0000FF00); 2548 tlb->prot = tlb->prot & PAGE_VALID; 2549 if (value & 0x1) { 2550 tlb->prot |= PAGE_READ << 4; 2551 } 2552 if (value & 0x2) { 2553 tlb->prot |= PAGE_WRITE << 4; 2554 } 2555 if (value & 0x4) { 2556 tlb->prot |= PAGE_EXEC << 4; 2557 } 2558 if (value & 0x8) { 2559 tlb->prot |= PAGE_READ; 2560 } 2561 if (value & 0x10) { 2562 tlb->prot |= PAGE_WRITE; 2563 } 2564 if (value & 0x20) { 2565 tlb->prot |= PAGE_EXEC; 2566 } 2567 break; 2568 } 2569 } 2570 2571 target_ulong helper_440_tlbre(CPUPPCState *env, uint32_t word, 2572 target_ulong entry) 2573 { 2574 ppcemb_tlb_t *tlb; 2575 target_ulong ret; 2576 int size; 2577 2578 entry &= 0x3F; 2579 tlb = &env->tlb.tlbe[entry]; 2580 switch (word) { 2581 default: 2582 /* Just here to please gcc */ 2583 case 0: 2584 ret = tlb->EPN; 2585 size = booke_page_size_to_tlb(tlb->size); 2586 if (size < 0 || size > 0xF) { 2587 size = 1; 2588 } 2589 ret |= size << 4; 2590 if (tlb->attr & 0x1) { 2591 ret |= 0x100; 2592 } 2593 if (tlb->prot & PAGE_VALID) { 2594 ret |= 0x200; 2595 } 2596 env->spr[SPR_440_MMUCR] &= ~0x000000FF; 2597 env->spr[SPR_440_MMUCR] |= tlb->PID; 2598 break; 2599 case 1: 2600 ret = tlb->RPN; 2601 break; 2602 case 2: 2603 ret = tlb->attr & ~0x1; 2604 if (tlb->prot & (PAGE_READ << 4)) { 2605 ret |= 0x1; 2606 } 2607 if (tlb->prot & (PAGE_WRITE << 4)) { 2608 ret |= 0x2; 2609 } 2610 if (tlb->prot & (PAGE_EXEC << 4)) { 2611 ret |= 0x4; 2612 } 2613 if (tlb->prot & PAGE_READ) { 2614 ret |= 0x8; 2615 } 2616 if (tlb->prot & PAGE_WRITE) { 2617 ret |= 0x10; 2618 } 2619 if (tlb->prot & PAGE_EXEC) { 2620 ret |= 0x20; 2621 } 2622 break; 2623 } 2624 return ret; 2625 } 2626 2627 target_ulong helper_440_tlbsx(CPUPPCState *env, target_ulong address) 2628 { 2629 return ppcemb_tlb_search(env, address, env->spr[SPR_440_MMUCR] & 0xFF); 2630 } 2631 2632 /* PowerPC BookE 2.06 TLB management */ 2633 2634 static ppcmas_tlb_t *booke206_cur_tlb(CPUPPCState *env) 2635 { 2636 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2637 uint32_t tlbncfg = 0; 2638 int esel = (env->spr[SPR_BOOKE_MAS0] & MAS0_ESEL_MASK) >> MAS0_ESEL_SHIFT; 2639 int ea = (env->spr[SPR_BOOKE_MAS2] & MAS2_EPN_MASK); 2640 int tlb; 2641 2642 tlb = (env->spr[SPR_BOOKE_MAS0] & MAS0_TLBSEL_MASK) >> MAS0_TLBSEL_SHIFT; 2643 tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlb]; 2644 2645 if ((tlbncfg & TLBnCFG_HES) && (env->spr[SPR_BOOKE_MAS0] & MAS0_HES)) { 2646 cpu_abort(CPU(cpu), "we don't support HES yet\n"); 2647 } 2648 2649 return booke206_get_tlbm(env, tlb, ea, esel); 2650 } 2651 2652 void helper_booke_setpid(CPUPPCState *env, uint32_t pidn, target_ulong pid) 2653 { 2654 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2655 2656 env->spr[pidn] = pid; 2657 /* changing PIDs mean we're in a different address space now */ 2658 tlb_flush(CPU(cpu)); 2659 } 2660 2661 void helper_booke_set_eplc(CPUPPCState *env, target_ulong val) 2662 { 2663 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2664 env->spr[SPR_BOOKE_EPLC] = val & EPID_MASK; 2665 tlb_flush_by_mmuidx(CPU(cpu), 1 << PPC_TLB_EPID_LOAD); 2666 } 2667 void helper_booke_set_epsc(CPUPPCState *env, target_ulong val) 2668 { 2669 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2670 env->spr[SPR_BOOKE_EPSC] = val & EPID_MASK; 2671 tlb_flush_by_mmuidx(CPU(cpu), 1 << PPC_TLB_EPID_STORE); 2672 } 2673 2674 static inline void flush_page(CPUPPCState *env, ppcmas_tlb_t *tlb) 2675 { 2676 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2677 2678 if (booke206_tlb_to_page_size(env, tlb) == TARGET_PAGE_SIZE) { 2679 tlb_flush_page(CPU(cpu), tlb->mas2 & MAS2_EPN_MASK); 2680 } else { 2681 tlb_flush(CPU(cpu)); 2682 } 2683 } 2684 2685 void helper_booke206_tlbwe(CPUPPCState *env) 2686 { 2687 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2688 uint32_t tlbncfg, tlbn; 2689 ppcmas_tlb_t *tlb; 2690 uint32_t size_tlb, size_ps; 2691 target_ulong mask; 2692 2693 2694 switch (env->spr[SPR_BOOKE_MAS0] & MAS0_WQ_MASK) { 2695 case MAS0_WQ_ALWAYS: 2696 /* good to go, write that entry */ 2697 break; 2698 case MAS0_WQ_COND: 2699 /* XXX check if reserved */ 2700 if (0) { 2701 return; 2702 } 2703 break; 2704 case MAS0_WQ_CLR_RSRV: 2705 /* XXX clear entry */ 2706 return; 2707 default: 2708 /* no idea what to do */ 2709 return; 2710 } 2711 2712 if (((env->spr[SPR_BOOKE_MAS0] & MAS0_ATSEL) == MAS0_ATSEL_LRAT) && 2713 !msr_gs) { 2714 /* XXX we don't support direct LRAT setting yet */ 2715 fprintf(stderr, "cpu: don't support LRAT setting yet\n"); 2716 return; 2717 } 2718 2719 tlbn = (env->spr[SPR_BOOKE_MAS0] & MAS0_TLBSEL_MASK) >> MAS0_TLBSEL_SHIFT; 2720 tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn]; 2721 2722 tlb = booke206_cur_tlb(env); 2723 2724 if (!tlb) { 2725 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 2726 POWERPC_EXCP_INVAL | 2727 POWERPC_EXCP_INVAL_INVAL, GETPC()); 2728 } 2729 2730 /* check that we support the targeted size */ 2731 size_tlb = (env->spr[SPR_BOOKE_MAS1] & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT; 2732 size_ps = booke206_tlbnps(env, tlbn); 2733 if ((env->spr[SPR_BOOKE_MAS1] & MAS1_VALID) && (tlbncfg & TLBnCFG_AVAIL) && 2734 !(size_ps & (1 << size_tlb))) { 2735 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 2736 POWERPC_EXCP_INVAL | 2737 POWERPC_EXCP_INVAL_INVAL, GETPC()); 2738 } 2739 2740 if (msr_gs) { 2741 cpu_abort(CPU(cpu), "missing HV implementation\n"); 2742 } 2743 2744 if (tlb->mas1 & MAS1_VALID) { 2745 /* Invalidate the page in QEMU TLB if it was a valid entry. 2746 * 2747 * In "PowerPC e500 Core Family Reference Manual, Rev. 1", 2748 * Section "12.4.2 TLB Write Entry (tlbwe) Instruction": 2749 * (https://www.nxp.com/docs/en/reference-manual/E500CORERM.pdf) 2750 * 2751 * "Note that when an L2 TLB entry is written, it may be displacing an 2752 * already valid entry in the same L2 TLB location (a victim). If a 2753 * valid L1 TLB entry corresponds to the L2 MMU victim entry, that L1 2754 * TLB entry is automatically invalidated." */ 2755 flush_page(env, tlb); 2756 } 2757 2758 tlb->mas7_3 = ((uint64_t)env->spr[SPR_BOOKE_MAS7] << 32) | 2759 env->spr[SPR_BOOKE_MAS3]; 2760 tlb->mas1 = env->spr[SPR_BOOKE_MAS1]; 2761 2762 if ((env->spr[SPR_MMUCFG] & MMUCFG_MAVN) == MMUCFG_MAVN_V2) { 2763 /* For TLB which has a fixed size TSIZE is ignored with MAV2 */ 2764 booke206_fixed_size_tlbn(env, tlbn, tlb); 2765 } else { 2766 if (!(tlbncfg & TLBnCFG_AVAIL)) { 2767 /* force !AVAIL TLB entries to correct page size */ 2768 tlb->mas1 &= ~MAS1_TSIZE_MASK; 2769 /* XXX can be configured in MMUCSR0 */ 2770 tlb->mas1 |= (tlbncfg & TLBnCFG_MINSIZE) >> 12; 2771 } 2772 } 2773 2774 /* Make a mask from TLB size to discard invalid bits in EPN field */ 2775 mask = ~(booke206_tlb_to_page_size(env, tlb) - 1); 2776 /* Add a mask for page attributes */ 2777 mask |= MAS2_ACM | MAS2_VLE | MAS2_W | MAS2_I | MAS2_M | MAS2_G | MAS2_E; 2778 2779 if (!msr_cm) { 2780 /* Executing a tlbwe instruction in 32-bit mode will set 2781 * bits 0:31 of the TLB EPN field to zero. 2782 */ 2783 mask &= 0xffffffff; 2784 } 2785 2786 tlb->mas2 = env->spr[SPR_BOOKE_MAS2] & mask; 2787 2788 if (!(tlbncfg & TLBnCFG_IPROT)) { 2789 /* no IPROT supported by TLB */ 2790 tlb->mas1 &= ~MAS1_IPROT; 2791 } 2792 2793 flush_page(env, tlb); 2794 } 2795 2796 static inline void booke206_tlb_to_mas(CPUPPCState *env, ppcmas_tlb_t *tlb) 2797 { 2798 int tlbn = booke206_tlbm_to_tlbn(env, tlb); 2799 int way = booke206_tlbm_to_way(env, tlb); 2800 2801 env->spr[SPR_BOOKE_MAS0] = tlbn << MAS0_TLBSEL_SHIFT; 2802 env->spr[SPR_BOOKE_MAS0] |= way << MAS0_ESEL_SHIFT; 2803 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT; 2804 2805 env->spr[SPR_BOOKE_MAS1] = tlb->mas1; 2806 env->spr[SPR_BOOKE_MAS2] = tlb->mas2; 2807 env->spr[SPR_BOOKE_MAS3] = tlb->mas7_3; 2808 env->spr[SPR_BOOKE_MAS7] = tlb->mas7_3 >> 32; 2809 } 2810 2811 void helper_booke206_tlbre(CPUPPCState *env) 2812 { 2813 ppcmas_tlb_t *tlb = NULL; 2814 2815 tlb = booke206_cur_tlb(env); 2816 if (!tlb) { 2817 env->spr[SPR_BOOKE_MAS1] = 0; 2818 } else { 2819 booke206_tlb_to_mas(env, tlb); 2820 } 2821 } 2822 2823 void helper_booke206_tlbsx(CPUPPCState *env, target_ulong address) 2824 { 2825 ppcmas_tlb_t *tlb = NULL; 2826 int i, j; 2827 hwaddr raddr; 2828 uint32_t spid, sas; 2829 2830 spid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID_MASK) >> MAS6_SPID_SHIFT; 2831 sas = env->spr[SPR_BOOKE_MAS6] & MAS6_SAS; 2832 2833 for (i = 0; i < BOOKE206_MAX_TLBN; i++) { 2834 int ways = booke206_tlb_ways(env, i); 2835 2836 for (j = 0; j < ways; j++) { 2837 tlb = booke206_get_tlbm(env, i, address, j); 2838 2839 if (!tlb) { 2840 continue; 2841 } 2842 2843 if (ppcmas_tlb_check(env, tlb, &raddr, address, spid)) { 2844 continue; 2845 } 2846 2847 if (sas != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) { 2848 continue; 2849 } 2850 2851 booke206_tlb_to_mas(env, tlb); 2852 return; 2853 } 2854 } 2855 2856 /* no entry found, fill with defaults */ 2857 env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK; 2858 env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK; 2859 env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK; 2860 env->spr[SPR_BOOKE_MAS3] = 0; 2861 env->spr[SPR_BOOKE_MAS7] = 0; 2862 2863 if (env->spr[SPR_BOOKE_MAS6] & MAS6_SAS) { 2864 env->spr[SPR_BOOKE_MAS1] |= MAS1_TS; 2865 } 2866 2867 env->spr[SPR_BOOKE_MAS1] |= (env->spr[SPR_BOOKE_MAS6] >> 16) 2868 << MAS1_TID_SHIFT; 2869 2870 /* next victim logic */ 2871 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT; 2872 env->last_way++; 2873 env->last_way &= booke206_tlb_ways(env, 0) - 1; 2874 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT; 2875 } 2876 2877 static inline void booke206_invalidate_ea_tlb(CPUPPCState *env, int tlbn, 2878 uint32_t ea) 2879 { 2880 int i; 2881 int ways = booke206_tlb_ways(env, tlbn); 2882 target_ulong mask; 2883 2884 for (i = 0; i < ways; i++) { 2885 ppcmas_tlb_t *tlb = booke206_get_tlbm(env, tlbn, ea, i); 2886 if (!tlb) { 2887 continue; 2888 } 2889 mask = ~(booke206_tlb_to_page_size(env, tlb) - 1); 2890 if (((tlb->mas2 & MAS2_EPN_MASK) == (ea & mask)) && 2891 !(tlb->mas1 & MAS1_IPROT)) { 2892 tlb->mas1 &= ~MAS1_VALID; 2893 } 2894 } 2895 } 2896 2897 void helper_booke206_tlbivax(CPUPPCState *env, target_ulong address) 2898 { 2899 CPUState *cs; 2900 2901 if (address & 0x4) { 2902 /* flush all entries */ 2903 if (address & 0x8) { 2904 /* flush all of TLB1 */ 2905 booke206_flush_tlb(env, BOOKE206_FLUSH_TLB1, 1); 2906 } else { 2907 /* flush all of TLB0 */ 2908 booke206_flush_tlb(env, BOOKE206_FLUSH_TLB0, 0); 2909 } 2910 return; 2911 } 2912 2913 if (address & 0x8) { 2914 /* flush TLB1 entries */ 2915 booke206_invalidate_ea_tlb(env, 1, address); 2916 CPU_FOREACH(cs) { 2917 tlb_flush(cs); 2918 } 2919 } else { 2920 /* flush TLB0 entries */ 2921 booke206_invalidate_ea_tlb(env, 0, address); 2922 CPU_FOREACH(cs) { 2923 tlb_flush_page(cs, address & MAS2_EPN_MASK); 2924 } 2925 } 2926 } 2927 2928 void helper_booke206_tlbilx0(CPUPPCState *env, target_ulong address) 2929 { 2930 /* XXX missing LPID handling */ 2931 booke206_flush_tlb(env, -1, 1); 2932 } 2933 2934 void helper_booke206_tlbilx1(CPUPPCState *env, target_ulong address) 2935 { 2936 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2937 int i, j; 2938 int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID); 2939 ppcmas_tlb_t *tlb = env->tlb.tlbm; 2940 int tlb_size; 2941 2942 /* XXX missing LPID handling */ 2943 for (i = 0; i < BOOKE206_MAX_TLBN; i++) { 2944 tlb_size = booke206_tlb_size(env, i); 2945 for (j = 0; j < tlb_size; j++) { 2946 if (!(tlb[j].mas1 & MAS1_IPROT) && 2947 ((tlb[j].mas1 & MAS1_TID_MASK) == tid)) { 2948 tlb[j].mas1 &= ~MAS1_VALID; 2949 } 2950 } 2951 tlb += booke206_tlb_size(env, i); 2952 } 2953 tlb_flush(CPU(cpu)); 2954 } 2955 2956 void helper_booke206_tlbilx3(CPUPPCState *env, target_ulong address) 2957 { 2958 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2959 int i, j; 2960 ppcmas_tlb_t *tlb; 2961 int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID); 2962 int pid = tid >> MAS6_SPID_SHIFT; 2963 int sgs = env->spr[SPR_BOOKE_MAS5] & MAS5_SGS; 2964 int ind = (env->spr[SPR_BOOKE_MAS6] & MAS6_SIND) ? MAS1_IND : 0; 2965 /* XXX check for unsupported isize and raise an invalid opcode then */ 2966 int size = env->spr[SPR_BOOKE_MAS6] & MAS6_ISIZE_MASK; 2967 /* XXX implement MAV2 handling */ 2968 bool mav2 = false; 2969 2970 /* XXX missing LPID handling */ 2971 /* flush by pid and ea */ 2972 for (i = 0; i < BOOKE206_MAX_TLBN; i++) { 2973 int ways = booke206_tlb_ways(env, i); 2974 2975 for (j = 0; j < ways; j++) { 2976 tlb = booke206_get_tlbm(env, i, address, j); 2977 if (!tlb) { 2978 continue; 2979 } 2980 if ((ppcmas_tlb_check(env, tlb, NULL, address, pid) != 0) || 2981 (tlb->mas1 & MAS1_IPROT) || 2982 ((tlb->mas1 & MAS1_IND) != ind) || 2983 ((tlb->mas8 & MAS8_TGS) != sgs)) { 2984 continue; 2985 } 2986 if (mav2 && ((tlb->mas1 & MAS1_TSIZE_MASK) != size)) { 2987 /* XXX only check when MMUCFG[TWC] || TLBnCFG[HES] */ 2988 continue; 2989 } 2990 /* XXX e500mc doesn't match SAS, but other cores might */ 2991 tlb->mas1 &= ~MAS1_VALID; 2992 } 2993 } 2994 tlb_flush(CPU(cpu)); 2995 } 2996 2997 void helper_booke206_tlbflush(CPUPPCState *env, target_ulong type) 2998 { 2999 int flags = 0; 3000 3001 if (type & 2) { 3002 flags |= BOOKE206_FLUSH_TLB1; 3003 } 3004 3005 if (type & 4) { 3006 flags |= BOOKE206_FLUSH_TLB0; 3007 } 3008 3009 booke206_flush_tlb(env, flags, 1); 3010 } 3011 3012 3013 void helper_check_tlb_flush_local(CPUPPCState *env) 3014 { 3015 check_tlb_flush(env, false); 3016 } 3017 3018 void helper_check_tlb_flush_global(CPUPPCState *env) 3019 { 3020 check_tlb_flush(env, true); 3021 } 3022 3023 /*****************************************************************************/ 3024 3025 /* try to fill the TLB and return an exception if error. If retaddr is 3026 NULL, it means that the function was called in C code (i.e. not 3027 from generated code or from helper.c) */ 3028 /* XXX: fix it to restore all registers */ 3029 void tlb_fill(CPUState *cs, target_ulong addr, int size, 3030 MMUAccessType access_type, int mmu_idx, uintptr_t retaddr) 3031 { 3032 PowerPCCPU *cpu = POWERPC_CPU(cs); 3033 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); 3034 CPUPPCState *env = &cpu->env; 3035 int ret; 3036 3037 if (pcc->handle_mmu_fault) { 3038 ret = pcc->handle_mmu_fault(cpu, addr, access_type, mmu_idx); 3039 } else { 3040 ret = cpu_ppc_handle_mmu_fault(env, addr, access_type, mmu_idx); 3041 } 3042 if (unlikely(ret != 0)) { 3043 raise_exception_err_ra(env, cs->exception_index, env->error_code, 3044 retaddr); 3045 } 3046 } 3047