/*
 *  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;

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

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

int cpu_cris_handle_mmu_fault(CPUCRISState * env, target_ulong address, int rw,
                              int mmu_idx)
{
    CRISCPU *cpu = cris_env_get_cpu(env);

    env->exception_index = 0xaa;
    env->pregs[PR_EDA] = address;
    cpu_dump_state(CPU(cpu), 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 cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw,
                              int mmu_idx)
{
    D(CPUState *cpu = CPU(cris_env_get_cpu(env)));
    struct cris_mmu_result res;
    int prot, miss;
    int r = -1;
    target_ulong phy;

    D(printf("%s addr=%x 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 (env->exception_index == EXCP_BUSFAULT) {
            cpu_abort(env,
                      "CRIS: Illegal recursive bus fault."
                      "addr=%x rw=%d\n",
                      address, rw);
        }

        env->pregs[PR_EDA] = address;
        env->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(env, address & TARGET_PAGE_MASK, phy,
                     prot, mmu_idx, TARGET_PAGE_SIZE);
        r = 0;
    }
    if (r > 0) {
        D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n",
              __func__, r, cpu->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",
          env->exception_index,
          cs->interrupt_request);

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

    assert(!(env->pregs[PR_CCS] & PFIX_FLAG));
    switch (env->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(env, "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",
          env->exception_index,
          cs->interrupt_request);

    switch (env->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.  */
    env->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
