/*
 *  MicroBlaze helper routines.
 *
 *  Copyright (c) 2009 Edgar E. Iglesias <edgar.iglesias@gmail.com>
 *  Copyright (c) 2009-2012 PetaLogix Qld Pty Ltd.
 *
 * 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 "cpu.h"
#include "exec/exec-all.h"
#include "qemu/host-utils.h"
#include "exec/log.h"

#if defined(CONFIG_USER_ONLY)

bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                     MMUAccessType access_type, int mmu_idx,
                     bool probe, uintptr_t retaddr)
{
    cs->exception_index = 0xaa;
    cpu_loop_exit_restore(cs, retaddr);
}

#else /* !CONFIG_USER_ONLY */

static bool mb_cpu_access_is_secure(MicroBlazeCPU *cpu,
                                    MMUAccessType access_type)
{
    if (access_type == MMU_INST_FETCH) {
        return !cpu->ns_axi_ip;
    } else {
        return !cpu->ns_axi_dp;
    }
}

bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                     MMUAccessType access_type, int mmu_idx,
                     bool probe, uintptr_t retaddr)
{
    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
    CPUMBState *env = &cpu->env;
    MicroBlazeMMULookup lu;
    unsigned int hit;
    int prot;
    MemTxAttrs attrs = {};

    attrs.secure = mb_cpu_access_is_secure(cpu, access_type);

    if (mmu_idx == MMU_NOMMU_IDX) {
        /* MMU disabled or not available.  */
        address &= TARGET_PAGE_MASK;
        prot = PAGE_BITS;
        tlb_set_page_with_attrs(cs, address, address, attrs, prot, mmu_idx,
                                TARGET_PAGE_SIZE);
        return true;
    }

    hit = mmu_translate(cpu, &lu, address, access_type, mmu_idx);
    if (likely(hit)) {
        uint32_t vaddr = address & TARGET_PAGE_MASK;
        uint32_t paddr = lu.paddr + vaddr - lu.vaddr;

        qemu_log_mask(CPU_LOG_MMU, "MMU map mmu=%d v=%x p=%x prot=%x\n",
                      mmu_idx, vaddr, paddr, lu.prot);
        tlb_set_page_with_attrs(cs, vaddr, paddr, attrs, lu.prot, mmu_idx,
                                TARGET_PAGE_SIZE);
        return true;
    }

    /* TLB miss.  */
    if (probe) {
        return false;
    }

    qemu_log_mask(CPU_LOG_MMU, "mmu=%d miss v=%" VADDR_PRIx "\n",
                  mmu_idx, address);

    env->ear = address;
    switch (lu.err) {
    case ERR_PROT:
        env->esr = access_type == MMU_INST_FETCH ? 17 : 16;
        env->esr |= (access_type == MMU_DATA_STORE) << 10;
        break;
    case ERR_MISS:
        env->esr = access_type == MMU_INST_FETCH ? 19 : 18;
        env->esr |= (access_type == MMU_DATA_STORE) << 10;
        break;
    default:
        abort();
    }

    if (cs->exception_index == EXCP_MMU) {
        cpu_abort(cs, "recursive faults\n");
    }

    /* TLB miss.  */
    cs->exception_index = EXCP_MMU;
    cpu_loop_exit_restore(cs, retaddr);
}

void mb_cpu_do_interrupt(CPUState *cs)
{
    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
    CPUMBState *env = &cpu->env;
    uint32_t t, msr = mb_cpu_read_msr(env);
    bool set_esr;

    /* IMM flag cannot propagate across a branch and into the dslot.  */
    assert((env->iflags & (D_FLAG | IMM_FLAG)) != (D_FLAG | IMM_FLAG));
    /* BIMM flag cannot be set without D_FLAG. */
    assert((env->iflags & (D_FLAG | BIMM_FLAG)) != BIMM_FLAG);
    /* RTI flags are private to translate. */
    assert(!(env->iflags & (DRTI_FLAG | DRTE_FLAG | DRTB_FLAG)));

    switch (cs->exception_index) {
    case EXCP_HW_EXCP:
        if (!(cpu->cfg.pvr_regs[0] & PVR0_USE_EXC_MASK)) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "Exception raised on system without exceptions!\n");
            return;
        }

        qemu_log_mask(CPU_LOG_INT,
                      "INT: HWE at pc=%08x msr=%08x iflags=%x\n",
                      env->pc, msr, env->iflags);

        /* Exception breaks branch + dslot sequence?  */
        set_esr = true;
        env->esr &= ~D_FLAG;
        if (env->iflags & D_FLAG) {
            env->esr |= D_FLAG;
            env->btr = env->btarget;
        }

        /* Exception in progress. */
        msr |= MSR_EIP;
        env->regs[17] = env->pc + 4;
        env->pc = cpu->cfg.base_vectors + 0x20;
        break;

    case EXCP_MMU:
        qemu_log_mask(CPU_LOG_INT,
                      "INT: MMU at pc=%08x msr=%08x "
                      "ear=%" PRIx64 " iflags=%x\n",
                      env->pc, msr, env->ear, env->iflags);

        /* Exception breaks branch + dslot sequence? */
        set_esr = true;
        env->esr &= ~D_FLAG;
        if (env->iflags & D_FLAG) {
            env->esr |= D_FLAG;
            env->btr = env->btarget;
            /* Reexecute the branch. */
            env->regs[17] = env->pc - (env->iflags & BIMM_FLAG ? 8 : 4);
        } else if (env->iflags & IMM_FLAG) {
            /* Reexecute the imm. */
            env->regs[17] = env->pc - 4;
        } else {
            env->regs[17] = env->pc;
        }

        /* Exception in progress. */
        msr |= MSR_EIP;
        env->pc = cpu->cfg.base_vectors + 0x20;
        break;

    case EXCP_IRQ:
        assert(!(msr & (MSR_EIP | MSR_BIP)));
        assert(msr & MSR_IE);
        assert(!(env->iflags & (D_FLAG | IMM_FLAG)));

        qemu_log_mask(CPU_LOG_INT,
                      "INT: DEV at pc=%08x msr=%08x iflags=%x\n",
                      env->pc, msr, env->iflags);
        set_esr = false;

        /* Disable interrupts.  */
        msr &= ~MSR_IE;
        env->regs[14] = env->pc;
        env->pc = cpu->cfg.base_vectors + 0x10;
        break;

    case EXCP_HW_BREAK:
        assert(!(env->iflags & (D_FLAG | IMM_FLAG)));

        qemu_log_mask(CPU_LOG_INT,
                      "INT: BRK at pc=%08x msr=%08x iflags=%x\n",
                      env->pc, msr, env->iflags);
        set_esr = false;

        /* Break in progress. */
        msr |= MSR_BIP;
        env->regs[16] = env->pc;
        env->pc = cpu->cfg.base_vectors + 0x18;
        break;

    default:
        cpu_abort(cs, "unhandled exception type=%d\n", cs->exception_index);
        /* not reached */
    }

    /* Save previous mode, disable mmu, disable user-mode. */
    t = (msr & (MSR_VM | MSR_UM)) << 1;
    msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
    msr |= t;
    mb_cpu_write_msr(env, msr);

    env->res_addr = RES_ADDR_NONE;
    env->iflags = 0;

    if (!set_esr) {
        qemu_log_mask(CPU_LOG_INT,
                      "         to pc=%08x msr=%08x\n", env->pc, msr);
    } else if (env->esr & D_FLAG) {
        qemu_log_mask(CPU_LOG_INT,
                      "         to pc=%08x msr=%08x esr=%04x btr=%08x\n",
                      env->pc, msr, env->esr, env->btr);
    } else {
        qemu_log_mask(CPU_LOG_INT,
                      "         to pc=%08x msr=%08x esr=%04x\n",
                      env->pc, msr, env->esr);
    }
}

hwaddr mb_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
                                        MemTxAttrs *attrs)
{
    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
    CPUMBState *env = &cpu->env;
    target_ulong vaddr, paddr = 0;
    MicroBlazeMMULookup lu;
    int mmu_idx = cpu_mmu_index(env, false);
    unsigned int hit;

    /* Caller doesn't initialize */
    *attrs = (MemTxAttrs) {};
    attrs->secure = mb_cpu_access_is_secure(cpu, MMU_DATA_LOAD);

    if (mmu_idx != MMU_NOMMU_IDX) {
        hit = mmu_translate(cpu, &lu, addr, 0, 0);
        if (hit) {
            vaddr = addr & TARGET_PAGE_MASK;
            paddr = lu.paddr + vaddr - lu.vaddr;
        } else
            paddr = 0; /* ???.  */
    } else
        paddr = addr & TARGET_PAGE_MASK;

    return paddr;
}

bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
    CPUMBState *env = &cpu->env;

    if ((interrupt_request & CPU_INTERRUPT_HARD)
        && (env->msr & MSR_IE)
        && !(env->msr & (MSR_EIP | MSR_BIP))
        && !(env->iflags & (D_FLAG | IMM_FLAG))) {
        cs->exception_index = EXCP_IRQ;
        mb_cpu_do_interrupt(cs);
        return true;
    }
    return false;
}

#endif /* !CONFIG_USER_ONLY */

void mb_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
                                MMUAccessType access_type,
                                int mmu_idx, uintptr_t retaddr)
{
    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
    uint32_t esr, iflags;

    /* Recover the pc and iflags from the corresponding insn_start.  */
    cpu_restore_state(cs, retaddr, true);
    iflags = cpu->env.iflags;

    qemu_log_mask(CPU_LOG_INT,
                  "Unaligned access addr=" TARGET_FMT_lx " pc=%x iflags=%x\n",
                  (target_ulong)addr, cpu->env.pc, iflags);

    esr = ESR_EC_UNALIGNED_DATA;
    if (likely(iflags & ESR_ESS_FLAG)) {
        esr |= iflags & ESR_ESS_MASK;
    } else {
        qemu_log_mask(LOG_UNIMP, "Unaligned access without ESR_ESS_FLAG\n");
    }

    cpu->env.ear = addr;
    cpu->env.esr = esr;
    cs->exception_index = EXCP_HW_EXCP;
    cpu_loop_exit(cs);
}
