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