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,6 +35,7 @@
35 #include "hw.h" 35 #include "hw.h"
36 #include "ppc_mac.h" 36 #include "ppc_mac.h"
37 #include "pci.h" 37 #include "pci.h"
  38 +#include "openpic.h"
38 39
39 //#define DEBUG_OPENPIC 40 //#define DEBUG_OPENPIC
40 41
@@ -60,14 +61,10 @@ @@ -60,14 +61,10 @@
60 61
61 #define VID (0x00000000) 62 #define VID (0x00000000)
62 63
63 -#define OPENPIC_LITTLE_ENDIAN 1  
64 -#define OPENPIC_BIG_ENDIAN 0  
65 -  
66 #elif defined(USE_MPCxxx) 64 #elif defined(USE_MPCxxx)
67 65
68 #define MAX_CPU 2 66 #define MAX_CPU 2
69 -#define MAX_IRQ 64  
70 -#define EXT_IRQ 48 67 +#define MAX_IRQ 128
71 #define MAX_DBL 0 68 #define MAX_DBL 0
72 #define MAX_MBX 0 69 #define MAX_MBX 0
73 #define MAX_TMR 4 70 #define MAX_TMR 4
@@ -81,28 +78,68 @@ enum { @@ -81,28 +78,68 @@ enum {
81 IRQ_IDE, 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 #else 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 #endif 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 /* Interrupt definitions */ 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 #else 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 #endif 143 #endif
107 144
108 #define BF_WIDTH(_bits_) \ 145 #define BF_WIDTH(_bits_) \
@@ -157,6 +194,7 @@ enum IPVP_bits { @@ -157,6 +194,7 @@ enum IPVP_bits {
157 #define IPVP_VECTOR(_ipvpr_) ((_ipvpr_) & IPVP_VECTOR_MASK) 194 #define IPVP_VECTOR(_ipvpr_) ((_ipvpr_) & IPVP_VECTOR_MASK)
158 195
159 typedef struct IRQ_dst_t { 196 typedef struct IRQ_dst_t {
  197 + uint32_t tfrr;
160 uint32_t pctp; /* CPU current task priority */ 198 uint32_t pctp; /* CPU current task priority */
161 uint32_t pcsr; /* CPU sensitivity register */ 199 uint32_t pcsr; /* CPU sensitivity register */
162 IRQ_queue_t raised; 200 IRQ_queue_t raised;
@@ -200,8 +238,22 @@ typedef struct openpic_t { @@ -200,8 +238,22 @@ typedef struct openpic_t {
200 #endif 238 #endif
201 /* IRQ out is used when in bypass mode (not implemented) */ 239 /* IRQ out is used when in bypass mode (not implemented) */
202 qemu_irq irq_out; 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 } openpic_t; 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 static inline void IRQ_setbit (IRQ_queue_t *q, int n_IRQ) 257 static inline void IRQ_setbit (IRQ_queue_t *q, int n_IRQ)
206 { 258 {
207 set_bit(q->queue, n_IRQ); 259 set_bit(q->queue, n_IRQ);
@@ -224,7 +276,7 @@ static void IRQ_check (openpic_t *opp, IRQ_queue_t *q) @@ -224,7 +276,7 @@ static void IRQ_check (openpic_t *opp, IRQ_queue_t *q)
224 276
225 next = -1; 277 next = -1;
226 priority = -1; 278 priority = -1;
227 - for (i = 0; i < MAX_IRQ; i++) { 279 + for (i = 0; i < opp->max_irq; i++) {
228 if (IRQ_testbit(q, i)) { 280 if (IRQ_testbit(q, i)) {
229 DPRINTF("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n", 281 DPRINTF("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n",
230 i, IPVP_PRIORITY(opp->src[i].ipvp), priority); 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,7 +338,7 @@ static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ)
286 return; 338 return;
287 } 339 }
288 DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", n_CPU, n_IRQ); 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 /* update pic state because registers for n_IRQ have changed value */ 344 /* update pic state because registers for n_IRQ have changed value */
@@ -374,7 +426,7 @@ static void openpic_reset (void *opaque) @@ -374,7 +426,7 @@ static void openpic_reset (void *opaque)
374 426
375 opp->glbc = 0x80000000; 427 opp->glbc = 0x80000000;
376 /* Initialise controller registers */ 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 opp->veni = VENI; 430 opp->veni = VENI;
379 opp->pint = 0x00000000; 431 opp->pint = 0x00000000;
380 opp->spve = 0x000000FF; 432 opp->spve = 0x000000FF;
@@ -382,7 +434,7 @@ static void openpic_reset (void *opaque) @@ -382,7 +434,7 @@ static void openpic_reset (void *opaque)
382 /* ? */ 434 /* ? */
383 opp->micr = 0x00000000; 435 opp->micr = 0x00000000;
384 /* Initialise IRQ sources */ 436 /* Initialise IRQ sources */
385 - for (i = 0; i < MAX_IRQ; i++) { 437 + for (i = 0; i < opp->max_irq; i++) {
386 opp->src[i].ipvp = 0xA0000000; 438 opp->src[i].ipvp = 0xA0000000;
387 opp->src[i].ide = 0x00000000; 439 opp->src[i].ide = 0x00000000;
388 } 440 }
@@ -535,7 +587,7 @@ static void write_mailbox_register (openpic_t *opp, int n_mbx, @@ -535,7 +587,7 @@ static void write_mailbox_register (openpic_t *opp, int n_mbx,
535 #endif 587 #endif
536 #endif /* 0 : Code provision for Intel model */ 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 openpic_t *opp = opaque; 592 openpic_t *opp = opaque;
541 IRQ_dst_t *dst; 593 IRQ_dst_t *dst;
@@ -544,16 +596,16 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val) @@ -544,16 +596,16 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
544 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val); 596 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
545 if (addr & 0xF) 597 if (addr & 0xF)
546 return; 598 return;
547 -#if defined OPENPIC_SWAP  
548 - val = bswap32(val); 599 +#if defined TARGET_WORDS_BIGENDIAN
  600 + val = openpic_swap32(opp, val);
549 #endif 601 #endif
550 addr &= 0xFF; 602 addr &= 0xFF;
551 switch (addr) { 603 switch (addr) {
552 case 0x00: /* FREP */ 604 case 0x00: /* FREP */
553 break; 605 break;
554 case 0x20: /* GLBC */ 606 case 0x20: /* GLBC */
555 - if (val & 0x80000000)  
556 - openpic_reset(opp); 607 + if (val & 0x80000000 && opp->reset)
  608 + opp->reset(opp);
557 opp->glbc = val & ~0x80000000; 609 opp->glbc = val & ~0x80000000;
558 break; 610 break;
559 case 0x80: /* VENI */ 611 case 0x80: /* VENI */
@@ -580,7 +632,7 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val) @@ -580,7 +632,7 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
580 { 632 {
581 int idx; 633 int idx;
582 idx = (addr - 0xA0) >> 4; 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 break; 637 break;
586 #endif 638 #endif
@@ -595,7 +647,7 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val) @@ -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 openpic_t *opp = opaque; 652 openpic_t *opp = opaque;
601 uint32_t retval; 653 uint32_t retval;
@@ -626,7 +678,7 @@ static uint32_t openpic_gbl_read (void *opaque, uint32_t addr) @@ -626,7 +678,7 @@ static uint32_t openpic_gbl_read (void *opaque, uint32_t addr)
626 { 678 {
627 int idx; 679 int idx;
628 idx = (addr - 0xA0) >> 4; 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 break; 683 break;
632 #endif 684 #endif
@@ -640,8 +692,8 @@ static uint32_t openpic_gbl_read (void *opaque, uint32_t addr) @@ -640,8 +692,8 @@ static uint32_t openpic_gbl_read (void *opaque, uint32_t addr)
640 break; 692 break;
641 } 693 }
642 DPRINTF("%s: => %08x\n", __func__, retval); 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 #endif 697 #endif
646 698
647 return retval; 699 return retval;
@@ -655,8 +707,8 @@ static void openpic_timer_write (void *opaque, uint32_t addr, uint32_t val) @@ -655,8 +707,8 @@ static void openpic_timer_write (void *opaque, uint32_t addr, uint32_t val)
655 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val); 707 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
656 if (addr & 0xF) 708 if (addr & 0xF)
657 return; 709 return;
658 -#if defined OPENPIC_SWAP  
659 - val = bswap32(val); 710 +#if defined TARGET_WORDS_BIGENDIAN
  711 + val = openpic_swap32(opp, val);
660 #endif 712 #endif
661 addr -= 0x1100; 713 addr -= 0x1100;
662 addr &= 0xFFFF; 714 addr &= 0xFFFF;
@@ -673,10 +725,10 @@ static void openpic_timer_write (void *opaque, uint32_t addr, uint32_t val) @@ -673,10 +725,10 @@ static void openpic_timer_write (void *opaque, uint32_t addr, uint32_t val)
673 opp->timers[idx].tibc = val; 725 opp->timers[idx].tibc = val;
674 break; 726 break;
675 case 0x20: /* TIVP */ 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 break; 729 break;
678 case 0x30: /* TIDE */ 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 break; 732 break;
681 } 733 }
682 } 734 }
@@ -703,15 +755,15 @@ static uint32_t openpic_timer_read (void *opaque, uint32_t addr) @@ -703,15 +755,15 @@ static uint32_t openpic_timer_read (void *opaque, uint32_t addr)
703 retval = opp->timers[idx].tibc; 755 retval = opp->timers[idx].tibc;
704 break; 756 break;
705 case 0x20: /* TIPV */ 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 break; 759 break;
708 case 0x30: /* TIDE */ 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 break; 762 break;
711 } 763 }
712 DPRINTF("%s: => %08x\n", __func__, retval); 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 #endif 767 #endif
716 768
717 return retval; 769 return retval;
@@ -725,8 +777,8 @@ static void openpic_src_write (void *opaque, uint32_t addr, uint32_t val) @@ -725,8 +777,8 @@ static void openpic_src_write (void *opaque, uint32_t addr, uint32_t val)
725 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val); 777 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
726 if (addr & 0xF) 778 if (addr & 0xF)
727 return; 779 return;
728 -#if defined OPENPIC_SWAP  
729 - val = tswap32(val); 780 +#if defined TARGET_WORDS_BIGENDIAN
  781 + val = openpic_swap32(opp, val);
730 #endif 782 #endif
731 addr = addr & 0xFFF0; 783 addr = addr & 0xFFF0;
732 idx = addr >> 5; 784 idx = addr >> 5;
@@ -759,14 +811,14 @@ static uint32_t openpic_src_read (void *opaque, uint32_t addr) @@ -759,14 +811,14 @@ static uint32_t openpic_src_read (void *opaque, uint32_t addr)
759 retval = read_IRQreg(opp, idx, IRQ_IPVP); 811 retval = read_IRQreg(opp, idx, IRQ_IPVP);
760 } 812 }
761 DPRINTF("%s: => %08x\n", __func__, retval); 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 #endif 816 #endif
765 817
766 return retval; 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 openpic_t *opp = opaque; 823 openpic_t *opp = opaque;
772 IRQ_src_t *src; 824 IRQ_src_t *src;
@@ -776,8 +828,8 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val) @@ -776,8 +828,8 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
776 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val); 828 DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
777 if (addr & 0xF) 829 if (addr & 0xF)
778 return; 830 return;
779 -#if defined OPENPIC_SWAP  
780 - val = bswap32(val); 831 +#if defined TARGET_WORDS_BIGENDIAN
  832 + val = openpic_swap32(opp, val);
781 #endif 833 #endif
782 addr &= 0x1FFF0; 834 addr &= 0x1FFF0;
783 idx = addr / 0x1000; 835 idx = addr / 0x1000;
@@ -790,9 +842,9 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val) @@ -790,9 +842,9 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
790 case 0x60: 842 case 0x60:
791 case 0x70: 843 case 0x70:
792 idx = (addr - 0x40) >> 4; 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 break; 848 break;
797 #endif 849 #endif
798 case 0x80: /* PCTP */ 850 case 0x80: /* PCTP */
@@ -819,7 +871,7 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val) @@ -819,7 +871,7 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
819 IPVP_PRIORITY(src->ipvp) > dst->servicing.priority)) { 871 IPVP_PRIORITY(src->ipvp) > dst->servicing.priority)) {
820 DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", 872 DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n",
821 idx, n_IRQ); 873 idx, n_IRQ);
822 - qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]); 874 + opp->irq_raise(opp, idx, src);
823 } 875 }
824 break; 876 break;
825 default: 877 default:
@@ -827,7 +879,7 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val) @@ -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 openpic_t *opp = opaque; 884 openpic_t *opp = opaque;
833 IRQ_src_t *src; 885 IRQ_src_t *src;
@@ -889,15 +941,15 @@ static uint32_t openpic_cpu_read (void *opaque, uint32_t addr) @@ -889,15 +941,15 @@ static uint32_t openpic_cpu_read (void *opaque, uint32_t addr)
889 case 0x40: /* IDE */ 941 case 0x40: /* IDE */
890 case 0x50: 942 case 0x50:
891 idx = (addr - 0x40) >> 4; 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 break; 945 break;
894 #endif 946 #endif
895 default: 947 default:
896 break; 948 break;
897 } 949 }
898 DPRINTF("%s: => %08x\n", __func__, retval); 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 #endif 953 #endif
902 954
903 return retval; 955 return retval;
@@ -989,7 +1041,7 @@ static void openpic_map(PCIDevice *pci_dev, int region_num, @@ -989,7 +1041,7 @@ static void openpic_map(PCIDevice *pci_dev, int region_num,
989 addr + 0x1100, addr + 0x1100 + 0x40 * MAX_TMR); 1041 addr + 0x1100, addr + 0x1100 + 0x40 * MAX_TMR);
990 /* Interrupt source registers */ 1042 /* Interrupt source registers */
991 DPRINTF("Register OPENPIC src %08x => %08x\n", 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 /* Per CPU registers */ 1045 /* Per CPU registers */
994 DPRINTF("Register OPENPIC dst %08x => %08x\n", 1046 DPRINTF("Register OPENPIC dst %08x => %08x\n",
995 addr + 0x20000, addr + 0x20000 + 0x1000 * MAX_CPU); 1047 addr + 0x20000, addr + 0x20000 + 0x1000 * MAX_CPU);
@@ -1026,7 +1078,7 @@ static void openpic_save(QEMUFile* f, void *opaque) @@ -1026,7 +1078,7 @@ static void openpic_save(QEMUFile* f, void *opaque)
1026 qemu_put_be32s(f, &opp->spve); 1078 qemu_put_be32s(f, &opp->spve);
1027 qemu_put_be32s(f, &opp->tifr); 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 qemu_put_be32s(f, &opp->src[i].ipvp); 1082 qemu_put_be32s(f, &opp->src[i].ipvp);
1031 qemu_put_be32s(f, &opp->src[i].ide); 1083 qemu_put_be32s(f, &opp->src[i].ide);
1032 qemu_put_sbe32s(f, &opp->src[i].type); 1084 qemu_put_sbe32s(f, &opp->src[i].type);
@@ -1034,15 +1086,16 @@ static void openpic_save(QEMUFile* f, void *opaque) @@ -1034,15 +1086,16 @@ static void openpic_save(QEMUFile* f, void *opaque)
1034 qemu_put_sbe32s(f, &opp->src[i].pending); 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 qemu_put_be32s(f, &opp->dst[i].pctp); 1093 qemu_put_be32s(f, &opp->dst[i].pctp);
1039 qemu_put_be32s(f, &opp->dst[i].pcsr); 1094 qemu_put_be32s(f, &opp->dst[i].pcsr);
1040 openpic_save_IRQ_queue(f, &opp->dst[i].raised); 1095 openpic_save_IRQ_queue(f, &opp->dst[i].raised);
1041 openpic_save_IRQ_queue(f, &opp->dst[i].servicing); 1096 openpic_save_IRQ_queue(f, &opp->dst[i].servicing);
1042 } 1097 }
1043 1098
1044 - qemu_put_sbe32s(f, &opp->nb_cpus);  
1045 -  
1046 for (i = 0; i < MAX_TMR; i++) { 1099 for (i = 0; i < MAX_TMR; i++) {
1047 qemu_put_be32s(f, &opp->timers[i].ticc); 1100 qemu_put_be32s(f, &opp->timers[i].ticc);
1048 qemu_put_be32s(f, &opp->timers[i].tibc); 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,7 +1145,7 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)
1092 qemu_get_be32s(f, &opp->spve); 1145 qemu_get_be32s(f, &opp->spve);
1093 qemu_get_be32s(f, &opp->tifr); 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 qemu_get_be32s(f, &opp->src[i].ipvp); 1149 qemu_get_be32s(f, &opp->src[i].ipvp);
1097 qemu_get_be32s(f, &opp->src[i].ide); 1150 qemu_get_be32s(f, &opp->src[i].ide);
1098 qemu_get_sbe32s(f, &opp->src[i].type); 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,15 +1153,16 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)
1100 qemu_get_sbe32s(f, &opp->src[i].pending); 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 qemu_get_be32s(f, &opp->dst[i].pctp); 1160 qemu_get_be32s(f, &opp->dst[i].pctp);
1105 qemu_get_be32s(f, &opp->dst[i].pcsr); 1161 qemu_get_be32s(f, &opp->dst[i].pcsr);
1106 openpic_load_IRQ_queue(f, &opp->dst[i].raised); 1162 openpic_load_IRQ_queue(f, &opp->dst[i].raised);
1107 openpic_load_IRQ_queue(f, &opp->dst[i].servicing); 1163 openpic_load_IRQ_queue(f, &opp->dst[i].servicing);
1108 } 1164 }
1109 1165
1110 - qemu_get_sbe32s(f, &opp->nb_cpus);  
1111 -  
1112 for (i = 0; i < MAX_TMR; i++) { 1166 for (i = 0; i < MAX_TMR; i++) {
1113 qemu_get_be32s(f, &opp->timers[i].ticc); 1167 qemu_get_be32s(f, &opp->timers[i].ticc);
1114 qemu_get_be32s(f, &opp->timers[i].tibc); 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,6 +1185,11 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)
1131 return pci_device_load(&opp->pci_dev, f); 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 qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus, 1193 qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
1135 qemu_irq **irqs, qemu_irq irq_out) 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,33 +1223,499 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
1164 1223
1165 // isu_base &= 0xFFFC0000; 1224 // isu_base &= 0xFFFC0000;
1166 opp->nb_cpus = nb_cpus; 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 /* Set IRQ types */ 1229 /* Set IRQ types */
1168 - for (i = 0; i < EXT_IRQ; i++) { 1230 + for (i = 0; i < OPENPIC_EXT_IRQ; i++) {
1169 opp->src[i].type = IRQ_EXTERNAL; 1231 opp->src[i].type = IRQ_EXTERNAL;
1170 } 1232 }
1171 - for (; i < IRQ_TIM0; i++) { 1233 + for (; i < OPENPIC_IRQ_TIM0; i++) {
1172 opp->src[i].type = IRQ_SPECIAL; 1234 opp->src[i].type = IRQ_SPECIAL;
1173 } 1235 }
1174 #if MAX_IPI > 0 1236 #if MAX_IPI > 0
1175 - m = IRQ_IPI0; 1237 + m = OPENPIC_IRQ_IPI0;
1176 #else 1238 #else
1177 - m = IRQ_DBL0; 1239 + m = OPENPIC_IRQ_DBL0;
1178 #endif 1240 #endif
1179 for (; i < m; i++) { 1241 for (; i < m; i++) {
1180 opp->src[i].type = IRQ_TIMER; 1242 opp->src[i].type = IRQ_TIMER;
1181 } 1243 }
1182 - for (; i < MAX_IRQ; i++) { 1244 + for (; i < OPENPIC_MAX_IRQ; i++) {
1183 opp->src[i].type = IRQ_INTERNAL; 1245 opp->src[i].type = IRQ_INTERNAL;
1184 } 1246 }
1185 for (i = 0; i < nb_cpus; i++) 1247 for (i = 0; i < nb_cpus; i++)
1186 opp->dst[i].irqs = irqs[i]; 1248 opp->dst[i].irqs = irqs[i];
1187 opp->irq_out = irq_out; 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 qemu_register_reset(openpic_reset, opp); 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 if (pmem_index) 1259 if (pmem_index)
1193 *pmem_index = opp->mem_index; 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,17 +112,4 @@ void adb_mouse_init(ADBBusState *bus);
112 112
113 extern ADBBusState adb_bus; 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 #endif /* !defined(__PPC_MAC_H__) */ 115 #endif /* !defined(__PPC_MAC_H__) */
hw/ppc_newworld.c
@@ -34,6 +34,7 @@ @@ -34,6 +34,7 @@
34 #include "boards.h" 34 #include "boards.h"
35 #include "fw_cfg.h" 35 #include "fw_cfg.h"
36 #include "escc.h" 36 #include "escc.h"
  37 +#include "openpic.h"
37 38
38 #define MAX_IDE_BUS 2 39 #define MAX_IDE_BUS 2
39 #define VGA_BIOS_SIZE 65536 40 #define VGA_BIOS_SIZE 65536