| 53 |
#ifdef DEBUG_IRQ_COUNT |
#ifdef DEBUG_IRQ_COUNT |
| 54 |
uint64_t irq_count[32]; |
uint64_t irq_count[32]; |
| 55 |
#endif |
#endif |
| 56 |
|
CPUState *cpu_envs[MAX_CPUS]; |
| 57 |
} SLAVIO_INTCTLState; |
} SLAVIO_INTCTLState; |
| 58 |
|
|
| 59 |
#define INTCTL_MAXADDR 0xf |
#define INTCTL_MAXADDR 0xf |
| 97 |
case 2: // set softint |
case 2: // set softint |
| 98 |
val &= 0xfffe0000; |
val &= 0xfffe0000; |
| 99 |
s->intreg_pending[cpu] |= val; |
s->intreg_pending[cpu] |= val; |
| 100 |
|
slavio_check_interrupts(s); |
| 101 |
DPRINTF("Set cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]); |
DPRINTF("Set cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]); |
| 102 |
break; |
break; |
| 103 |
default: |
default: |
| 218 |
CPUState *env; |
CPUState *env; |
| 219 |
SLAVIO_INTCTLState *s = opaque; |
SLAVIO_INTCTLState *s = opaque; |
| 220 |
uint32_t pending = s->intregm_pending; |
uint32_t pending = s->intregm_pending; |
| 221 |
unsigned int i, max = 0; |
unsigned int i, j, max = 0; |
| 222 |
|
|
| 223 |
pending &= ~s->intregm_disabled; |
pending &= ~s->intregm_disabled; |
| 224 |
|
|
| 229 |
max = intbit_to_level[i]; |
max = intbit_to_level[i]; |
| 230 |
} |
} |
| 231 |
} |
} |
| 232 |
env = first_cpu; |
env = s->cpu_envs[s->target_cpu]; |
| 233 |
if (env->interrupt_index == 0) { |
if (!env) { |
| 234 |
DPRINTF("Triggered pil %d\n", max); |
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); |
| 241 |
#ifdef DEBUG_IRQ_COUNT |
#ifdef DEBUG_IRQ_COUNT |
| 242 |
s->irq_count[max]++; |
s->irq_count[max]++; |
| 243 |
#endif |
#endif |
| 244 |
env->interrupt_index = TT_EXTINT | max; |
env->interrupt_index = TT_EXTINT | max; |
| 245 |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
| 246 |
|
} |
| 247 |
|
else |
| 248 |
|
DPRINTF("Not triggered (pending %x), pending exception %x\n", pending, env->interrupt_index); |
| 249 |
} |
} |
|
else |
|
|
DPRINTF("Not triggered (pending %x), pending exception %x\n", pending, env->interrupt_index); |
|
| 250 |
} |
} |
| 251 |
else |
else |
| 252 |
DPRINTF("Not triggered (pending %x), disabled %x\n", pending, s->intregm_disabled); |
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 |
|
} |
| 278 |
} |
} |
| 279 |
|
|
| 280 |
/* |
/* |
| 285 |
{ |
{ |
| 286 |
SLAVIO_INTCTLState *s = opaque; |
SLAVIO_INTCTLState *s = opaque; |
| 287 |
|
|
| 288 |
DPRINTF("Set irq %d level %d\n", irq, level); |
DPRINTF("Set cpu %d irq %d level %d\n", s->target_cpu, irq, level); |
| 289 |
if (irq < 32) { |
if (irq < 32) { |
| 290 |
uint32_t mask = 1 << irq; |
uint32_t mask = 1 << irq; |
| 291 |
uint32_t pil = intbit_to_level[irq]; |
uint32_t pil = intbit_to_level[irq]; |
| 303 |
slavio_check_interrupts(s); |
slavio_check_interrupts(s); |
| 304 |
} |
} |
| 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 |
|
|
| 329 |
static void slavio_intctl_save(QEMUFile *f, void *opaque) |
static void slavio_intctl_save(QEMUFile *f, void *opaque) |
| 330 |
{ |
{ |
| 331 |
SLAVIO_INTCTLState *s = opaque; |
SLAVIO_INTCTLState *s = opaque; |
| 369 |
s->target_cpu = 0; |
s->target_cpu = 0; |
| 370 |
} |
} |
| 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 |
|
|
| 378 |
void *slavio_intctl_init(uint32_t addr, uint32_t addrg) |
void *slavio_intctl_init(uint32_t addr, uint32_t addrg) |
| 379 |
{ |
{ |
| 380 |
int slavio_intctl_io_memory, slavio_intctlm_io_memory, i; |
int slavio_intctl_io_memory, slavio_intctlm_io_memory, i; |