/*
 * OpenRISC interrupt.
 *
 * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
 *
 * 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 "qemu/osdep.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "qemu-common.h"
#include "exec/gdbstub.h"
#include "qemu/host-utils.h"
#ifndef CONFIG_USER_ONLY
#include "hw/loader.h"
#endif

void openrisc_cpu_do_interrupt(CPUState *cs)
{
#ifndef CONFIG_USER_ONLY
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    CPUOpenRISCState *env = &cpu->env;
    int exception = cs->exception_index;

    env->epcr = env->pc;
    if (exception == EXCP_SYSCALL) {
        env->epcr += 4;
    }
    /* When we have an illegal instruction the error effective address
       shall be set to the illegal instruction address.  */
    if (exception == EXCP_ILLEGAL) {
        env->eear = env->pc;
    }

    /* During exceptions esr is populared with the pre-exception sr.  */
    env->esr = cpu_get_sr(env);
    /* In parallel sr is updated to disable mmu, interrupts, timers and
       set the delay slot exception flag.  */
    env->sr &= ~SR_DME;
    env->sr &= ~SR_IME;
    env->sr |= SR_SM;
    env->sr &= ~SR_IEE;
    env->sr &= ~SR_TEE;
    env->pmr &= ~PMR_DME;
    env->pmr &= ~PMR_SME;
    env->lock_addr = -1;

    /* Set/clear dsx to indicate if we are in a delay slot exception.  */
    if (env->dflag) {
        env->dflag = 0;
        env->sr |= SR_DSX;
        env->epcr -= 4;
    } else {
        env->sr &= ~SR_DSX;
    }

    if (exception > 0 && exception < EXCP_NR) {
        static const char * const int_name[EXCP_NR] = {
            [EXCP_RESET]    = "RESET",
            [EXCP_BUSERR]   = "BUSERR (bus error)",
            [EXCP_DPF]      = "DFP (data protection fault)",
            [EXCP_IPF]      = "IPF (code protection fault)",
            [EXCP_TICK]     = "TICK (timer interrupt)",
            [EXCP_ALIGN]    = "ALIGN",
            [EXCP_ILLEGAL]  = "ILLEGAL",
            [EXCP_INT]      = "INT (device interrupt)",
            [EXCP_DTLBMISS] = "DTLBMISS (data tlb miss)",
            [EXCP_ITLBMISS] = "ITLBMISS (code tlb miss)",
            [EXCP_RANGE]    = "RANGE",
            [EXCP_SYSCALL]  = "SYSCALL",
            [EXCP_FPE]      = "FPE",
            [EXCP_TRAP]     = "TRAP",
        };

        qemu_log_mask(CPU_LOG_INT, "INT: %s\n", int_name[exception]);

        hwaddr vect_pc = exception << 8;
        if (env->cpucfgr & CPUCFGR_EVBARP) {
            vect_pc |= env->evbar;
        }
        if (env->sr & SR_EPH) {
            vect_pc |= 0xf0000000;
        }
        env->pc = vect_pc;
    } else {
        cpu_abort(cs, "Unhandled exception 0x%x\n", exception);
    }
#endif

    cs->exception_index = -1;
}

bool openrisc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    CPUOpenRISCState *env = &cpu->env;
    int idx = -1;

    if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->sr & SR_IEE)) {
        idx = EXCP_INT;
    }
    if ((interrupt_request & CPU_INTERRUPT_TIMER) && (env->sr & SR_TEE)) {
        idx = EXCP_TICK;
    }
    if (idx >= 0) {
        cs->exception_index = idx;
        openrisc_cpu_do_interrupt(cs);
        return true;
    }
    return false;
}
