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