Commit 471035729088e3aa7f69140ac0ad0b248ff7ec07

Authored by j_mayer
1 parent de270b3c

New model for PowerPC CPU hardware interrupt events:

move all PowerPC specific code into target-ppc/helper.c to avoid polluting
the common code in cpu-exec.c. This makes implementation of new features
(ie embedded PowerPC timers, critical interrupts, ...) easier.
This also avoid hardcoding the IRQ callback in the OpenPIC controller,
making it more easily reusable and allowing cascading.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2542 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-exec.c
@@ -256,8 +256,7 @@ int cpu_exec(CPUState *env1) @@ -256,8 +256,7 @@ int cpu_exec(CPUState *env1)
256 #elif defined(TARGET_PPC) 256 #elif defined(TARGET_PPC)
257 if (env1->halted) { 257 if (env1->halted) {
258 if (env1->msr[MSR_EE] && 258 if (env1->msr[MSR_EE] &&
259 - (env1->interrupt_request &  
260 - (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER))) { 259 + (env1->interrupt_request & CPU_INTERRUPT_HARD)) {
261 env1->halted = 0; 260 env1->halted = 0;
262 } else { 261 } else {
263 return EXCP_HALTED; 262 return EXCP_HALTED;
@@ -448,24 +447,11 @@ int cpu_exec(CPUState *env1) @@ -448,24 +447,11 @@ int cpu_exec(CPUState *env1)
448 cpu_ppc_reset(env); 447 cpu_ppc_reset(env);
449 } 448 }
450 #endif 449 #endif
451 - if (msr_ee != 0) {  
452 - if ((interrupt_request & CPU_INTERRUPT_HARD)) {  
453 - /* Raise it */  
454 - env->exception_index = EXCP_EXTERNAL;  
455 - env->error_code = 0;  
456 - do_interrupt(env);  
457 - env->interrupt_request &= ~CPU_INTERRUPT_HARD;  
458 -#if defined(__sparc__) && !defined(HOST_SOLARIS)  
459 - tmp_T0 = 0;  
460 -#else  
461 - T0 = 0;  
462 -#endif  
463 - } else if ((interrupt_request & CPU_INTERRUPT_TIMER)) {  
464 - /* Raise it */  
465 - env->exception_index = EXCP_DECR;  
466 - env->error_code = 0;  
467 - do_interrupt(env);  
468 - env->interrupt_request &= ~CPU_INTERRUPT_TIMER; 450 + if (interrupt_request & CPU_INTERRUPT_HARD) {
  451 + if (ppc_hw_interrupt(env) == 1) {
  452 + /* Some exception was raised */
  453 + if (env->pending_interrupts == 0)
  454 + env->interrupt_request &= ~CPU_INTERRUPT_HARD;
469 #if defined(__sparc__) && !defined(HOST_SOLARIS) 455 #if defined(__sparc__) && !defined(HOST_SOLARIS)
470 tmp_T0 = 0; 456 tmp_T0 = 0;
471 #else 457 #else
hw/openpic.c
@@ -164,6 +164,7 @@ typedef struct IRQ_dst_t { @@ -164,6 +164,7 @@ typedef struct IRQ_dst_t {
164 164
165 struct openpic_t { 165 struct openpic_t {
166 PCIDevice pci_dev; 166 PCIDevice pci_dev;
  167 + SetIRQFunc *set_irq;
167 int mem_index; 168 int mem_index;
168 /* Global registers */ 169 /* Global registers */
169 uint32_t frep; /* Feature reporting register */ 170 uint32_t frep; /* Feature reporting register */
@@ -264,8 +265,8 @@ static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ) @@ -264,8 +265,8 @@ static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ)
264 IRQ_setbit(&dst->raised, n_IRQ); 265 IRQ_setbit(&dst->raised, n_IRQ);
265 if (priority > dst->raised.priority) { 266 if (priority > dst->raised.priority) {
266 IRQ_get_next(opp, &dst->raised); 267 IRQ_get_next(opp, &dst->raised);
267 - DPRINTF("Raise CPU IRQ\n");  
268 - cpu_interrupt(dst->env, CPU_INTERRUPT_HARD); 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);
269 } 270 }
270 } 271 }
271 272
@@ -532,7 +533,7 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val) @@ -532,7 +533,7 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
532 /* XXX: Should be able to reset any CPU */ 533 /* XXX: Should be able to reset any CPU */
533 if (val & 1) { 534 if (val & 1) {
534 DPRINTF("Reset CPU IRQ\n"); 535 DPRINTF("Reset CPU IRQ\n");
535 - // cpu_interrupt(first_cpu, CPU_INTERRUPT_RESET); 536 + // opp->set_irq(dst->env, OPENPIC_EVT_RESET, 1);
536 } 537 }
537 break; 538 break;
538 #if MAX_IPI > 0 539 #if MAX_IPI > 0
@@ -781,7 +782,7 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val) @@ -781,7 +782,7 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
781 src = &opp->src[n_IRQ]; 782 src = &opp->src[n_IRQ];
782 if (IPVP_PRIORITY(src->ipvp) > dst->servicing.priority) { 783 if (IPVP_PRIORITY(src->ipvp) > dst->servicing.priority) {
783 DPRINTF("Raise CPU IRQ\n"); 784 DPRINTF("Raise CPU IRQ\n");
784 - cpu_interrupt(dst->env, CPU_INTERRUPT_HARD); 785 + opp->set_irq(dst->env, OPENPIC_EVT_INT, 1);
785 } 786 }
786 } 787 }
787 break; 788 break;
@@ -963,8 +964,8 @@ static void openpic_map(PCIDevice *pci_dev, int region_num, @@ -963,8 +964,8 @@ static void openpic_map(PCIDevice *pci_dev, int region_num,
963 #endif 964 #endif
964 } 965 }
965 966
966 -openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,  
967 - CPUPPCState **envp) 967 +openpic_t *openpic_init (PCIBus *bus, SetIRQFunc *set_irq,
  968 + int *pmem_index, int nb_cpus, CPUPPCState **envp)
968 { 969 {
969 openpic_t *opp; 970 openpic_t *opp;
970 uint8_t *pci_conf; 971 uint8_t *pci_conf;
@@ -994,7 +995,7 @@ openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus, @@ -994,7 +995,7 @@ openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
994 } else { 995 } else {
995 opp = qemu_mallocz(sizeof(openpic_t)); 996 opp = qemu_mallocz(sizeof(openpic_t));
996 } 997 }
997 - 998 + opp->set_irq = set_irq;
998 opp->mem_index = cpu_register_io_memory(0, openpic_read, 999 opp->mem_index = cpu_register_io_memory(0, openpic_read,
999 openpic_write, opp); 1000 openpic_write, opp);
1000 1001
hw/ppc.c
@@ -24,6 +24,57 @@ @@ -24,6 +24,57 @@
24 #include "vl.h" 24 #include "vl.h"
25 #include "m48t59.h" 25 #include "m48t59.h"
26 26
  27 +extern FILE *logfile;
  28 +extern int loglevel;
  29 +
  30 +/*****************************************************************************/
  31 +/* PowerPC internal fake IRQ controller
  32 + * used to manage multiple sources hardware events
  33 + */
  34 +/* XXX: should be protected */
  35 +void ppc_set_irq (void *opaque, int n_IRQ, int level)
  36 +{
  37 + CPUState *env;
  38 +
  39 + env = opaque;
  40 + if (level) {
  41 + env->pending_interrupts |= 1 << n_IRQ;
  42 + cpu_interrupt(env, CPU_INTERRUPT_HARD);
  43 + } else {
  44 + env->pending_interrupts &= ~(1 << n_IRQ);
  45 + if (env->pending_interrupts == 0)
  46 + cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
  47 + }
  48 +#if 0
  49 + printf("%s: %p n_IRQ %d level %d => pending %08x req %08x\n", __func__,
  50 + env, n_IRQ, level, env->pending_interrupts, env->interrupt_request);
  51 +#endif
  52 +}
  53 +
  54 +/* External IRQ callback from OpenPIC IRQ controller */
  55 +void ppc_openpic_irq (void *opaque, int n_IRQ, int level)
  56 +{
  57 + switch (n_IRQ) {
  58 + case OPENPIC_EVT_INT:
  59 + n_IRQ = PPC_INTERRUPT_EXT;
  60 + break;
  61 + case OPENPIC_EVT_CINT:
  62 + /* On PowerPC BookE, critical input use vector 0 */
  63 + n_IRQ = PPC_INTERRUPT_RESET;
  64 + break;
  65 + case OPENPIC_EVT_MCK:
  66 + n_IRQ = PPC_INTERRUPT_MCK;
  67 + break;
  68 + case OPENPIC_EVT_DEBUG:
  69 + n_IRQ = PPC_INTERRUPT_DEBUG;
  70 + break;
  71 + case OPENPIC_EVT_RESET:
  72 + qemu_system_reset_request();
  73 + return;
  74 + }
  75 + ppc_set_irq(opaque, n_IRQ, level);
  76 +}
  77 +
27 /*****************************************************************************/ 78 /*****************************************************************************/
28 /* PPC time base and decrementer emulation */ 79 /* PPC time base and decrementer emulation */
29 //#define DEBUG_TB 80 //#define DEBUG_TB
@@ -35,6 +86,7 @@ struct ppc_tb_t { @@ -35,6 +86,7 @@ struct ppc_tb_t {
35 /* Decrementer management */ 86 /* Decrementer management */
36 uint64_t decr_next; /* Tick for next decr interrupt */ 87 uint64_t decr_next; /* Tick for next decr interrupt */
37 struct QEMUTimer *decr_timer; 88 struct QEMUTimer *decr_timer;
  89 + void *opaque;
38 }; 90 };
39 91
40 static inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env) 92 static inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env)
@@ -131,7 +183,7 @@ static inline void cpu_ppc_decr_excp (CPUState *env) @@ -131,7 +183,7 @@ static inline void cpu_ppc_decr_excp (CPUState *env)
131 #ifdef DEBUG_TB 183 #ifdef DEBUG_TB
132 printf("raise decrementer exception\n"); 184 printf("raise decrementer exception\n");
133 #endif 185 #endif
134 - cpu_interrupt(env, CPU_INTERRUPT_TIMER); 186 + ppc_set_irq(env, PPC_INTERRUPT_DECR, 1);
135 } 187 }
136 188
137 static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr, 189 static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
hw/ppc_chrp.c
1 /* 1 /*
2 * QEMU PPC CHRP/PMAC hardware System Emulator 2 * QEMU PPC CHRP/PMAC hardware System Emulator
3 * 3 *
4 - * Copyright (c) 2004 Fabrice Bellard 4 + * Copyright (c) 2004-2007 Fabrice Bellard
5 * 5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy 6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal 7 * of this software and associated documentation files (the "Software"), to deal
@@ -449,21 +449,21 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, @@ -449,21 +449,21 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
449 } 449 }
450 450
451 macio_init(pci_bus, 0x0017); 451 macio_init(pci_bus, 0x0017);
452 - 452 +
453 nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE, 59); 453 nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
454 - 454 +
455 arch_name = "HEATHROW"; 455 arch_name = "HEATHROW";
456 } else { 456 } else {
457 isa_mem_base = 0x80000000; 457 isa_mem_base = 0x80000000;
458 - 458 +
459 /* Register 8 MB of ISA IO space */ 459 /* Register 8 MB of ISA IO space */
460 isa_mmio_init(0xf2000000, 0x00800000); 460 isa_mmio_init(0xf2000000, 0x00800000);
461 - 461 +
462 /* UniN init */ 462 /* UniN init */
463 unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL); 463 unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL);
464 cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory); 464 cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory);
465 465
466 - pic = openpic_init(NULL, &openpic_mem_index, 1, &env); 466 + pic = openpic_init(NULL, &ppc_openpic_irq, &openpic_mem_index, 1, &env);
467 set_irq = openpic_set_irq; 467 set_irq = openpic_set_irq;
468 pci_bus = pci_pmac_init(pic); 468 pci_bus = pci_pmac_init(pic);
469 /* init basic PC hardware */ 469 /* init basic PC hardware */
hw/ppc_prep.c
1 /* 1 /*
2 * QEMU PPC PREP hardware System Emulator 2 * QEMU PPC PREP hardware System Emulator
3 * 3 *
4 - * Copyright (c) 2003-2004 Jocelyn Mayer 4 + * Copyright (c) 2003-2007 Jocelyn Mayer
5 * 5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy 6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal 7 * of this software and associated documentation files (the "Software"), to deal
@@ -84,29 +84,27 @@ static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val) @@ -84,29 +84,27 @@ static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
84 #endif 84 #endif
85 } 85 }
86 86
87 -static uint32_t speaker_ioport_read(void *opaque, uint32_t addr) 87 +static uint32_t speaker_ioport_read (void *opaque, uint32_t addr)
88 { 88 {
89 #if 0 89 #if 0
90 int out; 90 int out;
91 out = pit_get_out(pit, 2, qemu_get_clock(vm_clock)); 91 out = pit_get_out(pit, 2, qemu_get_clock(vm_clock));
92 dummy_refresh_clock ^= 1; 92 dummy_refresh_clock ^= 1;
93 return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) | 93 return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
94 - (dummy_refresh_clock << 4); 94 + (dummy_refresh_clock << 4);
95 #endif 95 #endif
96 return 0; 96 return 0;
97 } 97 }
98 98
99 -static void pic_irq_request(void *opaque, int level) 99 +static void pic_irq_request (void *opaque, int level)
100 { 100 {
101 - if (level)  
102 - cpu_interrupt(first_cpu, CPU_INTERRUPT_HARD);  
103 - else  
104 - cpu_reset_interrupt(first_cpu, CPU_INTERRUPT_HARD); 101 + ppc_set_irq(opaque, PPC_INTERRUPT_EXT, level);
105 } 102 }
106 103
107 /* PCI intack register */ 104 /* PCI intack register */
108 /* Read-only register (?) */ 105 /* Read-only register (?) */
109 -static void _PPC_intack_write (void *opaque, target_phys_addr_t addr, uint32_t value) 106 +static void _PPC_intack_write (void *opaque,
  107 + target_phys_addr_t addr, uint32_t value)
110 { 108 {
111 // printf("%s: 0x%08x => 0x%08x\n", __func__, addr, value); 109 // printf("%s: 0x%08x => 0x%08x\n", __func__, addr, value);
112 } 110 }
@@ -294,7 +292,7 @@ static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val) @@ -294,7 +292,7 @@ static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
294 /* Special port 92 */ 292 /* Special port 92 */
295 /* Check soft reset asked */ 293 /* Check soft reset asked */
296 if (val & 0x01) { 294 if (val & 0x01) {
297 - // cpu_interrupt(first_cpu, CPU_INTERRUPT_RESET); 295 + // cpu_interrupt(first_cpu, PPC_INTERRUPT_RESET);
298 } 296 }
299 /* Check LE mode */ 297 /* Check LE mode */
300 if (val & 0x02) { 298 if (val & 0x02) {
target-ppc/cpu.h
@@ -740,6 +740,7 @@ struct CPUPPCState { @@ -740,6 +740,7 @@ struct CPUPPCState {
740 int exception_index; 740 int exception_index;
741 int error_code; 741 int error_code;
742 int interrupt_request; 742 int interrupt_request;
  743 + uint32_t pending_interrupts;
743 744
744 /* Those resources are used only during code translation */ 745 /* Those resources are used only during code translation */
745 /* Next instruction pointer */ 746 /* Next instruction pointer */
@@ -1267,6 +1268,21 @@ enum { @@ -1267,6 +1268,21 @@ enum {
1267 EXCP_TRAP = 0x40, 1268 EXCP_TRAP = 0x40,
1268 }; 1269 };
1269 1270
  1271 +/* Hardware interruption sources:
  1272 + * all those exception can be raised simulteaneously
  1273 + */
  1274 +enum {
  1275 + PPC_INTERRUPT_RESET = 0, /* Reset / critical input */
  1276 + PPC_INTERRUPT_MCK = 1, /* Machine check exception */
  1277 + PPC_INTERRUPT_EXT = 2, /* External interrupt */
  1278 + PPC_INTERRUPT_DECR = 3, /* Decrementer exception */
  1279 + PPC_INTERRUPT_HDECR = 4, /* Hypervisor decrementer exception */
  1280 + PPC_INTERRUPT_PIT = 5, /* Programmable inteval timer interrupt */
  1281 + PPC_INTERRUPT_FIT = 6, /* Fixed interval timer interrupt */
  1282 + PPC_INTERRUPT_WDT = 7, /* Watchdog timer interrupt */
  1283 + PPC_INTERRUPT_DEBUG = 8, /* External debug exception */
  1284 +};
  1285 +
1270 /*****************************************************************************/ 1286 /*****************************************************************************/
1271 1287
1272 #endif /* !defined (__CPU_PPC_H__) */ 1288 #endif /* !defined (__CPU_PPC_H__) */
target-ppc/helper.c
@@ -1229,6 +1229,13 @@ void do_interrupt (CPUState *env) @@ -1229,6 +1229,13 @@ void do_interrupt (CPUState *env)
1229 { 1229 {
1230 env->exception_index = -1; 1230 env->exception_index = -1;
1231 } 1231 }
  1232 +
  1233 +int ppc_hw_interrupt (CPUState *env)
  1234 +{
  1235 + env->exception_index = -1;
  1236 +
  1237 + return 0;
  1238 +}
1232 #else /* defined (CONFIG_USER_ONLY) */ 1239 #else /* defined (CONFIG_USER_ONLY) */
1233 static void dump_syscall(CPUState *env) 1240 static void dump_syscall(CPUState *env)
1234 { 1241 {
@@ -1753,4 +1760,80 @@ void do_interrupt (CPUState *env) @@ -1753,4 +1760,80 @@ void do_interrupt (CPUState *env)
1753 env->nip = excp; 1760 env->nip = excp;
1754 env->exception_index = EXCP_NONE; 1761 env->exception_index = EXCP_NONE;
1755 } 1762 }
  1763 +
  1764 +int ppc_hw_interrupt (CPUState *env)
  1765 +{
  1766 + int raised = 0;
  1767 +
  1768 +#if 0
  1769 + printf("%s: %p pending %08x req %08x %08x me %d ee %d\n",
  1770 + __func__, env, env->pending_interrupts,
  1771 + env->interrupt_request, interrupt_request,
  1772 + msr_me, msr_ee);
  1773 +#endif
  1774 + /* Raise it */
  1775 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
  1776 + /* External reset / critical input */
  1777 + env->exception_index = EXCP_RESET;
  1778 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
  1779 + raised = 1;
  1780 + }
  1781 + if (raised == 0 && msr_me != 0) {
  1782 + /* Machine check exception */
  1783 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
  1784 + env->exception_index = EXCP_MACHINE_CHECK;
  1785 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
  1786 + raised = 1;
  1787 + }
  1788 + }
  1789 + if (raised == 0 && msr_ee != 0) {
  1790 +#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
  1791 + /* Hypervisor decrementer exception */
  1792 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
  1793 + env->exception_index = EXCP_HDECR;
  1794 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
  1795 + raised = 1;
  1796 + } else
  1797 +#endif
  1798 + /* Decrementer exception */
  1799 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
  1800 + env->exception_index = EXCP_DECR;
  1801 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
  1802 + raised = 1;
  1803 + /* Programmable interval timer on embedded PowerPC */
  1804 + } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
  1805 + env->exception_index = EXCP_40x_PIT;
  1806 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
  1807 + raised = 1;
  1808 + /* Fixed interval timer on embedded PowerPC */
  1809 + } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
  1810 + env->exception_index = EXCP_40x_FIT;
  1811 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
  1812 + raised = 1;
  1813 + /* Watchdog timer on embedded PowerPC */
  1814 + } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
  1815 + env->exception_index = EXCP_40x_WATCHDOG;
  1816 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
  1817 + raised = 1;
  1818 + /* External interrupt */
  1819 + } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
  1820 + env->exception_index = EXCP_EXTERNAL;
  1821 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
  1822 + raised = 1;
  1823 + }
  1824 +#if 0 // TODO
  1825 + /* External debug exception */
  1826 + } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
  1827 + env->exception_index = EXCP_xxx;
  1828 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
  1829 + raised = 1;
  1830 +#endif
  1831 + }
  1832 + if (raised != 0) {
  1833 + env->error_code = 0;
  1834 + do_interrupt(env);
  1835 + }
  1836 +
  1837 + return raised;
  1838 +}
1756 #endif /* !CONFIG_USER_ONLY */ 1839 #endif /* !CONFIG_USER_ONLY */
@@ -852,9 +852,16 @@ int piix4_init(PCIBus *bus, int devfn); @@ -852,9 +852,16 @@ int piix4_init(PCIBus *bus, int devfn);
852 852
853 /* openpic.c */ 853 /* openpic.c */
854 typedef struct openpic_t openpic_t; 854 typedef struct openpic_t openpic_t;
  855 +enum {
  856 + OPENPIC_EVT_INT = 0, /* IRQ */
  857 + OPENPIC_EVT_CINT, /* critical IRQ */
  858 + OPENPIC_EVT_MCK, /* Machine check event */
  859 + OPENPIC_EVT_DEBUG, /* Inconditional debug event */
  860 + OPENPIC_EVT_RESET, /* Core reset event */
  861 +};
855 void openpic_set_irq(void *opaque, int n_IRQ, int level); 862 void openpic_set_irq(void *opaque, int n_IRQ, int level);
856 -openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,  
857 - CPUState **envp); 863 +openpic_t *openpic_init (PCIBus *bus, SetIRQFunc *set_irq,
  864 + int *pmem_index, int nb_cpus, CPUPPCState **envp);
858 865
859 /* heathrow_pic.c */ 866 /* heathrow_pic.c */
860 typedef struct HeathrowPICS HeathrowPICS; 867 typedef struct HeathrowPICS HeathrowPICS;
@@ -1115,6 +1122,10 @@ extern void cpu_mips_irqctrl_init (void); @@ -1115,6 +1122,10 @@ extern void cpu_mips_irqctrl_init (void);
1115 extern QEMUMachine shix_machine; 1122 extern QEMUMachine shix_machine;
1116 1123
1117 #ifdef TARGET_PPC 1124 #ifdef TARGET_PPC
  1125 +/* PowerPC hardware exceptions management helpers */
  1126 +void ppc_set_irq (void *opaque, int n_IRQ, int level);
  1127 +void ppc_openpic_irq (void *opaque, int n_IRQ, int level);
  1128 +int ppc_hw_interrupt (CPUState *env);
1118 ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq); 1129 ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq);
1119 #endif 1130 #endif
1120 void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val); 1131 void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val);