Revision 327ac2e7
b/cpu-exec.c | ||
---|---|---|
461 | 461 |
env->interrupt_request &= ~CPU_INTERRUPT_HARD; |
462 | 462 |
do_interrupt(env->interrupt_index); |
463 | 463 |
env->interrupt_index = 0; |
464 |
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) |
|
465 |
cpu_check_irqs(env); |
|
466 |
#endif |
|
464 | 467 |
#if defined(__sparc__) && !defined(HOST_SOLARIS) |
465 | 468 |
tmp_T0 = 0; |
466 | 469 |
#else |
b/hw/slavio_intctl.c | ||
---|---|---|
104 | 104 |
val |= 80000000; |
105 | 105 |
val &= 0xfffe0000; |
106 | 106 |
s->intreg_pending[cpu] &= ~val; |
107 |
slavio_check_interrupts(s); |
|
107 | 108 |
DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]); |
108 | 109 |
break; |
109 | 110 |
case 2: // set softint |
... | ... | |
175 | 176 |
val &= ~0x4fb2007f; |
176 | 177 |
s->intregm_disabled |= val; |
177 | 178 |
s->intregm_pending &= ~val; |
179 |
slavio_check_interrupts(s); |
|
178 | 180 |
DPRINTF("Disabled master irq mask %x, curmask %x\n", val, s->intregm_disabled); |
179 | 181 |
break; |
180 | 182 |
case 4: |
181 | 183 |
s->target_cpu = val & (MAX_CPUS - 1); |
184 |
slavio_check_interrupts(s); |
|
182 | 185 |
DPRINTF("Set master irq cpu %d\n", s->target_cpu); |
183 | 186 |
break; |
184 | 187 |
default: |
... | ... | |
227 | 230 |
#endif |
228 | 231 |
} |
229 | 232 |
|
230 |
static void raise_pil(SLAVIO_INTCTLState *s, unsigned int pil, |
|
231 |
unsigned int cpu) |
|
232 |
{ |
|
233 |
qemu_irq irq; |
|
234 |
unsigned int oldmax; |
|
235 |
|
|
236 |
irq = s->cpu_irqs[cpu][pil]; |
|
237 |
|
|
238 |
#ifdef DEBUG_IRQ_COUNT |
|
239 |
s->irq_count[pil]++; |
|
240 |
#endif |
|
241 |
oldmax = s->pil_out[cpu]; |
|
242 |
if (oldmax > 0 && oldmax != pil) |
|
243 |
qemu_irq_lower(s->cpu_irqs[cpu][oldmax]); |
|
244 |
s->pil_out[cpu] = pil; |
|
245 |
if (pil > 0) |
|
246 |
qemu_irq_raise(irq); |
|
247 |
DPRINTF("cpu %d pil %d\n", cpu, pil); |
|
248 |
} |
|
249 |
|
|
250 | 233 |
static void slavio_check_interrupts(void *opaque) |
251 | 234 |
{ |
252 | 235 |
SLAVIO_INTCTLState *s = opaque; |
253 |
uint32_t pending = s->intregm_pending; |
|
254 |
unsigned int i, j, max = 0;
|
|
236 |
uint32_t pending = s->intregm_pending, pil_pending;
|
|
237 |
unsigned int i, j; |
|
255 | 238 |
|
256 | 239 |
pending &= ~s->intregm_disabled; |
257 | 240 |
|
258 | 241 |
DPRINTF("pending %x disabled %x\n", pending, s->intregm_disabled); |
259 | 242 |
for (i = 0; i < MAX_CPUS; i++) { |
260 |
max = 0;
|
|
243 |
pil_pending = 0;
|
|
261 | 244 |
if (pending && !(s->intregm_disabled & 0x80000000) && |
262 | 245 |
(i == s->target_cpu)) { |
263 | 246 |
for (j = 0; j < 32; j++) { |
264 |
if (pending & (1 << j)) { |
|
265 |
if (max < s->intbit_to_level[j]) |
|
266 |
max = s->intbit_to_level[j]; |
|
267 |
} |
|
247 |
if (pending & (1 << j)) |
|
248 |
pil_pending |= 1 << s->intbit_to_level[j]; |
|
268 | 249 |
} |
269 | 250 |
} |
270 |
for (j = 17; j < 32; j++) { |
|
271 |
if (s->intreg_pending[i] & (1 << j)) { |
|
272 |
if (max < j - 16) |
|
273 |
max = j - 16; |
|
251 |
pil_pending |= (s->intreg_pending[i] >> 16) & 0xfffe; |
|
252 |
|
|
253 |
for (j = 0; j < MAX_PILS; j++) { |
|
254 |
if (pil_pending & (1 << j)) { |
|
255 |
if (!(s->pil_out[i] & (1 << j))) |
|
256 |
qemu_irq_raise(s->cpu_irqs[i][j]); |
|
257 |
} else { |
|
258 |
if (s->pil_out[i] & (1 << j)) |
|
259 |
qemu_irq_lower(s->cpu_irqs[i][j]); |
|
274 | 260 |
} |
275 | 261 |
} |
276 |
raise_pil(s, max, i);
|
|
262 |
s->pil_out[i] = pil_pending;
|
|
277 | 263 |
} |
278 | 264 |
} |
279 | 265 |
|
... | ... | |
291 | 277 |
level); |
292 | 278 |
if (pil > 0) { |
293 | 279 |
if (level) { |
280 |
#ifdef DEBUG_IRQ_COUNT |
|
281 |
s->irq_count[pil]++; |
|
282 |
#endif |
|
294 | 283 |
s->intregm_pending |= mask; |
295 | 284 |
s->intreg_pending[s->target_cpu] |= 1 << pil; |
296 | 285 |
} else { |
... | ... | |
342 | 331 |
qemu_get_be32s(f, &s->intregm_pending); |
343 | 332 |
qemu_get_be32s(f, &s->intregm_disabled); |
344 | 333 |
qemu_get_be32s(f, &s->target_cpu); |
334 |
slavio_check_interrupts(s); |
|
345 | 335 |
return 0; |
346 | 336 |
} |
347 | 337 |
|
... | ... | |
356 | 346 |
s->intregm_disabled = ~0xffb2007f; |
357 | 347 |
s->intregm_pending = 0; |
358 | 348 |
s->target_cpu = 0; |
349 |
slavio_check_interrupts(s); |
|
359 | 350 |
} |
360 | 351 |
|
361 | 352 |
void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg, |
b/hw/sun4m.c | ||
---|---|---|
240 | 240 |
slavio_irq_info(slavio_intctl); |
241 | 241 |
} |
242 | 242 |
|
243 |
void cpu_check_irqs(CPUState *env) |
|
244 |
{ |
|
245 |
if (env->pil_in && (env->interrupt_index == 0 || |
|
246 |
(env->interrupt_index & ~15) == TT_EXTINT)) { |
|
247 |
unsigned int i; |
|
248 |
|
|
249 |
for (i = 15; i > 0; i--) { |
|
250 |
if (env->pil_in & (1 << i)) { |
|
251 |
int old_interrupt = env->interrupt_index; |
|
252 |
|
|
253 |
env->interrupt_index = TT_EXTINT | i; |
|
254 |
if (old_interrupt != env->interrupt_index) |
|
255 |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
|
256 |
break; |
|
257 |
} |
|
258 |
} |
|
259 |
} else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) { |
|
260 |
env->interrupt_index = 0; |
|
261 |
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); |
|
262 |
} |
|
263 |
} |
|
264 |
|
|
243 | 265 |
static void cpu_set_irq(void *opaque, int irq, int level) |
244 | 266 |
{ |
245 | 267 |
CPUState *env = opaque; |
246 | 268 |
|
247 | 269 |
if (level) { |
248 | 270 |
DPRINTF("Raise CPU IRQ %d\n", irq); |
249 |
|
|
250 | 271 |
env->halted = 0; |
251 |
|
|
252 |
if (env->interrupt_index == 0 || |
|
253 |
((env->interrupt_index & ~15) == TT_EXTINT && |
|
254 |
(env->interrupt_index & 15) < irq)) { |
|
255 |
env->interrupt_index = TT_EXTINT | irq; |
|
256 |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
|
257 |
} else { |
|
258 |
DPRINTF("Not triggered, pending exception %d\n", |
|
259 |
env->interrupt_index); |
|
260 |
} |
|
272 |
env->pil_in |= 1 << irq; |
|
273 |
cpu_check_irqs(env); |
|
261 | 274 |
} else { |
262 | 275 |
DPRINTF("Lower CPU IRQ %d\n", irq); |
276 |
env->pil_in &= ~(1 << irq); |
|
277 |
cpu_check_irqs(env); |
|
263 | 278 |
} |
264 | 279 |
} |
265 | 280 |
|
b/target-sparc/cpu.h | ||
---|---|---|
181 | 181 |
int psrs; /* supervisor mode (extracted from PSR) */ |
182 | 182 |
int psrps; /* previous supervisor mode */ |
183 | 183 |
int psret; /* enable traps */ |
184 |
uint32_t psrpil; /* interrupt level */ |
|
184 |
uint32_t psrpil; /* interrupt blocking level */ |
|
185 |
uint32_t pil_in; /* incoming interrupt level bitmap */ |
|
185 | 186 |
int psref; /* enable fpu */ |
186 | 187 |
target_ulong version; |
187 | 188 |
jmp_buf jmp_env; |
... | ... | |
306 | 307 |
void do_tick_set_count(void *opaque, uint64_t count); |
307 | 308 |
uint64_t do_tick_get_count(void *opaque); |
308 | 309 |
void do_tick_set_limit(void *opaque, uint64_t limit); |
310 |
void cpu_check_irqs(CPUSPARCState *env); |
|
309 | 311 |
|
310 | 312 |
#define CPUState CPUSPARCState |
311 | 313 |
#define cpu_init cpu_sparc_init |
Also available in: Unified diff