/* * Sparc32 interrupt helpers * * Copyright (c) 2003-2005 Fabrice Bellard * * 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 . */ #include "qemu/osdep.h" #include "cpu.h" //#include "sysemu/runstate.h" void sparc_cpu_do_interrupt(CPUState *cs) { SPARCCPU *cpu = SPARC_CPU(cs); CPUSPARCState *env = &cpu->env; int cwp, intno = cs->exception_index; /* Compute PSR before exposing state. */ if (env->cc_op != CC_OP_FLAGS) { cpu_get_psr(env); } if (env->psret == 0) { if (cs->exception_index == 0x80 && env->def.features & CPU_FEATURE_TA0_SHUTDOWN) { // qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); } else { cpu_abort(cs, "Trap 0x%02x while interrupts disabled, Error state", cs->exception_index); } return; } env->psret = 0; cwp = cpu_cwp_dec(env, env->cwp - 1); cpu_set_cwp(env, cwp); env->regwptr[9] = env->pc; env->regwptr[10] = env->npc; env->psrps = env->psrs; env->psrs = 1; env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4); env->pc = env->tbr; env->npc = env->pc + 4; cs->exception_index = -1; /* IRQ acknowledgment */ if ((intno & ~15) == TT_EXTINT && env->qemu_irq_ack != NULL) { env->qemu_irq_ack(env, env->irq_manager, intno); } } static void leon3_cache_control_int(CPUSPARCState *env) { uint32_t state = 0; if (env->cache_control & CACHE_CTRL_IF) { /* Instruction cache state */ state = env->cache_control & CACHE_STATE_MASK; if (state == CACHE_ENABLED) { state = CACHE_FROZEN; } env->cache_control &= ~CACHE_STATE_MASK; env->cache_control |= state; } if (env->cache_control & CACHE_CTRL_DF) { /* Data cache state */ state = (env->cache_control >> 2) & CACHE_STATE_MASK; if (state == CACHE_ENABLED) { state = CACHE_FROZEN; } env->cache_control &= ~(CACHE_STATE_MASK << 2); env->cache_control |= (state << 2); } } void leon3_irq_manager(CPUSPARCState *env, void *irq_manager, int intno) { // leon3_irq_ack(irq_manager, intno); leon3_cache_control_int(env); }