Revision 825463b3 hw/openpic.c

b/hw/openpic.c
53 53
#define MAX_IPI     4
54 54
#define MAX_IRQ     (MAX_SRC + MAX_IPI + MAX_TMR)
55 55
#define VID         0x03 /* MPIC version ID */
56
#define VENI        0x00000000 /* Vendor ID */
57 56

  
58 57
enum {
59 58
    IRQ_IPVP = 0,
......
125 124
#define FSL_BRR1_IPMJ (0x00 << 8) /* 8 bit IP major number */
126 125
#define FSL_BRR1_IPMN 0x00 /* 8 bit IP minor number */
127 126

  
127
#define FREP_NIRQ_SHIFT   16
128
#define FREP_NCPU_SHIFT    8
129
#define FREP_VID_SHIFT     0
130

  
131
#define VID_REVISION_1_2   2
132

  
133
#define VENI_GENERIC      0x00000000 /* Generic Vendor ID */
134

  
128 135
enum mpic_ide_bits {
129 136
    IDR_EP     = 31,
130 137
    IDR_CI0     = 30,
......
208 215

  
209 216
    /* Behavior control */
210 217
    uint32_t flags;
218
    uint32_t nb_irqs;
219
    uint32_t vid;
220
    uint32_t veni; /* Vendor identification register */
221
    uint32_t spve_mask;
222
    uint32_t tifr_reset;
223
    uint32_t ipvp_reset;
224
    uint32_t ide_reset;
211 225

  
212 226
    /* Sub-regions */
213 227
    MemoryRegion sub_io_mem[7];
......
215 229
    /* Global registers */
216 230
    uint32_t frep; /* Feature reporting register */
217 231
    uint32_t glbc; /* Global configuration register  */
218
    uint32_t micr; /* MPIC interrupt configuration register */
219
    uint32_t veni; /* Vendor identification register */
220 232
    uint32_t pint; /* Processor initialization register */
221 233
    uint32_t spve; /* Spurious vector register */
222 234
    uint32_t tifr; /* Timer frequency reporting register */
......
235 247
    int max_irq;
236 248
    int irq_ipi0;
237 249
    int irq_tim0;
238
    void (*reset) (void *);
239 250
} openpic_t;
240 251

  
241 252
static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src);
......
412 423

  
413 424
    opp->glbc = 0x80000000;
414 425
    /* Initialise controller registers */
415
    opp->frep = ((OPENPIC_EXT_IRQ - 1) << 16) | ((MAX_CPU - 1) << 8) | VID;
416
    opp->veni = VENI;
426
    opp->frep = ((opp->nb_irqs -1) << FREP_NIRQ_SHIFT) |
427
                ((opp->nb_cpus -1) << FREP_NCPU_SHIFT) |
428
                (opp->vid << FREP_VID_SHIFT);
429

  
417 430
    opp->pint = 0x00000000;
418
    opp->spve = 0x000000FF;
419
    opp->tifr = 0x003F7A00;
420
    /* ? */
421
    opp->micr = 0x00000000;
431
    opp->spve = -1 & opp->spve_mask;
432
    opp->tifr = opp->tifr_reset;
422 433
    /* Initialise IRQ sources */
423 434
    for (i = 0; i < opp->max_irq; i++) {
424
        opp->src[i].ipvp = 0xA0000000;
425
        opp->src[i].ide  = 0x00000000;
435
        opp->src[i].ipvp = opp->ipvp_reset;
436
        opp->src[i].ide  = opp->ide_reset;
426 437
    }
427 438
    /* Initialise IRQ destinations */
428 439
    for (i = 0; i < MAX_CPU; i++) {
......
499 510
    case 0x1000: /* FREP */
500 511
        break;
501 512
    case 0x1020: /* GLBC */
502
        if (val & 0x80000000 && opp->reset)
503
            opp->reset(opp);
504
        opp->glbc = val & ~0x80000000;
513
        if (val & 0x80000000) {
514
            openpic_reset(opp);
515
        }
505 516
        break;
506 517
    case 0x1080: /* VENI */
507 518
        break;
......
530 541
        }
531 542
        break;
532 543
    case 0x10E0: /* SPVE */
533
        opp->spve = val & 0x000000FF;
544
        opp->spve = val & opp->spve_mask;
534 545
        break;
535 546
    default:
536 547
        break;
......
912 923
    openpic_t *opp = (openpic_t *)opaque;
913 924
    unsigned int i;
914 925

  
915
    qemu_put_be32s(f, &opp->frep);
916 926
    qemu_put_be32s(f, &opp->glbc);
917
    qemu_put_be32s(f, &opp->micr);
918 927
    qemu_put_be32s(f, &opp->veni);
919 928
    qemu_put_be32s(f, &opp->pint);
920 929
    qemu_put_be32s(f, &opp->spve);
......
964 973
    if (version_id != 1)
965 974
        return -EINVAL;
966 975

  
967
    qemu_get_be32s(f, &opp->frep);
968 976
    qemu_get_be32s(f, &opp->glbc);
969
    qemu_get_be32s(f, &opp->micr);
970 977
    qemu_get_be32s(f, &opp->veni);
971 978
    qemu_get_be32s(f, &opp->pint);
972 979
    qemu_get_be32s(f, &opp->spve);
......
1043 1050

  
1044 1051
    //    isu_base &= 0xFFFC0000;
1045 1052
    opp->nb_cpus = nb_cpus;
1053
    opp->nb_irqs = OPENPIC_EXT_IRQ;
1054
    opp->vid = VID;
1055
    opp->veni = VENI_GENERIC;
1056
    opp->spve_mask = 0xFF;
1057
    opp->tifr_reset = 0x003F7A00;
1046 1058
    opp->max_irq = OPENPIC_MAX_IRQ;
1047 1059
    opp->irq_ipi0 = OPENPIC_IRQ_IPI0;
1048 1060
    opp->irq_tim0 = OPENPIC_IRQ_TIM0;
......
1068 1080
                    openpic_save, openpic_load, opp);
1069 1081
    qemu_register_reset(openpic_reset, opp);
1070 1082

  
1071
    opp->reset = openpic_reset;
1072

  
1073 1083
    if (pmem)
1074 1084
        *pmem = &opp->mem;
1075 1085

  
1076 1086
    return qemu_allocate_irqs(openpic_set_irq, opp, opp->max_irq);
1077 1087
}
1078 1088

  
1079
static void mpic_reset (void *opaque)
1080
{
1081
    openpic_t *mpp = (openpic_t *)opaque;
1082
    int i;
1083

  
1084
    mpp->glbc = 0x80000000;
1085
    /* Initialise controller registers */
1086
    mpp->frep = 0x004f0002 | ((mpp->nb_cpus - 1) << 8);
1087
    mpp->veni = VENI;
1088
    mpp->pint = 0x00000000;
1089
    mpp->spve = 0x0000FFFF;
1090
    /* Initialise IRQ sources */
1091
    for (i = 0; i < mpp->max_irq; i++) {
1092
        mpp->src[i].ipvp = 0x80800000;
1093
        mpp->src[i].ide  = 0x00000001;
1094
    }
1095
    /* Set IDE for IPIs to 0 so we don't get spurious interrupts */
1096
    for (i = mpp->irq_ipi0; i < (mpp->irq_ipi0 + MAX_IPI); i++) {
1097
        mpp->src[i].ide = 0;
1098
    }
1099
    /* Initialise IRQ destinations */
1100
    for (i = 0; i < MAX_CPU; i++) {
1101
        mpp->dst[i].pctp      = 0x0000000F;
1102
        memset(&mpp->dst[i].raised, 0, sizeof(IRQ_queue_t));
1103
        mpp->dst[i].raised.next = -1;
1104
        memset(&mpp->dst[i].servicing, 0, sizeof(IRQ_queue_t));
1105
        mpp->dst[i].servicing.next = -1;
1106
    }
1107
    /* Initialise timers */
1108
    for (i = 0; i < MAX_TMR; i++) {
1109
        mpp->timers[i].ticc = 0x00000000;
1110
        mpp->timers[i].tibc = 0x80000000;
1111
    }
1112
    /* Go out of RESET state */
1113
    mpp->glbc = 0x00000000;
1114
}
1115

  
1116 1089
static const MemoryRegionOps mpic_glb_ops = {
1117 1090
    .write = openpic_gbl_write,
1118 1091
    .read  = openpic_gbl_read,
......
1185 1158
    }
1186 1159

  
1187 1160
    mpp->nb_cpus = nb_cpus;
1161
    /* 12 external sources, 48 internal sources , 4 timer sources,
1162
       4 IPI sources, 4 messaging sources, and 8 Shared MSI sources */
1163
    mpp->nb_irqs = 80;
1164
    mpp->vid = VID_REVISION_1_2;
1165
    mpp->veni = VENI_GENERIC;
1166
    mpp->spve_mask = 0xFFFF;
1167
    mpp->tifr_reset = 0x00000000;
1168
    mpp->ipvp_reset = 0x80000000;
1169
    mpp->ide_reset = 0x00000001;
1188 1170
    mpp->max_irq = MPIC_MAX_IRQ;
1189 1171
    mpp->irq_ipi0 = MPIC_IPI_IRQ;
1190 1172
    mpp->irq_tim0 = MPIC_TMR_IRQ;
......
1195 1177

  
1196 1178
    /* Enable critical interrupt support */
1197 1179
    mpp->flags |= OPENPIC_FLAG_IDE_CRIT;
1198
    mpp->reset = mpic_reset;
1199 1180

  
1200 1181
    register_savevm(NULL, "mpic", 0, 2, openpic_save, openpic_load, mpp);
1201
    qemu_register_reset(mpic_reset, mpp);
1182
    qemu_register_reset(openpic_reset, mpp);
1202 1183

  
1203 1184
    return qemu_allocate_irqs(openpic_set_irq, mpp, mpp->max_irq);
1204 1185
}

Also available in: Unified diff