|
|
1.1 ! root 1: /* ! 2: * Sparc32 interrupt helpers ! 3: * ! 4: * Copyright (c) 2003-2005 Fabrice Bellard ! 5: * ! 6: * This library is free software; you can redistribute it and/or ! 7: * modify it under the terms of the GNU Lesser General Public ! 8: * License as published by the Free Software Foundation; either ! 9: * version 2 of the License, or (at your option) any later version. ! 10: * ! 11: * This library is distributed in the hope that it will be useful, ! 12: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 14: * Lesser General Public License for more details. ! 15: * ! 16: * You should have received a copy of the GNU Lesser General Public ! 17: * License along with this library; if not, see <http://www.gnu.org/licenses/>. ! 18: */ ! 19: ! 20: #include "cpu.h" ! 21: #include "trace.h" ! 22: #include "sysemu.h" ! 23: ! 24: //#define DEBUG_PCALL ! 25: ! 26: #ifdef DEBUG_PCALL ! 27: static const char * const excp_names[0x80] = { ! 28: [TT_TFAULT] = "Instruction Access Fault", ! 29: [TT_ILL_INSN] = "Illegal Instruction", ! 30: [TT_PRIV_INSN] = "Privileged Instruction", ! 31: [TT_NFPU_INSN] = "FPU Disabled", ! 32: [TT_WIN_OVF] = "Window Overflow", ! 33: [TT_WIN_UNF] = "Window Underflow", ! 34: [TT_UNALIGNED] = "Unaligned Memory Access", ! 35: [TT_FP_EXCP] = "FPU Exception", ! 36: [TT_DFAULT] = "Data Access Fault", ! 37: [TT_TOVF] = "Tag Overflow", ! 38: [TT_EXTINT | 0x1] = "External Interrupt 1", ! 39: [TT_EXTINT | 0x2] = "External Interrupt 2", ! 40: [TT_EXTINT | 0x3] = "External Interrupt 3", ! 41: [TT_EXTINT | 0x4] = "External Interrupt 4", ! 42: [TT_EXTINT | 0x5] = "External Interrupt 5", ! 43: [TT_EXTINT | 0x6] = "External Interrupt 6", ! 44: [TT_EXTINT | 0x7] = "External Interrupt 7", ! 45: [TT_EXTINT | 0x8] = "External Interrupt 8", ! 46: [TT_EXTINT | 0x9] = "External Interrupt 9", ! 47: [TT_EXTINT | 0xa] = "External Interrupt 10", ! 48: [TT_EXTINT | 0xb] = "External Interrupt 11", ! 49: [TT_EXTINT | 0xc] = "External Interrupt 12", ! 50: [TT_EXTINT | 0xd] = "External Interrupt 13", ! 51: [TT_EXTINT | 0xe] = "External Interrupt 14", ! 52: [TT_EXTINT | 0xf] = "External Interrupt 15", ! 53: [TT_TOVF] = "Tag Overflow", ! 54: [TT_CODE_ACCESS] = "Instruction Access Error", ! 55: [TT_DATA_ACCESS] = "Data Access Error", ! 56: [TT_DIV_ZERO] = "Division By Zero", ! 57: [TT_NCP_INSN] = "Coprocessor Disabled", ! 58: }; ! 59: #endif ! 60: ! 61: void do_interrupt(CPUState *env) ! 62: { ! 63: int cwp, intno = env->exception_index; ! 64: ! 65: #ifdef DEBUG_PCALL ! 66: if (qemu_loglevel_mask(CPU_LOG_INT)) { ! 67: static int count; ! 68: const char *name; ! 69: ! 70: if (intno < 0 || intno >= 0x100) { ! 71: name = "Unknown"; ! 72: } else if (intno >= 0x80) { ! 73: name = "Trap Instruction"; ! 74: } else { ! 75: name = excp_names[intno]; ! 76: if (!name) { ! 77: name = "Unknown"; ! 78: } ! 79: } ! 80: ! 81: qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n", ! 82: count, name, intno, ! 83: env->pc, ! 84: env->npc, env->regwptr[6]); ! 85: log_cpu_state(env, 0); ! 86: #if 0 ! 87: { ! 88: int i; ! 89: uint8_t *ptr; ! 90: ! 91: qemu_log(" code="); ! 92: ptr = (uint8_t *)env->pc; ! 93: for (i = 0; i < 16; i++) { ! 94: qemu_log(" %02x", ldub(ptr + i)); ! 95: } ! 96: qemu_log("\n"); ! 97: } ! 98: #endif ! 99: count++; ! 100: } ! 101: #endif ! 102: #if !defined(CONFIG_USER_ONLY) ! 103: if (env->psret == 0) { ! 104: if (env->exception_index == 0x80 && ! 105: env->def->features & CPU_FEATURE_TA0_SHUTDOWN) { ! 106: qemu_system_shutdown_request(); ! 107: } else { ! 108: cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", ! 109: env->exception_index); ! 110: } ! 111: return; ! 112: } ! 113: #endif ! 114: env->psret = 0; ! 115: cwp = cpu_cwp_dec(env, env->cwp - 1); ! 116: cpu_set_cwp(env, cwp); ! 117: env->regwptr[9] = env->pc; ! 118: env->regwptr[10] = env->npc; ! 119: env->psrps = env->psrs; ! 120: env->psrs = 1; ! 121: env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4); ! 122: env->pc = env->tbr; ! 123: env->npc = env->pc + 4; ! 124: env->exception_index = -1; ! 125: ! 126: #if !defined(CONFIG_USER_ONLY) ! 127: /* IRQ acknowledgment */ ! 128: if ((intno & ~15) == TT_EXTINT && env->qemu_irq_ack != NULL) { ! 129: env->qemu_irq_ack(env, env->irq_manager, intno); ! 130: } ! 131: #endif ! 132: } ! 133: ! 134: #if !defined(CONFIG_USER_ONLY) ! 135: static void leon3_cache_control_int(CPUState *env) ! 136: { ! 137: uint32_t state = 0; ! 138: ! 139: if (env->cache_control & CACHE_CTRL_IF) { ! 140: /* Instruction cache state */ ! 141: state = env->cache_control & CACHE_STATE_MASK; ! 142: if (state == CACHE_ENABLED) { ! 143: state = CACHE_FROZEN; ! 144: trace_int_helper_icache_freeze(); ! 145: } ! 146: ! 147: env->cache_control &= ~CACHE_STATE_MASK; ! 148: env->cache_control |= state; ! 149: } ! 150: ! 151: if (env->cache_control & CACHE_CTRL_DF) { ! 152: /* Data cache state */ ! 153: state = (env->cache_control >> 2) & CACHE_STATE_MASK; ! 154: if (state == CACHE_ENABLED) { ! 155: state = CACHE_FROZEN; ! 156: trace_int_helper_dcache_freeze(); ! 157: } ! 158: ! 159: env->cache_control &= ~(CACHE_STATE_MASK << 2); ! 160: env->cache_control |= (state << 2); ! 161: } ! 162: } ! 163: ! 164: void leon3_irq_manager(CPUState *env, void *irq_manager, int intno) ! 165: { ! 166: leon3_irq_ack(irq_manager, intno); ! 167: leon3_cache_control_int(env); ! 168: } ! 169: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.