Revision b7169916

b/hw/openpic.c
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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
}
b/hw/openpic.h
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__ */
b/hw/ppc_mac.h
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__) */
b/hw/ppc_newworld.c
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

Also available in: Unified diff