/*
 *  CRIS helper routines.
 *
 *  Copyright (c) 2007 AXIS Communications AB
 *  Written by Edgar E. Iglesias.
 *
 * 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 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 "cpu.h"
#include "mmu.h"
#include "qemu/host-utils.h"


//#define CRIS_HELPER_DEBUG


#ifdef CRIS_HELPER_DEBUG
#define D(x) x
#define D_LOG(...) qemu_log(__VA_ARGS__)
#else
#define D(x)
#define D_LOG(...) do { } while (0)
#endif

#if defined(CONFIG_USER_ONLY)

void cris_cpu_do_interrupt(CPUState *cs)
{
    CRISCPU *cpu = CRIS_CPU(cs);
    CPUCRISState *env = &cpu->env;

    cs->exception_index = -1;
    env->pregs[PR_ERP] = env->pc;
}

void crisv10_cpu_do_interrupt(CPUState *cs)
{
    cris_cpu_do_interrupt(cs);
}

int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
                              int mmu_idx)
{
    CRISCPU *cpu = CRIS_CPU(cs);

    cs->exception_index = 0xaa;
    cpu->env.pregs[PR_EDA] = address;
    cpu_dump_state(cs, stderr, fprintf, 0);
    return 1;
}

#else /* !CONFIG_USER_ONLY */


static void cris_shift_ccs(CPUCRISState *env)
{
    uint32_t ccs;
    /* Apply the ccs shift.  */
    ccs = env->pregs[PR_CCS];
    ccs = ((ccs & 0xc0000000) | ((ccs << 12) >> 2)) & ~0x3ff;
    env->pregs[PR_CCS] = ccs;
}

int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
                              int mmu_idx)
{
    CRISCPU *cpu = CRIS_CPU(cs);
    CPUCRISState *env = &cpu->env;
    struct cris_mmu_result res;
    int prot, miss;
    int r = -1;
    target_ulong phy;

    D(printf("%s addr=%" VADDR_PRIx " pc=%x rw=%x\n",
             __func__, address, env->pc, rw));
    miss = cris_mmu_translate(&res, env, address & TARGET_PAGE_MASK,
                              rw, mmu_idx, 0);
    if (miss) {
        if (cs->exception_index == EXCP_BUSFAULT) {
            cpu_abort(cs,
                      "CRIS: Illegal recursive bus fault."
                      "addr=%" VADDR_PRIx " rw=%d\n",
                      address, rw);
        }

        env->pregs[PR_EDA] = address;
        cs->exception_index = EXCP_BUSFAULT;
        env->fault_vector = res.bf_vec;
        r = 1;
    } else {
        /*
         * Mask off the cache selection bit. The ETRAX busses do not
         * see the top bit.
         */
        phy = res.phy & ~0x80000000;
        prot = res.prot;
        tlb_set_page(cs, address & TARGET_PAGE_MASK, phy,
                     prot, mmu_idx, TARGET_PAGE_SIZE);
        r = 0;
    }
    if (r > 0) {
        D_LOG("%s returns %d irqreq=%x addr=%" VADDR_PRIx " phy=%x vec=%x"
              " pc=%x\n", __func__, r, cs->interrupt_request, address, res.phy,
              res.bf_vec, env->pc);
    }
    return r;
}

void crisv10_cpu_do_interrupt(CPUState *cs)
{
    CRISCPU *cpu = CRIS_CPU(cs);
    CPUCRISState *env = &cpu->env;
    int ex_vec = -1;

    D_LOG("exception index=%d interrupt_req=%d\n",
          cs->exception_index,
          cs->interrupt_request);

    if (env->dslot) {
        /* CRISv10 never takes interrupts while in a delay-slot.  */
        cpu_abort(cs, "CRIS: Interrupt on delay-slot\n");
    }

    assert(!(env->pregs[PR_CCS] & PFIX_FLAG));
    switch (cs->exception_index) {
    case EXCP_BREAK:
        /* These exceptions are genereated by the core itself.
           ERP should point to the insn following the brk.  */
        ex_vec = env->trap_vector;
        env->pregs[PRV10_BRP] = env->pc;
        break;

    case EXCP_NMI:
        /* NMI is hardwired to vector zero.  */
        ex_vec = 0;
        env->pregs[PR_CCS] &= ~M_FLAG_V10;
        env->pregs[PRV10_BRP] = env->pc;
        break;

    case EXCP_BUSFAULT:
        cpu_abort(cs, "Unhandled busfault");
        break;

    default:
        /* The interrupt controller gives us the vector.  */
        ex_vec = env->interrupt_vector;
        /* Normal interrupts are taken between
           TB's.  env->pc is valid here.  */
        env->pregs[PR_ERP] = env->pc;
        break;
    }

    if (env->pregs[PR_CCS] & U_FLAG) {
        /* Swap stack pointers.  */
        env->pregs[PR_USP] = env->regs[R_SP];
        env->regs[R_SP] = env->ksp;
    }

    /* Now that we are in kernel mode, load the handlers address.  */
    env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4);
    env->locked_irq = 1;
    env->pregs[PR_CCS] |= F_FLAG_V10; /* set F.  */

    qemu_log_mask(CPU_LOG_INT, "%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n",
                  __func__, env->pc, ex_vec,
                  env->pregs[PR_CCS],
                  env->pregs[PR_PID],
                  env->pregs[PR_ERP]);
}

void cris_cpu_do_interrupt(CPUState *cs)
{
    CRISCPU *cpu = CRIS_CPU(cs);
    CPUCRISState *env = &cpu->env;
    int ex_vec = -1;

    D_LOG("exception index=%d interrupt_req=%d\n",
          cs->exception_index,
          cs->interrupt_request);

    switch (cs->exception_index) {
    case EXCP_BREAK:
        /* These exceptions are genereated by the core itself.
           ERP should point to the insn following the brk.  */
        ex_vec = env->trap_vector;
        env->pregs[PR_ERP] = env->pc;
        break;

    case EXCP_NMI:
        /* NMI is hardwired to vector zero.  */
        ex_vec = 0;
        env->pregs[PR_CCS] &= ~M_FLAG_V32;
        env->pregs[PR_NRP] = env->pc;
        break;

    case EXCP_BUSFAULT:
        ex_vec = env->fault_vector;
        env->pregs[PR_ERP] = env->pc;
        break;

    default:
        /* The interrupt controller gives us the vector.  */
        ex_vec = env->interrupt_vector;
        /* Normal interrupts are taken between
           TB's.  env->pc is valid here.  */
        env->pregs[PR_ERP] = env->pc;
        break;
    }

    /* Fill in the IDX field.  */
    env->pregs[PR_EXS] = (ex_vec & 0xff) << 8;

    if (env->dslot) {
        D_LOG("excp isr=%x PC=%x ds=%d SP=%x"
              " ERP=%x pid=%x ccs=%x cc=%d %x\n",
              ex_vec, env->pc, env->dslot,
              env->regs[R_SP],
              env->pregs[PR_ERP], env->pregs[PR_PID],
              env->pregs[PR_CCS],
              env->cc_op, env->cc_mask);
        /* We loose the btarget, btaken state here so rexec the
           branch.  */
        env->pregs[PR_ERP] -= env->dslot;
        /* Exception starts with dslot cleared.  */
        env->dslot = 0;
    }
	
    if (env->pregs[PR_CCS] & U_FLAG) {
        /* Swap stack pointers.  */
        env->pregs[PR_USP] = env->regs[R_SP];
        env->regs[R_SP] = env->ksp;
    }

    /* Apply the CRIS CCS shift. Clears U if set.  */
    cris_shift_ccs(env);

    /* Now that we are in kernel mode, load the handlers address.
       This load may not fault, real hw leaves that behaviour as
       undefined.  */
    env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4);

    /* Clear the excption_index to avoid spurios hw_aborts for recursive
       bus faults.  */
    cs->exception_index = -1;

    D_LOG("%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n",
          __func__, env->pc, ex_vec,
          env->pregs[PR_CCS],
          env->pregs[PR_PID],
          env->pregs[PR_ERP]);
}

hwaddr cris_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
{
    CRISCPU *cpu = CRIS_CPU(cs);
    uint32_t phy = addr;
    struct cris_mmu_result res;
    int miss;

    miss = cris_mmu_translate(&res, &cpu->env, addr, 0, 0, 1);
    /* If D TLB misses, try I TLB.  */
    if (miss) {
        miss = cris_mmu_translate(&res, &cpu->env, addr, 2, 0, 1);
    }

    if (!miss) {
        phy = res.phy;
    }
    D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy));
    return phy;
}
#endif
