qemu/target/sparc/mmu_helper.c
<<
>>
Prefs
   1/*
   2 *  Sparc MMU helpers
   3 *
   4 *  Copyright (c) 2003-2005 Fabrice Bellard
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2.1 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include "qemu/osdep.h"
  21#include "qemu/log.h"
  22#include "cpu.h"
  23#include "exec/exec-all.h"
  24#include "qemu/qemu-print.h"
  25#include "trace.h"
  26
  27/* Sparc MMU emulation */
  28
  29#ifndef TARGET_SPARC64
  30/*
  31 * Sparc V8 Reference MMU (SRMMU)
  32 */
  33static const int access_table[8][8] = {
  34    { 0, 0, 0, 0, 8, 0, 12, 12 },
  35    { 0, 0, 0, 0, 8, 0, 0, 0 },
  36    { 8, 8, 0, 0, 0, 8, 12, 12 },
  37    { 8, 8, 0, 0, 0, 8, 0, 0 },
  38    { 8, 0, 8, 0, 8, 8, 12, 12 },
  39    { 8, 0, 8, 0, 8, 0, 8, 0 },
  40    { 8, 8, 8, 0, 8, 8, 12, 12 },
  41    { 8, 8, 8, 0, 8, 8, 8, 0 }
  42};
  43
  44static const int perm_table[2][8] = {
  45    {
  46        PAGE_READ,
  47        PAGE_READ | PAGE_WRITE,
  48        PAGE_READ | PAGE_EXEC,
  49        PAGE_READ | PAGE_WRITE | PAGE_EXEC,
  50        PAGE_EXEC,
  51        PAGE_READ | PAGE_WRITE,
  52        PAGE_READ | PAGE_EXEC,
  53        PAGE_READ | PAGE_WRITE | PAGE_EXEC
  54    },
  55    {
  56        PAGE_READ,
  57        PAGE_READ | PAGE_WRITE,
  58        PAGE_READ | PAGE_EXEC,
  59        PAGE_READ | PAGE_WRITE | PAGE_EXEC,
  60        PAGE_EXEC,
  61        PAGE_READ,
  62        0,
  63        0,
  64    }
  65};
  66
  67static int get_physical_address(CPUSPARCState *env, CPUTLBEntryFull *full,
  68                                int *access_index, target_ulong address,
  69                                int rw, int mmu_idx)
  70{
  71    int access_perms = 0;
  72    hwaddr pde_ptr;
  73    uint32_t pde;
  74    int error_code = 0, is_dirty, is_user;
  75    unsigned long page_offset;
  76    CPUState *cs = env_cpu(env);
  77    MemTxResult result;
  78
  79    is_user = mmu_idx == MMU_USER_IDX;
  80
  81    if (mmu_idx == MMU_PHYS_IDX) {
  82        full->lg_page_size = TARGET_PAGE_BITS;
  83        /* Boot mode: instruction fetches are taken from PROM */
  84        if (rw == 2 && (env->mmuregs[0] & env->def.mmu_bm)) {
  85            full->phys_addr = env->prom_addr | (address & 0x7ffffULL);
  86            full->prot = PAGE_READ | PAGE_EXEC;
  87            return 0;
  88        }
  89        full->phys_addr = address;
  90        full->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
  91        return 0;
  92    }
  93
  94    *access_index = ((rw & 1) << 2) | (rw & 2) | (is_user ? 0 : 1);
  95    full->phys_addr = 0xffffffffffff0000ULL;
  96
  97    /* SPARC reference MMU table walk: Context table->L1->L2->PTE */
  98    /* Context base + context number */
  99    pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
 100    pde = address_space_ldl(cs->as, pde_ptr, MEMTXATTRS_UNSPECIFIED, &result);
 101    if (result != MEMTX_OK) {
 102        return 4 << 2; /* Translation fault, L = 0 */
 103    }
 104
 105    /* Ctx pde */
 106    switch (pde & PTE_ENTRYTYPE_MASK) {
 107    default:
 108    case 0: /* Invalid */
 109        return 1 << 2;
 110    case 2: /* L0 PTE, maybe should not happen? */
 111    case 3: /* Reserved */
 112        return 4 << 2;
 113    case 1: /* L0 PDE */
 114        pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
 115        pde = address_space_ldl(cs->as, pde_ptr,
 116                                MEMTXATTRS_UNSPECIFIED, &result);
 117        if (result != MEMTX_OK) {
 118            return (1 << 8) | (4 << 2); /* Translation fault, L = 1 */
 119        }
 120
 121        switch (pde & PTE_ENTRYTYPE_MASK) {
 122        default:
 123        case 0: /* Invalid */
 124            return (1 << 8) | (1 << 2);
 125        case 3: /* Reserved */
 126            return (1 << 8) | (4 << 2);
 127        case 1: /* L1 PDE */
 128            pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
 129            pde = address_space_ldl(cs->as, pde_ptr,
 130                                    MEMTXATTRS_UNSPECIFIED, &result);
 131            if (result != MEMTX_OK) {
 132                return (2 << 8) | (4 << 2); /* Translation fault, L = 2 */
 133            }
 134
 135            switch (pde & PTE_ENTRYTYPE_MASK) {
 136            default:
 137            case 0: /* Invalid */
 138                return (2 << 8) | (1 << 2);
 139            case 3: /* Reserved */
 140                return (2 << 8) | (4 << 2);
 141            case 1: /* L2 PDE */
 142                pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
 143                pde = address_space_ldl(cs->as, pde_ptr,
 144                                        MEMTXATTRS_UNSPECIFIED, &result);
 145                if (result != MEMTX_OK) {
 146                    return (3 << 8) | (4 << 2); /* Translation fault, L = 3 */
 147                }
 148
 149                switch (pde & PTE_ENTRYTYPE_MASK) {
 150                default:
 151                case 0: /* Invalid */
 152                    return (3 << 8) | (1 << 2);
 153                case 1: /* PDE, should not happen */
 154                case 3: /* Reserved */
 155                    return (3 << 8) | (4 << 2);
 156                case 2: /* L3 PTE */
 157                    page_offset = 0;
 158                }
 159                full->lg_page_size = TARGET_PAGE_BITS;
 160                break;
 161            case 2: /* L2 PTE */
 162                page_offset = address & 0x3f000;
 163                full->lg_page_size = 18;
 164            }
 165            break;
 166        case 2: /* L1 PTE */
 167            page_offset = address & 0xfff000;
 168            full->lg_page_size = 24;
 169            break;
 170        }
 171    }
 172
 173    /* check access */
 174    access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
 175    error_code = access_table[*access_index][access_perms];
 176    if (error_code && !((env->mmuregs[0] & MMU_NF) && is_user)) {
 177        return error_code;
 178    }
 179
 180    /* update page modified and dirty bits */
 181    is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
 182    if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
 183        pde |= PG_ACCESSED_MASK;
 184        if (is_dirty) {
 185            pde |= PG_MODIFIED_MASK;
 186        }
 187        stl_phys_notdirty(cs->as, pde_ptr, pde);
 188    }
 189
 190    /* the page can be put in the TLB */
 191    full->prot = perm_table[is_user][access_perms];
 192    if (!(pde & PG_MODIFIED_MASK)) {
 193        /* only set write access if already dirty... otherwise wait
 194           for dirty access */
 195        full->prot &= ~PAGE_WRITE;
 196    }
 197
 198    /* Even if large ptes, we map only one 4KB page in the cache to
 199       avoid filling it too fast */
 200    full->phys_addr = ((hwaddr)(pde & PTE_ADDR_MASK) << 4) + page_offset;
 201    return error_code;
 202}
 203
 204/* Perform address translation */
 205bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 206                        MMUAccessType access_type, int mmu_idx,
 207                        bool probe, uintptr_t retaddr)
 208{
 209    SPARCCPU *cpu = SPARC_CPU(cs);
 210    CPUSPARCState *env = &cpu->env;
 211    CPUTLBEntryFull full = {};
 212    target_ulong vaddr;
 213    int error_code = 0, access_index;
 214
 215    /*
 216     * TODO: If we ever need tlb_vaddr_to_host for this target,
 217     * then we must figure out how to manipulate FSR and FAR
 218     * when both MMU_NF and probe are set.  In the meantime,
 219     * do not support this use case.
 220     */
 221    assert(!probe);
 222
 223    address &= TARGET_PAGE_MASK;
 224    error_code = get_physical_address(env, &full, &access_index,
 225                                      address, access_type, mmu_idx);
 226    vaddr = address;
 227    if (likely(error_code == 0)) {
 228        qemu_log_mask(CPU_LOG_MMU,
 229                      "Translate at %" VADDR_PRIx " -> "
 230                      HWADDR_FMT_plx ", vaddr " TARGET_FMT_lx "\n",
 231                      address, full.phys_addr, vaddr);
 232        tlb_set_page_full(cs, mmu_idx, vaddr, &full);
 233        return true;
 234    }
 235
 236    if (env->mmuregs[3]) { /* Fault status register */
 237        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
 238    }
 239    env->mmuregs[3] |= (access_index << 5) | error_code | 2;
 240    env->mmuregs[4] = address; /* Fault address register */
 241
 242    if ((env->mmuregs[0] & MMU_NF) || env->psret == 0)  {
 243        /* No fault mode: if a mapping is available, just override
 244           permissions. If no mapping is available, redirect accesses to
 245           neverland. Fake/overridden mappings will be flushed when
 246           switching to normal mode. */
 247        full.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 248        tlb_set_page_full(cs, mmu_idx, vaddr, &full);
 249        return true;
 250    } else {
 251        if (access_type == MMU_INST_FETCH) {
 252            cs->exception_index = TT_TFAULT;
 253        } else {
 254            cs->exception_index = TT_DFAULT;
 255        }
 256        cpu_loop_exit_restore(cs, retaddr);
 257    }
 258}
 259
 260target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev)
 261{
 262    CPUState *cs = env_cpu(env);
 263    hwaddr pde_ptr;
 264    uint32_t pde;
 265    MemTxResult result;
 266
 267    /*
 268     * TODO: MMU probe operations are supposed to set the fault
 269     * status registers, but we don't do this.
 270     */
 271
 272    /* Context base + context number */
 273    pde_ptr = (hwaddr)(env->mmuregs[1] << 4) +
 274        (env->mmuregs[2] << 2);
 275    pde = address_space_ldl(cs->as, pde_ptr, MEMTXATTRS_UNSPECIFIED, &result);
 276    if (result != MEMTX_OK) {
 277        return 0;
 278    }
 279
 280    switch (pde & PTE_ENTRYTYPE_MASK) {
 281    default:
 282    case 0: /* Invalid */
 283    case 2: /* PTE, maybe should not happen? */
 284    case 3: /* Reserved */
 285        return 0;
 286    case 1: /* L1 PDE */
 287        if (mmulev == 3) {
 288            return pde;
 289        }
 290        pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
 291        pde = address_space_ldl(cs->as, pde_ptr,
 292                                MEMTXATTRS_UNSPECIFIED, &result);
 293        if (result != MEMTX_OK) {
 294            return 0;
 295        }
 296
 297        switch (pde & PTE_ENTRYTYPE_MASK) {
 298        default:
 299        case 0: /* Invalid */
 300        case 3: /* Reserved */
 301            return 0;
 302        case 2: /* L1 PTE */
 303            return pde;
 304        case 1: /* L2 PDE */
 305            if (mmulev == 2) {
 306                return pde;
 307            }
 308            pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
 309            pde = address_space_ldl(cs->as, pde_ptr,
 310                                    MEMTXATTRS_UNSPECIFIED, &result);
 311            if (result != MEMTX_OK) {
 312                return 0;
 313            }
 314
 315            switch (pde & PTE_ENTRYTYPE_MASK) {
 316            default:
 317            case 0: /* Invalid */
 318            case 3: /* Reserved */
 319                return 0;
 320            case 2: /* L2 PTE */
 321                return pde;
 322            case 1: /* L3 PDE */
 323                if (mmulev == 1) {
 324                    return pde;
 325                }
 326                pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
 327                pde = address_space_ldl(cs->as, pde_ptr,
 328                                        MEMTXATTRS_UNSPECIFIED, &result);
 329                if (result != MEMTX_OK) {
 330                    return 0;
 331                }
 332
 333                switch (pde & PTE_ENTRYTYPE_MASK) {
 334                default:
 335                case 0: /* Invalid */
 336                case 1: /* PDE, should not happen */
 337                case 3: /* Reserved */
 338                    return 0;
 339                case 2: /* L3 PTE */
 340                    return pde;
 341                }
 342            }
 343        }
 344    }
 345    return 0;
 346}
 347
 348void dump_mmu(CPUSPARCState *env)
 349{
 350    CPUState *cs = env_cpu(env);
 351    target_ulong va, va1, va2;
 352    unsigned int n, m, o;
 353    hwaddr pa;
 354    uint32_t pde;
 355
 356    qemu_printf("Root ptr: " HWADDR_FMT_plx ", ctx: %d\n",
 357                (hwaddr)env->mmuregs[1] << 4, env->mmuregs[2]);
 358    for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
 359        pde = mmu_probe(env, va, 2);
 360        if (pde) {
 361            pa = cpu_get_phys_page_debug(cs, va);
 362            qemu_printf("VA: " TARGET_FMT_lx ", PA: " HWADDR_FMT_plx
 363                        " PDE: " TARGET_FMT_lx "\n", va, pa, pde);
 364            for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
 365                pde = mmu_probe(env, va1, 1);
 366                if (pde) {
 367                    pa = cpu_get_phys_page_debug(cs, va1);
 368                    qemu_printf(" VA: " TARGET_FMT_lx ", PA: "
 369                                HWADDR_FMT_plx " PDE: " TARGET_FMT_lx "\n",
 370                                va1, pa, pde);
 371                    for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
 372                        pde = mmu_probe(env, va2, 0);
 373                        if (pde) {
 374                            pa = cpu_get_phys_page_debug(cs, va2);
 375                            qemu_printf("  VA: " TARGET_FMT_lx ", PA: "
 376                                        HWADDR_FMT_plx " PTE: "
 377                                        TARGET_FMT_lx "\n",
 378                                        va2, pa, pde);
 379                        }
 380                    }
 381                }
 382            }
 383        }
 384    }
 385}
 386
 387/* Gdb expects all registers windows to be flushed in ram. This function handles
 388 * reads (and only reads) in stack frames as if windows were flushed. We assume
 389 * that the sparc ABI is followed.
 390 */
 391int sparc_cpu_memory_rw_debug(CPUState *cs, vaddr address,
 392                              uint8_t *buf, int len, bool is_write)
 393{
 394    SPARCCPU *cpu = SPARC_CPU(cs);
 395    CPUSPARCState *env = &cpu->env;
 396    target_ulong addr = address;
 397    int i;
 398    int len1;
 399    int cwp = env->cwp;
 400
 401    if (!is_write) {
 402        for (i = 0; i < env->nwindows; i++) {
 403            int off;
 404            target_ulong fp = env->regbase[cwp * 16 + 22];
 405
 406            /* Assume fp == 0 means end of frame.  */
 407            if (fp == 0) {
 408                break;
 409            }
 410
 411            cwp = cpu_cwp_inc(env, cwp + 1);
 412
 413            /* Invalid window ? */
 414            if (env->wim & (1 << cwp)) {
 415                break;
 416            }
 417
 418            /* According to the ABI, the stack is growing downward.  */
 419            if (addr + len < fp) {
 420                break;
 421            }
 422
 423            /* Not in this frame.  */
 424            if (addr > fp + 64) {
 425                continue;
 426            }
 427
 428            /* Handle access before this window.  */
 429            if (addr < fp) {
 430                len1 = fp - addr;
 431                if (cpu_memory_rw_debug(cs, addr, buf, len1, is_write) != 0) {
 432                    return -1;
 433                }
 434                addr += len1;
 435                len -= len1;
 436                buf += len1;
 437            }
 438
 439            /* Access byte per byte to registers. Not very efficient but speed
 440             * is not critical.
 441             */
 442            off = addr - fp;
 443            len1 = 64 - off;
 444
 445            if (len1 > len) {
 446                len1 = len;
 447            }
 448
 449            for (; len1; len1--) {
 450                int reg = cwp * 16 + 8 + (off >> 2);
 451                union {
 452                    uint32_t v;
 453                    uint8_t c[4];
 454                } u;
 455                u.v = cpu_to_be32(env->regbase[reg]);
 456                *buf++ = u.c[off & 3];
 457                addr++;
 458                len--;
 459                off++;
 460            }
 461
 462            if (len == 0) {
 463                return 0;
 464            }
 465        }
 466    }
 467    return cpu_memory_rw_debug(cs, addr, buf, len, is_write);
 468}
 469
 470#else /* !TARGET_SPARC64 */
 471
 472/* 41 bit physical address space */
 473static inline hwaddr ultrasparc_truncate_physical(uint64_t x)
 474{
 475    return x & 0x1ffffffffffULL;
 476}
 477
 478/*
 479 * UltraSparc IIi I/DMMUs
 480 */
 481
 482/* Returns true if TTE tag is valid and matches virtual address value
 483   in context requires virtual address mask value calculated from TTE
 484   entry size */
 485static inline int ultrasparc_tag_match(SparcTLBEntry *tlb,
 486                                       uint64_t address, uint64_t context,
 487                                       hwaddr *physical)
 488{
 489    uint64_t mask = -(8192ULL << 3 * TTE_PGSIZE(tlb->tte));
 490
 491    /* valid, context match, virtual address match? */
 492    if (TTE_IS_VALID(tlb->tte) &&
 493        (TTE_IS_GLOBAL(tlb->tte) || tlb_compare_context(tlb, context))
 494        && compare_masked(address, tlb->tag, mask)) {
 495        /* decode physical address */
 496        *physical = ((tlb->tte & mask) | (address & ~mask)) & 0x1ffffffe000ULL;
 497        return 1;
 498    }
 499
 500    return 0;
 501}
 502
 503static uint64_t build_sfsr(CPUSPARCState *env, int mmu_idx, int rw)
 504{
 505    uint64_t sfsr = SFSR_VALID_BIT;
 506
 507    switch (mmu_idx) {
 508    case MMU_PHYS_IDX:
 509        sfsr |= SFSR_CT_NOTRANS;
 510        break;
 511    case MMU_USER_IDX:
 512    case MMU_KERNEL_IDX:
 513        sfsr |= SFSR_CT_PRIMARY;
 514        break;
 515    case MMU_USER_SECONDARY_IDX:
 516    case MMU_KERNEL_SECONDARY_IDX:
 517        sfsr |= SFSR_CT_SECONDARY;
 518        break;
 519    case MMU_NUCLEUS_IDX:
 520        sfsr |= SFSR_CT_NUCLEUS;
 521        break;
 522    default:
 523        g_assert_not_reached();
 524    }
 525
 526    if (rw == 1) {
 527        sfsr |= SFSR_WRITE_BIT;
 528    } else if (rw == 4) {
 529        sfsr |= SFSR_NF_BIT;
 530    }
 531
 532    if (env->pstate & PS_PRIV) {
 533        sfsr |= SFSR_PR_BIT;
 534    }
 535
 536    if (env->dmmu.sfsr & SFSR_VALID_BIT) { /* Fault status register */
 537        sfsr |= SFSR_OW_BIT; /* overflow (not read before another fault) */
 538    }
 539
 540    /* FIXME: ASI field in SFSR must be set */
 541
 542    return sfsr;
 543}
 544
 545static int get_physical_address_data(CPUSPARCState *env, CPUTLBEntryFull *full,
 546                                     target_ulong address, int rw, int mmu_idx)
 547{
 548    CPUState *cs = env_cpu(env);
 549    unsigned int i;
 550    uint64_t sfsr;
 551    uint64_t context;
 552    bool is_user = false;
 553
 554    sfsr = build_sfsr(env, mmu_idx, rw);
 555
 556    switch (mmu_idx) {
 557    case MMU_PHYS_IDX:
 558        g_assert_not_reached();
 559    case MMU_USER_IDX:
 560        is_user = true;
 561        /* fallthru */
 562    case MMU_KERNEL_IDX:
 563        context = env->dmmu.mmu_primary_context & 0x1fff;
 564        break;
 565    case MMU_USER_SECONDARY_IDX:
 566        is_user = true;
 567        /* fallthru */
 568    case MMU_KERNEL_SECONDARY_IDX:
 569        context = env->dmmu.mmu_secondary_context & 0x1fff;
 570        break;
 571    default:
 572        context = 0;
 573        break;
 574    }
 575
 576    for (i = 0; i < 64; i++) {
 577        /* ctx match, vaddr match, valid? */
 578        if (ultrasparc_tag_match(&env->dtlb[i], address, context,
 579                                 &full->phys_addr)) {
 580            int do_fault = 0;
 581
 582            if (TTE_IS_IE(env->dtlb[i].tte)) {
 583                full->attrs.byte_swap = true;
 584            }
 585
 586            /* access ok? */
 587            /* multiple bits in SFSR.FT may be set on TT_DFAULT */
 588            if (TTE_IS_PRIV(env->dtlb[i].tte) && is_user) {
 589                do_fault = 1;
 590                sfsr |= SFSR_FT_PRIV_BIT; /* privilege violation */
 591                trace_mmu_helper_dfault(address, context, mmu_idx, env->tl);
 592            }
 593            if (rw == 4) {
 594                if (TTE_IS_SIDEEFFECT(env->dtlb[i].tte)) {
 595                    do_fault = 1;
 596                    sfsr |= SFSR_FT_NF_E_BIT;
 597                }
 598            } else {
 599                if (TTE_IS_NFO(env->dtlb[i].tte)) {
 600                    do_fault = 1;
 601                    sfsr |= SFSR_FT_NFO_BIT;
 602                }
 603            }
 604
 605            if (do_fault) {
 606                /* faults above are reported with TT_DFAULT. */
 607                cs->exception_index = TT_DFAULT;
 608            } else if (!TTE_IS_W_OK(env->dtlb[i].tte) && (rw == 1)) {
 609                do_fault = 1;
 610                cs->exception_index = TT_DPROT;
 611
 612                trace_mmu_helper_dprot(address, context, mmu_idx, env->tl);
 613            }
 614
 615            if (!do_fault) {
 616                full->prot = PAGE_READ;
 617                if (TTE_IS_W_OK(env->dtlb[i].tte)) {
 618                    full->prot |= PAGE_WRITE;
 619                }
 620
 621                TTE_SET_USED(env->dtlb[i].tte);
 622
 623                return 0;
 624            }
 625
 626            env->dmmu.sfsr = sfsr;
 627            env->dmmu.sfar = address; /* Fault address register */
 628            env->dmmu.tag_access = (address & ~0x1fffULL) | context;
 629            return 1;
 630        }
 631    }
 632
 633    trace_mmu_helper_dmiss(address, context);
 634
 635    /*
 636     * On MMU misses:
 637     * - UltraSPARC IIi: SFSR and SFAR unmodified
 638     * - JPS1: SFAR updated and some fields of SFSR updated
 639     */
 640    env->dmmu.tag_access = (address & ~0x1fffULL) | context;
 641    cs->exception_index = TT_DMISS;
 642    return 1;
 643}
 644
 645static int get_physical_address_code(CPUSPARCState *env, CPUTLBEntryFull *full,
 646                                     target_ulong address, int mmu_idx)
 647{
 648    CPUState *cs = env_cpu(env);
 649    unsigned int i;
 650    uint64_t context;
 651    bool is_user = false;
 652
 653    switch (mmu_idx) {
 654    case MMU_PHYS_IDX:
 655    case MMU_USER_SECONDARY_IDX:
 656    case MMU_KERNEL_SECONDARY_IDX:
 657        g_assert_not_reached();
 658    case MMU_USER_IDX:
 659        is_user = true;
 660        /* fallthru */
 661    case MMU_KERNEL_IDX:
 662        context = env->dmmu.mmu_primary_context & 0x1fff;
 663        break;
 664    default:
 665        context = 0;
 666        break;
 667    }
 668
 669    if (env->tl == 0) {
 670        /* PRIMARY context */
 671        context = env->dmmu.mmu_primary_context & 0x1fff;
 672    } else {
 673        /* NUCLEUS context */
 674        context = 0;
 675    }
 676
 677    for (i = 0; i < 64; i++) {
 678        /* ctx match, vaddr match, valid? */
 679        if (ultrasparc_tag_match(&env->itlb[i],
 680                                 address, context, &full->phys_addr)) {
 681            /* access ok? */
 682            if (TTE_IS_PRIV(env->itlb[i].tte) && is_user) {
 683                /* Fault status register */
 684                if (env->immu.sfsr & SFSR_VALID_BIT) {
 685                    env->immu.sfsr = SFSR_OW_BIT; /* overflow (not read before
 686                                                     another fault) */
 687                } else {
 688                    env->immu.sfsr = 0;
 689                }
 690                if (env->pstate & PS_PRIV) {
 691                    env->immu.sfsr |= SFSR_PR_BIT;
 692                }
 693                if (env->tl > 0) {
 694                    env->immu.sfsr |= SFSR_CT_NUCLEUS;
 695                }
 696
 697                /* FIXME: ASI field in SFSR must be set */
 698                env->immu.sfsr |= SFSR_FT_PRIV_BIT | SFSR_VALID_BIT;
 699                cs->exception_index = TT_TFAULT;
 700
 701                env->immu.tag_access = (address & ~0x1fffULL) | context;
 702
 703                trace_mmu_helper_tfault(address, context);
 704
 705                return 1;
 706            }
 707            full->prot = PAGE_EXEC;
 708            TTE_SET_USED(env->itlb[i].tte);
 709            return 0;
 710        }
 711    }
 712
 713    trace_mmu_helper_tmiss(address, context);
 714
 715    /* Context is stored in DMMU (dmmuregs[1]) also for IMMU */
 716    env->immu.tag_access = (address & ~0x1fffULL) | context;
 717    cs->exception_index = TT_TMISS;
 718    return 1;
 719}
 720
 721static int get_physical_address(CPUSPARCState *env, CPUTLBEntryFull *full,
 722                                int *access_index, target_ulong address,
 723                                int rw, int mmu_idx)
 724{
 725    /* ??? We treat everything as a small page, then explicitly flush
 726       everything when an entry is evicted.  */
 727    full->lg_page_size = TARGET_PAGE_BITS;
 728
 729    /* safety net to catch wrong softmmu index use from dynamic code */
 730    if (env->tl > 0 && mmu_idx != MMU_NUCLEUS_IDX) {
 731        if (rw == 2) {
 732            trace_mmu_helper_get_phys_addr_code(env->tl, mmu_idx,
 733                                                env->dmmu.mmu_primary_context,
 734                                                env->dmmu.mmu_secondary_context,
 735                                                address);
 736        } else {
 737            trace_mmu_helper_get_phys_addr_data(env->tl, mmu_idx,
 738                                                env->dmmu.mmu_primary_context,
 739                                                env->dmmu.mmu_secondary_context,
 740                                                address);
 741        }
 742    }
 743
 744    if (mmu_idx == MMU_PHYS_IDX) {
 745        full->phys_addr = ultrasparc_truncate_physical(address);
 746        full->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 747        return 0;
 748    }
 749
 750    if (rw == 2) {
 751        return get_physical_address_code(env, full, address, mmu_idx);
 752    } else {
 753        return get_physical_address_data(env, full, address, rw, mmu_idx);
 754    }
 755}
 756
 757/* Perform address translation */
 758bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 759                        MMUAccessType access_type, int mmu_idx,
 760                        bool probe, uintptr_t retaddr)
 761{
 762    SPARCCPU *cpu = SPARC_CPU(cs);
 763    CPUSPARCState *env = &cpu->env;
 764    CPUTLBEntryFull full = {};
 765    int error_code = 0, access_index;
 766
 767    address &= TARGET_PAGE_MASK;
 768    error_code = get_physical_address(env, &full, &access_index,
 769                                      address, access_type, mmu_idx);
 770    if (likely(error_code == 0)) {
 771        trace_mmu_helper_mmu_fault(address, full.phys_addr, mmu_idx, env->tl,
 772                                   env->dmmu.mmu_primary_context,
 773                                   env->dmmu.mmu_secondary_context);
 774        tlb_set_page_full(cs, mmu_idx, address, &full);
 775        return true;
 776    }
 777    if (probe) {
 778        return false;
 779    }
 780    cpu_loop_exit_restore(cs, retaddr);
 781}
 782
 783void dump_mmu(CPUSPARCState *env)
 784{
 785    unsigned int i;
 786    const char *mask;
 787
 788    qemu_printf("MMU contexts: Primary: %" PRId64 ", Secondary: %"
 789                PRId64 "\n",
 790                env->dmmu.mmu_primary_context,
 791                env->dmmu.mmu_secondary_context);
 792    qemu_printf("DMMU Tag Access: %" PRIx64 ", TSB Tag Target: %" PRIx64
 793                "\n", env->dmmu.tag_access, env->dmmu.tsb_tag_target);
 794    if ((env->lsu & DMMU_E) == 0) {
 795        qemu_printf("DMMU disabled\n");
 796    } else {
 797        qemu_printf("DMMU dump\n");
 798        for (i = 0; i < 64; i++) {
 799            switch (TTE_PGSIZE(env->dtlb[i].tte)) {
 800            default:
 801            case 0x0:
 802                mask = "  8k";
 803                break;
 804            case 0x1:
 805                mask = " 64k";
 806                break;
 807            case 0x2:
 808                mask = "512k";
 809                break;
 810            case 0x3:
 811                mask = "  4M";
 812                break;
 813            }
 814            if (TTE_IS_VALID(env->dtlb[i].tte)) {
 815                qemu_printf("[%02u] VA: %" PRIx64 ", PA: %llx"
 816                            ", %s, %s, %s, %s, ie %s, ctx %" PRId64 " %s\n",
 817                            i,
 818                            env->dtlb[i].tag & (uint64_t)~0x1fffULL,
 819                            TTE_PA(env->dtlb[i].tte),
 820                            mask,
 821                            TTE_IS_PRIV(env->dtlb[i].tte) ? "priv" : "user",
 822                            TTE_IS_W_OK(env->dtlb[i].tte) ? "RW" : "RO",
 823                            TTE_IS_LOCKED(env->dtlb[i].tte) ?
 824                            "locked" : "unlocked",
 825                            TTE_IS_IE(env->dtlb[i].tte) ?
 826                            "yes" : "no",
 827                            env->dtlb[i].tag & (uint64_t)0x1fffULL,
 828                            TTE_IS_GLOBAL(env->dtlb[i].tte) ?
 829                            "global" : "local");
 830            }
 831        }
 832    }
 833    if ((env->lsu & IMMU_E) == 0) {
 834        qemu_printf("IMMU disabled\n");
 835    } else {
 836        qemu_printf("IMMU dump\n");
 837        for (i = 0; i < 64; i++) {
 838            switch (TTE_PGSIZE(env->itlb[i].tte)) {
 839            default:
 840            case 0x0:
 841                mask = "  8k";
 842                break;
 843            case 0x1:
 844                mask = " 64k";
 845                break;
 846            case 0x2:
 847                mask = "512k";
 848                break;
 849            case 0x3:
 850                mask = "  4M";
 851                break;
 852            }
 853            if (TTE_IS_VALID(env->itlb[i].tte)) {
 854                qemu_printf("[%02u] VA: %" PRIx64 ", PA: %llx"
 855                            ", %s, %s, %s, ctx %" PRId64 " %s\n",
 856                            i,
 857                            env->itlb[i].tag & (uint64_t)~0x1fffULL,
 858                            TTE_PA(env->itlb[i].tte),
 859                            mask,
 860                            TTE_IS_PRIV(env->itlb[i].tte) ? "priv" : "user",
 861                            TTE_IS_LOCKED(env->itlb[i].tte) ?
 862                            "locked" : "unlocked",
 863                            env->itlb[i].tag & (uint64_t)0x1fffULL,
 864                            TTE_IS_GLOBAL(env->itlb[i].tte) ?
 865                            "global" : "local");
 866            }
 867        }
 868    }
 869}
 870
 871#endif /* TARGET_SPARC64 */
 872
 873static int cpu_sparc_get_phys_page(CPUSPARCState *env, hwaddr *phys,
 874                                   target_ulong addr, int rw, int mmu_idx)
 875{
 876    CPUTLBEntryFull full = {};
 877    int access_index, ret;
 878
 879    ret = get_physical_address(env, &full, &access_index, addr, rw, mmu_idx);
 880    if (ret == 0) {
 881        *phys = full.phys_addr;
 882    }
 883    return ret;
 884}
 885
 886#if defined(TARGET_SPARC64)
 887hwaddr cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr,
 888                                           int mmu_idx)
 889{
 890    hwaddr phys_addr;
 891
 892    if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 4, mmu_idx) != 0) {
 893        return -1;
 894    }
 895    return phys_addr;
 896}
 897#endif
 898
 899hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 900{
 901    SPARCCPU *cpu = SPARC_CPU(cs);
 902    CPUSPARCState *env = &cpu->env;
 903    hwaddr phys_addr;
 904    int mmu_idx = cpu_mmu_index(env, false);
 905
 906    if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 2, mmu_idx) != 0) {
 907        if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 0, mmu_idx) != 0) {
 908            return -1;
 909        }
 910    }
 911    return phys_addr;
 912}
 913
 914G_NORETURN void sparc_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
 915                                              MMUAccessType access_type,
 916                                              int mmu_idx,
 917                                              uintptr_t retaddr)
 918{
 919    SPARCCPU *cpu = SPARC_CPU(cs);
 920    CPUSPARCState *env = &cpu->env;
 921
 922#ifdef TARGET_SPARC64
 923    env->dmmu.sfsr = build_sfsr(env, mmu_idx, access_type);
 924    env->dmmu.sfar = addr;
 925#else
 926    env->mmuregs[4] = addr;
 927#endif
 928
 929    cpu_raise_exception_ra(env, TT_UNALIGNED, retaddr);
 930}
 931