1 /* 2 * SH4 emulation 3 * 4 * Copyright (c) 2005 Samuel Tardieu 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 22 #include "cpu.h" 23 #include "exec/exec-all.h" 24 #include "exec/log.h" 25 26 #if !defined(CONFIG_USER_ONLY) 27 #include "hw/sh4/sh_intc.h" 28 #include "sysemu/runstate.h" 29 #endif 30 31 #define MMU_OK 0 32 #define MMU_ITLB_MISS (-1) 33 #define MMU_ITLB_MULTIPLE (-2) 34 #define MMU_ITLB_VIOLATION (-3) 35 #define MMU_DTLB_MISS_READ (-4) 36 #define MMU_DTLB_MISS_WRITE (-5) 37 #define MMU_DTLB_INITIAL_WRITE (-6) 38 #define MMU_DTLB_VIOLATION_READ (-7) 39 #define MMU_DTLB_VIOLATION_WRITE (-8) 40 #define MMU_DTLB_MULTIPLE (-9) 41 #define MMU_DTLB_MISS (-10) 42 #define MMU_IADDR_ERROR (-11) 43 #define MMU_DADDR_ERROR_READ (-12) 44 #define MMU_DADDR_ERROR_WRITE (-13) 45 46 #if defined(CONFIG_USER_ONLY) 47 48 int cpu_sh4_is_cached(CPUSH4State *env, target_ulong addr) 49 { 50 /* For user mode, only U0 area is cacheable. */ 51 return !(addr & 0x80000000); 52 } 53 54 #else /* !CONFIG_USER_ONLY */ 55 56 void superh_cpu_do_interrupt(CPUState *cs) 57 { 58 CPUSH4State *env = cpu_env(cs); 59 int do_irq = cs->interrupt_request & CPU_INTERRUPT_HARD; 60 int do_exp, irq_vector = cs->exception_index; 61 62 /* prioritize exceptions over interrupts */ 63 64 do_exp = cs->exception_index != -1; 65 do_irq = do_irq && (cs->exception_index == -1); 66 67 if (env->sr & (1u << SR_BL)) { 68 if (do_exp && cs->exception_index != 0x1e0) { 69 /* In theory a masked exception generates a reset exception, 70 which in turn jumps to the reset vector. However this only 71 works when using a bootloader. When using a kernel and an 72 initrd, they need to be reloaded and the program counter 73 should be loaded with the kernel entry point. 74 qemu_system_reset_request takes care of that. */ 75 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); 76 return; 77 } 78 if (do_irq && !env->in_sleep) { 79 return; /* masked */ 80 } 81 } 82 env->in_sleep = 0; 83 84 if (do_irq) { 85 irq_vector = sh_intc_get_pending_vector(env->intc_handle, 86 (env->sr >> 4) & 0xf); 87 if (irq_vector == -1) { 88 return; /* masked */ 89 } 90 } 91 92 if (qemu_loglevel_mask(CPU_LOG_INT)) { 93 const char *expname; 94 switch (cs->exception_index) { 95 case 0x0e0: 96 expname = "addr_error"; 97 break; 98 case 0x040: 99 expname = "tlb_miss"; 100 break; 101 case 0x0a0: 102 expname = "tlb_violation"; 103 break; 104 case 0x180: 105 expname = "illegal_instruction"; 106 break; 107 case 0x1a0: 108 expname = "slot_illegal_instruction"; 109 break; 110 case 0x800: 111 expname = "fpu_disable"; 112 break; 113 case 0x820: 114 expname = "slot_fpu"; 115 break; 116 case 0x100: 117 expname = "data_write"; 118 break; 119 case 0x060: 120 expname = "dtlb_miss_write"; 121 break; 122 case 0x0c0: 123 expname = "dtlb_violation_write"; 124 break; 125 case 0x120: 126 expname = "fpu_exception"; 127 break; 128 case 0x080: 129 expname = "initial_page_write"; 130 break; 131 case 0x160: 132 expname = "trapa"; 133 break; 134 default: 135 expname = do_irq ? "interrupt" : "???"; 136 break; 137 } 138 qemu_log("exception 0x%03x [%s] raised\n", 139 irq_vector, expname); 140 log_cpu_state(cs, 0); 141 } 142 143 env->ssr = cpu_read_sr(env); 144 env->spc = env->pc; 145 env->sgr = env->gregs[15]; 146 env->sr |= (1u << SR_BL) | (1u << SR_MD) | (1u << SR_RB); 147 env->lock_addr = -1; 148 149 if (env->flags & TB_FLAG_DELAY_SLOT_MASK) { 150 /* Branch instruction should be executed again before delay slot. */ 151 env->spc -= 2; 152 /* Clear flags for exception/interrupt routine. */ 153 env->flags &= ~TB_FLAG_DELAY_SLOT_MASK; 154 } 155 156 if (do_exp) { 157 env->expevt = cs->exception_index; 158 switch (cs->exception_index) { 159 case 0x000: 160 case 0x020: 161 case 0x140: 162 env->sr &= ~(1u << SR_FD); 163 env->sr |= 0xf << 4; /* IMASK */ 164 env->pc = 0xa0000000; 165 break; 166 case 0x040: 167 case 0x060: 168 env->pc = env->vbr + 0x400; 169 break; 170 case 0x160: 171 env->spc += 2; /* special case for TRAPA */ 172 /* fall through */ 173 default: 174 env->pc = env->vbr + 0x100; 175 break; 176 } 177 return; 178 } 179 180 if (do_irq) { 181 env->intevt = irq_vector; 182 env->pc = env->vbr + 0x600; 183 return; 184 } 185 } 186 187 static void update_itlb_use(CPUSH4State * env, int itlbnb) 188 { 189 uint8_t or_mask = 0, and_mask = (uint8_t) - 1; 190 191 switch (itlbnb) { 192 case 0: 193 and_mask = 0x1f; 194 break; 195 case 1: 196 and_mask = 0xe7; 197 or_mask = 0x80; 198 break; 199 case 2: 200 and_mask = 0xfb; 201 or_mask = 0x50; 202 break; 203 case 3: 204 or_mask = 0x2c; 205 break; 206 } 207 208 env->mmucr &= (and_mask << 24) | 0x00ffffff; 209 env->mmucr |= (or_mask << 24); 210 } 211 212 static int itlb_replacement(CPUSH4State * env) 213 { 214 if ((env->mmucr & 0xe0000000) == 0xe0000000) { 215 return 0; 216 } 217 if ((env->mmucr & 0x98000000) == 0x18000000) { 218 return 1; 219 } 220 if ((env->mmucr & 0x54000000) == 0x04000000) { 221 return 2; 222 } 223 if ((env->mmucr & 0x2c000000) == 0x00000000) { 224 return 3; 225 } 226 cpu_abort(env_cpu(env), "Unhandled itlb_replacement"); 227 } 228 229 /* Find the corresponding entry in the right TLB 230 Return entry, MMU_DTLB_MISS or MMU_DTLB_MULTIPLE 231 */ 232 static int find_tlb_entry(CPUSH4State * env, target_ulong address, 233 tlb_t * entries, uint8_t nbtlb, int use_asid) 234 { 235 int match = MMU_DTLB_MISS; 236 uint32_t start, end; 237 uint8_t asid; 238 int i; 239 240 asid = env->pteh & 0xff; 241 242 for (i = 0; i < nbtlb; i++) { 243 if (!entries[i].v) 244 continue; /* Invalid entry */ 245 if (!entries[i].sh && use_asid && entries[i].asid != asid) 246 continue; /* Bad ASID */ 247 start = (entries[i].vpn << 10) & ~(entries[i].size - 1); 248 end = start + entries[i].size - 1; 249 if (address >= start && address <= end) { /* Match */ 250 if (match != MMU_DTLB_MISS) 251 return MMU_DTLB_MULTIPLE; /* Multiple match */ 252 match = i; 253 } 254 } 255 return match; 256 } 257 258 static void increment_urc(CPUSH4State * env) 259 { 260 uint8_t urb, urc; 261 262 /* Increment URC */ 263 urb = ((env->mmucr) >> 18) & 0x3f; 264 urc = ((env->mmucr) >> 10) & 0x3f; 265 urc++; 266 if ((urb > 0 && urc > urb) || urc > (UTLB_SIZE - 1)) 267 urc = 0; 268 env->mmucr = (env->mmucr & 0xffff03ff) | (urc << 10); 269 } 270 271 /* Copy and utlb entry into itlb 272 Return entry 273 */ 274 static int copy_utlb_entry_itlb(CPUSH4State *env, int utlb) 275 { 276 int itlb; 277 278 tlb_t * ientry; 279 itlb = itlb_replacement(env); 280 ientry = &env->itlb[itlb]; 281 if (ientry->v) { 282 tlb_flush_page(env_cpu(env), ientry->vpn << 10); 283 } 284 *ientry = env->utlb[utlb]; 285 update_itlb_use(env, itlb); 286 return itlb; 287 } 288 289 /* Find itlb entry 290 Return entry, MMU_ITLB_MISS, MMU_ITLB_MULTIPLE or MMU_DTLB_MULTIPLE 291 */ 292 static int find_itlb_entry(CPUSH4State * env, target_ulong address, 293 int use_asid) 294 { 295 int e; 296 297 e = find_tlb_entry(env, address, env->itlb, ITLB_SIZE, use_asid); 298 if (e == MMU_DTLB_MULTIPLE) { 299 e = MMU_ITLB_MULTIPLE; 300 } else if (e == MMU_DTLB_MISS) { 301 e = MMU_ITLB_MISS; 302 } else if (e >= 0) { 303 update_itlb_use(env, e); 304 } 305 return e; 306 } 307 308 /* Find utlb entry 309 Return entry, MMU_DTLB_MISS, MMU_DTLB_MULTIPLE */ 310 static int find_utlb_entry(CPUSH4State * env, target_ulong address, int use_asid) 311 { 312 /* per utlb access */ 313 increment_urc(env); 314 315 /* Return entry */ 316 return find_tlb_entry(env, address, env->utlb, UTLB_SIZE, use_asid); 317 } 318 319 /* Match address against MMU 320 Return MMU_OK, MMU_DTLB_MISS_READ, MMU_DTLB_MISS_WRITE, 321 MMU_DTLB_INITIAL_WRITE, MMU_DTLB_VIOLATION_READ, 322 MMU_DTLB_VIOLATION_WRITE, MMU_ITLB_MISS, 323 MMU_ITLB_MULTIPLE, MMU_ITLB_VIOLATION, 324 MMU_IADDR_ERROR, MMU_DADDR_ERROR_READ, MMU_DADDR_ERROR_WRITE. 325 */ 326 static int get_mmu_address(CPUSH4State * env, target_ulong * physical, 327 int *prot, target_ulong address, 328 MMUAccessType access_type) 329 { 330 int use_asid, n; 331 tlb_t *matching = NULL; 332 333 use_asid = !(env->mmucr & MMUCR_SV) || !(env->sr & (1u << SR_MD)); 334 335 if (access_type == MMU_INST_FETCH) { 336 n = find_itlb_entry(env, address, use_asid); 337 if (n >= 0) { 338 matching = &env->itlb[n]; 339 if (!(env->sr & (1u << SR_MD)) && !(matching->pr & 2)) { 340 n = MMU_ITLB_VIOLATION; 341 } else { 342 *prot = PAGE_EXEC; 343 } 344 } else { 345 n = find_utlb_entry(env, address, use_asid); 346 if (n >= 0) { 347 n = copy_utlb_entry_itlb(env, n); 348 matching = &env->itlb[n]; 349 if (!(env->sr & (1u << SR_MD)) && !(matching->pr & 2)) { 350 n = MMU_ITLB_VIOLATION; 351 } else { 352 *prot = PAGE_READ | PAGE_EXEC; 353 if ((matching->pr & 1) && matching->d) { 354 *prot |= PAGE_WRITE; 355 } 356 } 357 } else if (n == MMU_DTLB_MULTIPLE) { 358 n = MMU_ITLB_MULTIPLE; 359 } else if (n == MMU_DTLB_MISS) { 360 n = MMU_ITLB_MISS; 361 } 362 } 363 } else { 364 n = find_utlb_entry(env, address, use_asid); 365 if (n >= 0) { 366 matching = &env->utlb[n]; 367 if (!(env->sr & (1u << SR_MD)) && !(matching->pr & 2)) { 368 n = (access_type == MMU_DATA_STORE) 369 ? MMU_DTLB_VIOLATION_WRITE : MMU_DTLB_VIOLATION_READ; 370 } else if ((access_type == MMU_DATA_STORE) && !(matching->pr & 1)) { 371 n = MMU_DTLB_VIOLATION_WRITE; 372 } else if ((access_type == MMU_DATA_STORE) && !matching->d) { 373 n = MMU_DTLB_INITIAL_WRITE; 374 } else { 375 *prot = PAGE_READ; 376 if ((matching->pr & 1) && matching->d) { 377 *prot |= PAGE_WRITE; 378 } 379 } 380 } else if (n == MMU_DTLB_MISS) { 381 n = (access_type == MMU_DATA_STORE) 382 ? MMU_DTLB_MISS_WRITE : MMU_DTLB_MISS_READ; 383 } 384 } 385 if (n >= 0) { 386 n = MMU_OK; 387 *physical = ((matching->ppn << 10) & ~(matching->size - 1)) 388 | (address & (matching->size - 1)); 389 } 390 return n; 391 } 392 393 static int get_physical_address(CPUSH4State * env, target_ulong * physical, 394 int *prot, target_ulong address, 395 MMUAccessType access_type) 396 { 397 /* P1, P2 and P4 areas do not use translation */ 398 if ((address >= 0x80000000 && address < 0xc0000000) || address >= 0xe0000000) { 399 if (!(env->sr & (1u << SR_MD)) 400 && (address < 0xe0000000 || address >= 0xe4000000)) { 401 /* Unauthorized access in user mode (only store queues are available) */ 402 qemu_log_mask(LOG_GUEST_ERROR, "Unauthorized access\n"); 403 if (access_type == MMU_DATA_LOAD) { 404 return MMU_DADDR_ERROR_READ; 405 } else if (access_type == MMU_DATA_STORE) { 406 return MMU_DADDR_ERROR_WRITE; 407 } else { 408 return MMU_IADDR_ERROR; 409 } 410 } 411 if (address >= 0x80000000 && address < 0xc0000000) { 412 /* Mask upper 3 bits for P1 and P2 areas */ 413 *physical = address & 0x1fffffff; 414 } else { 415 *physical = address; 416 } 417 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 418 return MMU_OK; 419 } 420 421 /* If MMU is disabled, return the corresponding physical page */ 422 if (!(env->mmucr & MMUCR_AT)) { 423 *physical = address & 0x1FFFFFFF; 424 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 425 return MMU_OK; 426 } 427 428 /* We need to resort to the MMU */ 429 return get_mmu_address(env, physical, prot, address, access_type); 430 } 431 432 hwaddr superh_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) 433 { 434 target_ulong physical; 435 int prot; 436 437 if (get_physical_address(cpu_env(cs), &physical, &prot, addr, MMU_DATA_LOAD) 438 == MMU_OK) { 439 return physical; 440 } 441 442 return -1; 443 } 444 445 void cpu_load_tlb(CPUSH4State * env) 446 { 447 CPUState *cs = env_cpu(env); 448 int n = cpu_mmucr_urc(env->mmucr); 449 tlb_t * entry = &env->utlb[n]; 450 451 if (entry->v) { 452 /* Overwriting valid entry in utlb. */ 453 target_ulong address = entry->vpn << 10; 454 tlb_flush_page(cs, address); 455 } 456 457 /* Take values into cpu status from registers. */ 458 entry->asid = (uint8_t)cpu_pteh_asid(env->pteh); 459 entry->vpn = cpu_pteh_vpn(env->pteh); 460 entry->v = (uint8_t)cpu_ptel_v(env->ptel); 461 entry->ppn = cpu_ptel_ppn(env->ptel); 462 entry->sz = (uint8_t)cpu_ptel_sz(env->ptel); 463 switch (entry->sz) { 464 case 0: /* 00 */ 465 entry->size = 1024; /* 1K */ 466 break; 467 case 1: /* 01 */ 468 entry->size = 1024 * 4; /* 4K */ 469 break; 470 case 2: /* 10 */ 471 entry->size = 1024 * 64; /* 64K */ 472 break; 473 case 3: /* 11 */ 474 entry->size = 1024 * 1024; /* 1M */ 475 break; 476 default: 477 cpu_abort(cs, "Unhandled load_tlb"); 478 break; 479 } 480 entry->sh = (uint8_t)cpu_ptel_sh(env->ptel); 481 entry->c = (uint8_t)cpu_ptel_c(env->ptel); 482 entry->pr = (uint8_t)cpu_ptel_pr(env->ptel); 483 entry->d = (uint8_t)cpu_ptel_d(env->ptel); 484 entry->wt = (uint8_t)cpu_ptel_wt(env->ptel); 485 entry->sa = (uint8_t)cpu_ptea_sa(env->ptea); 486 entry->tc = (uint8_t)cpu_ptea_tc(env->ptea); 487 } 488 489 void cpu_sh4_invalidate_tlb(CPUSH4State *s) 490 { 491 int i; 492 493 /* UTLB */ 494 for (i = 0; i < UTLB_SIZE; i++) { 495 tlb_t * entry = &s->utlb[i]; 496 entry->v = 0; 497 } 498 /* ITLB */ 499 for (i = 0; i < ITLB_SIZE; i++) { 500 tlb_t * entry = &s->itlb[i]; 501 entry->v = 0; 502 } 503 504 tlb_flush(env_cpu(s)); 505 } 506 507 uint32_t cpu_sh4_read_mmaped_itlb_addr(CPUSH4State *s, 508 hwaddr addr) 509 { 510 int index = (addr & 0x00000300) >> 8; 511 tlb_t * entry = &s->itlb[index]; 512 513 return (entry->vpn << 10) | 514 (entry->v << 8) | 515 (entry->asid); 516 } 517 518 void cpu_sh4_write_mmaped_itlb_addr(CPUSH4State *s, hwaddr addr, 519 uint32_t mem_value) 520 { 521 uint32_t vpn = (mem_value & 0xfffffc00) >> 10; 522 uint8_t v = (uint8_t)((mem_value & 0x00000100) >> 8); 523 uint8_t asid = (uint8_t)(mem_value & 0x000000ff); 524 525 int index = (addr & 0x00000300) >> 8; 526 tlb_t * entry = &s->itlb[index]; 527 if (entry->v) { 528 /* Overwriting valid entry in itlb. */ 529 target_ulong address = entry->vpn << 10; 530 tlb_flush_page(env_cpu(s), address); 531 } 532 entry->asid = asid; 533 entry->vpn = vpn; 534 entry->v = v; 535 } 536 537 uint32_t cpu_sh4_read_mmaped_itlb_data(CPUSH4State *s, 538 hwaddr addr) 539 { 540 int array = (addr & 0x00800000) >> 23; 541 int index = (addr & 0x00000300) >> 8; 542 tlb_t * entry = &s->itlb[index]; 543 544 if (array == 0) { 545 /* ITLB Data Array 1 */ 546 return (entry->ppn << 10) | 547 (entry->v << 8) | 548 (entry->pr << 5) | 549 ((entry->sz & 1) << 6) | 550 ((entry->sz & 2) << 4) | 551 (entry->c << 3) | 552 (entry->sh << 1); 553 } else { 554 /* ITLB Data Array 2 */ 555 return (entry->tc << 1) | 556 (entry->sa); 557 } 558 } 559 560 void cpu_sh4_write_mmaped_itlb_data(CPUSH4State *s, hwaddr addr, 561 uint32_t mem_value) 562 { 563 int array = (addr & 0x00800000) >> 23; 564 int index = (addr & 0x00000300) >> 8; 565 tlb_t * entry = &s->itlb[index]; 566 567 if (array == 0) { 568 /* ITLB Data Array 1 */ 569 if (entry->v) { 570 /* Overwriting valid entry in utlb. */ 571 target_ulong address = entry->vpn << 10; 572 tlb_flush_page(env_cpu(s), address); 573 } 574 entry->ppn = (mem_value & 0x1ffffc00) >> 10; 575 entry->v = (mem_value & 0x00000100) >> 8; 576 entry->sz = (mem_value & 0x00000080) >> 6 | 577 (mem_value & 0x00000010) >> 4; 578 entry->pr = (mem_value & 0x00000040) >> 5; 579 entry->c = (mem_value & 0x00000008) >> 3; 580 entry->sh = (mem_value & 0x00000002) >> 1; 581 } else { 582 /* ITLB Data Array 2 */ 583 entry->tc = (mem_value & 0x00000008) >> 3; 584 entry->sa = (mem_value & 0x00000007); 585 } 586 } 587 588 uint32_t cpu_sh4_read_mmaped_utlb_addr(CPUSH4State *s, 589 hwaddr addr) 590 { 591 int index = (addr & 0x00003f00) >> 8; 592 tlb_t * entry = &s->utlb[index]; 593 594 increment_urc(s); /* per utlb access */ 595 596 return (entry->vpn << 10) | 597 (entry->v << 8) | 598 (entry->asid); 599 } 600 601 void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, hwaddr addr, 602 uint32_t mem_value) 603 { 604 int associate = addr & 0x0000080; 605 uint32_t vpn = (mem_value & 0xfffffc00) >> 10; 606 uint8_t d = (uint8_t)((mem_value & 0x00000200) >> 9); 607 uint8_t v = (uint8_t)((mem_value & 0x00000100) >> 8); 608 uint8_t asid = (uint8_t)(mem_value & 0x000000ff); 609 int use_asid = !(s->mmucr & MMUCR_SV) || !(s->sr & (1u << SR_MD)); 610 611 if (associate) { 612 int i; 613 tlb_t * utlb_match_entry = NULL; 614 int needs_tlb_flush = 0; 615 616 /* search UTLB */ 617 for (i = 0; i < UTLB_SIZE; i++) { 618 tlb_t * entry = &s->utlb[i]; 619 if (!entry->v) 620 continue; 621 622 if (entry->vpn == vpn 623 && (!use_asid || entry->asid == asid || entry->sh)) { 624 if (utlb_match_entry) { 625 CPUState *cs = env_cpu(s); 626 627 /* Multiple TLB Exception */ 628 cs->exception_index = 0x140; 629 s->tea = addr; 630 break; 631 } 632 if (entry->v && !v) 633 needs_tlb_flush = 1; 634 entry->v = v; 635 entry->d = d; 636 utlb_match_entry = entry; 637 } 638 increment_urc(s); /* per utlb access */ 639 } 640 641 /* search ITLB */ 642 for (i = 0; i < ITLB_SIZE; i++) { 643 tlb_t * entry = &s->itlb[i]; 644 if (entry->vpn == vpn 645 && (!use_asid || entry->asid == asid || entry->sh)) { 646 if (entry->v && !v) 647 needs_tlb_flush = 1; 648 if (utlb_match_entry) 649 *entry = *utlb_match_entry; 650 else 651 entry->v = v; 652 break; 653 } 654 } 655 656 if (needs_tlb_flush) { 657 tlb_flush_page(env_cpu(s), vpn << 10); 658 } 659 } else { 660 int index = (addr & 0x00003f00) >> 8; 661 tlb_t * entry = &s->utlb[index]; 662 if (entry->v) { 663 CPUState *cs = env_cpu(s); 664 665 /* Overwriting valid entry in utlb. */ 666 target_ulong address = entry->vpn << 10; 667 tlb_flush_page(cs, address); 668 } 669 entry->asid = asid; 670 entry->vpn = vpn; 671 entry->d = d; 672 entry->v = v; 673 increment_urc(s); 674 } 675 } 676 677 uint32_t cpu_sh4_read_mmaped_utlb_data(CPUSH4State *s, 678 hwaddr addr) 679 { 680 int array = (addr & 0x00800000) >> 23; 681 int index = (addr & 0x00003f00) >> 8; 682 tlb_t * entry = &s->utlb[index]; 683 684 increment_urc(s); /* per utlb access */ 685 686 if (array == 0) { 687 /* ITLB Data Array 1 */ 688 return (entry->ppn << 10) | 689 (entry->v << 8) | 690 (entry->pr << 5) | 691 ((entry->sz & 1) << 6) | 692 ((entry->sz & 2) << 4) | 693 (entry->c << 3) | 694 (entry->d << 2) | 695 (entry->sh << 1) | 696 (entry->wt); 697 } else { 698 /* ITLB Data Array 2 */ 699 return (entry->tc << 1) | 700 (entry->sa); 701 } 702 } 703 704 void cpu_sh4_write_mmaped_utlb_data(CPUSH4State *s, hwaddr addr, 705 uint32_t mem_value) 706 { 707 int array = (addr & 0x00800000) >> 23; 708 int index = (addr & 0x00003f00) >> 8; 709 tlb_t * entry = &s->utlb[index]; 710 711 increment_urc(s); /* per utlb access */ 712 713 if (array == 0) { 714 /* UTLB Data Array 1 */ 715 if (entry->v) { 716 /* Overwriting valid entry in utlb. */ 717 target_ulong address = entry->vpn << 10; 718 tlb_flush_page(env_cpu(s), address); 719 } 720 entry->ppn = (mem_value & 0x1ffffc00) >> 10; 721 entry->v = (mem_value & 0x00000100) >> 8; 722 entry->sz = (mem_value & 0x00000080) >> 6 | 723 (mem_value & 0x00000010) >> 4; 724 entry->pr = (mem_value & 0x00000060) >> 5; 725 entry->c = (mem_value & 0x00000008) >> 3; 726 entry->d = (mem_value & 0x00000004) >> 2; 727 entry->sh = (mem_value & 0x00000002) >> 1; 728 entry->wt = (mem_value & 0x00000001); 729 } else { 730 /* UTLB Data Array 2 */ 731 entry->tc = (mem_value & 0x00000008) >> 3; 732 entry->sa = (mem_value & 0x00000007); 733 } 734 } 735 736 int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr) 737 { 738 int n; 739 int use_asid = !(env->mmucr & MMUCR_SV) || !(env->sr & (1u << SR_MD)); 740 741 /* check area */ 742 if (env->sr & (1u << SR_MD)) { 743 /* For privileged mode, P2 and P4 area is not cacheable. */ 744 if ((0xA0000000 <= addr && addr < 0xC0000000) || 0xE0000000 <= addr) 745 return 0; 746 } else { 747 /* For user mode, only U0 area is cacheable. */ 748 if (0x80000000 <= addr) 749 return 0; 750 } 751 752 /* 753 * TODO : Evaluate CCR and check if the cache is on or off. 754 * Now CCR is not in CPUSH4State, but in SH7750State. 755 * When you move the ccr into CPUSH4State, the code will be 756 * as follows. 757 */ 758 #if 0 759 /* check if operand cache is enabled or not. */ 760 if (!(env->ccr & 1)) 761 return 0; 762 #endif 763 764 /* if MMU is off, no check for TLB. */ 765 if (env->mmucr & MMUCR_AT) 766 return 1; 767 768 /* check TLB */ 769 n = find_tlb_entry(env, addr, env->itlb, ITLB_SIZE, use_asid); 770 if (n >= 0) 771 return env->itlb[n].c; 772 773 n = find_tlb_entry(env, addr, env->utlb, UTLB_SIZE, use_asid); 774 if (n >= 0) 775 return env->utlb[n].c; 776 777 return 0; 778 } 779 780 bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request) 781 { 782 if (interrupt_request & CPU_INTERRUPT_HARD) { 783 /* Delay slots are indivisible, ignore interrupts */ 784 if (cpu_env(cs)->flags & TB_FLAG_DELAY_SLOT_MASK) { 785 return false; 786 } else { 787 superh_cpu_do_interrupt(cs); 788 return true; 789 } 790 } 791 return false; 792 } 793 794 bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size, 795 MMUAccessType access_type, int mmu_idx, 796 bool probe, uintptr_t retaddr) 797 { 798 CPUSH4State *env = cpu_env(cs); 799 int ret; 800 801 target_ulong physical; 802 int prot; 803 804 ret = get_physical_address(env, &physical, &prot, address, access_type); 805 806 if (ret == MMU_OK) { 807 address &= TARGET_PAGE_MASK; 808 physical &= TARGET_PAGE_MASK; 809 tlb_set_page(cs, address, physical, prot, mmu_idx, TARGET_PAGE_SIZE); 810 return true; 811 } 812 if (probe) { 813 return false; 814 } 815 816 if (ret != MMU_DTLB_MULTIPLE && ret != MMU_ITLB_MULTIPLE) { 817 env->pteh = (env->pteh & PTEH_ASID_MASK) | (address & PTEH_VPN_MASK); 818 } 819 820 env->tea = address; 821 switch (ret) { 822 case MMU_ITLB_MISS: 823 case MMU_DTLB_MISS_READ: 824 cs->exception_index = 0x040; 825 break; 826 case MMU_DTLB_MULTIPLE: 827 case MMU_ITLB_MULTIPLE: 828 cs->exception_index = 0x140; 829 break; 830 case MMU_ITLB_VIOLATION: 831 cs->exception_index = 0x0a0; 832 break; 833 case MMU_DTLB_MISS_WRITE: 834 cs->exception_index = 0x060; 835 break; 836 case MMU_DTLB_INITIAL_WRITE: 837 cs->exception_index = 0x080; 838 break; 839 case MMU_DTLB_VIOLATION_READ: 840 cs->exception_index = 0x0a0; 841 break; 842 case MMU_DTLB_VIOLATION_WRITE: 843 cs->exception_index = 0x0c0; 844 break; 845 case MMU_IADDR_ERROR: 846 case MMU_DADDR_ERROR_READ: 847 cs->exception_index = 0x0e0; 848 break; 849 case MMU_DADDR_ERROR_WRITE: 850 cs->exception_index = 0x100; 851 break; 852 default: 853 cpu_abort(cs, "Unhandled MMU fault"); 854 } 855 cpu_loop_exit_restore(cs, retaddr); 856 } 857 #endif /* !CONFIG_USER_ONLY */ 858