Commit b71699167155d3ae17bc18e74ea6d4360aa2540b

Authored by aurel32
1 parent 72249e34

kvm/powerpc: Enable MPIC for E500 platform.

MPIC and OpenPIC have very similar design.
So a lot of code can be reused.

Signed-off-by: Liu Yu <yu.liu@freescale.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6659 c046a42c-6fe2-441c-8c8c-71466251a162
hw/openpic.c
... ... @@ -35,6 +35,7 @@
35 35 #include "hw.h"
36 36 #include "ppc_mac.h"
37 37 #include "pci.h"
  38 +#include "openpic.h"
38 39  
39 40 //#define DEBUG_OPENPIC
40 41  
... ... @@ -60,14 +61,10 @@
60 61  
61 62 #define VID (0x00000000)
62 63  
63   -#define OPENPIC_LITTLE_ENDIAN 1
64   -#define OPENPIC_BIG_ENDIAN 0
65   -
66 64 #elif defined(USE_MPCxxx)
67 65  
68 66 #define MAX_CPU 2
69   -#define MAX_IRQ 64
70   -#define EXT_IRQ 48
  67 +#define MAX_IRQ 128
71 68 #define MAX_DBL 0
72 69 #define MAX_MBX 0
73 70 #define MAX_TMR 4
... ... @@ -81,28 +78,68 @@ enum {
81 78 IRQ_IDE,
82 79 };
83 80  
84   -#define OPENPIC_LITTLE_ENDIAN 1
85   -#define OPENPIC_BIG_ENDIAN 0
  81 +/* OpenPIC */
  82 +#define OPENPIC_MAX_CPU 2
  83 +#define OPENPIC_MAX_IRQ 64
  84 +#define OPENPIC_EXT_IRQ 48
  85 +#define OPENPIC_MAX_TMR MAX_TMR
  86 +#define OPENPIC_MAX_IPI MAX_IPI
86 87  
  88 +/* Interrupt definitions */
  89 +#define OPENPIC_IRQ_FE (OPENPIC_EXT_IRQ) /* Internal functional IRQ */
  90 +#define OPENPIC_IRQ_ERR (OPENPIC_EXT_IRQ + 1) /* Error IRQ */
  91 +#define OPENPIC_IRQ_TIM0 (OPENPIC_EXT_IRQ + 2) /* First timer IRQ */
  92 +#if OPENPIC_MAX_IPI > 0
  93 +#define OPENPIC_IRQ_IPI0 (OPENPIC_IRQ_TIM0 + OPENPIC_MAX_TMR) /* First IPI IRQ */
  94 +#define OPENPIC_IRQ_DBL0 (OPENPIC_IRQ_IPI0 + (OPENPIC_MAX_CPU * OPENPIC_MAX_IPI)) /* First doorbell IRQ */
87 95 #else
88   -#error "Please select which OpenPic implementation is to be emulated"
  96 +#define OPENPIC_IRQ_DBL0 (OPENPIC_IRQ_TIM0 + OPENPIC_MAX_TMR) /* First doorbell IRQ */
  97 +#define OPENPIC_IRQ_MBX0 (OPENPIC_IRQ_DBL0 + OPENPIC_MAX_DBL) /* First mailbox IRQ */
89 98 #endif
90 99  
91   -#if (OPENPIC_BIG_ENDIAN && !TARGET_WORDS_BIGENDIAN) || \
92   - (OPENPIC_LITTLE_ENDIAN && TARGET_WORDS_BIGENDIAN)
93   -#define OPENPIC_SWAP
94   -#endif
  100 +/* MPIC */
  101 +#define MPIC_MAX_CPU 1
  102 +#define MPIC_MAX_EXT 12
  103 +#define MPIC_MAX_INT 64
  104 +#define MPIC_MAX_MSG 4
  105 +#define MPIC_MAX_MSI 8
  106 +#define MPIC_MAX_TMR MAX_TMR
  107 +#define MPIC_MAX_IPI MAX_IPI
  108 +#define MPIC_MAX_IRQ (MPIC_MAX_EXT + MPIC_MAX_INT + MPIC_MAX_TMR + MPIC_MAX_MSG + MPIC_MAX_MSI + (MPIC_MAX_IPI * MPIC_MAX_CPU))
95 109  
96 110 /* Interrupt definitions */
97   -#define IRQ_FE (EXT_IRQ) /* Internal functional IRQ */
98   -#define IRQ_ERR (EXT_IRQ + 1) /* Error IRQ */
99   -#define IRQ_TIM0 (EXT_IRQ + 2) /* First timer IRQ */
100   -#if MAX_IPI > 0
101   -#define IRQ_IPI0 (IRQ_TIM0 + MAX_TMR) /* First IPI IRQ */
102   -#define IRQ_DBL0 (IRQ_IPI0 + (MAX_CPU * MAX_IPI)) /* First doorbell IRQ */
  111 +#define MPIC_EXT_IRQ 0
  112 +#define MPIC_INT_IRQ (MPIC_EXT_IRQ + MPIC_MAX_EXT)
  113 +#define MPIC_TMR_IRQ (MPIC_INT_IRQ + MPIC_MAX_INT)
  114 +#define MPIC_MSG_IRQ (MPIC_TMR_IRQ + MPIC_MAX_TMR)
  115 +#define MPIC_MSI_IRQ (MPIC_MSG_IRQ + MPIC_MAX_MSG)
  116 +#define MPIC_IPI_IRQ (MPIC_MSI_IRQ + MPIC_MAX_MSI)
  117 +
  118 +#define MPIC_GLB_REG_START 0x0
  119 +#define MPIC_GLB_REG_SIZE 0x10F0
  120 +#define MPIC_TMR_REG_START 0x10F0
  121 +#define MPIC_TMR_REG_SIZE 0x220
  122 +#define MPIC_EXT_REG_START 0x10000
  123 +#define MPIC_EXT_REG_SIZE 0x180
  124 +#define MPIC_INT_REG_START 0x10200
  125 +#define MPIC_INT_REG_SIZE 0x800
  126 +#define MPIC_MSG_REG_START 0x11600
  127 +#define MPIC_MSG_REG_SIZE 0x100
  128 +#define MPIC_MSI_REG_START 0x11C00
  129 +#define MPIC_MSI_REG_SIZE 0x100
  130 +#define MPIC_CPU_REG_START 0x20000
  131 +#define MPIC_CPU_REG_SIZE 0x100
  132 +
  133 +enum mpic_ide_bits {
  134 + IDR_EP = 0,
  135 + IDR_CI0 = 1,
  136 + IDR_CI1 = 2,
  137 + IDR_P1 = 30,
  138 + IDR_P0 = 31,
  139 +};
  140 +
103 141 #else
104   -#define IRQ_DBL0 (IRQ_TIM0 + MAX_TMR) /* First doorbell IRQ */
105   -#define IRQ_MBX0 (IRQ_DBL0 + MAX_DBL) /* First mailbox IRQ */
  142 +#error "Please select which OpenPic implementation is to be emulated"
106 143 #endif
107 144  
108 145 #define BF_WIDTH(_bits_) \
... ... @@ -157,6 +194,7 @@ enum IPVP_bits {
157 194 #define IPVP_VECTOR(_ipvpr_) ((_ipvpr_) & IPVP_VECTOR_MASK)
158 195  
159 196 typedef struct IRQ_dst_t {
  197 + uint32_t tfrr;
160 198 uint32_t pctp; /* CPU current task priority */
161 199 uint32_t pcsr; /* CPU sensitivity register */
162 200 IRQ_queue_t raised;
... ... @@ -200,8 +238,22 @@ typedef struct openpic_t {
200 238 #endif
201 239 /* IRQ out is used when in bypass mode (not implemented) */
202 240 qemu_irq irq_out;
  241 + int max_irq;
  242 + int irq_ipi0;
  243 + int irq_tim0;
  244 + int need_swap;
  245 + void (*reset) (void *);
  246 + void (*irq_raise) (struct openpic_t *, int, IRQ_src_t *);
203 247 } openpic_t;
204 248  
  249 +static inline uint32_t openpic_swap32(openpic_t *opp, uint32_t val)
  250 +{
  251 + if (opp->need_swap)
  252 + return bswap32(val);
  253 +
  254 + return val;
  255 +}
  256 +
205 257 static inline void IRQ_setbit (IRQ_queue_t *q, int n_IRQ)
206 258 {
207 259 set_bit(q->queue, n_IRQ);
... ... @@ -224,7 +276,7 @@ static void IRQ_check (openpic_t *opp, IRQ_queue_t *q)
224 276  
225 277 next = -1;
226 278 priority = -1;
227   - for (i = 0; i < MAX_IRQ; i++) {
  279 + for (i = 0; i < opp->max_irq; i++) {
228 280 if (IRQ_testbit(q, i)) {
229 281 DPRINTF("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n",
230 282 i, IPVP_PRIORITY(opp->src[i].ipvp), priority);
... ... @@ -286,7 +338,7 @@ static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ)
286 338 return;
287 339 }
288 340 DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", n_CPU, n_IRQ);
289   - qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]);
  341 + opp->irq_raise(opp, n_CPU, src);
290 342 }
291 343  
292 344 /* update pic state because registers for n_IRQ have changed value */
... ... @@ -374,7 +426,7 @@ static void openpic_reset (void *opaque)
374 426  
375 427 opp->glbc = 0x80000000;
376 428 /* Initialise controller registers */
377   - opp->frep = ((EXT_IRQ - 1) << 16) | ((MAX_CPU - 1) << 8) | VID;
  429 + opp->frep = ((OPENPIC_EXT_IRQ - 1) << 16) | ((MAX_CPU - 1) << 8) | VID;
378 430 opp->veni = VENI;
379 431 opp->pint = 0x00000000;
380 432 opp->spve = 0x000000FF;
... ... @@ -382,7 +434,7 @@ static void openpic_reset (void *opaque)
382 434 /* ? */
383 435 opp->micr = 0x00000000;
384 436 /* Initialise IRQ sources */
385   - for (i = 0; i < MAX_IRQ; i++) {
  437 + for (i = 0; i < opp->max_irq; i++) {
386 438 opp->src[i].ipvp = 0xA0000000;
387 439 opp->src[i].ide = 0x00000000;
388 440 }
... ... @@ -535,7 +587,7 @@ static void write_mailbox_register (openpic_t *opp, int n_mbx,
535 587 #endif
536 588 #endif /* 0 : Code provision for Intel model */
537 589  
538   -static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
  590 +static void openpic_gbl_write (void *opaque, target_phys_addr_t addr, uint32_t val)
539 591 {
540 592 openpic_t *opp = opaque;
541 593 IRQ_dst_t *dst;
... ... @@ -544,16 +596,16 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
544 596 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
545 597 if (addr & 0xF)
546 598 return;
547   -#if defined OPENPIC_SWAP
548   - val = bswap32(val);
  599 +#if defined TARGET_WORDS_BIGENDIAN
  600 + val = openpic_swap32(opp, val);
549 601 #endif
550 602 addr &= 0xFF;
551 603 switch (addr) {
552 604 case 0x00: /* FREP */
553 605 break;
554 606 case 0x20: /* GLBC */
555   - if (val & 0x80000000)
556   - openpic_reset(opp);
  607 + if (val & 0x80000000 && opp->reset)
  608 + opp->reset(opp);
557 609 opp->glbc = val & ~0x80000000;
558 610 break;
559 611 case 0x80: /* VENI */
... ... @@ -580,7 +632,7 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
580 632 {
581 633 int idx;
582 634 idx = (addr - 0xA0) >> 4;
583   - write_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IPVP, val);
  635 + write_IRQreg(opp, opp->irq_ipi0 + idx, IRQ_IPVP, val);
584 636 }
585 637 break;
586 638 #endif
... ... @@ -595,7 +647,7 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
595 647 }
596 648 }
597 649  
598   -static uint32_t openpic_gbl_read (void *opaque, uint32_t addr)
  650 +static uint32_t openpic_gbl_read (void *opaque, target_phys_addr_t addr)
599 651 {
600 652 openpic_t *opp = opaque;
601 653 uint32_t retval;
... ... @@ -626,7 +678,7 @@ static uint32_t openpic_gbl_read (void *opaque, uint32_t addr)
626 678 {
627 679 int idx;
628 680 idx = (addr - 0xA0) >> 4;
629   - retval = read_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IPVP);
  681 + retval = read_IRQreg(opp, opp->irq_ipi0 + idx, IRQ_IPVP);
630 682 }
631 683 break;
632 684 #endif
... ... @@ -640,8 +692,8 @@ static uint32_t openpic_gbl_read (void *opaque, uint32_t addr)
640 692 break;
641 693 }
642 694 DPRINTF("%s: => %08x\n", __func__, retval);
643   -#if defined OPENPIC_SWAP
644   - retval = bswap32(retval);
  695 +#if defined TARGET_WORDS_BIGENDIAN
  696 + retval = openpic_swap32(opp, retval);
645 697 #endif
646 698  
647 699 return retval;
... ... @@ -655,8 +707,8 @@ static void openpic_timer_write (void *opaque, uint32_t addr, uint32_t val)
655 707 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
656 708 if (addr & 0xF)
657 709 return;
658   -#if defined OPENPIC_SWAP
659   - val = bswap32(val);
  710 +#if defined TARGET_WORDS_BIGENDIAN
  711 + val = openpic_swap32(opp, val);
660 712 #endif
661 713 addr -= 0x1100;
662 714 addr &= 0xFFFF;
... ... @@ -673,10 +725,10 @@ static void openpic_timer_write (void *opaque, uint32_t addr, uint32_t val)
673 725 opp->timers[idx].tibc = val;
674 726 break;
675 727 case 0x20: /* TIVP */
676   - write_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IPVP, val);
  728 + write_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IPVP, val);
677 729 break;
678 730 case 0x30: /* TIDE */
679   - write_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IDE, val);
  731 + write_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IDE, val);
680 732 break;
681 733 }
682 734 }
... ... @@ -703,15 +755,15 @@ static uint32_t openpic_timer_read (void *opaque, uint32_t addr)
703 755 retval = opp->timers[idx].tibc;
704 756 break;
705 757 case 0x20: /* TIPV */
706   - retval = read_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IPVP);
  758 + retval = read_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IPVP);
707 759 break;
708 760 case 0x30: /* TIDE */
709   - retval = read_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IDE);
  761 + retval = read_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IDE);
710 762 break;
711 763 }
712 764 DPRINTF("%s: => %08x\n", __func__, retval);
713   -#if defined OPENPIC_SWAP
714   - retval = bswap32(retval);
  765 +#if defined TARGET_WORDS_BIGENDIAN
  766 + retval = openpic_swap32(opp, retval);
715 767 #endif
716 768  
717 769 return retval;
... ... @@ -725,8 +777,8 @@ static void openpic_src_write (void *opaque, uint32_t addr, uint32_t val)
725 777 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
726 778 if (addr & 0xF)
727 779 return;
728   -#if defined OPENPIC_SWAP
729   - val = tswap32(val);
  780 +#if defined TARGET_WORDS_BIGENDIAN
  781 + val = openpic_swap32(opp, val);
730 782 #endif
731 783 addr = addr & 0xFFF0;
732 784 idx = addr >> 5;
... ... @@ -759,14 +811,14 @@ static uint32_t openpic_src_read (void *opaque, uint32_t addr)
759 811 retval = read_IRQreg(opp, idx, IRQ_IPVP);
760 812 }
761 813 DPRINTF("%s: => %08x\n", __func__, retval);
762   -#if defined OPENPIC_SWAP
763   - retval = tswap32(retval);
  814 +#if defined TARGET_WORDS_BIGENDIAN
  815 + retval = openpic_swap32(opp, retval);
764 816 #endif
765 817  
766 818 return retval;
767 819 }
768 820  
769   -static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
  821 +static void openpic_cpu_write (void *opaque, target_phys_addr_t addr, uint32_t val)
770 822 {
771 823 openpic_t *opp = opaque;
772 824 IRQ_src_t *src;
... ... @@ -776,8 +828,8 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
776 828 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
777 829 if (addr & 0xF)
778 830 return;
779   -#if defined OPENPIC_SWAP
780   - val = bswap32(val);
  831 +#if defined TARGET_WORDS_BIGENDIAN
  832 + val = openpic_swap32(opp, val);
781 833 #endif
782 834 addr &= 0x1FFF0;
783 835 idx = addr / 0x1000;
... ... @@ -790,9 +842,9 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
790 842 case 0x60:
791 843 case 0x70:
792 844 idx = (addr - 0x40) >> 4;
793   - write_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IDE, val);
794   - openpic_set_irq(opp, IRQ_IPI0 + idx, 1);
795   - openpic_set_irq(opp, IRQ_IPI0 + idx, 0);
  845 + write_IRQreg(opp, opp->irq_ipi0 + idx, IRQ_IDE, val);
  846 + openpic_set_irq(opp, opp->irq_ipi0 + idx, 1);
  847 + openpic_set_irq(opp, opp->irq_ipi0 + idx, 0);
796 848 break;
797 849 #endif
798 850 case 0x80: /* PCTP */
... ... @@ -819,7 +871,7 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
819 871 IPVP_PRIORITY(src->ipvp) > dst->servicing.priority)) {
820 872 DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n",
821 873 idx, n_IRQ);
822   - qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]);
  874 + opp->irq_raise(opp, idx, src);
823 875 }
824 876 break;
825 877 default:
... ... @@ -827,7 +879,7 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
827 879 }
828 880 }
829 881  
830   -static uint32_t openpic_cpu_read (void *opaque, uint32_t addr)
  882 +static uint32_t openpic_cpu_read (void *opaque, target_phys_addr_t addr)
831 883 {
832 884 openpic_t *opp = opaque;
833 885 IRQ_src_t *src;
... ... @@ -889,15 +941,15 @@ static uint32_t openpic_cpu_read (void *opaque, uint32_t addr)
889 941 case 0x40: /* IDE */
890 942 case 0x50:
891 943 idx = (addr - 0x40) >> 4;
892   - retval = read_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IDE);
  944 + retval = read_IRQreg(opp, opp->irq_ipi0 + idx, IRQ_IDE);
893 945 break;
894 946 #endif
895 947 default:
896 948 break;
897 949 }
898 950 DPRINTF("%s: => %08x\n", __func__, retval);
899   -#if defined OPENPIC_SWAP
900   - retval= bswap32(retval);
  951 +#if defined TARGET_WORDS_BIGENDIAN
  952 + retval = openpic_swap32(opp, retval);
901 953 #endif
902 954  
903 955 return retval;
... ... @@ -989,7 +1041,7 @@ static void openpic_map(PCIDevice *pci_dev, int region_num,
989 1041 addr + 0x1100, addr + 0x1100 + 0x40 * MAX_TMR);
990 1042 /* Interrupt source registers */
991 1043 DPRINTF("Register OPENPIC src %08x => %08x\n",
992   - addr + 0x10000, addr + 0x10000 + 0x20 * (EXT_IRQ + 2));
  1044 + addr + 0x10000, addr + 0x10000 + 0x20 * (OPENPIC_EXT_IRQ + 2));
993 1045 /* Per CPU registers */
994 1046 DPRINTF("Register OPENPIC dst %08x => %08x\n",
995 1047 addr + 0x20000, addr + 0x20000 + 0x1000 * MAX_CPU);
... ... @@ -1026,7 +1078,7 @@ static void openpic_save(QEMUFile* f, void *opaque)
1026 1078 qemu_put_be32s(f, &opp->spve);
1027 1079 qemu_put_be32s(f, &opp->tifr);
1028 1080  
1029   - for (i = 0; i < MAX_IRQ; i++) {
  1081 + for (i = 0; i < opp->max_irq; i++) {
1030 1082 qemu_put_be32s(f, &opp->src[i].ipvp);
1031 1083 qemu_put_be32s(f, &opp->src[i].ide);
1032 1084 qemu_put_sbe32s(f, &opp->src[i].type);
... ... @@ -1034,15 +1086,16 @@ static void openpic_save(QEMUFile* f, void *opaque)
1034 1086 qemu_put_sbe32s(f, &opp->src[i].pending);
1035 1087 }
1036 1088  
1037   - for (i = 0; i < MAX_IRQ; i++) {
  1089 + qemu_put_sbe32s(f, &opp->nb_cpus);
  1090 +
  1091 + for (i = 0; i < opp->nb_cpus; i++) {
  1092 + qemu_put_be32s(f, &opp->dst[i].tfrr);
1038 1093 qemu_put_be32s(f, &opp->dst[i].pctp);
1039 1094 qemu_put_be32s(f, &opp->dst[i].pcsr);
1040 1095 openpic_save_IRQ_queue(f, &opp->dst[i].raised);
1041 1096 openpic_save_IRQ_queue(f, &opp->dst[i].servicing);
1042 1097 }
1043 1098  
1044   - qemu_put_sbe32s(f, &opp->nb_cpus);
1045   -
1046 1099 for (i = 0; i < MAX_TMR; i++) {
1047 1100 qemu_put_be32s(f, &opp->timers[i].ticc);
1048 1101 qemu_put_be32s(f, &opp->timers[i].tibc);
... ... @@ -1092,7 +1145,7 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)
1092 1145 qemu_get_be32s(f, &opp->spve);
1093 1146 qemu_get_be32s(f, &opp->tifr);
1094 1147  
1095   - for (i = 0; i < MAX_IRQ; i++) {
  1148 + for (i = 0; i < opp->max_irq; i++) {
1096 1149 qemu_get_be32s(f, &opp->src[i].ipvp);
1097 1150 qemu_get_be32s(f, &opp->src[i].ide);
1098 1151 qemu_get_sbe32s(f, &opp->src[i].type);
... ... @@ -1100,15 +1153,16 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)
1100 1153 qemu_get_sbe32s(f, &opp->src[i].pending);
1101 1154 }
1102 1155  
1103   - for (i = 0; i < MAX_IRQ; i++) {
  1156 + qemu_get_sbe32s(f, &opp->nb_cpus);
  1157 +
  1158 + for (i = 0; i < opp->nb_cpus; i++) {
  1159 + qemu_get_be32s(f, &opp->dst[i].tfrr);
1104 1160 qemu_get_be32s(f, &opp->dst[i].pctp);
1105 1161 qemu_get_be32s(f, &opp->dst[i].pcsr);
1106 1162 openpic_load_IRQ_queue(f, &opp->dst[i].raised);
1107 1163 openpic_load_IRQ_queue(f, &opp->dst[i].servicing);
1108 1164 }
1109 1165  
1110   - qemu_get_sbe32s(f, &opp->nb_cpus);
1111   -
1112 1166 for (i = 0; i < MAX_TMR; i++) {
1113 1167 qemu_get_be32s(f, &opp->timers[i].ticc);
1114 1168 qemu_get_be32s(f, &opp->timers[i].tibc);
... ... @@ -1131,6 +1185,11 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)
1131 1185 return pci_device_load(&opp->pci_dev, f);
1132 1186 }
1133 1187  
  1188 +static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src)
  1189 +{
  1190 + qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
  1191 +}
  1192 +
1134 1193 qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
1135 1194 qemu_irq **irqs, qemu_irq irq_out)
1136 1195 {
... ... @@ -1164,33 +1223,499 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
1164 1223  
1165 1224 // isu_base &= 0xFFFC0000;
1166 1225 opp->nb_cpus = nb_cpus;
  1226 + opp->max_irq = OPENPIC_MAX_IRQ;
  1227 + opp->irq_ipi0 = OPENPIC_IRQ_IPI0;
  1228 + opp->irq_tim0 = OPENPIC_IRQ_TIM0;
1167 1229 /* Set IRQ types */
1168   - for (i = 0; i < EXT_IRQ; i++) {
  1230 + for (i = 0; i < OPENPIC_EXT_IRQ; i++) {
1169 1231 opp->src[i].type = IRQ_EXTERNAL;
1170 1232 }
1171   - for (; i < IRQ_TIM0; i++) {
  1233 + for (; i < OPENPIC_IRQ_TIM0; i++) {
1172 1234 opp->src[i].type = IRQ_SPECIAL;
1173 1235 }
1174 1236 #if MAX_IPI > 0
1175   - m = IRQ_IPI0;
  1237 + m = OPENPIC_IRQ_IPI0;
1176 1238 #else
1177   - m = IRQ_DBL0;
  1239 + m = OPENPIC_IRQ_DBL0;
1178 1240 #endif
1179 1241 for (; i < m; i++) {
1180 1242 opp->src[i].type = IRQ_TIMER;
1181 1243 }
1182   - for (; i < MAX_IRQ; i++) {
  1244 + for (; i < OPENPIC_MAX_IRQ; i++) {
1183 1245 opp->src[i].type = IRQ_INTERNAL;
1184 1246 }
1185 1247 for (i = 0; i < nb_cpus; i++)
1186 1248 opp->dst[i].irqs = irqs[i];
1187 1249 opp->irq_out = irq_out;
  1250 + opp->need_swap = 1;
1188 1251  
1189   - register_savevm("openpic", 0, 1, openpic_save, openpic_load, opp);
  1252 + register_savevm("openpic", 0, 2, openpic_save, openpic_load, opp);
1190 1253 qemu_register_reset(openpic_reset, opp);
1191   - openpic_reset(opp);
  1254 +
  1255 + opp->irq_raise = openpic_irq_raise;
  1256 + opp->reset = openpic_reset;
  1257 +
  1258 + opp->reset(opp);
1192 1259 if (pmem_index)
1193 1260 *pmem_index = opp->mem_index;
1194 1261  
1195   - return qemu_allocate_irqs(openpic_set_irq, opp, MAX_IRQ);
  1262 + return qemu_allocate_irqs(openpic_set_irq, opp, opp->max_irq);
  1263 +}
  1264 +
  1265 +static void mpic_irq_raise(openpic_t *mpp, int n_CPU, IRQ_src_t *src)
  1266 +{
  1267 + int n_ci = IDR_CI0 - n_CPU;
  1268 + DPRINTF("%s: cpu:%d irq:%d (testbit idr:%x ci:%d)\n", __func__,
  1269 + n_CPU, n_IRQ, mpp->src[n_IRQ].ide, n_ci);
  1270 + if(test_bit(&src->ide, n_ci)) {
  1271 + qemu_irq_raise(mpp->dst[n_CPU].irqs[OPENPIC_OUTPUT_CINT]);
  1272 + }
  1273 + else {
  1274 + qemu_irq_raise(mpp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
  1275 + }
  1276 +}
  1277 +
  1278 +static void mpic_reset (void *opaque)
  1279 +{
  1280 + openpic_t *mpp = (openpic_t *)opaque;
  1281 + int i;
  1282 +
  1283 + mpp->glbc = 0x80000000;
  1284 + /* Initialise controller registers */
  1285 + mpp->frep = 0x004f0002;
  1286 + mpp->veni = VENI;
  1287 + mpp->pint = 0x00000000;
  1288 + mpp->spve = 0x0000FFFF;
  1289 + /* Initialise IRQ sources */
  1290 + for (i = 0; i < mpp->max_irq; i++) {
  1291 + mpp->src[i].ipvp = 0x80800000;
  1292 + mpp->src[i].ide = 0x00000001;
  1293 + }
  1294 + /* Initialise IRQ destinations */
  1295 + for (i = 0; i < MAX_CPU; i++) {
  1296 + mpp->dst[i].pctp = 0x0000000F;
  1297 + mpp->dst[i].tfrr = 0x00000000;
  1298 + memset(&mpp->dst[i].raised, 0, sizeof(IRQ_queue_t));
  1299 + mpp->dst[i].raised.next = -1;
  1300 + memset(&mpp->dst[i].servicing, 0, sizeof(IRQ_queue_t));
  1301 + mpp->dst[i].servicing.next = -1;
  1302 + }
  1303 + /* Initialise timers */
  1304 + for (i = 0; i < MAX_TMR; i++) {
  1305 + mpp->timers[i].ticc = 0x00000000;
  1306 + mpp->timers[i].tibc = 0x80000000;
  1307 + }
  1308 + /* Go out of RESET state */
  1309 + mpp->glbc = 0x00000000;
  1310 +}
  1311 +
  1312 +static void mpic_timer_write (void *opaque, target_phys_addr_t addr, uint32_t val)
  1313 +{
  1314 + openpic_t *mpp = opaque;
  1315 + int idx, cpu;
  1316 +
  1317 + DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
  1318 + if (addr & 0xF)
  1319 + return;
  1320 + addr &= 0xFFFF;
  1321 + cpu = addr >> 12;
  1322 + idx = (addr >> 6) & 0x3;
  1323 + switch (addr & 0x30) {
  1324 + case 0x00: /* gtccr */
  1325 + break;
  1326 + case 0x10: /* gtbcr */
  1327 + if ((mpp->timers[idx].ticc & 0x80000000) != 0 &&
  1328 + (val & 0x80000000) == 0 &&
  1329 + (mpp->timers[idx].tibc & 0x80000000) != 0)
  1330 + mpp->timers[idx].ticc &= ~0x80000000;
  1331 + mpp->timers[idx].tibc = val;
  1332 + break;
  1333 + case 0x20: /* GTIVPR */
  1334 + write_IRQreg(mpp, MPIC_TMR_IRQ + idx, IRQ_IPVP, val);
  1335 + break;
  1336 + case 0x30: /* GTIDR & TFRR */
  1337 + if ((addr & 0xF0) == 0xF0)
  1338 + mpp->dst[cpu].tfrr = val;
  1339 + else
  1340 + write_IRQreg(mpp, MPIC_TMR_IRQ + idx, IRQ_IDE, val);
  1341 + break;
  1342 + }
  1343 +}
  1344 +
  1345 +static uint32_t mpic_timer_read (void *opaque, target_phys_addr_t addr)
  1346 +{
  1347 + openpic_t *mpp = opaque;
  1348 + uint32_t retval;
  1349 + int idx, cpu;
  1350 +
  1351 + DPRINTF("%s: addr %08x\n", __func__, addr);
  1352 + retval = 0xFFFFFFFF;
  1353 + if (addr & 0xF)
  1354 + return retval;
  1355 + addr &= 0xFFFF;
  1356 + cpu = addr >> 12;
  1357 + idx = (addr >> 6) & 0x3;
  1358 + switch (addr & 0x30) {
  1359 + case 0x00: /* gtccr */
  1360 + retval = mpp->timers[idx].ticc;
  1361 + break;
  1362 + case 0x10: /* gtbcr */
  1363 + retval = mpp->timers[idx].tibc;
  1364 + break;
  1365 + case 0x20: /* TIPV */
  1366 + retval = read_IRQreg(mpp, MPIC_TMR_IRQ + idx, IRQ_IPVP);
  1367 + break;
  1368 + case 0x30: /* TIDR */
  1369 + if ((addr &0xF0) == 0XF0)
  1370 + retval = mpp->dst[cpu].tfrr;
  1371 + else
  1372 + retval = read_IRQreg(mpp, MPIC_TMR_IRQ + idx, IRQ_IDE);
  1373 + break;
  1374 + }
  1375 + DPRINTF("%s: => %08x\n", __func__, retval);
  1376 +
  1377 + return retval;
  1378 +}
  1379 +
  1380 +static void mpic_src_ext_write (void *opaque, target_phys_addr_t addr,
  1381 + uint32_t val)
  1382 +{
  1383 + openpic_t *mpp = opaque;
  1384 + int idx = MPIC_EXT_IRQ;
  1385 +
  1386 + DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
  1387 + if (addr & 0xF)
  1388 + return;
  1389 +
  1390 + addr -= MPIC_EXT_REG_START & (TARGET_PAGE_SIZE - 1);
  1391 + if (addr < MPIC_EXT_REG_SIZE) {
  1392 + idx += (addr & 0xFFF0) >> 5;
  1393 + if (addr & 0x10) {
  1394 + /* EXDE / IFEDE / IEEDE */
  1395 + write_IRQreg(mpp, idx, IRQ_IDE, val);
  1396 + } else {
  1397 + /* EXVP / IFEVP / IEEVP */
  1398 + write_IRQreg(mpp, idx, IRQ_IPVP, val);
  1399 + }
  1400 + }
  1401 +}
  1402 +
  1403 +static uint32_t mpic_src_ext_read (void *opaque, target_phys_addr_t addr)
  1404 +{
  1405 + openpic_t *mpp = opaque;
  1406 + uint32_t retval;
  1407 + int idx = MPIC_EXT_IRQ;
  1408 +
  1409 + DPRINTF("%s: addr %08x\n", __func__, addr);
  1410 + retval = 0xFFFFFFFF;
  1411 + if (addr & 0xF)
  1412 + return retval;
  1413 +
  1414 + addr -= MPIC_EXT_REG_START & (TARGET_PAGE_SIZE - 1);
  1415 + if (addr < MPIC_EXT_REG_SIZE) {
  1416 + idx += (addr & 0xFFF0) >> 5;
  1417 + if (addr & 0x10) {
  1418 + /* EXDE / IFEDE / IEEDE */
  1419 + retval = read_IRQreg(mpp, idx, IRQ_IDE);
  1420 + } else {
  1421 + /* EXVP / IFEVP / IEEVP */
  1422 + retval = read_IRQreg(mpp, idx, IRQ_IPVP);
  1423 + }
  1424 + DPRINTF("%s: => %08x\n", __func__, retval);
  1425 + }
  1426 +
  1427 + return retval;
  1428 +}
  1429 +
  1430 +static void mpic_src_int_write (void *opaque, target_phys_addr_t addr,
  1431 + uint32_t val)
  1432 +{
  1433 + openpic_t *mpp = opaque;
  1434 + int idx = MPIC_INT_IRQ;
  1435 +
  1436 + DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
  1437 + if (addr & 0xF)
  1438 + return;
  1439 +
  1440 + addr -= MPIC_INT_REG_START & (TARGET_PAGE_SIZE - 1);
  1441 + if (addr < MPIC_INT_REG_SIZE) {
  1442 + idx += (addr & 0xFFF0) >> 5;
  1443 + if (addr & 0x10) {
  1444 + /* EXDE / IFEDE / IEEDE */
  1445 + write_IRQreg(mpp, idx, IRQ_IDE, val);
  1446 + } else {
  1447 + /* EXVP / IFEVP / IEEVP */
  1448 + write_IRQreg(mpp, idx, IRQ_IPVP, val);
  1449 + }
  1450 + }
  1451 +}
  1452 +
  1453 +static uint32_t mpic_src_int_read (void *opaque, target_phys_addr_t addr)
  1454 +{
  1455 + openpic_t *mpp = opaque;
  1456 + uint32_t retval;
  1457 + int idx = MPIC_INT_IRQ;
  1458 +
  1459 + DPRINTF("%s: addr %08x\n", __func__, addr);
  1460 + retval = 0xFFFFFFFF;
  1461 + if (addr & 0xF)
  1462 + return retval;
  1463 +
  1464 + addr -= MPIC_INT_REG_START & (TARGET_PAGE_SIZE - 1);
  1465 + if (addr < MPIC_INT_REG_SIZE) {
  1466 + idx += (addr & 0xFFF0) >> 5;
  1467 + if (addr & 0x10) {
  1468 + /* EXDE / IFEDE / IEEDE */
  1469 + retval = read_IRQreg(mpp, idx, IRQ_IDE);
  1470 + } else {
  1471 + /* EXVP / IFEVP / IEEVP */
  1472 + retval = read_IRQreg(mpp, idx, IRQ_IPVP);
  1473 + }
  1474 + DPRINTF("%s: => %08x\n", __func__, retval);
  1475 + }
  1476 +
  1477 + return retval;
  1478 +}
  1479 +
  1480 +static void mpic_src_msg_write (void *opaque, target_phys_addr_t addr,
  1481 + uint32_t val)
  1482 +{
  1483 + openpic_t *mpp = opaque;
  1484 + int idx = MPIC_MSG_IRQ;
  1485 +
  1486 + DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
  1487 + if (addr & 0xF)
  1488 + return;
  1489 +
  1490 + addr -= MPIC_MSG_REG_START & (TARGET_PAGE_SIZE - 1);
  1491 + if (addr < MPIC_MSG_REG_SIZE) {
  1492 + idx += (addr & 0xFFF0) >> 5;
  1493 + if (addr & 0x10) {
  1494 + /* EXDE / IFEDE / IEEDE */
  1495 + write_IRQreg(mpp, idx, IRQ_IDE, val);
  1496 + } else {
  1497 + /* EXVP / IFEVP / IEEVP */
  1498 + write_IRQreg(mpp, idx, IRQ_IPVP, val);
  1499 + }
  1500 + }
  1501 +}
  1502 +
  1503 +static uint32_t mpic_src_msg_read (void *opaque, target_phys_addr_t addr)
  1504 +{
  1505 + openpic_t *mpp = opaque;
  1506 + uint32_t retval;
  1507 + int idx = MPIC_MSG_IRQ;
  1508 +
  1509 + DPRINTF("%s: addr %08x\n", __func__, addr);
  1510 + retval = 0xFFFFFFFF;
  1511 + if (addr & 0xF)
  1512 + return retval;
  1513 +
  1514 + addr -= MPIC_MSG_REG_START & (TARGET_PAGE_SIZE - 1);
  1515 + if (addr < MPIC_MSG_REG_SIZE) {
  1516 + idx += (addr & 0xFFF0) >> 5;
  1517 + if (addr & 0x10) {
  1518 + /* EXDE / IFEDE / IEEDE */
  1519 + retval = read_IRQreg(mpp, idx, IRQ_IDE);
  1520 + } else {
  1521 + /* EXVP / IFEVP / IEEVP */
  1522 + retval = read_IRQreg(mpp, idx, IRQ_IPVP);
  1523 + }
  1524 + DPRINTF("%s: => %08x\n", __func__, retval);
  1525 + }
  1526 +
  1527 + return retval;
  1528 +}
  1529 +
  1530 +static void mpic_src_msi_write (void *opaque, target_phys_addr_t addr,
  1531 + uint32_t val)
  1532 +{
  1533 + openpic_t *mpp = opaque;
  1534 + int idx = MPIC_MSI_IRQ;
  1535 +
  1536 + DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
  1537 + if (addr & 0xF)
  1538 + return;
  1539 +
  1540 + addr -= MPIC_MSI_REG_START & (TARGET_PAGE_SIZE - 1);
  1541 + if (addr < MPIC_MSI_REG_SIZE) {
  1542 + idx += (addr & 0xFFF0) >> 5;
  1543 + if (addr & 0x10) {
  1544 + /* EXDE / IFEDE / IEEDE */
  1545 + write_IRQreg(mpp, idx, IRQ_IDE, val);
  1546 + } else {
  1547 + /* EXVP / IFEVP / IEEVP */
  1548 + write_IRQreg(mpp, idx, IRQ_IPVP, val);
  1549 + }
  1550 + }
  1551 +}
  1552 +static uint32_t mpic_src_msi_read (void *opaque, target_phys_addr_t addr)
  1553 +{
  1554 + openpic_t *mpp = opaque;
  1555 + uint32_t retval;
  1556 + int idx = MPIC_MSI_IRQ;
  1557 +
  1558 + DPRINTF("%s: addr %08x\n", __func__, addr);
  1559 + retval = 0xFFFFFFFF;
  1560 + if (addr & 0xF)
  1561 + return retval;
  1562 +
  1563 + addr -= MPIC_MSI_REG_START & (TARGET_PAGE_SIZE - 1);
  1564 + if (addr < MPIC_MSI_REG_SIZE) {
  1565 + idx += (addr & 0xFFF0) >> 5;
  1566 + if (addr & 0x10) {
  1567 + /* EXDE / IFEDE / IEEDE */
  1568 + retval = read_IRQreg(mpp, idx, IRQ_IDE);
  1569 + } else {
  1570 + /* EXVP / IFEVP / IEEVP */
  1571 + retval = read_IRQreg(mpp, idx, IRQ_IPVP);
  1572 + }
  1573 + DPRINTF("%s: => %08x\n", __func__, retval);
  1574 + }
  1575 +
  1576 + return retval;
  1577 +}
  1578 +
  1579 +static CPUWriteMemoryFunc *mpic_glb_write[] = {
  1580 + &openpic_buggy_write,
  1581 + &openpic_buggy_write,
  1582 + &openpic_gbl_write,
  1583 +};
  1584 +
  1585 +static CPUReadMemoryFunc *mpic_glb_read[] = {
  1586 + &openpic_buggy_read,
  1587 + &openpic_buggy_read,
  1588 + &openpic_gbl_read,
  1589 +};
  1590 +
  1591 +static CPUWriteMemoryFunc *mpic_tmr_write[] = {
  1592 + &openpic_buggy_write,
  1593 + &openpic_buggy_write,
  1594 + &mpic_timer_write,
  1595 +};
  1596 +
  1597 +static CPUReadMemoryFunc *mpic_tmr_read[] = {
  1598 + &openpic_buggy_read,
  1599 + &openpic_buggy_read,
  1600 + &mpic_timer_read,
  1601 +};
  1602 +
  1603 +static CPUWriteMemoryFunc *mpic_cpu_write[] = {
  1604 + &openpic_buggy_write,
  1605 + &openpic_buggy_write,
  1606 + &openpic_cpu_write,
  1607 +};
  1608 +
  1609 +static CPUReadMemoryFunc *mpic_cpu_read[] = {
  1610 + &openpic_buggy_read,
  1611 + &openpic_buggy_read,
  1612 + &openpic_cpu_read,
  1613 +};
  1614 +
  1615 +static CPUWriteMemoryFunc *mpic_ext_write[] = {
  1616 + &openpic_buggy_write,
  1617 + &openpic_buggy_write,
  1618 + &mpic_src_ext_write,
  1619 +};
  1620 +
  1621 +static CPUReadMemoryFunc *mpic_ext_read[] = {
  1622 + &openpic_buggy_read,
  1623 + &openpic_buggy_read,
  1624 + &mpic_src_ext_read,
  1625 +};
  1626 +
  1627 +static CPUWriteMemoryFunc *mpic_int_write[] = {
  1628 + &openpic_buggy_write,
  1629 + &openpic_buggy_write,
  1630 + &mpic_src_int_write,
  1631 +};
  1632 +
  1633 +static CPUReadMemoryFunc *mpic_int_read[] = {
  1634 + &openpic_buggy_read,
  1635 + &openpic_buggy_read,
  1636 + &mpic_src_int_read,
  1637 +};
  1638 +
  1639 +static CPUWriteMemoryFunc *mpic_msg_write[] = {
  1640 + &openpic_buggy_write,
  1641 + &openpic_buggy_write,
  1642 + &mpic_src_msg_write,
  1643 +};
  1644 +
  1645 +static CPUReadMemoryFunc *mpic_msg_read[] = {
  1646 + &openpic_buggy_read,
  1647 + &openpic_buggy_read,
  1648 + &mpic_src_msg_read,
  1649 +};
  1650 +static CPUWriteMemoryFunc *mpic_msi_write[] = {
  1651 + &openpic_buggy_write,
  1652 + &openpic_buggy_write,
  1653 + &mpic_src_msi_write,
  1654 +};
  1655 +
  1656 +static CPUReadMemoryFunc *mpic_msi_read[] = {
  1657 + &openpic_buggy_read,
  1658 + &openpic_buggy_read,
  1659 + &mpic_src_msi_read,
  1660 +};
  1661 +
  1662 +qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
  1663 + qemu_irq **irqs, qemu_irq irq_out)
  1664 +{
  1665 + openpic_t *mpp;
  1666 + int i;
  1667 + struct {
  1668 + CPUReadMemoryFunc **read;
  1669 + CPUWriteMemoryFunc **write;
  1670 + target_phys_addr_t start_addr;
  1671 + ram_addr_t size;
  1672 + } list[] = {
  1673 + {mpic_glb_read, mpic_glb_write, MPIC_GLB_REG_START, MPIC_GLB_REG_SIZE},
  1674 + {mpic_tmr_read, mpic_tmr_write, MPIC_TMR_REG_START, MPIC_TMR_REG_SIZE},
  1675 + {mpic_ext_read, mpic_ext_write, MPIC_EXT_REG_START, MPIC_EXT_REG_SIZE},
  1676 + {mpic_int_read, mpic_int_write, MPIC_INT_REG_START, MPIC_INT_REG_SIZE},
  1677 + {mpic_msg_read, mpic_msg_write, MPIC_MSG_REG_START, MPIC_MSG_REG_SIZE},
  1678 + {mpic_msi_read, mpic_msi_write, MPIC_MSI_REG_START, MPIC_MSI_REG_SIZE},
  1679 + {mpic_cpu_read, mpic_cpu_write, MPIC_CPU_REG_START, MPIC_CPU_REG_SIZE},
  1680 + };
  1681 +
  1682 + /* XXX: for now, only one CPU is supported */
  1683 + if (nb_cpus != 1)
  1684 + return NULL;
  1685 +
  1686 + mpp = qemu_mallocz(sizeof(openpic_t));
  1687 +
  1688 + for (i = 0; i < sizeof(list)/sizeof(list[0]); i++) {
  1689 + int mem_index;
  1690 +
  1691 + mem_index = cpu_register_io_memory(0, list[i].read, list[i].write, mpp);
  1692 + if (mem_index < 0) {
  1693 + goto free;
  1694 + }
  1695 + cpu_register_physical_memory(base + list[i].start_addr,
  1696 + list[i].size, mem_index);
  1697 + }
  1698 +
  1699 + mpp->nb_cpus = nb_cpus;
  1700 + mpp->max_irq = MPIC_MAX_IRQ;
  1701 + mpp->irq_ipi0 = MPIC_IPI_IRQ;
  1702 + mpp->irq_tim0 = MPIC_TMR_IRQ;
  1703 +
  1704 + for (i = 0; i < nb_cpus; i++)
  1705 + mpp->dst[i].irqs = irqs[i];
  1706 + mpp->irq_out = irq_out;
  1707 + mpp->need_swap = 0; /* MPIC has the same endian as target */
  1708 +
  1709 + mpp->irq_raise = mpic_irq_raise;
  1710 + mpp->reset = mpic_reset;
  1711 +
  1712 + register_savevm("mpic", 0, 2, openpic_save, openpic_load, mpp);
  1713 + qemu_register_reset(mpic_reset, mpp);
  1714 + mpp->reset(mpp);
  1715 +
  1716 + return qemu_allocate_irqs(openpic_set_irq, mpp, mpp->max_irq);
  1717 +
  1718 +free:
  1719 + qemu_free(mpp);
  1720 + return NULL;
1196 1721 }
... ...
hw/openpic.h 0 → 100644
  1 +#if !defined(__OPENPIC_H__)
  2 +#define __OPENPIC_H__
  3 +
  4 +/* OpenPIC have 5 outputs per CPU connected and one IRQ out single output */
  5 +enum {
  6 + OPENPIC_OUTPUT_INT = 0, /* IRQ */
  7 + OPENPIC_OUTPUT_CINT, /* critical IRQ */
  8 + OPENPIC_OUTPUT_MCK, /* Machine check event */
  9 + OPENPIC_OUTPUT_DEBUG, /* Inconditional debug event */
  10 + OPENPIC_OUTPUT_RESET, /* Core reset event */
  11 + OPENPIC_OUTPUT_NB,
  12 +};
  13 +
  14 +qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
  15 + qemu_irq **irqs, qemu_irq irq_out);
  16 +qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
  17 + qemu_irq **irqs, qemu_irq irq_out);
  18 +#endif /* __OPENPIC_H__ */
... ...
hw/ppc_mac.h
... ... @@ -112,17 +112,4 @@ void adb_mouse_init(ADBBusState *bus);
112 112  
113 113 extern ADBBusState adb_bus;
114 114  
115   -/* openpic.c */
116   -/* OpenPIC have 5 outputs per CPU connected and one IRQ out single output */
117   -enum {
118   - OPENPIC_OUTPUT_INT = 0, /* IRQ */
119   - OPENPIC_OUTPUT_CINT, /* critical IRQ */
120   - OPENPIC_OUTPUT_MCK, /* Machine check event */
121   - OPENPIC_OUTPUT_DEBUG, /* Inconditional debug event */
122   - OPENPIC_OUTPUT_RESET, /* Core reset event */
123   - OPENPIC_OUTPUT_NB,
124   -};
125   -qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
126   - qemu_irq **irqs, qemu_irq irq_out);
127   -
128 115 #endif /* !defined(__PPC_MAC_H__) */
... ...
hw/ppc_newworld.c
... ... @@ -34,6 +34,7 @@
34 34 #include "boards.h"
35 35 #include "fw_cfg.h"
36 36 #include "escc.h"
  37 +#include "openpic.h"
37 38  
38 39 #define MAX_IDE_BUS 2
39 40 #define VGA_BIOS_SIZE 65536
... ...