Revision ba3c64fb hw/slavio_intctl.c
b/hw/slavio_intctl.c | ||
---|---|---|
53 | 53 |
#ifdef DEBUG_IRQ_COUNT |
54 | 54 |
uint64_t irq_count[32]; |
55 | 55 |
#endif |
56 |
CPUState *cpu_envs[MAX_CPUS]; |
|
56 | 57 |
} SLAVIO_INTCTLState; |
57 | 58 |
|
58 | 59 |
#define INTCTL_MAXADDR 0xf |
... | ... | |
96 | 97 |
case 2: // set softint |
97 | 98 |
val &= 0xfffe0000; |
98 | 99 |
s->intreg_pending[cpu] |= val; |
100 |
slavio_check_interrupts(s); |
|
99 | 101 |
DPRINTF("Set cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]); |
100 | 102 |
break; |
101 | 103 |
default: |
... | ... | |
216 | 218 |
CPUState *env; |
217 | 219 |
SLAVIO_INTCTLState *s = opaque; |
218 | 220 |
uint32_t pending = s->intregm_pending; |
219 |
unsigned int i, max = 0; |
|
221 |
unsigned int i, j, max = 0;
|
|
220 | 222 |
|
221 | 223 |
pending &= ~s->intregm_disabled; |
222 | 224 |
|
... | ... | |
227 | 229 |
max = intbit_to_level[i]; |
228 | 230 |
} |
229 | 231 |
} |
230 |
env = first_cpu; |
|
231 |
if (env->interrupt_index == 0) { |
|
232 |
DPRINTF("Triggered pil %d\n", max); |
|
232 |
env = s->cpu_envs[s->target_cpu]; |
|
233 |
if (!env) { |
|
234 |
DPRINTF("No CPU %d, not triggered (pending %x)\n", s->target_cpu, pending); |
|
235 |
} |
|
236 |
else { |
|
237 |
if (env->halted) |
|
238 |
env->halted = 0; |
|
239 |
if (env->interrupt_index == 0) { |
|
240 |
DPRINTF("Triggered CPU %d pil %d\n", s->target_cpu, max); |
|
233 | 241 |
#ifdef DEBUG_IRQ_COUNT |
234 |
s->irq_count[max]++;
|
|
242 |
s->irq_count[max]++;
|
|
235 | 243 |
#endif |
236 |
env->interrupt_index = TT_EXTINT | max; |
|
237 |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
|
244 |
env->interrupt_index = TT_EXTINT | max; |
|
245 |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
|
246 |
} |
|
247 |
else |
|
248 |
DPRINTF("Not triggered (pending %x), pending exception %x\n", pending, env->interrupt_index); |
|
238 | 249 |
} |
239 |
else |
|
240 |
DPRINTF("Not triggered (pending %x), pending exception %x\n", pending, env->interrupt_index); |
|
241 | 250 |
} |
242 | 251 |
else |
243 | 252 |
DPRINTF("Not triggered (pending %x), disabled %x\n", pending, s->intregm_disabled); |
253 |
|
|
254 |
for (i = 0; i < MAX_CPUS; i++) { |
|
255 |
max = 0; |
|
256 |
env = s->cpu_envs[i]; |
|
257 |
if (!env) |
|
258 |
continue; |
|
259 |
for (j = 17; j < 32; j++) { |
|
260 |
if (s->intreg_pending[i] & (1 << j)) { |
|
261 |
if (max < j - 16) |
|
262 |
max = j - 16; |
|
263 |
} |
|
264 |
} |
|
265 |
if (max > 0) { |
|
266 |
if (env->halted) |
|
267 |
env->halted = 0; |
|
268 |
if (env->interrupt_index == 0) { |
|
269 |
DPRINTF("Triggered softint %d for cpu %d (pending %x)\n", max, i, pending); |
|
270 |
#ifdef DEBUG_IRQ_COUNT |
|
271 |
s->irq_count[max]++; |
|
272 |
#endif |
|
273 |
env->interrupt_index = TT_EXTINT | max; |
|
274 |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
|
275 |
} |
|
276 |
} |
|
277 |
} |
|
244 | 278 |
} |
245 | 279 |
|
246 | 280 |
/* |
... | ... | |
251 | 285 |
{ |
252 | 286 |
SLAVIO_INTCTLState *s = opaque; |
253 | 287 |
|
254 |
DPRINTF("Set irq %d level %d\n", irq, level);
|
|
288 |
DPRINTF("Set cpu %d irq %d level %d\n", s->target_cpu, irq, level);
|
|
255 | 289 |
if (irq < 32) { |
256 | 290 |
uint32_t mask = 1 << irq; |
257 | 291 |
uint32_t pil = intbit_to_level[irq]; |
... | ... | |
269 | 303 |
slavio_check_interrupts(s); |
270 | 304 |
} |
271 | 305 |
|
306 |
void slavio_pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu) |
|
307 |
{ |
|
308 |
SLAVIO_INTCTLState *s = opaque; |
|
309 |
|
|
310 |
DPRINTF("Set cpu %d local irq %d level %d\n", cpu, irq, level); |
|
311 |
if (cpu == (unsigned int)-1) { |
|
312 |
slavio_pic_set_irq(opaque, irq, level); |
|
313 |
return; |
|
314 |
} |
|
315 |
if (irq < 32) { |
|
316 |
uint32_t pil = intbit_to_level[irq]; |
|
317 |
if (pil > 0) { |
|
318 |
if (level) { |
|
319 |
s->intreg_pending[cpu] |= 1 << pil; |
|
320 |
} |
|
321 |
else { |
|
322 |
s->intreg_pending[cpu] &= ~(1 << pil); |
|
323 |
} |
|
324 |
} |
|
325 |
} |
|
326 |
slavio_check_interrupts(s); |
|
327 |
} |
|
328 |
|
|
272 | 329 |
static void slavio_intctl_save(QEMUFile *f, void *opaque) |
273 | 330 |
{ |
274 | 331 |
SLAVIO_INTCTLState *s = opaque; |
... | ... | |
312 | 369 |
s->target_cpu = 0; |
313 | 370 |
} |
314 | 371 |
|
372 |
void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env) |
|
373 |
{ |
|
374 |
SLAVIO_INTCTLState *s = opaque; |
|
375 |
s->cpu_envs[cpu] = env; |
|
376 |
} |
|
377 |
|
|
315 | 378 |
void *slavio_intctl_init(uint32_t addr, uint32_t addrg) |
316 | 379 |
{ |
317 | 380 |
int slavio_intctl_io_memory, slavio_intctlm_io_memory, i; |
Also available in: Unified diff