Revision 3f1beaca target-arm/helper.c
b/target-arm/helper.c | ||
---|---|---|
1974 | 1974 |
pointer. */ |
1975 | 1975 |
} |
1976 | 1976 |
|
1977 |
/* Exception names for debug logging; note that not all of these |
|
1978 |
* precisely correspond to architectural exceptions. |
|
1979 |
*/ |
|
1980 |
static const char * const excnames[] = { |
|
1981 |
[EXCP_UDEF] = "Undefined Instruction", |
|
1982 |
[EXCP_SWI] = "SVC", |
|
1983 |
[EXCP_PREFETCH_ABORT] = "Prefetch Abort", |
|
1984 |
[EXCP_DATA_ABORT] = "Data Abort", |
|
1985 |
[EXCP_IRQ] = "IRQ", |
|
1986 |
[EXCP_FIQ] = "FIQ", |
|
1987 |
[EXCP_BKPT] = "Breakpoint", |
|
1988 |
[EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit", |
|
1989 |
[EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage", |
|
1990 |
[EXCP_STREX] = "QEMU intercept of STREX", |
|
1991 |
}; |
|
1992 |
|
|
1993 |
static inline void arm_log_exception(int idx) |
|
1994 |
{ |
|
1995 |
if (qemu_loglevel_mask(CPU_LOG_INT)) { |
|
1996 |
const char *exc = NULL; |
|
1997 |
|
|
1998 |
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) { |
|
1999 |
exc = excnames[idx]; |
|
2000 |
} |
|
2001 |
if (!exc) { |
|
2002 |
exc = "unknown"; |
|
2003 |
} |
|
2004 |
qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc); |
|
2005 |
} |
|
2006 |
} |
|
2007 |
|
|
1977 | 2008 |
void arm_v7m_cpu_do_interrupt(CPUState *cs) |
1978 | 2009 |
{ |
1979 | 2010 |
ARMCPU *cpu = ARM_CPU(cs); |
... | ... | |
1982 | 2013 |
uint32_t lr; |
1983 | 2014 |
uint32_t addr; |
1984 | 2015 |
|
2016 |
arm_log_exception(env->exception_index); |
|
2017 |
|
|
1985 | 2018 |
lr = 0xfffffff1; |
1986 | 2019 |
if (env->v7m.current_sp) |
1987 | 2020 |
lr |= 4; |
... | ... | |
2011 | 2044 |
if (nr == 0xab) { |
2012 | 2045 |
env->regs[15] += 2; |
2013 | 2046 |
env->regs[0] = do_arm_semihosting(env); |
2047 |
qemu_log_mask(CPU_LOG_INT, "...handled as semihosting call\n"); |
|
2014 | 2048 |
return; |
2015 | 2049 |
} |
2016 | 2050 |
} |
... | ... | |
2064 | 2098 |
|
2065 | 2099 |
assert(!IS_M(env)); |
2066 | 2100 |
|
2101 |
arm_log_exception(env->exception_index); |
|
2102 |
|
|
2067 | 2103 |
/* TODO: Vectored interrupt controller. */ |
2068 | 2104 |
switch (env->exception_index) { |
2069 | 2105 |
case EXCP_UDEF: |
... | ... | |
2091 | 2127 |
|| (mask == 0xab && env->thumb)) |
2092 | 2128 |
&& (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) { |
2093 | 2129 |
env->regs[0] = do_arm_semihosting(env); |
2130 |
qemu_log_mask(CPU_LOG_INT, "...handled as semihosting call\n"); |
|
2094 | 2131 |
return; |
2095 | 2132 |
} |
2096 | 2133 |
} |
... | ... | |
2108 | 2145 |
&& (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) { |
2109 | 2146 |
env->regs[15] += 2; |
2110 | 2147 |
env->regs[0] = do_arm_semihosting(env); |
2148 |
qemu_log_mask(CPU_LOG_INT, "...handled as semihosting call\n"); |
|
2111 | 2149 |
return; |
2112 | 2150 |
} |
2113 | 2151 |
} |
2114 | 2152 |
env->cp15.c5_insn = 2; |
2115 | 2153 |
/* Fall through to prefetch abort. */ |
2116 | 2154 |
case EXCP_PREFETCH_ABORT: |
2155 |
qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n", |
|
2156 |
env->cp15.c5_insn, env->cp15.c6_insn); |
|
2117 | 2157 |
new_mode = ARM_CPU_MODE_ABT; |
2118 | 2158 |
addr = 0x0c; |
2119 | 2159 |
mask = CPSR_A | CPSR_I; |
2120 | 2160 |
offset = 4; |
2121 | 2161 |
break; |
2122 | 2162 |
case EXCP_DATA_ABORT: |
2163 |
qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n", |
|
2164 |
env->cp15.c5_data, env->cp15.c6_data); |
|
2123 | 2165 |
new_mode = ARM_CPU_MODE_ABT; |
2124 | 2166 |
addr = 0x10; |
2125 | 2167 |
mask = CPSR_A | CPSR_I; |
Also available in: Unified diff