Revision e9df014c

b/cpu-exec.c
467 467
                    }
468 468
#endif
469 469
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
470
                        if (ppc_hw_interrupt(env) == 1) {
471
                            /* Some exception was raised */
472
                            if (env->pending_interrupts == 0)
473
                                env->interrupt_request &= ~CPU_INTERRUPT_HARD;
470
                        ppc_hw_interrupt(env);
471
                        if (env->pending_interrupts == 0)
472
                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
474 473
#if defined(__sparc__) && !defined(HOST_SOLARIS)
475
                            tmp_T0 = 0;
474
                        tmp_T0 = 0;
476 475
#else
477
                            T0 = 0;
476
                        T0 = 0;
478 477
#endif
479
                        }
480 478
                    }
481 479
#elif defined(TARGET_MIPS)
482 480
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
b/hw/openpic.c
159 159
    uint32_t pcsr; /* CPU sensitivity register */
160 160
    IRQ_queue_t raised;
161 161
    IRQ_queue_t servicing;
162
    CPUState *env;
162
    qemu_irq *irqs;
163 163
} IRQ_dst_t;
164 164

  
165 165
typedef struct openpic_t {
166 166
    PCIDevice pci_dev;
167
    SetIRQFunc *set_irq;
168 167
    int mem_index;
169 168
    /* Global registers */
170 169
    uint32_t frep; /* Feature reporting register */
171 170
    uint32_t glbc; /* Global configuration register  */
172 171
    uint32_t micr; /* MPIC interrupt configuration register */
173 172
    uint32_t veni; /* Vendor identification register */
173
    uint32_t pint; /* Processor initialization register */
174 174
    uint32_t spve; /* Spurious vector register */
175 175
    uint32_t tifr; /* Timer frequency reporting register */
176 176
    /* Source registers */
......
196 196
	uint32_t mbr;    /* Mailbox register */
197 197
    } mailboxes[MAX_MAILBOXES];
198 198
#endif
199
    /* IRQ out is used when in bypass mode (not implemented) */
200
    qemu_irq irq_out;
199 201
} openpic_t;
200 202

  
201 203
static inline void IRQ_setbit (IRQ_queue_t *q, int n_IRQ)
......
255 257
    priority = IPVP_PRIORITY(src->ipvp);
256 258
    if (priority <= dst->pctp) {
257 259
	/* Too low priority */
260
        DPRINTF("%s: IRQ %d has too low priority on CPU %d\n",
261
                __func__, n_IRQ, n_CPU);
258 262
	return;
259 263
    }
260 264
    if (IRQ_testbit(&dst->raised, n_IRQ)) {
261 265
	/* Interrupt miss */
266
        DPRINTF("%s: IRQ %d was missed on CPU %d\n",
267
                __func__, n_IRQ, n_CPU);
262 268
	return;
263 269
    }
264 270
    set_bit(&src->ipvp, IPVP_ACTIVITY);
265 271
    IRQ_setbit(&dst->raised, n_IRQ);
266
    if (priority > dst->raised.priority) {
267
        IRQ_get_next(opp, &dst->raised);
268
        DPRINTF("Raise CPU IRQ fn %p env %p\n", opp->set_irq, dst->env);
269
        opp->set_irq(dst->env, OPENPIC_EVT_INT, 1);
272
    if (priority < dst->raised.priority) {
273
        /* An higher priority IRQ is already raised */
274
        DPRINTF("%s: IRQ %d is hidden by raised IRQ %d on CPU %d\n",
275
                __func__, n_IRQ, dst->raised.next, n_CPU);
276
        return;
277
    }
278
    IRQ_get_next(opp, &dst->raised);
279
    if (IRQ_get_next(opp, &dst->servicing) != -1 &&
280
        priority < dst->servicing.priority) {
281
        DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n",
282
                __func__, n_IRQ, dst->servicing.next, n_CPU);
283
        /* Already servicing a higher priority IRQ */
284
        return;
270 285
    }
286
    DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", n_CPU, n_IRQ);
287
    qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]);
271 288
}
272 289

  
273 290
/* update pic state because registers for n_IRQ have changed value */
......
280 297

  
281 298
    if (!src->pending) {
282 299
        /* no irq pending */
300
        DPRINTF("%s: IRQ %d is not pending\n", __func__, n_IRQ);
283 301
        return;
284 302
    }
285 303
    if (test_bit(&src->ipvp, IPVP_MASK)) {
286 304
	/* Interrupt source is disabled */
305
        DPRINTF("%s: IRQ %d is disabled\n", __func__, n_IRQ);
287 306
	return;
288 307
    }
289 308
    if (IPVP_PRIORITY(src->ipvp) == 0) {
290 309
	/* Priority set to zero */
310
        DPRINTF("%s: IRQ %d has 0 priority\n", __func__, n_IRQ);
291 311
	return;
292 312
    }
293 313
    if (test_bit(&src->ipvp, IPVP_ACTIVITY)) {
294 314
        /* IRQ already active */
315
        DPRINTF("%s: IRQ %d is already active\n", __func__, n_IRQ);
295 316
        return;
296 317
    }
297 318
    if (src->ide == 0x00000000) {
298 319
	/* No target */
320
        DPRINTF("%s: IRQ %d has no target\n", __func__, n_IRQ);
299 321
	return;
300 322
    }
301 323

  
302
    if (!test_bit(&src->ipvp, IPVP_MODE) ||
303
        src->ide == (1 << src->last_cpu)) {
324
    if (src->ide == (1 << src->last_cpu)) {
325
        /* Only one CPU is allowed to receive this IRQ */
326
        IRQ_local_pipe(opp, src->last_cpu, n_IRQ);
327
    } else if (!test_bit(&src->ipvp, IPVP_MODE)) {
304 328
        /* Directed delivery mode */
305 329
        for (i = 0; i < opp->nb_cpus; i++) {
306 330
            if (test_bit(&src->ide, i))
......
308 332
        }
309 333
    } else {
310 334
        /* Distributed delivery mode */
311
        /* XXX: incorrect code */
312
        for (i = src->last_cpu; i < src->last_cpu; i++) {
313
            if (i == MAX_IRQ)
335
        for (i = src->last_cpu + 1; i != src->last_cpu; i++) {
336
            if (i == opp->nb_cpus)
314 337
                i = 0;
315 338
            if (test_bit(&src->ide, i)) {
316 339
                IRQ_local_pipe(opp, i, n_IRQ);
......
350 373
    /* Initialise controller registers */
351 374
    opp->frep = ((EXT_IRQ - 1) << 16) | ((MAX_CPU - 1) << 8) | VID;
352 375
    opp->veni = VENI;
376
    opp->pint = 0x00000000;
353 377
    opp->spve = 0x000000FF;
354 378
    opp->tifr = 0x003F7A00;
355 379
    /* ? */
......
360 384
	opp->src[i].ide  = 0x00000000;
361 385
    }
362 386
    /* Initialise IRQ destinations */
363
    for (i = 0; i < opp->nb_cpus; i++) {
387
    for (i = 0; i < MAX_CPU; i++) {
364 388
	opp->dst[i].pctp      = 0x0000000F;
365 389
	opp->dst[i].pcsr      = 0x00000000;
366 390
	memset(&opp->dst[i].raised, 0, sizeof(IRQ_queue_t));
......
511 535
static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
512 536
{
513 537
    openpic_t *opp = opaque;
538
    IRQ_dst_t *dst;
539
    int idx;
514 540

  
515 541
    DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
516 542
    if (addr & 0xF)
......
530 556
    case 0x80: /* VENI */
531 557
	break;
532 558
    case 0x90: /* PINT */
533
        /* XXX: Should be able to reset any CPU */
534
        if (val & 1) {
535
            DPRINTF("Reset CPU IRQ\n");
536
            //                opp->set_irq(dst->env, OPENPIC_EVT_RESET, 1);
559
        for (idx = 0; idx < opp->nb_cpus; idx++) {
560
            if ((val & (1 << idx)) && !(opp->pint & (1 << idx))) {
561
                DPRINTF("Raise OpenPIC RESET output for CPU %d\n", idx);
562
                dst = &opp->dst[idx];
563
                qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_RESET]);
564
            } else if (!(val & (1 << idx)) && (opp->pint & (1 << idx))) {
565
                DPRINTF("Lower OpenPIC RESET output for CPU %d\n", idx);
566
                dst = &opp->dst[idx];
567
                qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_RESET]);
568
            }
537 569
        }
570
        opp->pint = val;
538 571
	break;
539 572
#if MAX_IPI > 0
540 573
    case 0xA0: /* IPI_IPVP */
......
735 768
    openpic_t *opp = opaque;
736 769
    IRQ_src_t *src;
737 770
    IRQ_dst_t *dst;
738
    int idx, n_IRQ;
771
    int idx, s_IRQ, n_IRQ;
739 772

  
740 773
    DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
741 774
    if (addr & 0xF)
......
770 803
	break;
771 804
    case 0xB0: /* PEOI */
772 805
        DPRINTF("PEOI\n");
773
	n_IRQ = IRQ_get_next(opp, &dst->servicing);
774
	IRQ_resetbit(&dst->servicing, n_IRQ);
806
	s_IRQ = IRQ_get_next(opp, &dst->servicing);
807
	IRQ_resetbit(&dst->servicing, s_IRQ);
775 808
	dst->servicing.next = -1;
776
	src = &opp->src[n_IRQ];
777 809
	/* Set up next servicing IRQ */
778
	IRQ_get_next(opp, &dst->servicing);
779
	/* Check queued interrupts. */
780
	n_IRQ = IRQ_get_next(opp, &dst->raised);
781
	if (n_IRQ != -1) {
782
	    src = &opp->src[n_IRQ];
783
	    if (IPVP_PRIORITY(src->ipvp) > dst->servicing.priority) {
784
                DPRINTF("Raise CPU IRQ\n");
785
                opp->set_irq(dst->env, OPENPIC_EVT_INT, 1);
786
            }
787
	}
810
	s_IRQ = IRQ_get_next(opp, &dst->servicing);
811
        /* Check queued interrupts. */
812
        n_IRQ = IRQ_get_next(opp, &dst->raised);
813
        src = &opp->src[n_IRQ];
814
        if (n_IRQ != -1 &&
815
            (s_IRQ == -1 ||
816
             IPVP_PRIORITY(src->ipvp) > dst->servicing.priority)) {
817
            DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n",
818
                    idx, n_IRQ);
819
            qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]);
820
        }
788 821
	break;
789 822
    default:
790 823
        break;
......
815 848
	retval = idx;
816 849
	break;
817 850
    case 0xA0: /* PIAC */
851
        DPRINTF("Lower OpenPIC INT output\n");
852
        qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);
818 853
	n_IRQ = IRQ_get_next(opp, &dst->raised);
819 854
        DPRINTF("PIAC: irq=%d\n", n_IRQ);
820 855
	if (n_IRQ == -1) {
821 856
	    /* No more interrupt pending */
822
            retval = opp->spve;
857
            retval = IPVP_VECTOR(opp->spve);
823 858
	} else {
824 859
	    src = &opp->src[n_IRQ];
825 860
	    if (!test_bit(&src->ipvp, IPVP_ACTIVITY) ||
......
964 999
#endif
965 1000
}
966 1001

  
967
qemu_irq *openpic_init (PCIBus *bus, SetIRQFunc *set_irq,
968
                         int *pmem_index, int nb_cpus, CPUState **envp)
1002
qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
1003
                        qemu_irq **irqs, qemu_irq irq_out)
969 1004
{
970 1005
    openpic_t *opp;
971 1006
    uint8_t *pci_conf;
......
995 1030
    } else {
996 1031
        opp = qemu_mallocz(sizeof(openpic_t));
997 1032
    }
998
    opp->set_irq = set_irq;
999 1033
    opp->mem_index = cpu_register_io_memory(0, openpic_read,
1000 1034
                                            openpic_write, opp);
1001 1035
    
......
1020 1054
        opp->src[i].type = IRQ_INTERNAL;
1021 1055
    }
1022 1056
    for (i = 0; i < nb_cpus; i++)
1023
        opp->dst[i].env = envp[i];
1057
        opp->dst[i].irqs = irqs[i];
1058
    opp->irq_out = irq_out;
1024 1059
    openpic_reset(opp);
1025 1060
    if (pmem_index)
1026 1061
        *pmem_index = opp->mem_index;
1062

  
1027 1063
    return qemu_allocate_irqs(openpic_set_irq, opp, MAX_IRQ);
1028 1064
}
b/hw/ppc.c
1 1
/*
2
 * QEMU generic PPC hardware System Emulator
2
 * QEMU generic PowerPC hardware System Emulator
3 3
 * 
4 4
 * Copyright (c) 2003-2007 Jocelyn Mayer
5 5
 * 
......
24 24
#include "vl.h"
25 25
#include "m48t59.h"
26 26

  
27
//#define PPC_DEBUG_IRQ
28

  
27 29
extern FILE *logfile;
28 30
extern int loglevel;
29 31

  
30
/*****************************************************************************/
31
/* PowerPC internal fake IRQ controller
32
 * used to manage multiple sources hardware events
33
 */
34
static void ppc_set_irq (void *opaque, int n_IRQ, int level)
32
void ppc_set_irq (CPUState *env, int n_IRQ, int level)
35 33
{
36
    CPUState *env;
37

  
38
    env = opaque;
39 34
    if (level) {
40 35
        env->pending_interrupts |= 1 << n_IRQ;
41 36
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
......
44 39
        if (env->pending_interrupts == 0)
45 40
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
46 41
    }
47
#if 0
42
#if defined(PPC_DEBUG_IRQ)
48 43
    printf("%s: %p n_IRQ %d level %d => pending %08x req %08x\n", __func__,
49 44
           env, n_IRQ, level, env->pending_interrupts, env->interrupt_request);
50 45
#endif
51 46
}
52 47

  
53
void cpu_ppc_irq_init_cpu(CPUState *env)
48
/* PowerPC 6xx / 7xx internal IRQ controller */
49
static void ppc6xx_set_irq (void *opaque, int pin, int level)
54 50
{
55
    qemu_irq *qi;
56
    int i;
51
    CPUState *env = opaque;
52
    int cur_level;
57 53

  
58
    qi = qemu_allocate_irqs(ppc_set_irq, env, 32);
59
    for (i = 0; i < 32; i++) {
60
        env->irq[i] = qi[i];
54
#if defined(PPC_DEBUG_IRQ)
55
    printf("%s: env %p pin %d level %d\n", __func__, env, pin, level);
56
#endif
57
    cur_level = (env->irq_input_state >> pin) & 1;
58
    /* Don't generate spurious events */
59
    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0) || 0) {
60
        switch (pin) {
61
        case PPC_INPUT_INT:
62
            /* Level sensitive - asserted high */
63
#if defined(PPC_DEBUG_IRQ)
64
            printf("%s: set the external IRQ state to %d\n", __func__, level);
65
#endif
66
            ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
67
            break;
68
        case PPC_INPUT_SMI:
69
            /* Level sensitive - active high */
70
#if defined(PPC_DEBUG_IRQ)
71
            printf("%s: set the SMI IRQ state to %d\n", __func__, level);
72
#endif
73
            ppc_set_irq(env, PPC_INTERRUPT_SMI, level);
74
            break;
75
        case PPC_INPUT_MCP:
76
            /* Negative edge sensitive */
77
            /* XXX: TODO: actual reaction may depends on HID0 status
78
             *            603/604/740/750: check HID0[EMCP]
79
             */
80
            if (cur_level == 1 && level == 0) {
81
#if defined(PPC_DEBUG_IRQ)
82
                printf("%s: raise machine check state\n", __func__);
83
#endif
84
                ppc_set_irq(env, PPC_INTERRUPT_MCK, 1);
85
            }
86
            break;
87
        case PPC_INPUT_CKSTP_IN:
88
            /* Level sensitive - active low */
89
            /* XXX: TODO: relay the signal to CKSTP_OUT pin */
90
            if (level) {
91
#if defined(PPC_DEBUG_IRQ)
92
                printf("%s: stop the CPU\n", __func__);
93
#endif
94
                env->halted = 1;
95
            } else {
96
#if defined(PPC_DEBUG_IRQ)
97
                printf("%s: restart the CPU\n", __func__);
98
#endif
99
                env->halted = 0;
100
            }
101
            break;
102
        case PPC_INPUT_HRESET:
103
            /* Level sensitive - active low */
104
            if (level) {
105
#if 0 // XXX: TOFIX
106
#if defined(PPC_DEBUG_IRQ)
107
                printf("%s: reset the CPU\n", __func__);
108
#endif
109
                cpu_reset(env);
110
#endif
111
            }
112
            break;
113
        case PPC_INPUT_SRESET:
114
#if defined(PPC_DEBUG_IRQ)
115
            printf("%s: set the RESET IRQ state to %d\n", __func__, level);
116
#endif
117
            ppc_set_irq(env, PPC_INTERRUPT_RESET, level);
118
            break;
119
        default:
120
            /* Unknown pin - do nothing */
121
#if defined(PPC_DEBUG_IRQ)
122
            printf("%s: unknown IRQ pin %d\n", __func__, pin);
123
#endif
124
            return;
125
        }
126
        if (level)
127
            env->irq_input_state |= 1 << pin;
128
        else
129
            env->irq_input_state &= ~(1 << pin);
61 130
    }
62 131
}
63 132

  
64
/* External IRQ callback from OpenPIC IRQ controller */
65
void ppc_openpic_irq (void *opaque, int n_IRQ, int level)
133
void ppc6xx_irq_init (CPUState *env)
66 134
{
67
    switch (n_IRQ) {
68
    case OPENPIC_EVT_INT:
69
        n_IRQ = PPC_INTERRUPT_EXT;
70
        break;
71
    case OPENPIC_EVT_CINT:
72
        /* On PowerPC BookE, critical input use vector 0 */
73
        n_IRQ = PPC_INTERRUPT_RESET;
74
        break;
75
    case OPENPIC_EVT_MCK:
76
        n_IRQ = PPC_INTERRUPT_MCK;
77
        break;
78
    case OPENPIC_EVT_DEBUG:
79
        n_IRQ = PPC_INTERRUPT_DEBUG;
80
        break;
81
    case OPENPIC_EVT_RESET:
82
        qemu_system_reset_request();
83
        return;
84
    }
85
    ppc_set_irq(opaque, n_IRQ, level);
135
    env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, env, 6);
86 136
}
87 137

  
88 138
/*****************************************************************************/
89
/* PPC time base and decrementer emulation */
139
/* PowerPC time base and decrementer emulation */
90 140
//#define DEBUG_TB
91 141

  
92 142
struct ppc_tb_t {
b/hw/ppc_chrp.c
23 23
 */
24 24
#include "vl.h"
25 25

  
26
/* SMP is not enabled, for now */
27
#define MAX_CPUS 1
28

  
26 29
#define BIOS_FILENAME "ppc_rom.bin"
27 30
#define VGABIOS_FILENAME "video.x"
28 31
#define NVRAM_SIZE        0x2000
......
296 299
                           const char *cpu_model,
297 300
                           int is_heathrow)
298 301
{
299
    CPUState *env;
302
    CPUState *env, *envs[MAX_CPUS];
300 303
    char buf[1024];
301
    qemu_irq *pic;
304
    qemu_irq *pic, **openpic_irqs;
302 305
    m48t59_t *nvram;
303 306
    int unin_memory;
304 307
    int linux_boot, i;
......
329 332
    if (def == NULL) {
330 333
        cpu_abort(env, "Unable to find PowerPC CPU definition\n");
331 334
    }
332
    cpu_ppc_register(env, def);
333
    cpu_ppc_irq_init_cpu(env);
334

  
335
    /* Set time-base frequency to 100 Mhz */
336
    cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
337
    
338
    env->osi_call = vga_osi_call;
335
    for (i = 0; i < smp_cpus; i++) {
336
        cpu_ppc_register(env, def);
337
        /* Set time-base frequency to 100 Mhz */
338
        cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
339
        env->osi_call = vga_osi_call;
340
        envs[i] = env;
341
    }
339 342

  
340 343
    /* allocate RAM */
341 344
    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
......
458 461
        unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL);
459 462
        cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory);
460 463

  
461
        pic = openpic_init(NULL, &ppc_openpic_irq, &openpic_mem_index, 1, &env);
464
        openpic_irqs = qemu_mallocz(smp_cpus * sizeof(qemu_irq *));
465
        openpic_irqs[0] =
466
            qemu_mallocz(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
467
        for (i = 0; i < smp_cpus; i++) {
468
            /* Mac99 IRQ connection between OpenPIC outputs pins
469
             * and PowerPC input pins
470
             */
471
            openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
472
            openpic_irqs[i][OPENPIC_OUTPUT_INT] =
473
                ((qemu_irq *)env->irq_inputs)[PPC_INPUT_INT];
474
            openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
475
                ((qemu_irq *)env->irq_inputs)[PPC_INPUT_INT];
476
            openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
477
                ((qemu_irq *)env->irq_inputs)[PPC_INPUT_MCP];
478
            openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL; /* Not connected ? */
479
            openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
480
                ((qemu_irq *)env->irq_inputs)[PPC_INPUT_HRESET]; /* Check this */
481
        }
482
        pic = openpic_init(NULL, &openpic_mem_index, smp_cpus,
483
                           openpic_irqs, NULL);
462 484
        pci_bus = pci_pmac_init(pic);
463 485
        /* init basic PC hardware */
464 486
        pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,
b/hw/ppc_prep.c
548 548
        cpu_abort(env, "Unable to find PowerPC CPU definition\n");
549 549
    }
550 550
    cpu_ppc_register(env, def);
551
    cpu_ppc_irq_init_cpu(env);
552 551
    /* Set time-base frequency to 100 Mhz */
553 552
    cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
554 553

  
......
599 598
    }
600 599

  
601 600
    isa_mem_base = 0xc0000000;
602
    i8259 = i8259_init(first_cpu->irq[PPC_INTERRUPT_EXT]);
601
    i8259 = i8259_init(first_cpu->irq_inputs[PPC_INPUT_INT]);
603 602
    pci_bus = pci_prep_init(i8259);
604 603
    //    pci_bus = i440fx_init();
605 604
    /* Register 8 MB of ISA IO space (needed for non-contiguous map) */
b/target-ppc/cpu.h
758 758
    int error_code;
759 759
    int interrupt_request;
760 760
    uint32_t pending_interrupts;
761
    void *irq[32];
761
#if !defined(CONFIG_USER_ONLY)
762
    /* This is the IRQ controller, which is implementation dependant
763
     * and only relevant when emulating a complete machine.
764
     */
765
    uint32_t irq_input_state;
766
    void **irq_inputs;
767
#endif
762 768

  
763 769
    /* Those resources are used only during code translation */
764 770
    /* Next instruction pointer */
......
801 807
                           void *puc);
802 808

  
803 809
void do_interrupt (CPUPPCState *env);
810
void ppc_hw_interrupt (CPUPPCState *env);
804 811
void cpu_loop_exit(void);
805 812

  
806 813
void dump_stack (CPUPPCState *env);
......
1303 1310
/* Hardware interruption sources:
1304 1311
 * all those exception can be raised simulteaneously
1305 1312
 */
1313
/* Input pins definitions */
1314
enum {
1315
    /* 6xx bus input pins */
1316
    PPC_INPUT_HRESET     = 0,
1317
    PPC_INPUT_SRESET     = 1,
1318
    PPC_INPUT_CKSTP_IN   = 2,
1319
    PPC_INPUT_MCP        = 3,
1320
    PPC_INPUT_SMI        = 4,
1321
    PPC_INPUT_INT        = 5,
1322
    /* Embedded PowerPC input pins */
1323
    PPC_INPUT_CINT       = 6,
1324
    PPC_INPUT_NB,
1325
};
1326

  
1327
/* Hardware exceptions definitions */
1306 1328
enum {
1307
    PPC_INTERRUPT_RESET  = 0, /* Reset / critical input               */
1308
    PPC_INTERRUPT_MCK    = 1, /* Machine check exception              */
1309
    PPC_INTERRUPT_EXT    = 2, /* External interrupt                   */
1310
    PPC_INTERRUPT_DECR   = 3, /* Decrementer exception                */
1311
    PPC_INTERRUPT_HDECR  = 4, /* Hypervisor decrementer exception     */
1312
    PPC_INTERRUPT_PIT    = 5, /* Programmable inteval timer interrupt */
1313
    PPC_INTERRUPT_FIT    = 6, /* Fixed interval timer interrupt       */
1314
    PPC_INTERRUPT_WDT    = 7, /* Watchdog timer interrupt             */
1315
    PPC_INTERRUPT_DEBUG  = 8, /* External debug exception             */
1329
    /* External hardware exception sources */
1330
    PPC_INTERRUPT_RESET  = 0,  /* Reset exception                      */
1331
    PPC_INTERRUPT_MCK    = 1,  /* Machine check exception              */
1332
    PPC_INTERRUPT_EXT    = 2,  /* External interrupt                   */
1333
    PPC_INTERRUPT_SMI    = 3,  /* System management interrupt          */
1334
    PPC_INTERRUPT_CEXT   = 4,  /* Critical external interrupt          */
1335
    PPC_INTERRUPT_DEBUG  = 5,  /* External debug exception             */
1336
    /* Internal hardware exception sources */
1337
    PPC_INTERRUPT_DECR   = 6,  /* Decrementer exception                */
1338
    PPC_INTERRUPT_HDECR  = 7,  /* Hypervisor decrementer exception     */
1339
    PPC_INTERRUPT_PIT    = 8,  /* Programmable inteval timer interrupt */
1340
    PPC_INTERRUPT_FIT    = 9,  /* Fixed interval timer interrupt       */
1341
    PPC_INTERRUPT_WDT    = 10, /* Watchdog timer interrupt             */
1316 1342
};
1317 1343

  
1318 1344
/*****************************************************************************/
b/target-ppc/helper.c
1358 1358
    env->exception_index = -1;
1359 1359
}
1360 1360

  
1361
int ppc_hw_interrupt (CPUState *env)
1361
void ppc_hw_interrupt (CPUState *env)
1362 1362
{
1363 1363
    env->exception_index = -1;
1364

  
1365
    return 0;
1366 1364
}
1367 1365
#else /* defined (CONFIG_USER_ONLY) */
1368 1366
static void dump_syscall(CPUState *env)
......
1927 1925
    env->exception_index = EXCP_NONE;
1928 1926
}
1929 1927

  
1930
int ppc_hw_interrupt (CPUState *env)
1928
void ppc_hw_interrupt (CPUPPCState *env)
1931 1929
{
1932 1930
    int raised = 0;
1933 1931

  
......
1940 1938
    /* Raise it */
1941 1939
    if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
1942 1940
        /* External reset / critical input */
1941
        /* XXX: critical input should be handled another way.
1942
         *      This code is not correct !
1943
         */
1943 1944
        env->exception_index = EXCP_RESET;
1944 1945
        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
1945 1946
        raised = 1;
......
1984 1985
        /* External interrupt */
1985 1986
        } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
1986 1987
            env->exception_index = EXCP_EXTERNAL;
1988
            /* Taking an external interrupt does not clear the external
1989
             * interrupt status
1990
             */
1991
#if 0
1987 1992
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
1993
#endif
1988 1994
            raised = 1;
1989 1995
        }
1990 1996
#if 0 // TODO
......
1999 2005
        env->error_code = 0;
2000 2006
        do_interrupt(env);
2001 2007
    }
2002
    
2003
    return raised;
2004 2008
}
2005 2009
#endif /* !CONFIG_USER_ONLY */
b/target-ppc/translate_init.c
35 35
    uint64_t msr_mask;
36 36
};
37 37

  
38
/* For user-mode emulation, we don't emulate any IRQ controller */
39
#if defined(CONFIG_USER_ONLY)
40
#define PPC_IRQ_INIT_FN(name)                                         \
41
static inline void glue(glue(ppc, name),_irq_init) (CPUPPCState *env) \
42
{                                                                     \
43
}
44
#else
45
#define PPC_IRQ_INIT_FN(name)                                         \
46
void glue(glue(ppc, name),_irq_init) (CPUPPCState *env);
47
#endif
48
PPC_IRQ_INIT_FN(6xx);
49

  
38 50
/* Generic callbacks:
39 51
 * do nothing but store/retrieve spr value
40 52
 */
......
1865 1877
        env->nb_tlb = 64;
1866 1878
        env->nb_ways = 1;
1867 1879
        env->id_tlbs = 0;
1880
        /* XXX: TODO: allocate internal IRQ controller */
1868 1881
        break;
1869 1882

  
1870 1883
    case CPU_PPC_403GA:   /* 403 GA family                 */
......
1879 1892
        env->nb_tlb = 64;
1880 1893
        env->nb_ways = 1;
1881 1894
        env->id_tlbs = 0;
1895
        /* XXX: TODO: allocate internal IRQ controller */
1882 1896
        break;
1883 1897

  
1884 1898
    case CPU_PPC_405CR:   /* 405 GP/CR family              */
......
1895 1909
        env->nb_tlb = 64;
1896 1910
        env->nb_ways = 1;
1897 1911
        env->id_tlbs = 0;
1912
        /* XXX: TODO: allocate internal IRQ controller */
1898 1913
        break;
1899 1914

  
1900 1915
    case CPU_PPC_NPE405H: /* NPe405 H family               */
......
1909 1924
        env->nb_tlb = 64;
1910 1925
        env->nb_ways = 1;
1911 1926
        env->id_tlbs = 0;
1927
        /* XXX: TODO: allocate internal IRQ controller */
1912 1928
        break;
1913 1929

  
1914 1930
#if defined (TODO)
......
1940 1956
        env->nb_tlb = 64;
1941 1957
        env->nb_ways = 1;
1942 1958
        env->id_tlbs = 0;
1959
        /* XXX: TODO: allocate internal IRQ controller */
1943 1960
        break;
1944 1961

  
1945 1962
    case CPU_PPC_440EP:   /* 440 EP family                 */
......
1959 1976
        env->nb_tlb = 64;
1960 1977
        env->nb_ways = 1;
1961 1978
        env->id_tlbs = 0;
1979
        /* XXX: TODO: allocate internal IRQ controller */
1962 1980
        break;
1963 1981

  
1964 1982
    /* Embedded PowerPC from Freescale                     */
......
1994 2012
        env->nb_tlb = 64;
1995 2013
        env->nb_ways = 1;
1996 2014
        env->id_tlbs = 0;
2015
        /* XXX: TODO: allocate internal IRQ controller */
1997 2016
        break;
1998 2017

  
1999 2018
#if defined (TODO)
......
2038 2057
        env->nb_ways = 2;
2039 2058
        env->id_tlbs = 0;
2040 2059
        env->id_tlbs = 0;
2060
        /* XXX: TODO: allocate internal IRQ controller */
2041 2061
        break;
2042 2062

  
2043 2063
    case CPU_PPC_602:     /* PowerPC 602                   */
......
2060 2080
                     SPR_NOACCESS, SPR_NOACCESS,
2061 2081
                     &spr_read_generic, &spr_write_generic,
2062 2082
                     0x00000000);
2083
        /* Allocate hardware IRQ controller */
2084
        ppc6xx_irq_init(env);
2063 2085
        break;
2064 2086

  
2065 2087
    case CPU_PPC_603:     /* PowerPC 603                   */
......
2087 2109
                     SPR_NOACCESS, SPR_NOACCESS,
2088 2110
                     &spr_read_generic, &spr_write_generic,
2089 2111
                     0x00000000);
2112
        /* Allocate hardware IRQ controller */
2113
        ppc6xx_irq_init(env);
2090 2114
        break;
2091 2115
        
2092 2116
    case CPU_PPC_G2:      /* PowerPC G2 family             */
......
2123 2147
                     SPR_NOACCESS, SPR_NOACCESS,
2124 2148
                     &spr_read_generic, &spr_write_generic,
2125 2149
                     0x00000000);
2150
        /* Allocate hardware IRQ controller */
2151
        ppc6xx_irq_init(env);
2126 2152
        break;
2127 2153

  
2128 2154
    case CPU_PPC_604:     /* PowerPC 604                   */
......
2146 2172
                     SPR_NOACCESS, SPR_NOACCESS,
2147 2173
                     &spr_read_generic, &spr_write_generic,
2148 2174
                     0x00000000);
2175
        /* Allocate hardware IRQ controller */
2176
        ppc6xx_irq_init(env);
2149 2177
        break;
2150 2178

  
2151 2179
    case CPU_PPC_74x:     /* PowerPC 740 / 750             */
......
2178 2206
                     SPR_NOACCESS, SPR_NOACCESS,
2179 2207
                     &spr_read_generic, &spr_write_generic,
2180 2208
                     0x00000000);
2209
        /* Allocate hardware IRQ controller */
2210
        ppc6xx_irq_init(env);
2181 2211
        break;
2182 2212

  
2183 2213
    case CPU_PPC_750FX10: /* IBM PowerPC 750 FX            */
......
2213 2243
                     SPR_NOACCESS, SPR_NOACCESS,
2214 2244
                     &spr_read_generic, &spr_write_generic,
2215 2245
                     0x00000000);
2246
        /* Allocate hardware IRQ controller */
2247
        ppc6xx_irq_init(env);
2216 2248
        break;
2217 2249

  
2218 2250
    case CPU_PPC_755_10:  /* PowerPC 755                   */
......
2257 2289
                     SPR_NOACCESS, SPR_NOACCESS,
2258 2290
                     &spr_read_generic, &spr_write_generic,
2259 2291
                     0x00000000);
2292
        /* Allocate hardware IRQ controller */
2293
        ppc6xx_irq_init(env);
2260 2294
        break;
2261 2295

  
2262 2296
#if defined (TODO)
......
2326 2360

  
2327 2361
    default:
2328 2362
        gen_spr_generic(env);
2363
        /* XXX: TODO: allocate internal IRQ controller */
2329 2364
        break;
2330 2365
    }
2331 2366
    if (env->nb_BATs == -1)
b/vl.h
854 854
int piix4_init(PCIBus *bus, int devfn);
855 855

  
856 856
/* openpic.c */
857
/* OpenPIC have 5 outputs per CPU connected and one IRQ out single output */
857 858
enum {
858
    OPENPIC_EVT_INT = 0, /* IRQ                       */
859
    OPENPIC_EVT_CINT,    /* critical IRQ              */
860
    OPENPIC_EVT_MCK,     /* Machine check event       */
861
    OPENPIC_EVT_DEBUG,   /* Inconditional debug event */
862
    OPENPIC_EVT_RESET,   /* Core reset event          */
859
    OPENPIC_OUTPUT_INT = 0, /* IRQ                       */
860
    OPENPIC_OUTPUT_CINT,    /* critical IRQ              */
861
    OPENPIC_OUTPUT_MCK,     /* Machine check event       */
862
    OPENPIC_OUTPUT_DEBUG,   /* Inconditional debug event */
863
    OPENPIC_OUTPUT_RESET,   /* Core reset event          */
864
    OPENPIC_OUTPUT_NB,
863 865
};
864
qemu_irq *openpic_init (PCIBus *bus, SetIRQFunc *set_irq,
865
                        int *pmem_index, int nb_cpus,
866
                        struct CPUState **envp);
866
qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
867
                        qemu_irq **irqs, qemu_irq irq_out);
867 868

  
868 869
/* heathrow_pic.c */
869 870
qemu_irq *heathrow_pic_init(int *pmem_index);
......
1145 1146

  
1146 1147
#ifdef TARGET_PPC
1147 1148
/* PowerPC hardware exceptions management helpers */
1148
void cpu_ppc_irq_init_cpu(CPUState *env);
1149
void ppc_openpic_irq (void *opaque, int n_IRQ, int level);
1150
int ppc_hw_interrupt (CPUState *env);
1151 1149
ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq);
1152 1150
#endif
1153 1151
void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val);

Also available in: Unified diff