/*
 *  HPPA memory access helper routines
 *
 *  Copyright (c) 2017 Helge Deller
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "exec/page-protection.h"
#include "exec/helper-proto.h"
#include "hw/core/cpu.h"
#include "trace.h"

hwaddr hppa_abs_to_phys_pa2_w1(vaddr addr)
{
    /*
     * Figure H-8 "62-bit Absolute Accesses when PSW W-bit is 1" describes
     * an algorithm in which a 62-bit absolute address is transformed to
     * a 64-bit physical address.  This must then be combined with that
     * pictured in Figure H-11 "Physical Address Space Mapping", in which
     * the full physical address is truncated to the N-bit physical address
     * supported by the implementation.
     *
     * Since the supported physical address space is below 54 bits, the
     * H-8 algorithm is moot and all that is left is to truncate.
     */
    QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > 54);
    return sextract64(addr, 0, TARGET_PHYS_ADDR_SPACE_BITS);
}

hwaddr hppa_abs_to_phys_pa2_w0(vaddr addr)
{
    /*
     * See Figure H-10, "Absolute Accesses when PSW W-bit is 0",
     * combined with Figure H-11, as above.
     */
    if (likely(extract32(addr, 28, 4) != 0xf)) {
        /* Memory address space */
        addr = (uint32_t)addr;
    } else if (extract32(addr, 24, 4) != 0) {
        /* I/O address space */
        addr = (int32_t)addr;
    } else {
        /*
         * PDC address space:
         * Figures H-10 and H-11 of the parisc2.0 spec do not specify
         * where to map into the 64-bit PDC address space.
         * We map with an offset which equals the 32-bit address, which
         * is what can be seen on physical machines too.
         */
        addr = (uint32_t)addr;
        addr |= -1ull << (TARGET_PHYS_ADDR_SPACE_BITS - 4);
    }
    return addr;
}

static HPPATLBEntry *hppa_find_tlb(CPUHPPAState *env, vaddr addr)
{
    IntervalTreeNode *i = interval_tree_iter_first(&env->tlb_root, addr, addr);

    if (i) {
        HPPATLBEntry *ent = container_of(i, HPPATLBEntry, itree);
        trace_hppa_tlb_find_entry(env, ent, ent->entry_valid,
                                  ent->itree.start, ent->itree.last, ent->pa);
        return ent;
    }
    trace_hppa_tlb_find_entry_not_found(env, addr);
    return NULL;
}

static void hppa_flush_tlb_ent(CPUHPPAState *env, HPPATLBEntry *ent,
                               bool force_flush_btlb)
{
    CPUState *cs = env_cpu(env);
    bool is_btlb;

    if (!ent->entry_valid) {
        return;
    }

    trace_hppa_tlb_flush_ent(env, ent, ent->itree.start,
                             ent->itree.last, ent->pa);

    tlb_flush_range_by_mmuidx(cs, ent->itree.start,
                              ent->itree.last - ent->itree.start + 1,
                              HPPA_MMU_FLUSH_MASK, TARGET_LONG_BITS);

    /* Never clear BTLBs, unless forced to do so. */
    is_btlb = ent < &env->tlb[HPPA_BTLB_ENTRIES(env)];
    if (is_btlb && !force_flush_btlb) {
        return;
    }

    interval_tree_remove(&ent->itree, &env->tlb_root);
    memset(ent, 0, sizeof(*ent));

    if (!is_btlb) {
        ent->unused_next = env->tlb_unused;
        env->tlb_unused = ent;
    }
}

static void hppa_flush_tlb_range(CPUHPPAState *env, vaddr va_b, vaddr va_e)
{
    IntervalTreeNode *i, *n;

    i = interval_tree_iter_first(&env->tlb_root, va_b, va_e);
    for (; i ; i = n) {
        HPPATLBEntry *ent = container_of(i, HPPATLBEntry, itree);

        /*
         * Find the next entry now: In the normal case the current entry
         * will be removed, but in the BTLB case it will remain.
         */
        n = interval_tree_iter_next(i, va_b, va_e);
        hppa_flush_tlb_ent(env, ent, false);
    }
}

static HPPATLBEntry *hppa_alloc_tlb_ent(CPUHPPAState *env)
{
    HPPATLBEntry *ent = env->tlb_unused;

    if (ent == NULL) {
        uint32_t btlb_entries = HPPA_BTLB_ENTRIES(env);
        uint32_t i = env->tlb_last;

        if (i < btlb_entries || i >= ARRAY_SIZE(env->tlb)) {
            i = btlb_entries;
        }
        env->tlb_last = i + 1;

        ent = &env->tlb[i];
        hppa_flush_tlb_ent(env, ent, false);
    }

    env->tlb_unused = ent->unused_next;
    return ent;
}

#define ACCESS_ID_MASK 0xffff

/* Return the set of protections allowed by a PID match. */
static int match_prot_id_1(uint32_t access_id, uint32_t prot_id)
{
    if (((access_id ^ (prot_id >> 1)) & ACCESS_ID_MASK) == 0) {
        return (prot_id & 1
                ? PAGE_EXEC | PAGE_READ
                : PAGE_EXEC | PAGE_READ | PAGE_WRITE);
    }
    return 0;
}

static int match_prot_id32(CPUHPPAState *env, uint32_t access_id)
{
    int r, i;

    for (i = CR_PID1; i <= CR_PID4; ++i) {
        r = match_prot_id_1(access_id, env->cr[i]);
        if (r) {
            return r;
        }
    }
    return 0;
}

static int match_prot_id64(CPUHPPAState *env, uint32_t access_id)
{
    int r, i;

    for (i = CR_PID1; i <= CR_PID4; ++i) {
        r = match_prot_id_1(access_id, env->cr[i]);
        if (r) {
            return r;
        }
        r = match_prot_id_1(access_id, env->cr[i] >> 32);
        if (r) {
            return r;
        }
    }
    return 0;
}

int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
                              int type, hwaddr *pphys, int *pprot,
                              HPPATLBEntry **tlb_entry)
{
    hwaddr phys;
    int prot, r_prot, w_prot, x_prot, priv;
    HPPATLBEntry *ent;
    int ret = -1;

    if (tlb_entry) {
        *tlb_entry = NULL;
    }

    /* Virtual translation disabled.  Map absolute to physical.  */
    if (MMU_IDX_MMU_DISABLED(mmu_idx)) {
        switch (mmu_idx) {
        case MMU_ABS_W_IDX:
            phys = hppa_abs_to_phys_pa2_w1(addr);
            break;
        case MMU_ABS_IDX:
            if (hppa_is_pa20(env)) {
                phys = hppa_abs_to_phys_pa2_w0(addr);
            } else {
                phys = (uint32_t)addr;
            }
            break;
        default:
            g_assert_not_reached();
        }
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
        goto egress;
    }

    /* Find a valid tlb entry that matches the virtual address.  */
    ent = hppa_find_tlb(env, addr);
    if (ent == NULL) {
        phys = 0;
        prot = 0;
        ret = (type == PAGE_EXEC) ? EXCP_ITLB_MISS : EXCP_DTLB_MISS;
        goto egress;
    }

    if (tlb_entry) {
        *tlb_entry = ent;
    }

    /* We now know the physical address.  */
    phys = ent->pa + (addr - ent->itree.start);

    /* Map TLB access_rights field to QEMU protection.  */
    priv = MMU_IDX_TO_PRIV(mmu_idx);
    r_prot = (priv <= ent->ar_pl1) * PAGE_READ;
    w_prot = (priv <= ent->ar_pl2) * PAGE_WRITE;
    x_prot = (ent->ar_pl2 <= priv && priv <= ent->ar_pl1) * PAGE_EXEC;
    switch (ent->ar_type) {
    case 0: /* read-only: data page */
        prot = r_prot;
        break;
    case 1: /* read/write: dynamic data page */
        prot = r_prot | w_prot;
        break;
    case 2: /* read/execute: normal code page */
        prot = r_prot | x_prot;
        break;
    case 3: /* read/write/execute: dynamic code page */
        prot = r_prot | w_prot | x_prot;
        break;
    default: /* execute: promote to privilege level type & 3 */
        prot = x_prot;
        break;
    }

    /*
     * No guest access type indicates a non-architectural access from
     * within QEMU.  Bypass checks for access, D, B, P and T bits.
     */
    if (type == 0) {
        goto egress;
    }

    /* access_id == 0 means public page and no check is performed */
    if (ent->access_id && MMU_IDX_TO_P(mmu_idx)) {
        int access_prot = (hppa_is_pa20(env)
                           ? match_prot_id64(env, ent->access_id)
                           : match_prot_id32(env, ent->access_id));
        if (unlikely(!(type & access_prot))) {
            /* Not allowed -- Inst/Data Memory Protection Id Fault. */
            ret = type & PAGE_EXEC ? EXCP_IMP : EXCP_DMPI;
            goto egress;
        }
        /* Otherwise exclude permissions not allowed (i.e WD). */
        prot &= access_prot;
    }

    if (unlikely(!(prot & type))) {
        /* Not allowed -- Inst/Data Memory Access Rights Fault. */
        ret = (type & PAGE_EXEC) ? EXCP_IMP : EXCP_DMAR;
        goto egress;
    }

    /* In reverse priority order, check for conditions which raise faults.
       As we go, remove PROT bits that cover the condition we want to check.
       In this way, the resulting PROT will force a re-check of the
       architectural TLB entry for the next access.  */
    if (unlikely(!ent->d)) {
        if (type & PAGE_WRITE) {
            /* The D bit is not set -- TLB Dirty Bit Fault.  */
            ret = EXCP_TLB_DIRTY;
        }
        prot &= PAGE_READ | PAGE_EXEC;
    }
    if (unlikely(ent->b)) {
        if (type & PAGE_WRITE) {
            /* The B bit is set -- Data Memory Break Fault.  */
            ret = EXCP_DMB;
        }
        prot &= PAGE_READ | PAGE_EXEC;
    }
    if (unlikely(ent->t)) {
        if (!(type & PAGE_EXEC)) {
            /* The T bit is set -- Page Reference Fault.  */
            ret = EXCP_PAGE_REF;
        }
        prot &= PAGE_EXEC;
    }

 egress:
    *pphys = phys;
    *pprot = prot;
    trace_hppa_tlb_get_physical_address(env, ret, prot, addr, phys);
    return ret;
}

hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
{
    HPPACPU *cpu = HPPA_CPU(cs);
    hwaddr phys;
    int prot, excp, mmu_idx;

    /* If the (data) mmu is disabled, bypass translation.  */
    /* ??? We really ought to know if the code mmu is disabled too,
       in order to get the correct debugging dumps.  */
    mmu_idx = (cpu->env.psw & PSW_D ? MMU_KERNEL_IDX :
               cpu->env.psw & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX);

    excp = hppa_get_physical_address(&cpu->env, addr, mmu_idx, 0,
                                     &phys, &prot, NULL);

    /* Since we're translating for debugging, the only error that is a
       hard error is no translation at all.  Otherwise, while a real cpu
       access might not have permission, the debugger does.  */
    return excp == EXCP_DTLB_MISS ? -1 : phys;
}

void hppa_set_ior_and_isr(CPUHPPAState *env, vaddr addr, bool mmu_disabled)
{
    if (env->psw & PSW_Q) {
        /*
         * For pa1.x, the offset and space never overlap, and so we
         * simply extract the high and low part of the virtual address.
         *
         * For pa2.0, the formation of these are described in section
         * "Interruption Parameter Registers", page 2-15.
         */
        env->cr[CR_IOR] = (uint32_t)addr;
        env->cr[CR_ISR] = addr >> 32;

        if (hppa_is_pa20(env)) {
            if (mmu_disabled) {
                /*
                 * If data translation was disabled, the ISR contains
                 * the upper portion of the abs address, zero-extended.
                 */
                env->cr[CR_ISR] &= 0x3fffffff;
            } else {
                /*
                 * If data translation was enabled, the upper two bits
                 * of the IOR (the b field) are equal to the two space
                 * bits from the base register used to form the gva.
                 */
                uint64_t b;

                b = env->unwind_breg ? env->gr[env->unwind_breg] : 0;
                b >>= (env->psw & PSW_W ? 62 : 30);
                env->cr[CR_IOR] |= b << 62;
            }
        }
    }
}

G_NORETURN static void
raise_exception_with_ior(CPUHPPAState *env, int excp, uintptr_t retaddr,
                         vaddr addr, bool mmu_disabled)
{
    CPUState *cs = env_cpu(env);

    cs->exception_index = excp;
    cpu_restore_state(cs, retaddr);
    hppa_set_ior_and_isr(env, addr, mmu_disabled);

    cpu_loop_exit(cs);
}

void hppa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
                                     vaddr addr, unsigned size,
                                     MMUAccessType access_type,
                                     int mmu_idx, MemTxAttrs attrs,
                                     MemTxResult response, uintptr_t retaddr)
{
    CPUHPPAState *env = cpu_env(cs);

    qemu_log_mask(LOG_GUEST_ERROR, "HPMC at " TARGET_FMT_lx ":" TARGET_FMT_lx
                " while accessing I/O at %#08" HWADDR_PRIx "\n",
                env->iasq_f, env->iaoq_f, physaddr);

    /* FIXME: Enable HPMC exceptions when firmware has clean device probing */
    if (0) {
        raise_exception_with_ior(env, EXCP_HPMC, retaddr, addr,
                                 MMU_IDX_MMU_DISABLED(mmu_idx));
    }
}

bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
                       MMUAccessType type, int mmu_idx,
                       bool probe, uintptr_t retaddr)
{
    HPPACPU *cpu = HPPA_CPU(cs);
    CPUHPPAState *env = &cpu->env;
    HPPATLBEntry *ent;
    int prot, excp, a_prot;
    hwaddr phys;

    switch (type) {
    case MMU_INST_FETCH:
        a_prot = PAGE_EXEC;
        break;
    case MMU_DATA_STORE:
        a_prot = PAGE_WRITE;
        break;
    default:
        a_prot = PAGE_READ;
        break;
    }

    excp = hppa_get_physical_address(env, addr, mmu_idx,
                                     a_prot, &phys, &prot, &ent);
    if (unlikely(excp >= 0)) {
        if (probe) {
            return false;
        }
        trace_hppa_tlb_fill_excp(env, addr, size, type, mmu_idx);

        /* Failure.  Raise the indicated exception.  */
        raise_exception_with_ior(env, excp, retaddr, addr,
                                 MMU_IDX_MMU_DISABLED(mmu_idx));
    }

    trace_hppa_tlb_fill_success(env, addr & TARGET_PAGE_MASK,
                                phys & TARGET_PAGE_MASK, size, type, mmu_idx);

    /*
     * Success!  Store the translation into the QEMU TLB.
     * Note that we always install a single-page entry, because that
     * is what works best with softmmu -- anything else will trigger
     * the large page protection mask.  We do not require this,
     * because we record the large page here in the hppa tlb.
     */
    tlb_set_page(cs, addr & TARGET_PAGE_MASK, phys & TARGET_PAGE_MASK,
                 prot, mmu_idx, TARGET_PAGE_SIZE);
    return true;
}

/* Insert (Insn/Data) TLB Address.  Note this is PA 1.1 only.  */
void HELPER(itlba_pa11)(CPUHPPAState *env, target_ulong addr, target_ulong reg)
{
    HPPATLBEntry *ent;

    /* Zap any old entries covering ADDR. */
    addr &= TARGET_PAGE_MASK;
    hppa_flush_tlb_range(env, addr, addr + TARGET_PAGE_SIZE - 1);

    ent = env->tlb_partial;
    if (ent == NULL) {
        ent = hppa_alloc_tlb_ent(env);
        env->tlb_partial = ent;
    }

    /* Note that ent->entry_valid == 0 already.  */
    ent->itree.start = addr;
    ent->itree.last = addr + TARGET_PAGE_SIZE - 1;
    ent->pa = extract32(reg, 5, 20) << TARGET_PAGE_BITS;
    trace_hppa_tlb_itlba(env, ent, ent->itree.start, ent->itree.last, ent->pa);
}

static void set_access_bits_pa11(CPUHPPAState *env, HPPATLBEntry *ent,
                                 target_ulong reg)
{
    ent->access_id = extract32(reg, 1, 18);
    ent->u = extract32(reg, 19, 1);
    ent->ar_pl2 = extract32(reg, 20, 2);
    ent->ar_pl1 = extract32(reg, 22, 2);
    ent->ar_type = extract32(reg, 24, 3);
    ent->b = extract32(reg, 27, 1);
    ent->d = extract32(reg, 28, 1);
    ent->t = extract32(reg, 29, 1);
    ent->entry_valid = 1;

    interval_tree_insert(&ent->itree, &env->tlb_root);
    trace_hppa_tlb_itlbp(env, ent, ent->access_id, ent->u, ent->ar_pl2,
                         ent->ar_pl1, ent->ar_type, ent->b, ent->d, ent->t);
}

/* Insert (Insn/Data) TLB Protection.  Note this is PA 1.1 only.  */
void HELPER(itlbp_pa11)(CPUHPPAState *env, target_ulong addr, target_ulong reg)
{
    HPPATLBEntry *ent = env->tlb_partial;

    if (ent) {
        env->tlb_partial = NULL;
        if (ent->itree.start <= addr && addr <= ent->itree.last) {
            set_access_bits_pa11(env, ent, reg);
            return;
        }
    }
    qemu_log_mask(LOG_GUEST_ERROR, "ITLBP not following ITLBA\n");
}

static void itlbt_pa20(CPUHPPAState *env, target_ulong r1,
                       target_ulong r2, vaddr va_b)
{
    HPPATLBEntry *ent;
    vaddr va_e;
    uint64_t va_size;
    int mask_shift;

    mask_shift = 2 * (r1 & 0xf);
    va_size = (uint64_t)TARGET_PAGE_SIZE << mask_shift;
    va_b &= -va_size;
    va_e = va_b + va_size - 1;

    hppa_flush_tlb_range(env, va_b, va_e);
    ent = hppa_alloc_tlb_ent(env);

    ent->itree.start = va_b;
    ent->itree.last = va_e;

    /* Extract all 52 bits present in the page table entry. */
    ent->pa = r1 << (TARGET_PAGE_BITS - 5);
    /* Align per the page size. */
    ent->pa &= TARGET_PAGE_MASK << mask_shift;
    /* Ignore the bits beyond physical address space. */
    ent->pa = sextract64(ent->pa, 0, TARGET_PHYS_ADDR_SPACE_BITS);

    ent->t = extract64(r2, 61, 1);
    ent->d = extract64(r2, 60, 1);
    ent->b = extract64(r2, 59, 1);
    ent->ar_type = extract64(r2, 56, 3);
    ent->ar_pl1 = extract64(r2, 54, 2);
    ent->ar_pl2 = extract64(r2, 52, 2);
    ent->u = extract64(r2, 51, 1);
    /* o = bit 50 */
    /* p = bit 49 */
    ent->access_id = extract64(r2, 1, 31);
    ent->entry_valid = 1;

    interval_tree_insert(&ent->itree, &env->tlb_root);
    trace_hppa_tlb_itlba(env, ent, ent->itree.start, ent->itree.last, ent->pa);
    trace_hppa_tlb_itlbp(env, ent, ent->access_id, ent->u,
                         ent->ar_pl2, ent->ar_pl1, ent->ar_type,
                         ent->b, ent->d, ent->t);
}

void HELPER(idtlbt_pa20)(CPUHPPAState *env, target_ulong r1, target_ulong r2)
{
    vaddr va_b = deposit64(env->cr[CR_IOR], 32, 32, env->cr[CR_ISR]);
    itlbt_pa20(env, r1, r2, va_b);
}

void HELPER(iitlbt_pa20)(CPUHPPAState *env, target_ulong r1, target_ulong r2)
{
    vaddr va_b = deposit64(env->cr[CR_IIAOQ], 32, 32, env->cr[CR_IIASQ]);
    itlbt_pa20(env, r1, r2, va_b);
}

/* Purge (Insn/Data) TLB. */
static void ptlb_work(CPUState *cpu, run_on_cpu_data data)
{
    vaddr start = data.target_ptr;
    vaddr end;

    /*
     * PA2.0 allows a range of pages encoded into GR[b], which we have
     * copied into the bottom bits of the otherwise page-aligned address.
     * PA1.x will always provide zero here, for a single page flush.
     */
    end = start & 0xf;
    start &= TARGET_PAGE_MASK;
    end = (vaddr)TARGET_PAGE_SIZE << (2 * end);
    end = start + end - 1;

    hppa_flush_tlb_range(cpu_env(cpu), start, end);
}

/* This is local to the current cpu. */
void HELPER(ptlb_l)(CPUHPPAState *env, target_ulong addr)
{
    trace_hppa_tlb_ptlb_local(env);
    ptlb_work(env_cpu(env), RUN_ON_CPU_TARGET_PTR(addr));
}

/* This is synchronous across all processors.  */
void HELPER(ptlb)(CPUHPPAState *env, target_ulong addr)
{
    CPUState *src = env_cpu(env);
    CPUState *cpu;
    bool wait = false;

    trace_hppa_tlb_ptlb(env);
    run_on_cpu_data data = RUN_ON_CPU_TARGET_PTR(addr);

    CPU_FOREACH(cpu) {
        if (cpu != src) {
            async_run_on_cpu(cpu, ptlb_work, data);
            wait = true;
        }
    }
    if (wait) {
        async_safe_run_on_cpu(src, ptlb_work, data);
    } else {
        ptlb_work(src, data);
    }
}

void hppa_ptlbe(CPUHPPAState *env)
{
    uint32_t btlb_entries = HPPA_BTLB_ENTRIES(env);
    uint32_t i;

    /* Zap the (non-btlb) tlb entries themselves. */
    memset(&env->tlb[btlb_entries], 0,
           sizeof(env->tlb) - btlb_entries * sizeof(env->tlb[0]));
    env->tlb_last = btlb_entries;
    env->tlb_partial = NULL;

    /* Put them all onto the unused list. */
    env->tlb_unused = &env->tlb[btlb_entries];
    for (i = btlb_entries; i < ARRAY_SIZE(env->tlb) - 1; ++i) {
        env->tlb[i].unused_next = &env->tlb[i + 1];
    }

    /* Re-initialize the interval tree with only the btlb entries. */
    memset(&env->tlb_root, 0, sizeof(env->tlb_root));
    for (i = 0; i < btlb_entries; ++i) {
        if (env->tlb[i].entry_valid) {
            interval_tree_insert(&env->tlb[i].itree, &env->tlb_root);
        }
    }

    tlb_flush_by_mmuidx(env_cpu(env), HPPA_MMU_FLUSH_MASK);
}

/* Purge (Insn/Data) TLB entry.  This affects an implementation-defined
   number of pages/entries (we choose all), and is local to the cpu.  */
void HELPER(ptlbe)(CPUHPPAState *env)
{
    trace_hppa_tlb_ptlbe(env);
    qemu_log_mask(CPU_LOG_MMU, "FLUSH ALL TLB ENTRIES\n");
    hppa_ptlbe(env);
}

void cpu_hppa_change_prot_id(CPUHPPAState *env)
{
    tlb_flush_by_mmuidx(env_cpu(env), HPPA_MMU_FLUSH_P_MASK);
}

void HELPER(change_prot_id)(CPUHPPAState *env)
{
    cpu_hppa_change_prot_id(env);
}

target_ulong HELPER(lpa)(CPUHPPAState *env, target_ulong addr)
{
    hwaddr phys;
    int prot, excp;

    excp = hppa_get_physical_address(env, addr, MMU_KERNEL_IDX, 0,
                                     &phys, &prot, NULL);
    if (excp >= 0) {
        if (excp == EXCP_DTLB_MISS) {
            excp = EXCP_NA_DTLB_MISS;
        }
        trace_hppa_tlb_lpa_failed(env, addr);
        raise_exception_with_ior(env, excp, GETPC(), addr, false);
    }
    trace_hppa_tlb_lpa_success(env, addr, phys);
    return phys;
}

/* Return the ar_type of the TLB at VADDR, or -1.  */
int hppa_artype_for_page(CPUHPPAState *env, target_ulong vaddr)
{
    HPPATLBEntry *ent = hppa_find_tlb(env, vaddr);
    return ent ? ent->ar_type : -1;
}

/*
 * diag_btlb() emulates the PDC PDC_BLOCK_TLB firmware call to
 * allow operating systems to modify the Block TLB (BTLB) entries.
 * For implementation details see page 1-13 in
 * https://parisc.wiki.kernel.org/images-parisc/e/ef/Pdc11-v0.96-Ch1-procs.pdf
 */
void HELPER(diag_btlb)(CPUHPPAState *env)
{
    unsigned int phys_page, len, slot;
    int mmu_idx = cpu_mmu_index(env_cpu(env), 0);
    uintptr_t ra = GETPC();
    HPPATLBEntry *btlb;
    uint64_t virt_page;
    uint32_t *vaddr;
    uint32_t btlb_entries = HPPA_BTLB_ENTRIES(env);

    /* BTLBs are not supported on 64-bit CPUs */
    if (btlb_entries == 0) {
        env->gr[28] = -1; /* nonexistent procedure */
        return;
    }

    env->gr[28] = 0; /* PDC_OK */

    switch (env->gr[25]) {
    case 0:
        /* return BTLB parameters */
        qemu_log_mask(CPU_LOG_MMU, "PDC_BLOCK_TLB: PDC_BTLB_INFO\n");
        vaddr = probe_access(env, env->gr[24], 4 * sizeof(uint32_t),
                             MMU_DATA_STORE, mmu_idx, ra);
        if (vaddr == NULL) {
            env->gr[28] = -10; /* invalid argument */
        } else {
            vaddr[0] = cpu_to_be32(1);
            vaddr[1] = cpu_to_be32(16 * 1024);
            vaddr[2] = cpu_to_be32(PA10_BTLB_FIXED);
            vaddr[3] = cpu_to_be32(PA10_BTLB_VARIABLE);
        }
        break;
    case 1:
        /* insert BTLB entry */
        virt_page = env->gr[24];        /* upper 32 bits */
        virt_page <<= 32;
        virt_page |= env->gr[23];       /* lower 32 bits */
        phys_page = env->gr[22];
        len = env->gr[21];
        slot = env->gr[19];
        qemu_log_mask(CPU_LOG_MMU, "PDC_BLOCK_TLB: PDC_BTLB_INSERT "
                    "0x%08llx-0x%08llx: vpage 0x%llx for phys page 0x%04x len %d "
                    "into slot %d\n",
                    (long long) virt_page << TARGET_PAGE_BITS,
                    (long long) (virt_page + len) << TARGET_PAGE_BITS,
                    (long long) virt_page, phys_page, len, slot);
        if (slot < btlb_entries) {
            btlb = &env->tlb[slot];

            /* Force flush of possibly existing BTLB entry. */
            hppa_flush_tlb_ent(env, btlb, true);

            /* Create new BTLB entry */
            btlb->itree.start = virt_page << TARGET_PAGE_BITS;
            btlb->itree.last = btlb->itree.start + len * TARGET_PAGE_SIZE - 1;
            btlb->pa = phys_page << TARGET_PAGE_BITS;
            set_access_bits_pa11(env, btlb, env->gr[20]);
            btlb->t = 0;
            btlb->d = 1;
        } else {
            env->gr[28] = -10; /* invalid argument */
        }
        break;
    case 2:
        /* Purge BTLB entry */
        slot = env->gr[22];
        qemu_log_mask(CPU_LOG_MMU, "PDC_BLOCK_TLB: PDC_BTLB_PURGE slot %d\n",
                                    slot);
        if (slot < btlb_entries) {
            btlb = &env->tlb[slot];
            hppa_flush_tlb_ent(env, btlb, true);
        } else {
            env->gr[28] = -10; /* invalid argument */
        }
        break;
    case 3:
        /* Purge all BTLB entries */
        qemu_log_mask(CPU_LOG_MMU, "PDC_BLOCK_TLB: PDC_BTLB_PURGE_ALL\n");
        for (slot = 0; slot < btlb_entries; slot++) {
            btlb = &env->tlb[slot];
            hppa_flush_tlb_ent(env, btlb, true);
        }
        break;
    default:
        env->gr[28] = -2; /* nonexistent option */
        break;
    }
}
