Commit e9df014c0b433ecd9785db4a423e472bc3db386a

Authored by j_mayer
1 parent 682c4f15

Implement embedded IRQ controller for PowerPC 6xx/740 & 750.

Fix PowerPC external interrupt input handling and lowering.
Fix OpenPIC output pins management.
Fix multiples bugs in OpenPIC IRQ management.
Fix OpenPIC CPU(s) reset function.
Fix Mac99 machine to properly route OpenPIC outputs to the PowerPC input pins.
Fix PREP machine to properly route i8259 output to the PowerPC external
  interrupt pin.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2647 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-exec.c
@@ -467,16 +467,14 @@ int cpu_exec(CPUState *env1) @@ -467,16 +467,14 @@ int cpu_exec(CPUState *env1)
467 } 467 }
468 #endif 468 #endif
469 if (interrupt_request & CPU_INTERRUPT_HARD) { 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 #if defined(__sparc__) && !defined(HOST_SOLARIS) 473 #if defined(__sparc__) && !defined(HOST_SOLARIS)
475 - tmp_T0 = 0; 474 + tmp_T0 = 0;
476 #else 475 #else
477 - T0 = 0; 476 + T0 = 0;
478 #endif 477 #endif
479 - }  
480 } 478 }
481 #elif defined(TARGET_MIPS) 479 #elif defined(TARGET_MIPS)
482 if ((interrupt_request & CPU_INTERRUPT_HARD) && 480 if ((interrupt_request & CPU_INTERRUPT_HARD) &&
hw/openpic.c
@@ -159,18 +159,18 @@ typedef struct IRQ_dst_t { @@ -159,18 +159,18 @@ typedef struct IRQ_dst_t {
159 uint32_t pcsr; /* CPU sensitivity register */ 159 uint32_t pcsr; /* CPU sensitivity register */
160 IRQ_queue_t raised; 160 IRQ_queue_t raised;
161 IRQ_queue_t servicing; 161 IRQ_queue_t servicing;
162 - CPUState *env; 162 + qemu_irq *irqs;
163 } IRQ_dst_t; 163 } IRQ_dst_t;
164 164
165 typedef struct openpic_t { 165 typedef struct openpic_t {
166 PCIDevice pci_dev; 166 PCIDevice pci_dev;
167 - SetIRQFunc *set_irq;  
168 int mem_index; 167 int mem_index;
169 /* Global registers */ 168 /* Global registers */
170 uint32_t frep; /* Feature reporting register */ 169 uint32_t frep; /* Feature reporting register */
171 uint32_t glbc; /* Global configuration register */ 170 uint32_t glbc; /* Global configuration register */
172 uint32_t micr; /* MPIC interrupt configuration register */ 171 uint32_t micr; /* MPIC interrupt configuration register */
173 uint32_t veni; /* Vendor identification register */ 172 uint32_t veni; /* Vendor identification register */
  173 + uint32_t pint; /* Processor initialization register */
174 uint32_t spve; /* Spurious vector register */ 174 uint32_t spve; /* Spurious vector register */
175 uint32_t tifr; /* Timer frequency reporting register */ 175 uint32_t tifr; /* Timer frequency reporting register */
176 /* Source registers */ 176 /* Source registers */
@@ -196,6 +196,8 @@ typedef struct openpic_t { @@ -196,6 +196,8 @@ typedef struct openpic_t {
196 uint32_t mbr; /* Mailbox register */ 196 uint32_t mbr; /* Mailbox register */
197 } mailboxes[MAX_MAILBOXES]; 197 } mailboxes[MAX_MAILBOXES];
198 #endif 198 #endif
  199 + /* IRQ out is used when in bypass mode (not implemented) */
  200 + qemu_irq irq_out;
199 } openpic_t; 201 } openpic_t;
200 202
201 static inline void IRQ_setbit (IRQ_queue_t *q, int n_IRQ) 203 static inline void IRQ_setbit (IRQ_queue_t *q, int n_IRQ)
@@ -255,19 +257,34 @@ static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ) @@ -255,19 +257,34 @@ static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ)
255 priority = IPVP_PRIORITY(src->ipvp); 257 priority = IPVP_PRIORITY(src->ipvp);
256 if (priority <= dst->pctp) { 258 if (priority <= dst->pctp) {
257 /* Too low priority */ 259 /* Too low priority */
  260 + DPRINTF("%s: IRQ %d has too low priority on CPU %d\n",
  261 + __func__, n_IRQ, n_CPU);
258 return; 262 return;
259 } 263 }
260 if (IRQ_testbit(&dst->raised, n_IRQ)) { 264 if (IRQ_testbit(&dst->raised, n_IRQ)) {
261 /* Interrupt miss */ 265 /* Interrupt miss */
  266 + DPRINTF("%s: IRQ %d was missed on CPU %d\n",
  267 + __func__, n_IRQ, n_CPU);
262 return; 268 return;
263 } 269 }
264 set_bit(&src->ipvp, IPVP_ACTIVITY); 270 set_bit(&src->ipvp, IPVP_ACTIVITY);
265 IRQ_setbit(&dst->raised, n_IRQ); 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 /* update pic state because registers for n_IRQ have changed value */ 290 /* update pic state because registers for n_IRQ have changed value */
@@ -280,27 +297,34 @@ static void openpic_update_irq(openpic_t *opp, int n_IRQ) @@ -280,27 +297,34 @@ static void openpic_update_irq(openpic_t *opp, int n_IRQ)
280 297
281 if (!src->pending) { 298 if (!src->pending) {
282 /* no irq pending */ 299 /* no irq pending */
  300 + DPRINTF("%s: IRQ %d is not pending\n", __func__, n_IRQ);
283 return; 301 return;
284 } 302 }
285 if (test_bit(&src->ipvp, IPVP_MASK)) { 303 if (test_bit(&src->ipvp, IPVP_MASK)) {
286 /* Interrupt source is disabled */ 304 /* Interrupt source is disabled */
  305 + DPRINTF("%s: IRQ %d is disabled\n", __func__, n_IRQ);
287 return; 306 return;
288 } 307 }
289 if (IPVP_PRIORITY(src->ipvp) == 0) { 308 if (IPVP_PRIORITY(src->ipvp) == 0) {
290 /* Priority set to zero */ 309 /* Priority set to zero */
  310 + DPRINTF("%s: IRQ %d has 0 priority\n", __func__, n_IRQ);
291 return; 311 return;
292 } 312 }
293 if (test_bit(&src->ipvp, IPVP_ACTIVITY)) { 313 if (test_bit(&src->ipvp, IPVP_ACTIVITY)) {
294 /* IRQ already active */ 314 /* IRQ already active */
  315 + DPRINTF("%s: IRQ %d is already active\n", __func__, n_IRQ);
295 return; 316 return;
296 } 317 }
297 if (src->ide == 0x00000000) { 318 if (src->ide == 0x00000000) {
298 /* No target */ 319 /* No target */
  320 + DPRINTF("%s: IRQ %d has no target\n", __func__, n_IRQ);
299 return; 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 /* Directed delivery mode */ 328 /* Directed delivery mode */
305 for (i = 0; i < opp->nb_cpus; i++) { 329 for (i = 0; i < opp->nb_cpus; i++) {
306 if (test_bit(&src->ide, i)) 330 if (test_bit(&src->ide, i))
@@ -308,9 +332,8 @@ static void openpic_update_irq(openpic_t *opp, int n_IRQ) @@ -308,9 +332,8 @@ static void openpic_update_irq(openpic_t *opp, int n_IRQ)
308 } 332 }
309 } else { 333 } else {
310 /* Distributed delivery mode */ 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 i = 0; 337 i = 0;
315 if (test_bit(&src->ide, i)) { 338 if (test_bit(&src->ide, i)) {
316 IRQ_local_pipe(opp, i, n_IRQ); 339 IRQ_local_pipe(opp, i, n_IRQ);
@@ -350,6 +373,7 @@ static void openpic_reset (openpic_t *opp) @@ -350,6 +373,7 @@ static void openpic_reset (openpic_t *opp)
350 /* Initialise controller registers */ 373 /* Initialise controller registers */
351 opp->frep = ((EXT_IRQ - 1) << 16) | ((MAX_CPU - 1) << 8) | VID; 374 opp->frep = ((EXT_IRQ - 1) << 16) | ((MAX_CPU - 1) << 8) | VID;
352 opp->veni = VENI; 375 opp->veni = VENI;
  376 + opp->pint = 0x00000000;
353 opp->spve = 0x000000FF; 377 opp->spve = 0x000000FF;
354 opp->tifr = 0x003F7A00; 378 opp->tifr = 0x003F7A00;
355 /* ? */ 379 /* ? */
@@ -360,7 +384,7 @@ static void openpic_reset (openpic_t *opp) @@ -360,7 +384,7 @@ static void openpic_reset (openpic_t *opp)
360 opp->src[i].ide = 0x00000000; 384 opp->src[i].ide = 0x00000000;
361 } 385 }
362 /* Initialise IRQ destinations */ 386 /* Initialise IRQ destinations */
363 - for (i = 0; i < opp->nb_cpus; i++) { 387 + for (i = 0; i < MAX_CPU; i++) {
364 opp->dst[i].pctp = 0x0000000F; 388 opp->dst[i].pctp = 0x0000000F;
365 opp->dst[i].pcsr = 0x00000000; 389 opp->dst[i].pcsr = 0x00000000;
366 memset(&opp->dst[i].raised, 0, sizeof(IRQ_queue_t)); 390 memset(&opp->dst[i].raised, 0, sizeof(IRQ_queue_t));
@@ -511,6 +535,8 @@ static void write_mailbox_register (openpic_t *opp, int n_mbx, @@ -511,6 +535,8 @@ static void write_mailbox_register (openpic_t *opp, int n_mbx,
511 static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val) 535 static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
512 { 536 {
513 openpic_t *opp = opaque; 537 openpic_t *opp = opaque;
  538 + IRQ_dst_t *dst;
  539 + int idx;
514 540
515 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val); 541 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
516 if (addr & 0xF) 542 if (addr & 0xF)
@@ -530,11 +556,18 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val) @@ -530,11 +556,18 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
530 case 0x80: /* VENI */ 556 case 0x80: /* VENI */
531 break; 557 break;
532 case 0x90: /* PINT */ 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 break; 571 break;
539 #if MAX_IPI > 0 572 #if MAX_IPI > 0
540 case 0xA0: /* IPI_IPVP */ 573 case 0xA0: /* IPI_IPVP */
@@ -735,7 +768,7 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val) @@ -735,7 +768,7 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
735 openpic_t *opp = opaque; 768 openpic_t *opp = opaque;
736 IRQ_src_t *src; 769 IRQ_src_t *src;
737 IRQ_dst_t *dst; 770 IRQ_dst_t *dst;
738 - int idx, n_IRQ; 771 + int idx, s_IRQ, n_IRQ;
739 772
740 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val); 773 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
741 if (addr & 0xF) 774 if (addr & 0xF)
@@ -770,21 +803,21 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val) @@ -770,21 +803,21 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
770 break; 803 break;
771 case 0xB0: /* PEOI */ 804 case 0xB0: /* PEOI */
772 DPRINTF("PEOI\n"); 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 dst->servicing.next = -1; 808 dst->servicing.next = -1;
776 - src = &opp->src[n_IRQ];  
777 /* Set up next servicing IRQ */ 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 break; 821 break;
789 default: 822 default:
790 break; 823 break;
@@ -815,11 +848,13 @@ static uint32_t openpic_cpu_read (void *opaque, uint32_t addr) @@ -815,11 +848,13 @@ static uint32_t openpic_cpu_read (void *opaque, uint32_t addr)
815 retval = idx; 848 retval = idx;
816 break; 849 break;
817 case 0xA0: /* PIAC */ 850 case 0xA0: /* PIAC */
  851 + DPRINTF("Lower OpenPIC INT output\n");
  852 + qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);
818 n_IRQ = IRQ_get_next(opp, &dst->raised); 853 n_IRQ = IRQ_get_next(opp, &dst->raised);
819 DPRINTF("PIAC: irq=%d\n", n_IRQ); 854 DPRINTF("PIAC: irq=%d\n", n_IRQ);
820 if (n_IRQ == -1) { 855 if (n_IRQ == -1) {
821 /* No more interrupt pending */ 856 /* No more interrupt pending */
822 - retval = opp->spve; 857 + retval = IPVP_VECTOR(opp->spve);
823 } else { 858 } else {
824 src = &opp->src[n_IRQ]; 859 src = &opp->src[n_IRQ];
825 if (!test_bit(&src->ipvp, IPVP_ACTIVITY) || 860 if (!test_bit(&src->ipvp, IPVP_ACTIVITY) ||
@@ -964,8 +999,8 @@ static void openpic_map(PCIDevice *pci_dev, int region_num, @@ -964,8 +999,8 @@ static void openpic_map(PCIDevice *pci_dev, int region_num,
964 #endif 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 openpic_t *opp; 1005 openpic_t *opp;
971 uint8_t *pci_conf; 1006 uint8_t *pci_conf;
@@ -995,7 +1030,6 @@ qemu_irq *openpic_init (PCIBus *bus, SetIRQFunc *set_irq, @@ -995,7 +1030,6 @@ qemu_irq *openpic_init (PCIBus *bus, SetIRQFunc *set_irq,
995 } else { 1030 } else {
996 opp = qemu_mallocz(sizeof(openpic_t)); 1031 opp = qemu_mallocz(sizeof(openpic_t));
997 } 1032 }
998 - opp->set_irq = set_irq;  
999 opp->mem_index = cpu_register_io_memory(0, openpic_read, 1033 opp->mem_index = cpu_register_io_memory(0, openpic_read,
1000 openpic_write, opp); 1034 openpic_write, opp);
1001 1035
@@ -1020,9 +1054,11 @@ qemu_irq *openpic_init (PCIBus *bus, SetIRQFunc *set_irq, @@ -1020,9 +1054,11 @@ qemu_irq *openpic_init (PCIBus *bus, SetIRQFunc *set_irq,
1020 opp->src[i].type = IRQ_INTERNAL; 1054 opp->src[i].type = IRQ_INTERNAL;
1021 } 1055 }
1022 for (i = 0; i < nb_cpus; i++) 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 openpic_reset(opp); 1059 openpic_reset(opp);
1025 if (pmem_index) 1060 if (pmem_index)
1026 *pmem_index = opp->mem_index; 1061 *pmem_index = opp->mem_index;
  1062 +
1027 return qemu_allocate_irqs(openpic_set_irq, opp, MAX_IRQ); 1063 return qemu_allocate_irqs(openpic_set_irq, opp, MAX_IRQ);
1028 } 1064 }
hw/ppc.c
1 /* 1 /*
2 - * QEMU generic PPC hardware System Emulator 2 + * QEMU generic PowerPC hardware System Emulator
3 * 3 *
4 * Copyright (c) 2003-2007 Jocelyn Mayer 4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 * 5 *
@@ -24,18 +24,13 @@ @@ -24,18 +24,13 @@
24 #include "vl.h" 24 #include "vl.h"
25 #include "m48t59.h" 25 #include "m48t59.h"
26 26
  27 +//#define PPC_DEBUG_IRQ
  28 +
27 extern FILE *logfile; 29 extern FILE *logfile;
28 extern int loglevel; 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 if (level) { 34 if (level) {
40 env->pending_interrupts |= 1 << n_IRQ; 35 env->pending_interrupts |= 1 << n_IRQ;
41 cpu_interrupt(env, CPU_INTERRUPT_HARD); 36 cpu_interrupt(env, CPU_INTERRUPT_HARD);
@@ -44,49 +39,104 @@ static void ppc_set_irq (void *opaque, int n_IRQ, int level) @@ -44,49 +39,104 @@ static void ppc_set_irq (void *opaque, int n_IRQ, int level)
44 if (env->pending_interrupts == 0) 39 if (env->pending_interrupts == 0)
45 cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); 40 cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
46 } 41 }
47 -#if 0 42 +#if defined(PPC_DEBUG_IRQ)
48 printf("%s: %p n_IRQ %d level %d => pending %08x req %08x\n", __func__, 43 printf("%s: %p n_IRQ %d level %d => pending %08x req %08x\n", __func__,
49 env, n_IRQ, level, env->pending_interrupts, env->interrupt_request); 44 env, n_IRQ, level, env->pending_interrupts, env->interrupt_request);
50 #endif 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 //#define DEBUG_TB 140 //#define DEBUG_TB
91 141
92 struct ppc_tb_t { 142 struct ppc_tb_t {
hw/ppc_chrp.c
@@ -23,6 +23,9 @@ @@ -23,6 +23,9 @@
23 */ 23 */
24 #include "vl.h" 24 #include "vl.h"
25 25
  26 +/* SMP is not enabled, for now */
  27 +#define MAX_CPUS 1
  28 +
26 #define BIOS_FILENAME "ppc_rom.bin" 29 #define BIOS_FILENAME "ppc_rom.bin"
27 #define VGABIOS_FILENAME "video.x" 30 #define VGABIOS_FILENAME "video.x"
28 #define NVRAM_SIZE 0x2000 31 #define NVRAM_SIZE 0x2000
@@ -296,9 +299,9 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, @@ -296,9 +299,9 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
296 const char *cpu_model, 299 const char *cpu_model,
297 int is_heathrow) 300 int is_heathrow)
298 { 301 {
299 - CPUState *env; 302 + CPUState *env, *envs[MAX_CPUS];
300 char buf[1024]; 303 char buf[1024];
301 - qemu_irq *pic; 304 + qemu_irq *pic, **openpic_irqs;
302 m48t59_t *nvram; 305 m48t59_t *nvram;
303 int unin_memory; 306 int unin_memory;
304 int linux_boot, i; 307 int linux_boot, i;
@@ -329,13 +332,13 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, @@ -329,13 +332,13 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
329 if (def == NULL) { 332 if (def == NULL) {
330 cpu_abort(env, "Unable to find PowerPC CPU definition\n"); 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 /* allocate RAM */ 343 /* allocate RAM */
341 cpu_register_physical_memory(0, ram_size, IO_MEM_RAM); 344 cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
@@ -458,7 +461,26 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, @@ -458,7 +461,26 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
458 unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL); 461 unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL);
459 cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory); 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 pci_bus = pci_pmac_init(pic); 484 pci_bus = pci_pmac_init(pic);
463 /* init basic PC hardware */ 485 /* init basic PC hardware */
464 pci_vga_init(pci_bus, ds, phys_ram_base + ram_size, 486 pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,
hw/ppc_prep.c
@@ -548,7 +548,6 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device, @@ -548,7 +548,6 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
548 cpu_abort(env, "Unable to find PowerPC CPU definition\n"); 548 cpu_abort(env, "Unable to find PowerPC CPU definition\n");
549 } 549 }
550 cpu_ppc_register(env, def); 550 cpu_ppc_register(env, def);
551 - cpu_ppc_irq_init_cpu(env);  
552 /* Set time-base frequency to 100 Mhz */ 551 /* Set time-base frequency to 100 Mhz */
553 cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL); 552 cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
554 553
@@ -599,7 +598,7 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device, @@ -599,7 +598,7 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
599 } 598 }
600 599
601 isa_mem_base = 0xc0000000; 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 pci_bus = pci_prep_init(i8259); 602 pci_bus = pci_prep_init(i8259);
604 // pci_bus = i440fx_init(); 603 // pci_bus = i440fx_init();
605 /* Register 8 MB of ISA IO space (needed for non-contiguous map) */ 604 /* Register 8 MB of ISA IO space (needed for non-contiguous map) */
target-ppc/cpu.h
@@ -758,7 +758,13 @@ struct CPUPPCState { @@ -758,7 +758,13 @@ struct CPUPPCState {
758 int error_code; 758 int error_code;
759 int interrupt_request; 759 int interrupt_request;
760 uint32_t pending_interrupts; 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 /* Those resources are used only during code translation */ 769 /* Those resources are used only during code translation */
764 /* Next instruction pointer */ 770 /* Next instruction pointer */
@@ -801,6 +807,7 @@ int cpu_ppc_signal_handler(int host_signum, void *pinfo, @@ -801,6 +807,7 @@ int cpu_ppc_signal_handler(int host_signum, void *pinfo,
801 void *puc); 807 void *puc);
802 808
803 void do_interrupt (CPUPPCState *env); 809 void do_interrupt (CPUPPCState *env);
  810 +void ppc_hw_interrupt (CPUPPCState *env);
804 void cpu_loop_exit(void); 811 void cpu_loop_exit(void);
805 812
806 void dump_stack (CPUPPCState *env); 813 void dump_stack (CPUPPCState *env);
@@ -1303,16 +1310,35 @@ enum { @@ -1303,16 +1310,35 @@ enum {
1303 /* Hardware interruption sources: 1310 /* Hardware interruption sources:
1304 * all those exception can be raised simulteaneously 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 enum { 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 /*****************************************************************************/
target-ppc/helper.c
@@ -1358,11 +1358,9 @@ void do_interrupt (CPUState *env) @@ -1358,11 +1358,9 @@ void do_interrupt (CPUState *env)
1358 env->exception_index = -1; 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 env->exception_index = -1; 1363 env->exception_index = -1;
1364 -  
1365 - return 0;  
1366 } 1364 }
1367 #else /* defined (CONFIG_USER_ONLY) */ 1365 #else /* defined (CONFIG_USER_ONLY) */
1368 static void dump_syscall(CPUState *env) 1366 static void dump_syscall(CPUState *env)
@@ -1927,7 +1925,7 @@ void do_interrupt (CPUState *env) @@ -1927,7 +1925,7 @@ void do_interrupt (CPUState *env)
1927 env->exception_index = EXCP_NONE; 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 int raised = 0; 1930 int raised = 0;
1933 1931
@@ -1940,6 +1938,9 @@ int ppc_hw_interrupt (CPUState *env) @@ -1940,6 +1938,9 @@ int ppc_hw_interrupt (CPUState *env)
1940 /* Raise it */ 1938 /* Raise it */
1941 if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) { 1939 if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
1942 /* External reset / critical input */ 1940 /* External reset / critical input */
  1941 + /* XXX: critical input should be handled another way.
  1942 + * This code is not correct !
  1943 + */
1943 env->exception_index = EXCP_RESET; 1944 env->exception_index = EXCP_RESET;
1944 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET); 1945 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
1945 raised = 1; 1946 raised = 1;
@@ -1984,7 +1985,12 @@ int ppc_hw_interrupt (CPUState *env) @@ -1984,7 +1985,12 @@ int ppc_hw_interrupt (CPUState *env)
1984 /* External interrupt */ 1985 /* External interrupt */
1985 } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) { 1986 } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
1986 env->exception_index = EXCP_EXTERNAL; 1987 env->exception_index = EXCP_EXTERNAL;
  1988 + /* Taking an external interrupt does not clear the external
  1989 + * interrupt status
  1990 + */
  1991 +#if 0
1987 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT); 1992 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
  1993 +#endif
1988 raised = 1; 1994 raised = 1;
1989 } 1995 }
1990 #if 0 // TODO 1996 #if 0 // TODO
@@ -1999,7 +2005,5 @@ int ppc_hw_interrupt (CPUState *env) @@ -1999,7 +2005,5 @@ int ppc_hw_interrupt (CPUState *env)
1999 env->error_code = 0; 2005 env->error_code = 0;
2000 do_interrupt(env); 2006 do_interrupt(env);
2001 } 2007 }
2002 -  
2003 - return raised;  
2004 } 2008 }
2005 #endif /* !CONFIG_USER_ONLY */ 2009 #endif /* !CONFIG_USER_ONLY */
target-ppc/translate_init.c
@@ -35,6 +35,18 @@ struct ppc_def_t { @@ -35,6 +35,18 @@ struct ppc_def_t {
35 uint64_t msr_mask; 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 /* Generic callbacks: 50 /* Generic callbacks:
39 * do nothing but store/retrieve spr value 51 * do nothing but store/retrieve spr value
40 */ 52 */
@@ -1865,6 +1877,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -1865,6 +1877,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
1865 env->nb_tlb = 64; 1877 env->nb_tlb = 64;
1866 env->nb_ways = 1; 1878 env->nb_ways = 1;
1867 env->id_tlbs = 0; 1879 env->id_tlbs = 0;
  1880 + /* XXX: TODO: allocate internal IRQ controller */
1868 break; 1881 break;
1869 1882
1870 case CPU_PPC_403GA: /* 403 GA family */ 1883 case CPU_PPC_403GA: /* 403 GA family */
@@ -1879,6 +1892,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -1879,6 +1892,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
1879 env->nb_tlb = 64; 1892 env->nb_tlb = 64;
1880 env->nb_ways = 1; 1893 env->nb_ways = 1;
1881 env->id_tlbs = 0; 1894 env->id_tlbs = 0;
  1895 + /* XXX: TODO: allocate internal IRQ controller */
1882 break; 1896 break;
1883 1897
1884 case CPU_PPC_405CR: /* 405 GP/CR family */ 1898 case CPU_PPC_405CR: /* 405 GP/CR family */
@@ -1895,6 +1909,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -1895,6 +1909,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
1895 env->nb_tlb = 64; 1909 env->nb_tlb = 64;
1896 env->nb_ways = 1; 1910 env->nb_ways = 1;
1897 env->id_tlbs = 0; 1911 env->id_tlbs = 0;
  1912 + /* XXX: TODO: allocate internal IRQ controller */
1898 break; 1913 break;
1899 1914
1900 case CPU_PPC_NPE405H: /* NPe405 H family */ 1915 case CPU_PPC_NPE405H: /* NPe405 H family */
@@ -1909,6 +1924,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -1909,6 +1924,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
1909 env->nb_tlb = 64; 1924 env->nb_tlb = 64;
1910 env->nb_ways = 1; 1925 env->nb_ways = 1;
1911 env->id_tlbs = 0; 1926 env->id_tlbs = 0;
  1927 + /* XXX: TODO: allocate internal IRQ controller */
1912 break; 1928 break;
1913 1929
1914 #if defined (TODO) 1930 #if defined (TODO)
@@ -1940,6 +1956,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -1940,6 +1956,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
1940 env->nb_tlb = 64; 1956 env->nb_tlb = 64;
1941 env->nb_ways = 1; 1957 env->nb_ways = 1;
1942 env->id_tlbs = 0; 1958 env->id_tlbs = 0;
  1959 + /* XXX: TODO: allocate internal IRQ controller */
1943 break; 1960 break;
1944 1961
1945 case CPU_PPC_440EP: /* 440 EP family */ 1962 case CPU_PPC_440EP: /* 440 EP family */
@@ -1959,6 +1976,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -1959,6 +1976,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
1959 env->nb_tlb = 64; 1976 env->nb_tlb = 64;
1960 env->nb_ways = 1; 1977 env->nb_ways = 1;
1961 env->id_tlbs = 0; 1978 env->id_tlbs = 0;
  1979 + /* XXX: TODO: allocate internal IRQ controller */
1962 break; 1980 break;
1963 1981
1964 /* Embedded PowerPC from Freescale */ 1982 /* Embedded PowerPC from Freescale */
@@ -1994,6 +2012,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -1994,6 +2012,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
1994 env->nb_tlb = 64; 2012 env->nb_tlb = 64;
1995 env->nb_ways = 1; 2013 env->nb_ways = 1;
1996 env->id_tlbs = 0; 2014 env->id_tlbs = 0;
  2015 + /* XXX: TODO: allocate internal IRQ controller */
1997 break; 2016 break;
1998 2017
1999 #if defined (TODO) 2018 #if defined (TODO)
@@ -2038,6 +2057,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -2038,6 +2057,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
2038 env->nb_ways = 2; 2057 env->nb_ways = 2;
2039 env->id_tlbs = 0; 2058 env->id_tlbs = 0;
2040 env->id_tlbs = 0; 2059 env->id_tlbs = 0;
  2060 + /* XXX: TODO: allocate internal IRQ controller */
2041 break; 2061 break;
2042 2062
2043 case CPU_PPC_602: /* PowerPC 602 */ 2063 case CPU_PPC_602: /* PowerPC 602 */
@@ -2060,6 +2080,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -2060,6 +2080,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
2060 SPR_NOACCESS, SPR_NOACCESS, 2080 SPR_NOACCESS, SPR_NOACCESS,
2061 &spr_read_generic, &spr_write_generic, 2081 &spr_read_generic, &spr_write_generic,
2062 0x00000000); 2082 0x00000000);
  2083 + /* Allocate hardware IRQ controller */
  2084 + ppc6xx_irq_init(env);
2063 break; 2085 break;
2064 2086
2065 case CPU_PPC_603: /* PowerPC 603 */ 2087 case CPU_PPC_603: /* PowerPC 603 */
@@ -2087,6 +2109,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -2087,6 +2109,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
2087 SPR_NOACCESS, SPR_NOACCESS, 2109 SPR_NOACCESS, SPR_NOACCESS,
2088 &spr_read_generic, &spr_write_generic, 2110 &spr_read_generic, &spr_write_generic,
2089 0x00000000); 2111 0x00000000);
  2112 + /* Allocate hardware IRQ controller */
  2113 + ppc6xx_irq_init(env);
2090 break; 2114 break;
2091 2115
2092 case CPU_PPC_G2: /* PowerPC G2 family */ 2116 case CPU_PPC_G2: /* PowerPC G2 family */
@@ -2123,6 +2147,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -2123,6 +2147,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
2123 SPR_NOACCESS, SPR_NOACCESS, 2147 SPR_NOACCESS, SPR_NOACCESS,
2124 &spr_read_generic, &spr_write_generic, 2148 &spr_read_generic, &spr_write_generic,
2125 0x00000000); 2149 0x00000000);
  2150 + /* Allocate hardware IRQ controller */
  2151 + ppc6xx_irq_init(env);
2126 break; 2152 break;
2127 2153
2128 case CPU_PPC_604: /* PowerPC 604 */ 2154 case CPU_PPC_604: /* PowerPC 604 */
@@ -2146,6 +2172,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -2146,6 +2172,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
2146 SPR_NOACCESS, SPR_NOACCESS, 2172 SPR_NOACCESS, SPR_NOACCESS,
2147 &spr_read_generic, &spr_write_generic, 2173 &spr_read_generic, &spr_write_generic,
2148 0x00000000); 2174 0x00000000);
  2175 + /* Allocate hardware IRQ controller */
  2176 + ppc6xx_irq_init(env);
2149 break; 2177 break;
2150 2178
2151 case CPU_PPC_74x: /* PowerPC 740 / 750 */ 2179 case CPU_PPC_74x: /* PowerPC 740 / 750 */
@@ -2178,6 +2206,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -2178,6 +2206,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
2178 SPR_NOACCESS, SPR_NOACCESS, 2206 SPR_NOACCESS, SPR_NOACCESS,
2179 &spr_read_generic, &spr_write_generic, 2207 &spr_read_generic, &spr_write_generic,
2180 0x00000000); 2208 0x00000000);
  2209 + /* Allocate hardware IRQ controller */
  2210 + ppc6xx_irq_init(env);
2181 break; 2211 break;
2182 2212
2183 case CPU_PPC_750FX10: /* IBM PowerPC 750 FX */ 2213 case CPU_PPC_750FX10: /* IBM PowerPC 750 FX */
@@ -2213,6 +2243,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -2213,6 +2243,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
2213 SPR_NOACCESS, SPR_NOACCESS, 2243 SPR_NOACCESS, SPR_NOACCESS,
2214 &spr_read_generic, &spr_write_generic, 2244 &spr_read_generic, &spr_write_generic,
2215 0x00000000); 2245 0x00000000);
  2246 + /* Allocate hardware IRQ controller */
  2247 + ppc6xx_irq_init(env);
2216 break; 2248 break;
2217 2249
2218 case CPU_PPC_755_10: /* PowerPC 755 */ 2250 case CPU_PPC_755_10: /* PowerPC 755 */
@@ -2257,6 +2289,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -2257,6 +2289,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
2257 SPR_NOACCESS, SPR_NOACCESS, 2289 SPR_NOACCESS, SPR_NOACCESS,
2258 &spr_read_generic, &spr_write_generic, 2290 &spr_read_generic, &spr_write_generic,
2259 0x00000000); 2291 0x00000000);
  2292 + /* Allocate hardware IRQ controller */
  2293 + ppc6xx_irq_init(env);
2260 break; 2294 break;
2261 2295
2262 #if defined (TODO) 2296 #if defined (TODO)
@@ -2326,6 +2360,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) @@ -2326,6 +2360,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
2326 2360
2327 default: 2361 default:
2328 gen_spr_generic(env); 2362 gen_spr_generic(env);
  2363 + /* XXX: TODO: allocate internal IRQ controller */
2329 break; 2364 break;
2330 } 2365 }
2331 if (env->nb_BATs == -1) 2366 if (env->nb_BATs == -1)
@@ -854,16 +854,17 @@ void i440fx_init_memory_mappings(PCIDevice *d); @@ -854,16 +854,17 @@ void i440fx_init_memory_mappings(PCIDevice *d);
854 int piix4_init(PCIBus *bus, int devfn); 854 int piix4_init(PCIBus *bus, int devfn);
855 855
856 /* openpic.c */ 856 /* openpic.c */
  857 +/* OpenPIC have 5 outputs per CPU connected and one IRQ out single output */
857 enum { 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 /* heathrow_pic.c */ 869 /* heathrow_pic.c */
869 qemu_irq *heathrow_pic_init(int *pmem_index); 870 qemu_irq *heathrow_pic_init(int *pmem_index);
@@ -1145,9 +1146,6 @@ extern QEMUMachine shix_machine; @@ -1145,9 +1146,6 @@ extern QEMUMachine shix_machine;
1145 1146
1146 #ifdef TARGET_PPC 1147 #ifdef TARGET_PPC
1147 /* PowerPC hardware exceptions management helpers */ 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 ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq); 1149 ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq);
1152 #endif 1150 #endif
1153 void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val); 1151 void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val);