Revision e96e2044 target-sh4/helper.c
b/target-sh4/helper.c | ||
---|---|---|
27 | 27 |
|
28 | 28 |
#include "cpu.h" |
29 | 29 |
#include "exec-all.h" |
30 |
#include "hw/sh_intc.h" |
|
30 | 31 |
|
31 | 32 |
#if defined(CONFIG_USER_ONLY) |
32 | 33 |
|
... | ... | |
74 | 75 |
|
75 | 76 |
void do_interrupt(CPUState * env) |
76 | 77 |
{ |
78 |
int do_irq = env->interrupt_request & CPU_INTERRUPT_HARD; |
|
79 |
int do_exp, irq_vector = env->exception_index; |
|
80 |
|
|
81 |
/* prioritize exceptions over interrupts */ |
|
82 |
|
|
83 |
do_exp = env->exception_index != -1; |
|
84 |
do_irq = do_irq && (env->exception_index == -1); |
|
85 |
|
|
86 |
if (env->sr & SR_BL) { |
|
87 |
if (do_exp && env->exception_index != 0x1e0) { |
|
88 |
env->exception_index = 0x000; /* masked exception -> reset */ |
|
89 |
} |
|
90 |
if (do_irq) { |
|
91 |
return; /* masked */ |
|
92 |
} |
|
93 |
} |
|
94 |
|
|
95 |
if (do_irq) { |
|
96 |
irq_vector = sh_intc_get_pending_vector(env->intc_handle, |
|
97 |
(env->sr >> 4) & 0xf); |
|
98 |
if (irq_vector == -1) { |
|
99 |
return; /* masked */ |
|
100 |
} |
|
101 |
} |
|
102 |
|
|
77 | 103 |
if (loglevel & CPU_LOG_INT) { |
78 | 104 |
const char *expname; |
79 | 105 |
switch (env->exception_index) { |
... | ... | |
117 | 143 |
expname = "trapa"; |
118 | 144 |
break; |
119 | 145 |
default: |
120 |
expname = "???";
|
|
121 |
break;
|
|
146 |
expname = do_irq ? "interrupt" : "???";
|
|
147 |
break;
|
|
122 | 148 |
} |
123 | 149 |
fprintf(logfile, "exception 0x%03x [%s] raised\n", |
124 |
env->exception_index, expname);
|
|
150 |
irq_vector, expname);
|
|
125 | 151 |
cpu_dump_state(env, logfile, fprintf, 0); |
126 | 152 |
} |
127 | 153 |
|
128 | 154 |
env->ssr = env->sr; |
129 |
env->spc = env->spc;
|
|
155 |
env->spc = env->pc; |
|
130 | 156 |
env->sgr = env->gregs[15]; |
131 | 157 |
env->sr |= SR_BL | SR_MD | SR_RB; |
132 | 158 |
|
133 |
env->expevt = env->exception_index & 0x7ff; |
|
134 |
switch (env->exception_index) { |
|
135 |
case 0x040: |
|
136 |
case 0x060: |
|
137 |
case 0x080: |
|
138 |
env->pc = env->vbr + 0x400; |
|
139 |
break; |
|
140 |
case 0x140: |
|
141 |
env->pc = 0xa0000000; |
|
142 |
break; |
|
143 |
default: |
|
144 |
env->pc = env->vbr + 0x100; |
|
145 |
break; |
|
159 |
if (do_exp) { |
|
160 |
env->expevt = env->exception_index; |
|
161 |
switch (env->exception_index) { |
|
162 |
case 0x000: |
|
163 |
case 0x020: |
|
164 |
case 0x140: |
|
165 |
env->sr &= ~SR_FD; |
|
166 |
env->sr |= 0xf << 4; /* IMASK */ |
|
167 |
env->pc = 0xa0000000; |
|
168 |
break; |
|
169 |
case 0x040: |
|
170 |
case 0x060: |
|
171 |
env->pc = env->vbr + 0x400; |
|
172 |
break; |
|
173 |
case 0x160: |
|
174 |
env->spc += 2; /* special case for TRAPA */ |
|
175 |
/* fall through */ |
|
176 |
default: |
|
177 |
env->pc = env->vbr + 0x100; |
|
178 |
break; |
|
179 |
} |
|
180 |
return; |
|
181 |
} |
|
182 |
|
|
183 |
if (do_irq) { |
|
184 |
env->intevt = irq_vector; |
|
185 |
env->pc = env->vbr + 0x600; |
|
186 |
return; |
|
146 | 187 |
} |
147 | 188 |
} |
148 | 189 |
|
Also available in: Unified diff