Statistics
| Branch: | Revision:

root / hw / openpic.c @ 65b9d0d5

History | View | Annotate | Download (38.2 kB)

1
/*
2
 * OpenPIC emulation
3
 *
4
 * Copyright (c) 2004 Jocelyn Mayer
5
 *               2011 Alexander Graf
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 */
25
/*
26
 *
27
 * Based on OpenPic implementations:
28
 * - Intel GW80314 I/O companion chip developer's manual
29
 * - Motorola MPC8245 & MPC8540 user manuals.
30
 * - Motorola MCP750 (aka Raven) programmer manual.
31
 * - Motorola Harrier programmer manuel
32
 *
33
 * Serial interrupts, as implemented in Raven chipset are not supported yet.
34
 *
35
 */
36
#include "hw.h"
37
#include "ppc_mac.h"
38
#include "pci/pci.h"
39
#include "openpic.h"
40
#include "sysbus.h"
41
#include "pci/msi.h"
42
#include "qemu/bitops.h"
43

    
44
//#define DEBUG_OPENPIC
45

    
46
#ifdef DEBUG_OPENPIC
47
static const int debug_openpic = 1;
48
#else
49
static const int debug_openpic = 0;
50
#endif
51

    
52
#define DPRINTF(fmt, ...) do { \
53
        if (debug_openpic) { \
54
            printf(fmt , ## __VA_ARGS__); \
55
        } \
56
    } while (0)
57

    
58
#define MAX_CPU     15
59
#define MAX_SRC     256
60
#define MAX_TMR     4
61
#define MAX_IPI     4
62
#define MAX_MSI     8
63
#define MAX_IRQ     (MAX_SRC + MAX_IPI + MAX_TMR)
64
#define VID         0x03 /* MPIC version ID */
65

    
66
/* OpenPIC capability flags */
67
#define OPENPIC_FLAG_IDR_CRIT     (1 << 0)
68

    
69
/* OpenPIC address map */
70
#define OPENPIC_GLB_REG_START        0x0
71
#define OPENPIC_GLB_REG_SIZE         0x10F0
72
#define OPENPIC_TMR_REG_START        0x10F0
73
#define OPENPIC_TMR_REG_SIZE         0x220
74
#define OPENPIC_MSI_REG_START        0x1600
75
#define OPENPIC_MSI_REG_SIZE         0x200
76
#define OPENPIC_SRC_REG_START        0x10000
77
#define OPENPIC_SRC_REG_SIZE         (MAX_SRC * 0x20)
78
#define OPENPIC_CPU_REG_START        0x20000
79
#define OPENPIC_CPU_REG_SIZE         0x100 + ((MAX_CPU - 1) * 0x1000)
80

    
81
/* Raven */
82
#define RAVEN_MAX_CPU      2
83
#define RAVEN_MAX_EXT     48
84
#define RAVEN_MAX_IRQ     64
85
#define RAVEN_MAX_TMR      MAX_TMR
86
#define RAVEN_MAX_IPI      MAX_IPI
87

    
88
/* Interrupt definitions */
89
#define RAVEN_FE_IRQ     (RAVEN_MAX_EXT)     /* Internal functional IRQ */
90
#define RAVEN_ERR_IRQ    (RAVEN_MAX_EXT + 1) /* Error IRQ */
91
#define RAVEN_TMR_IRQ    (RAVEN_MAX_EXT + 2) /* First timer IRQ */
92
#define RAVEN_IPI_IRQ    (RAVEN_TMR_IRQ + RAVEN_MAX_TMR) /* First IPI IRQ */
93
/* First doorbell IRQ */
94
#define RAVEN_DBL_IRQ    (RAVEN_IPI_IRQ + (RAVEN_MAX_CPU * RAVEN_MAX_IPI))
95

    
96
/* FSL_MPIC_20 */
97
#define FSL_MPIC_20_MAX_CPU      1
98
#define FSL_MPIC_20_MAX_EXT     12
99
#define FSL_MPIC_20_MAX_INT     64
100
#define FSL_MPIC_20_MAX_IRQ     MAX_IRQ
101

    
102
/* Interrupt definitions */
103
/* IRQs, accessible through the IRQ region */
104
#define FSL_MPIC_20_EXT_IRQ      0x00
105
#define FSL_MPIC_20_INT_IRQ      0x10
106
#define FSL_MPIC_20_MSG_IRQ      0xb0
107
#define FSL_MPIC_20_MSI_IRQ      0xe0
108
/* These are available through separate regions, but
109
   for simplicity's sake mapped into the same number space */
110
#define FSL_MPIC_20_TMR_IRQ      0x100
111
#define FSL_MPIC_20_IPI_IRQ      0x104
112

    
113
/*
114
 * Block Revision Register1 (BRR1): QEMU does not fully emulate
115
 * any version on MPIC. So to start with, set the IP version to 0.
116
 *
117
 * NOTE: This is Freescale MPIC specific register. Keep it here till
118
 * this code is refactored for different variants of OPENPIC and MPIC.
119
 */
120
#define FSL_BRR1_IPID (0x0040 << 16) /* 16 bit IP-block ID */
121
#define FSL_BRR1_IPMJ (0x00 << 8) /* 8 bit IP major number */
122
#define FSL_BRR1_IPMN 0x00 /* 8 bit IP minor number */
123

    
124
#define FRR_NIRQ_SHIFT    16
125
#define FRR_NCPU_SHIFT     8
126
#define FRR_VID_SHIFT      0
127

    
128
#define VID_REVISION_1_2   2
129
#define VID_REVISION_1_3   3
130

    
131
#define VIR_GENERIC      0x00000000 /* Generic Vendor ID */
132

    
133
#define GCR_RESET        0x80000000
134

    
135
#define TBCR_CI           0x80000000 /* count inhibit */
136
#define TCCR_TOG          0x80000000 /* toggles when decrement to zero */
137

    
138
#define IDR_EP_SHIFT      31
139
#define IDR_EP_MASK       (1 << IDR_EP_SHIFT)
140
#define IDR_CI0_SHIFT     30
141
#define IDR_CI1_SHIFT     29
142
#define IDR_P1_SHIFT      1
143
#define IDR_P0_SHIFT      0
144

    
145
#define MSIIR_OFFSET       0x140
146
#define MSIIR_SRS_SHIFT    29
147
#define MSIIR_SRS_MASK     (0x7 << MSIIR_SRS_SHIFT)
148
#define MSIIR_IBS_SHIFT    24
149
#define MSIIR_IBS_MASK     (0x1f << MSIIR_IBS_SHIFT)
150

    
151
static int get_current_cpu(void)
152
{
153
    if (!cpu_single_env) {
154
        return -1;
155
    }
156

    
157
    return cpu_single_env->cpu_index;
158
}
159

    
160
static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
161
                                          int idx);
162
static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
163
                                       uint32_t val, int idx);
164

    
165
typedef struct IRQQueue {
166
    /* Round up to the nearest 64 IRQs so that the queue length
167
     * won't change when moving between 32 and 64 bit hosts.
168
     */
169
    unsigned long queue[BITS_TO_LONGS((MAX_IRQ + 63) & ~63)];
170
    int next;
171
    int priority;
172
} IRQQueue;
173

    
174
typedef struct IRQSource {
175
    uint32_t ivpr;  /* IRQ vector/priority register */
176
    uint32_t idr;   /* IRQ destination register */
177
    uint32_t destmask; /* bitmap of CPU destinations */
178
    int last_cpu;
179
    int output;     /* IRQ level, e.g. OPENPIC_OUTPUT_INT */
180
    int pending;    /* TRUE if IRQ is pending */
181
    bool nomask:1;  /* critical interrupts ignore mask on some FSL MPICs */
182
} IRQSource;
183

    
184
#define IVPR_MASK_SHIFT       31
185
#define IVPR_MASK_MASK        (1 << IVPR_MASK_SHIFT)
186
#define IVPR_ACTIVITY_SHIFT   30
187
#define IVPR_ACTIVITY_MASK    (1 << IVPR_ACTIVITY_SHIFT)
188
#define IVPR_MODE_SHIFT       29
189
#define IVPR_MODE_MASK        (1 << IVPR_MODE_SHIFT)
190
#define IVPR_POLARITY_SHIFT   23
191
#define IVPR_POLARITY_MASK    (1 << IVPR_POLARITY_SHIFT)
192
#define IVPR_SENSE_SHIFT      22
193
#define IVPR_SENSE_MASK       (1 << IVPR_SENSE_SHIFT)
194

    
195
#define IVPR_PRIORITY_MASK     (0xF << 16)
196
#define IVPR_PRIORITY(_ivprr_) ((int)(((_ivprr_) & IVPR_PRIORITY_MASK) >> 16))
197
#define IVPR_VECTOR(opp, _ivprr_) ((_ivprr_) & (opp)->vector_mask)
198

    
199
/* IDR[EP/CI] are only for FSL MPIC prior to v4.0 */
200
#define IDR_EP      0x80000000  /* external pin */
201
#define IDR_CI      0x40000000  /* critical interrupt */
202

    
203
typedef struct IRQDest {
204
    int32_t ctpr; /* CPU current task priority */
205
    IRQQueue raised;
206
    IRQQueue servicing;
207
    qemu_irq *irqs;
208
} IRQDest;
209

    
210
typedef struct OpenPICState {
211
    SysBusDevice busdev;
212
    MemoryRegion mem;
213

    
214
    /* Behavior control */
215
    uint32_t model;
216
    uint32_t flags;
217
    uint32_t nb_irqs;
218
    uint32_t vid;
219
    uint32_t vir; /* Vendor identification register */
220
    uint32_t vector_mask;
221
    uint32_t tfrr_reset;
222
    uint32_t ivpr_reset;
223
    uint32_t idr_reset;
224
    uint32_t brr1;
225

    
226
    /* Sub-regions */
227
    MemoryRegion sub_io_mem[5];
228

    
229
    /* Global registers */
230
    uint32_t frr; /* Feature reporting register */
231
    uint32_t gcr; /* Global configuration register  */
232
    uint32_t pir; /* Processor initialization register */
233
    uint32_t spve; /* Spurious vector register */
234
    uint32_t tfrr; /* Timer frequency reporting register */
235
    /* Source registers */
236
    IRQSource src[MAX_IRQ];
237
    /* Local registers per output pin */
238
    IRQDest dst[MAX_CPU];
239
    uint32_t nb_cpus;
240
    /* Timer registers */
241
    struct {
242
        uint32_t tccr;  /* Global timer current count register */
243
        uint32_t tbcr;  /* Global timer base count register */
244
    } timers[MAX_TMR];
245
    /* Shared MSI registers */
246
    struct {
247
        uint32_t msir;   /* Shared Message Signaled Interrupt Register */
248
    } msi[MAX_MSI];
249
    uint32_t max_irq;
250
    uint32_t irq_ipi0;
251
    uint32_t irq_tim0;
252
    uint32_t irq_msi;
253
} OpenPICState;
254

    
255
static inline void IRQ_setbit(IRQQueue *q, int n_IRQ)
256
{
257
    set_bit(n_IRQ, q->queue);
258
}
259

    
260
static inline void IRQ_resetbit(IRQQueue *q, int n_IRQ)
261
{
262
    clear_bit(n_IRQ, q->queue);
263
}
264

    
265
static inline int IRQ_testbit(IRQQueue *q, int n_IRQ)
266
{
267
    return test_bit(n_IRQ, q->queue);
268
}
269

    
270
static void IRQ_check(OpenPICState *opp, IRQQueue *q)
271
{
272
    int next, i;
273
    int priority;
274

    
275
    next = -1;
276
    priority = -1;
277
    for (i = 0; i < opp->max_irq; i++) {
278
        if (IRQ_testbit(q, i)) {
279
            DPRINTF("IRQ_check: irq %d set ivpr_pr=%d pr=%d\n",
280
                    i, IVPR_PRIORITY(opp->src[i].ivpr), priority);
281
            if (IVPR_PRIORITY(opp->src[i].ivpr) > priority) {
282
                next = i;
283
                priority = IVPR_PRIORITY(opp->src[i].ivpr);
284
            }
285
        }
286
    }
287
    q->next = next;
288
    q->priority = priority;
289
}
290

    
291
static int IRQ_get_next(OpenPICState *opp, IRQQueue *q)
292
{
293
    /* XXX: optimize */
294
    IRQ_check(opp, q);
295

    
296
    return q->next;
297
}
298

    
299
static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ)
300
{
301
    IRQDest *dst;
302
    IRQSource *src;
303
    int priority;
304

    
305
    dst = &opp->dst[n_CPU];
306
    src = &opp->src[n_IRQ];
307

    
308
    if (src->output != OPENPIC_OUTPUT_INT) {
309
        /* On Freescale MPIC, critical interrupts ignore priority,
310
         * IACK, EOI, etc.  Before MPIC v4.1 they also ignore
311
         * masking.
312
         */
313
        src->ivpr |= IVPR_ACTIVITY_MASK;
314
        DPRINTF("%s: Raise OpenPIC output %d cpu %d irq %d\n",
315
                __func__, src->output, n_CPU, n_IRQ);
316
        qemu_irq_raise(opp->dst[n_CPU].irqs[src->output]);
317
        return;
318
    }
319

    
320
    priority = IVPR_PRIORITY(src->ivpr);
321
    if (priority <= dst->ctpr) {
322
        /* Too low priority */
323
        DPRINTF("%s: IRQ %d has too low priority on CPU %d\n",
324
                __func__, n_IRQ, n_CPU);
325
        return;
326
    }
327
    if (IRQ_testbit(&dst->raised, n_IRQ)) {
328
        /* Interrupt miss */
329
        DPRINTF("%s: IRQ %d was missed on CPU %d\n",
330
                __func__, n_IRQ, n_CPU);
331
        return;
332
    }
333
    src->ivpr |= IVPR_ACTIVITY_MASK;
334
    IRQ_setbit(&dst->raised, n_IRQ);
335
    if (priority < dst->raised.priority) {
336
        /* An higher priority IRQ is already raised */
337
        DPRINTF("%s: IRQ %d is hidden by raised IRQ %d on CPU %d\n",
338
                __func__, n_IRQ, dst->raised.next, n_CPU);
339
        return;
340
    }
341
    IRQ_check(opp, &dst->raised);
342
    if (IRQ_get_next(opp, &dst->servicing) != -1 &&
343
        priority <= dst->servicing.priority) {
344
        DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n",
345
                __func__, n_IRQ, dst->servicing.next, n_CPU);
346
        /* Already servicing a higher priority IRQ */
347
        return;
348
    }
349
    DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", n_CPU, n_IRQ);
350
    qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
351
}
352

    
353
/* update pic state because registers for n_IRQ have changed value */
354
static void openpic_update_irq(OpenPICState *opp, int n_IRQ)
355
{
356
    IRQSource *src;
357
    int i;
358

    
359
    src = &opp->src[n_IRQ];
360

    
361
    if (!src->pending) {
362
        /* no irq pending */
363
        DPRINTF("%s: IRQ %d is not pending\n", __func__, n_IRQ);
364
        return;
365
    }
366
    if ((src->ivpr & IVPR_MASK_MASK) && !src->nomask) {
367
        /* Interrupt source is disabled */
368
        DPRINTF("%s: IRQ %d is disabled\n", __func__, n_IRQ);
369
        return;
370
    }
371
    if (IVPR_PRIORITY(src->ivpr) == 0) {
372
        /* Priority set to zero */
373
        DPRINTF("%s: IRQ %d has 0 priority\n", __func__, n_IRQ);
374
        return;
375
    }
376
    if (src->ivpr & IVPR_ACTIVITY_MASK) {
377
        /* IRQ already active */
378
        DPRINTF("%s: IRQ %d is already active\n", __func__, n_IRQ);
379
        return;
380
    }
381
    if (src->idr == 0) {
382
        /* No target */
383
        DPRINTF("%s: IRQ %d has no target\n", __func__, n_IRQ);
384
        return;
385
    }
386

    
387
    if (src->idr == (1 << src->last_cpu)) {
388
        /* Only one CPU is allowed to receive this IRQ */
389
        IRQ_local_pipe(opp, src->last_cpu, n_IRQ);
390
    } else if (!(src->ivpr & IVPR_MODE_MASK)) {
391
        /* Directed delivery mode */
392
        for (i = 0; i < opp->nb_cpus; i++) {
393
            if (src->destmask & (1 << i)) {
394
                IRQ_local_pipe(opp, i, n_IRQ);
395
            }
396
        }
397
    } else {
398
        /* Distributed delivery mode */
399
        for (i = src->last_cpu + 1; i != src->last_cpu; i++) {
400
            if (i == opp->nb_cpus) {
401
                i = 0;
402
            }
403
            if (src->destmask & (1 << i)) {
404
                IRQ_local_pipe(opp, i, n_IRQ);
405
                src->last_cpu = i;
406
                break;
407
            }
408
        }
409
    }
410
}
411

    
412
static void openpic_set_irq(void *opaque, int n_IRQ, int level)
413
{
414
    OpenPICState *opp = opaque;
415
    IRQSource *src;
416

    
417
    if (n_IRQ >= MAX_IRQ) {
418
        fprintf(stderr, "%s: IRQ %d out of range\n", __func__, n_IRQ);
419
        abort();
420
    }
421

    
422
    src = &opp->src[n_IRQ];
423
    DPRINTF("openpic: set irq %d = %d ivpr=0x%08x\n",
424
            n_IRQ, level, src->ivpr);
425
    if (src->ivpr & IVPR_SENSE_MASK) {
426
        /* level-sensitive irq */
427
        src->pending = level;
428
        if (!level) {
429
            src->ivpr &= ~IVPR_ACTIVITY_MASK;
430
        }
431
    } else {
432
        /* edge-sensitive irq */
433
        if (level) {
434
            src->pending = 1;
435
        }
436
    }
437
    openpic_update_irq(opp, n_IRQ);
438
}
439

    
440
static void openpic_reset(DeviceState *d)
441
{
442
    OpenPICState *opp = FROM_SYSBUS(typeof (*opp), sysbus_from_qdev(d));
443
    int i;
444

    
445
    opp->gcr = GCR_RESET;
446
    /* Initialise controller registers */
447
    opp->frr = ((opp->nb_irqs - 1) << FRR_NIRQ_SHIFT) |
448
               ((opp->nb_cpus - 1) << FRR_NCPU_SHIFT) |
449
               (opp->vid << FRR_VID_SHIFT);
450

    
451
    opp->pir = 0;
452
    opp->spve = -1 & opp->vector_mask;
453
    opp->tfrr = opp->tfrr_reset;
454
    /* Initialise IRQ sources */
455
    for (i = 0; i < opp->max_irq; i++) {
456
        opp->src[i].ivpr = opp->ivpr_reset;
457
        opp->src[i].idr  = opp->idr_reset;
458
    }
459
    /* Initialise IRQ destinations */
460
    for (i = 0; i < MAX_CPU; i++) {
461
        opp->dst[i].ctpr      = 15;
462
        memset(&opp->dst[i].raised, 0, sizeof(IRQQueue));
463
        opp->dst[i].raised.next = -1;
464
        memset(&opp->dst[i].servicing, 0, sizeof(IRQQueue));
465
        opp->dst[i].servicing.next = -1;
466
    }
467
    /* Initialise timers */
468
    for (i = 0; i < MAX_TMR; i++) {
469
        opp->timers[i].tccr = 0;
470
        opp->timers[i].tbcr = TBCR_CI;
471
    }
472
    /* Go out of RESET state */
473
    opp->gcr = 0;
474
}
475

    
476
static inline uint32_t read_IRQreg_idr(OpenPICState *opp, int n_IRQ)
477
{
478
    return opp->src[n_IRQ].idr;
479
}
480

    
481
static inline uint32_t read_IRQreg_ivpr(OpenPICState *opp, int n_IRQ)
482
{
483
    return opp->src[n_IRQ].ivpr;
484
}
485

    
486
static inline void write_IRQreg_idr(OpenPICState *opp, int n_IRQ, uint32_t val)
487
{
488
    IRQSource *src = &opp->src[n_IRQ];
489
    uint32_t normal_mask = (1UL << opp->nb_cpus) - 1;
490
    uint32_t crit_mask = 0;
491
    uint32_t mask = normal_mask;
492
    int crit_shift = IDR_EP_SHIFT - opp->nb_cpus;
493
    int i;
494

    
495
    if (opp->flags & OPENPIC_FLAG_IDR_CRIT) {
496
        crit_mask = mask << crit_shift;
497
        mask |= crit_mask | IDR_EP;
498
    }
499

    
500
    src->idr = val & mask;
501
    DPRINTF("Set IDR %d to 0x%08x\n", n_IRQ, src->idr);
502

    
503
    if (opp->flags & OPENPIC_FLAG_IDR_CRIT) {
504
        if (src->idr & crit_mask) {
505
            if (src->idr & normal_mask) {
506
                DPRINTF("%s: IRQ configured for multiple output types, using "
507
                        "critical\n", __func__);
508
            }
509

    
510
            src->output = OPENPIC_OUTPUT_CINT;
511
            src->nomask = true;
512
            src->destmask = 0;
513

    
514
            for (i = 0; i < opp->nb_cpus; i++) {
515
                int n_ci = IDR_CI0_SHIFT - i;
516

    
517
                if (src->idr & (1UL << n_ci)) {
518
                    src->destmask |= 1UL << i;
519
                }
520
            }
521
        } else {
522
            src->output = OPENPIC_OUTPUT_INT;
523
            src->nomask = false;
524
            src->destmask = src->idr & normal_mask;
525
        }
526
    } else {
527
        src->destmask = src->idr;
528
    }
529
}
530

    
531
static inline void write_IRQreg_ivpr(OpenPICState *opp, int n_IRQ, uint32_t val)
532
{
533
    /* NOTE: not fully accurate for special IRQs, but simple and sufficient */
534
    /* ACTIVITY bit is read-only */
535
    opp->src[n_IRQ].ivpr = (opp->src[n_IRQ].ivpr & IVPR_ACTIVITY_MASK) |
536
        (val & (IVPR_MASK_MASK | IVPR_PRIORITY_MASK | opp->vector_mask));
537
    openpic_update_irq(opp, n_IRQ);
538
    DPRINTF("Set IVPR %d to 0x%08x -> 0x%08x\n", n_IRQ, val,
539
            opp->src[n_IRQ].ivpr);
540
}
541

    
542
static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,
543
                              unsigned len)
544
{
545
    OpenPICState *opp = opaque;
546
    IRQDest *dst;
547
    int idx;
548

    
549
    DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n",
550
            __func__, addr, val);
551
    if (addr & 0xF) {
552
        return;
553
    }
554
    switch (addr) {
555
    case 0x00: /* Block Revision Register1 (BRR1) is Readonly */
556
        break;
557
    case 0x40:
558
    case 0x50:
559
    case 0x60:
560
    case 0x70:
561
    case 0x80:
562
    case 0x90:
563
    case 0xA0:
564
    case 0xB0:
565
        openpic_cpu_write_internal(opp, addr, val, get_current_cpu());
566
        break;
567
    case 0x1000: /* FRR */
568
        break;
569
    case 0x1020: /* GCR */
570
        if (val & GCR_RESET) {
571
            openpic_reset(&opp->busdev.qdev);
572
        }
573
        break;
574
    case 0x1080: /* VIR */
575
        break;
576
    case 0x1090: /* PIR */
577
        for (idx = 0; idx < opp->nb_cpus; idx++) {
578
            if ((val & (1 << idx)) && !(opp->pir & (1 << idx))) {
579
                DPRINTF("Raise OpenPIC RESET output for CPU %d\n", idx);
580
                dst = &opp->dst[idx];
581
                qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_RESET]);
582
            } else if (!(val & (1 << idx)) && (opp->pir & (1 << idx))) {
583
                DPRINTF("Lower OpenPIC RESET output for CPU %d\n", idx);
584
                dst = &opp->dst[idx];
585
                qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_RESET]);
586
            }
587
        }
588
        opp->pir = val;
589
        break;
590
    case 0x10A0: /* IPI_IVPR */
591
    case 0x10B0:
592
    case 0x10C0:
593
    case 0x10D0:
594
        {
595
            int idx;
596
            idx = (addr - 0x10A0) >> 4;
597
            write_IRQreg_ivpr(opp, opp->irq_ipi0 + idx, val);
598
        }
599
        break;
600
    case 0x10E0: /* SPVE */
601
        opp->spve = val & opp->vector_mask;
602
        break;
603
    default:
604
        break;
605
    }
606
}
607

    
608
static uint64_t openpic_gbl_read(void *opaque, hwaddr addr, unsigned len)
609
{
610
    OpenPICState *opp = opaque;
611
    uint32_t retval;
612

    
613
    DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
614
    retval = 0xFFFFFFFF;
615
    if (addr & 0xF) {
616
        return retval;
617
    }
618
    switch (addr) {
619
    case 0x1000: /* FRR */
620
        retval = opp->frr;
621
        break;
622
    case 0x1020: /* GCR */
623
        retval = opp->gcr;
624
        break;
625
    case 0x1080: /* VIR */
626
        retval = opp->vir;
627
        break;
628
    case 0x1090: /* PIR */
629
        retval = 0x00000000;
630
        break;
631
    case 0x00: /* Block Revision Register1 (BRR1) */
632
        retval = opp->brr1;
633
        break;
634
    case 0x40:
635
    case 0x50:
636
    case 0x60:
637
    case 0x70:
638
    case 0x80:
639
    case 0x90:
640
    case 0xA0:
641
    case 0xB0:
642
        retval = openpic_cpu_read_internal(opp, addr, get_current_cpu());
643
        break;
644
    case 0x10A0: /* IPI_IVPR */
645
    case 0x10B0:
646
    case 0x10C0:
647
    case 0x10D0:
648
        {
649
            int idx;
650
            idx = (addr - 0x10A0) >> 4;
651
            retval = read_IRQreg_ivpr(opp, opp->irq_ipi0 + idx);
652
        }
653
        break;
654
    case 0x10E0: /* SPVE */
655
        retval = opp->spve;
656
        break;
657
    default:
658
        break;
659
    }
660
    DPRINTF("%s: => 0x%08x\n", __func__, retval);
661

    
662
    return retval;
663
}
664

    
665
static void openpic_tmr_write(void *opaque, hwaddr addr, uint64_t val,
666
                                unsigned len)
667
{
668
    OpenPICState *opp = opaque;
669
    int idx;
670

    
671
    DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n",
672
            __func__, addr, val);
673
    if (addr & 0xF) {
674
        return;
675
    }
676
    idx = (addr >> 6) & 0x3;
677
    addr = addr & 0x30;
678

    
679
    if (addr == 0x0) {
680
        /* TFRR */
681
        opp->tfrr = val;
682
        return;
683
    }
684
    switch (addr & 0x30) {
685
    case 0x00: /* TCCR */
686
        break;
687
    case 0x10: /* TBCR */
688
        if ((opp->timers[idx].tccr & TCCR_TOG) != 0 &&
689
            (val & TBCR_CI) == 0 &&
690
            (opp->timers[idx].tbcr & TBCR_CI) != 0) {
691
            opp->timers[idx].tccr &= ~TCCR_TOG;
692
        }
693
        opp->timers[idx].tbcr = val;
694
        break;
695
    case 0x20: /* TVPR */
696
        write_IRQreg_ivpr(opp, opp->irq_tim0 + idx, val);
697
        break;
698
    case 0x30: /* TDR */
699
        write_IRQreg_idr(opp, opp->irq_tim0 + idx, val);
700
        break;
701
    }
702
}
703

    
704
static uint64_t openpic_tmr_read(void *opaque, hwaddr addr, unsigned len)
705
{
706
    OpenPICState *opp = opaque;
707
    uint32_t retval = -1;
708
    int idx;
709

    
710
    DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
711
    if (addr & 0xF) {
712
        goto out;
713
    }
714
    idx = (addr >> 6) & 0x3;
715
    if (addr == 0x0) {
716
        /* TFRR */
717
        retval = opp->tfrr;
718
        goto out;
719
    }
720
    switch (addr & 0x30) {
721
    case 0x00: /* TCCR */
722
        retval = opp->timers[idx].tccr;
723
        break;
724
    case 0x10: /* TBCR */
725
        retval = opp->timers[idx].tbcr;
726
        break;
727
    case 0x20: /* TIPV */
728
        retval = read_IRQreg_ivpr(opp, opp->irq_tim0 + idx);
729
        break;
730
    case 0x30: /* TIDE (TIDR) */
731
        retval = read_IRQreg_idr(opp, opp->irq_tim0 + idx);
732
        break;
733
    }
734

    
735
out:
736
    DPRINTF("%s: => 0x%08x\n", __func__, retval);
737

    
738
    return retval;
739
}
740

    
741
static void openpic_src_write(void *opaque, hwaddr addr, uint64_t val,
742
                              unsigned len)
743
{
744
    OpenPICState *opp = opaque;
745
    int idx;
746

    
747
    DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n",
748
            __func__, addr, val);
749
    if (addr & 0xF) {
750
        return;
751
    }
752
    addr = addr & 0xFFF0;
753
    idx = addr >> 5;
754
    if (addr & 0x10) {
755
        /* EXDE / IFEDE / IEEDE */
756
        write_IRQreg_idr(opp, idx, val);
757
    } else {
758
        /* EXVP / IFEVP / IEEVP */
759
        write_IRQreg_ivpr(opp, idx, val);
760
    }
761
}
762

    
763
static uint64_t openpic_src_read(void *opaque, uint64_t addr, unsigned len)
764
{
765
    OpenPICState *opp = opaque;
766
    uint32_t retval;
767
    int idx;
768

    
769
    DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
770
    retval = 0xFFFFFFFF;
771
    if (addr & 0xF) {
772
        return retval;
773
    }
774
    addr = addr & 0xFFF0;
775
    idx = addr >> 5;
776
    if (addr & 0x10) {
777
        /* EXDE / IFEDE / IEEDE */
778
        retval = read_IRQreg_idr(opp, idx);
779
    } else {
780
        /* EXVP / IFEVP / IEEVP */
781
        retval = read_IRQreg_ivpr(opp, idx);
782
    }
783
    DPRINTF("%s: => 0x%08x\n", __func__, retval);
784

    
785
    return retval;
786
}
787

    
788
static void openpic_msi_write(void *opaque, hwaddr addr, uint64_t val,
789
                              unsigned size)
790
{
791
    OpenPICState *opp = opaque;
792
    int idx = opp->irq_msi;
793
    int srs, ibs;
794

    
795
    DPRINTF("%s: addr %#" HWADDR_PRIx " <= 0x%08" PRIx64 "\n",
796
            __func__, addr, val);
797
    if (addr & 0xF) {
798
        return;
799
    }
800

    
801
    switch (addr) {
802
    case MSIIR_OFFSET:
803
        srs = val >> MSIIR_SRS_SHIFT;
804
        idx += srs;
805
        ibs = (val & MSIIR_IBS_MASK) >> MSIIR_IBS_SHIFT;
806
        opp->msi[srs].msir |= 1 << ibs;
807
        openpic_set_irq(opp, idx, 1);
808
        break;
809
    default:
810
        /* most registers are read-only, thus ignored */
811
        break;
812
    }
813
}
814

    
815
static uint64_t openpic_msi_read(void *opaque, hwaddr addr, unsigned size)
816
{
817
    OpenPICState *opp = opaque;
818
    uint64_t r = 0;
819
    int i, srs;
820

    
821
    DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
822
    if (addr & 0xF) {
823
        return -1;
824
    }
825

    
826
    srs = addr >> 4;
827

    
828
    switch (addr) {
829
    case 0x00:
830
    case 0x10:
831
    case 0x20:
832
    case 0x30:
833
    case 0x40:
834
    case 0x50:
835
    case 0x60:
836
    case 0x70: /* MSIRs */
837
        r = opp->msi[srs].msir;
838
        /* Clear on read */
839
        opp->msi[srs].msir = 0;
840
        openpic_set_irq(opp, opp->irq_msi + srs, 0);
841
        break;
842
    case 0x120: /* MSISR */
843
        for (i = 0; i < MAX_MSI; i++) {
844
            r |= (opp->msi[i].msir ? 1 : 0) << i;
845
        }
846
        break;
847
    }
848

    
849
    return r;
850
}
851

    
852
static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
853
                                       uint32_t val, int idx)
854
{
855
    OpenPICState *opp = opaque;
856
    IRQSource *src;
857
    IRQDest *dst;
858
    int s_IRQ, n_IRQ;
859

    
860
    DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx " <= 0x%08x\n", __func__, idx,
861
            addr, val);
862

    
863
    if (idx < 0) {
864
        return;
865
    }
866

    
867
    if (addr & 0xF) {
868
        return;
869
    }
870
    dst = &opp->dst[idx];
871
    addr &= 0xFF0;
872
    switch (addr) {
873
    case 0x40: /* IPIDR */
874
    case 0x50:
875
    case 0x60:
876
    case 0x70:
877
        idx = (addr - 0x40) >> 4;
878
        /* we use IDE as mask which CPUs to deliver the IPI to still. */
879
        write_IRQreg_idr(opp, opp->irq_ipi0 + idx,
880
                         opp->src[opp->irq_ipi0 + idx].idr | val);
881
        openpic_set_irq(opp, opp->irq_ipi0 + idx, 1);
882
        openpic_set_irq(opp, opp->irq_ipi0 + idx, 0);
883
        break;
884
    case 0x80: /* CTPR */
885
        dst->ctpr = val & 0x0000000F;
886
        break;
887
    case 0x90: /* WHOAMI */
888
        /* Read-only register */
889
        break;
890
    case 0xA0: /* IACK */
891
        /* Read-only register */
892
        break;
893
    case 0xB0: /* EOI */
894
        DPRINTF("EOI\n");
895
        s_IRQ = IRQ_get_next(opp, &dst->servicing);
896

    
897
        if (s_IRQ < 0) {
898
            DPRINTF("%s: EOI with no interrupt in service\n", __func__);
899
            break;
900
        }
901

    
902
        IRQ_resetbit(&dst->servicing, s_IRQ);
903
        /* Set up next servicing IRQ */
904
        s_IRQ = IRQ_get_next(opp, &dst->servicing);
905
        /* Check queued interrupts. */
906
        n_IRQ = IRQ_get_next(opp, &dst->raised);
907
        src = &opp->src[n_IRQ];
908
        if (n_IRQ != -1 &&
909
            (s_IRQ == -1 ||
910
             IVPR_PRIORITY(src->ivpr) > dst->servicing.priority)) {
911
            DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n",
912
                    idx, n_IRQ);
913
            qemu_irq_raise(opp->dst[idx].irqs[OPENPIC_OUTPUT_INT]);
914
        }
915
        break;
916
    default:
917
        break;
918
    }
919
}
920

    
921
static void openpic_cpu_write(void *opaque, hwaddr addr, uint64_t val,
922
                              unsigned len)
923
{
924
    openpic_cpu_write_internal(opaque, addr, val, (addr & 0x1f000) >> 12);
925
}
926

    
927
static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
928
                                          int idx)
929
{
930
    OpenPICState *opp = opaque;
931
    IRQSource *src;
932
    IRQDest *dst;
933
    uint32_t retval;
934
    int n_IRQ;
935

    
936
    DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx "\n", __func__, idx, addr);
937
    retval = 0xFFFFFFFF;
938

    
939
    if (idx < 0) {
940
        return retval;
941
    }
942

    
943
    if (addr & 0xF) {
944
        return retval;
945
    }
946
    dst = &opp->dst[idx];
947
    addr &= 0xFF0;
948
    switch (addr) {
949
    case 0x80: /* CTPR */
950
        retval = dst->ctpr;
951
        break;
952
    case 0x90: /* WHOAMI */
953
        retval = idx;
954
        break;
955
    case 0xA0: /* IACK */
956
        DPRINTF("Lower OpenPIC INT output\n");
957
        qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);
958
        n_IRQ = IRQ_get_next(opp, &dst->raised);
959
        DPRINTF("IACK: irq=%d\n", n_IRQ);
960
        if (n_IRQ == -1) {
961
            /* No more interrupt pending */
962
            retval = opp->spve;
963
        } else {
964
            src = &opp->src[n_IRQ];
965
            if (!(src->ivpr & IVPR_ACTIVITY_MASK) ||
966
                !(IVPR_PRIORITY(src->ivpr) > dst->ctpr)) {
967
                /* - Spurious level-sensitive IRQ
968
                 * - Priorities has been changed
969
                 *   and the pending IRQ isn't allowed anymore
970
                 */
971
                src->ivpr &= ~IVPR_ACTIVITY_MASK;
972
                retval = opp->spve;
973
            } else {
974
                /* IRQ enter servicing state */
975
                IRQ_setbit(&dst->servicing, n_IRQ);
976
                retval = IVPR_VECTOR(opp, src->ivpr);
977
            }
978
            IRQ_resetbit(&dst->raised, n_IRQ);
979
            if (!(src->ivpr & IVPR_SENSE_MASK)) {
980
                /* edge-sensitive IRQ */
981
                src->ivpr &= ~IVPR_ACTIVITY_MASK;
982
                src->pending = 0;
983
            }
984

    
985
            if ((n_IRQ >= opp->irq_ipi0) &&  (n_IRQ < (opp->irq_ipi0 + MAX_IPI))) {
986
                src->idr &= ~(1 << idx);
987
                if (src->idr && !(src->ivpr & IVPR_SENSE_MASK)) {
988
                    /* trigger on CPUs that didn't know about it yet */
989
                    openpic_set_irq(opp, n_IRQ, 1);
990
                    openpic_set_irq(opp, n_IRQ, 0);
991
                    /* if all CPUs knew about it, set active bit again */
992
                    src->ivpr |= IVPR_ACTIVITY_MASK;
993
                }
994
            }
995
        }
996
        break;
997
    case 0xB0: /* EOI */
998
        retval = 0;
999
        break;
1000
    default:
1001
        break;
1002
    }
1003
    DPRINTF("%s: => 0x%08x\n", __func__, retval);
1004

    
1005
    return retval;
1006
}
1007

    
1008
static uint64_t openpic_cpu_read(void *opaque, hwaddr addr, unsigned len)
1009
{
1010
    return openpic_cpu_read_internal(opaque, addr, (addr & 0x1f000) >> 12);
1011
}
1012

    
1013
static const MemoryRegionOps openpic_glb_ops_le = {
1014
    .write = openpic_gbl_write,
1015
    .read  = openpic_gbl_read,
1016
    .endianness = DEVICE_LITTLE_ENDIAN,
1017
    .impl = {
1018
        .min_access_size = 4,
1019
        .max_access_size = 4,
1020
    },
1021
};
1022

    
1023
static const MemoryRegionOps openpic_glb_ops_be = {
1024
    .write = openpic_gbl_write,
1025
    .read  = openpic_gbl_read,
1026
    .endianness = DEVICE_BIG_ENDIAN,
1027
    .impl = {
1028
        .min_access_size = 4,
1029
        .max_access_size = 4,
1030
    },
1031
};
1032

    
1033
static const MemoryRegionOps openpic_tmr_ops_le = {
1034
    .write = openpic_tmr_write,
1035
    .read  = openpic_tmr_read,
1036
    .endianness = DEVICE_LITTLE_ENDIAN,
1037
    .impl = {
1038
        .min_access_size = 4,
1039
        .max_access_size = 4,
1040
    },
1041
};
1042

    
1043
static const MemoryRegionOps openpic_tmr_ops_be = {
1044
    .write = openpic_tmr_write,
1045
    .read  = openpic_tmr_read,
1046
    .endianness = DEVICE_BIG_ENDIAN,
1047
    .impl = {
1048
        .min_access_size = 4,
1049
        .max_access_size = 4,
1050
    },
1051
};
1052

    
1053
static const MemoryRegionOps openpic_cpu_ops_le = {
1054
    .write = openpic_cpu_write,
1055
    .read  = openpic_cpu_read,
1056
    .endianness = DEVICE_LITTLE_ENDIAN,
1057
    .impl = {
1058
        .min_access_size = 4,
1059
        .max_access_size = 4,
1060
    },
1061
};
1062

    
1063
static const MemoryRegionOps openpic_cpu_ops_be = {
1064
    .write = openpic_cpu_write,
1065
    .read  = openpic_cpu_read,
1066
    .endianness = DEVICE_BIG_ENDIAN,
1067
    .impl = {
1068
        .min_access_size = 4,
1069
        .max_access_size = 4,
1070
    },
1071
};
1072

    
1073
static const MemoryRegionOps openpic_src_ops_le = {
1074
    .write = openpic_src_write,
1075
    .read  = openpic_src_read,
1076
    .endianness = DEVICE_LITTLE_ENDIAN,
1077
    .impl = {
1078
        .min_access_size = 4,
1079
        .max_access_size = 4,
1080
    },
1081
};
1082

    
1083
static const MemoryRegionOps openpic_src_ops_be = {
1084
    .write = openpic_src_write,
1085
    .read  = openpic_src_read,
1086
    .endianness = DEVICE_BIG_ENDIAN,
1087
    .impl = {
1088
        .min_access_size = 4,
1089
        .max_access_size = 4,
1090
    },
1091
};
1092

    
1093
static const MemoryRegionOps openpic_msi_ops_le = {
1094
    .read = openpic_msi_read,
1095
    .write = openpic_msi_write,
1096
    .endianness = DEVICE_LITTLE_ENDIAN,
1097
    .impl = {
1098
        .min_access_size = 4,
1099
        .max_access_size = 4,
1100
    },
1101
};
1102

    
1103
static const MemoryRegionOps openpic_msi_ops_be = {
1104
    .read = openpic_msi_read,
1105
    .write = openpic_msi_write,
1106
    .endianness = DEVICE_BIG_ENDIAN,
1107
    .impl = {
1108
        .min_access_size = 4,
1109
        .max_access_size = 4,
1110
    },
1111
};
1112

    
1113
static void openpic_save_IRQ_queue(QEMUFile* f, IRQQueue *q)
1114
{
1115
    unsigned int i;
1116

    
1117
    for (i = 0; i < ARRAY_SIZE(q->queue); i++) {
1118
        /* Always put the lower half of a 64-bit long first, in case we
1119
         * restore on a 32-bit host.  The least significant bits correspond
1120
         * to lower IRQ numbers in the bitmap.
1121
         */
1122
        qemu_put_be32(f, (uint32_t)q->queue[i]);
1123
#if LONG_MAX > 0x7FFFFFFF
1124
        qemu_put_be32(f, (uint32_t)(q->queue[i] >> 32));
1125
#endif
1126
    }
1127

    
1128
    qemu_put_sbe32s(f, &q->next);
1129
    qemu_put_sbe32s(f, &q->priority);
1130
}
1131

    
1132
static void openpic_save(QEMUFile* f, void *opaque)
1133
{
1134
    OpenPICState *opp = (OpenPICState *)opaque;
1135
    unsigned int i;
1136

    
1137
    qemu_put_be32s(f, &opp->gcr);
1138
    qemu_put_be32s(f, &opp->vir);
1139
    qemu_put_be32s(f, &opp->pir);
1140
    qemu_put_be32s(f, &opp->spve);
1141
    qemu_put_be32s(f, &opp->tfrr);
1142

    
1143
    qemu_put_be32s(f, &opp->nb_cpus);
1144

    
1145
    for (i = 0; i < opp->nb_cpus; i++) {
1146
        qemu_put_sbe32s(f, &opp->dst[i].ctpr);
1147
        openpic_save_IRQ_queue(f, &opp->dst[i].raised);
1148
        openpic_save_IRQ_queue(f, &opp->dst[i].servicing);
1149
    }
1150

    
1151
    for (i = 0; i < MAX_TMR; i++) {
1152
        qemu_put_be32s(f, &opp->timers[i].tccr);
1153
        qemu_put_be32s(f, &opp->timers[i].tbcr);
1154
    }
1155

    
1156
    for (i = 0; i < opp->max_irq; i++) {
1157
        qemu_put_be32s(f, &opp->src[i].ivpr);
1158
        qemu_put_be32s(f, &opp->src[i].idr);
1159
        qemu_put_sbe32s(f, &opp->src[i].last_cpu);
1160
        qemu_put_sbe32s(f, &opp->src[i].pending);
1161
    }
1162
}
1163

    
1164
static void openpic_load_IRQ_queue(QEMUFile* f, IRQQueue *q)
1165
{
1166
    unsigned int i;
1167

    
1168
    for (i = 0; i < ARRAY_SIZE(q->queue); i++) {
1169
        unsigned long val;
1170

    
1171
        val = qemu_get_be32(f);
1172
#if LONG_MAX > 0x7FFFFFFF
1173
        val <<= 32;
1174
        val |= qemu_get_be32(f);
1175
#endif
1176

    
1177
        q->queue[i] = val;
1178
    }
1179

    
1180
    qemu_get_sbe32s(f, &q->next);
1181
    qemu_get_sbe32s(f, &q->priority);
1182
}
1183

    
1184
static int openpic_load(QEMUFile* f, void *opaque, int version_id)
1185
{
1186
    OpenPICState *opp = (OpenPICState *)opaque;
1187
    unsigned int i;
1188

    
1189
    if (version_id != 1) {
1190
        return -EINVAL;
1191
    }
1192

    
1193
    qemu_get_be32s(f, &opp->gcr);
1194
    qemu_get_be32s(f, &opp->vir);
1195
    qemu_get_be32s(f, &opp->pir);
1196
    qemu_get_be32s(f, &opp->spve);
1197
    qemu_get_be32s(f, &opp->tfrr);
1198

    
1199
    qemu_get_be32s(f, &opp->nb_cpus);
1200

    
1201
    for (i = 0; i < opp->nb_cpus; i++) {
1202
        qemu_get_sbe32s(f, &opp->dst[i].ctpr);
1203
        openpic_load_IRQ_queue(f, &opp->dst[i].raised);
1204
        openpic_load_IRQ_queue(f, &opp->dst[i].servicing);
1205
    }
1206

    
1207
    for (i = 0; i < MAX_TMR; i++) {
1208
        qemu_get_be32s(f, &opp->timers[i].tccr);
1209
        qemu_get_be32s(f, &opp->timers[i].tbcr);
1210
    }
1211

    
1212
    for (i = 0; i < opp->max_irq; i++) {
1213
        uint32_t val;
1214

    
1215
        val = qemu_get_be32(f);
1216
        write_IRQreg_idr(opp, i, val);
1217
        val = qemu_get_be32(f);
1218
        write_IRQreg_ivpr(opp, i, val);
1219

    
1220
        qemu_get_be32s(f, &opp->src[i].ivpr);
1221
        qemu_get_be32s(f, &opp->src[i].idr);
1222
        qemu_get_sbe32s(f, &opp->src[i].last_cpu);
1223
        qemu_get_sbe32s(f, &opp->src[i].pending);
1224
    }
1225

    
1226
    return 0;
1227
}
1228

    
1229
typedef struct MemReg {
1230
    const char             *name;
1231
    MemoryRegionOps const  *ops;
1232
    bool                   map;
1233
    hwaddr      start_addr;
1234
    ram_addr_t              size;
1235
} MemReg;
1236

    
1237
static int openpic_init(SysBusDevice *dev)
1238
{
1239
    OpenPICState *opp = FROM_SYSBUS(typeof (*opp), dev);
1240
    int i, j;
1241
    MemReg list_le[] = {
1242
        {"glb", &openpic_glb_ops_le, true,
1243
                OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE},
1244
        {"tmr", &openpic_tmr_ops_le, true,
1245
                OPENPIC_TMR_REG_START, OPENPIC_TMR_REG_SIZE},
1246
        {"msi", &openpic_msi_ops_le, true,
1247
                OPENPIC_MSI_REG_START, OPENPIC_MSI_REG_SIZE},
1248
        {"src", &openpic_src_ops_le, true,
1249
                OPENPIC_SRC_REG_START, OPENPIC_SRC_REG_SIZE},
1250
        {"cpu", &openpic_cpu_ops_le, true,
1251
                OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE},
1252
    };
1253
    MemReg list_be[] = {
1254
        {"glb", &openpic_glb_ops_be, true,
1255
                OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE},
1256
        {"tmr", &openpic_tmr_ops_be, true,
1257
                OPENPIC_TMR_REG_START, OPENPIC_TMR_REG_SIZE},
1258
        {"msi", &openpic_msi_ops_be, true,
1259
                OPENPIC_MSI_REG_START, OPENPIC_MSI_REG_SIZE},
1260
        {"src", &openpic_src_ops_be, true,
1261
                OPENPIC_SRC_REG_START, OPENPIC_SRC_REG_SIZE},
1262
        {"cpu", &openpic_cpu_ops_be, true,
1263
                OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE},
1264
    };
1265
    MemReg *list;
1266

    
1267
    switch (opp->model) {
1268
    case OPENPIC_MODEL_FSL_MPIC_20:
1269
    default:
1270
        opp->flags |= OPENPIC_FLAG_IDR_CRIT;
1271
        opp->nb_irqs = 80;
1272
        opp->vid = VID_REVISION_1_2;
1273
        opp->vir = VIR_GENERIC;
1274
        opp->vector_mask = 0xFFFF;
1275
        opp->tfrr_reset = 0;
1276
        opp->ivpr_reset = IVPR_MASK_MASK;
1277
        opp->idr_reset = 1 << 0;
1278
        opp->max_irq = FSL_MPIC_20_MAX_IRQ;
1279
        opp->irq_ipi0 = FSL_MPIC_20_IPI_IRQ;
1280
        opp->irq_tim0 = FSL_MPIC_20_TMR_IRQ;
1281
        opp->irq_msi = FSL_MPIC_20_MSI_IRQ;
1282
        opp->brr1 = FSL_BRR1_IPID | FSL_BRR1_IPMJ | FSL_BRR1_IPMN;
1283
        msi_supported = true;
1284
        list = list_be;
1285
        break;
1286
    case OPENPIC_MODEL_RAVEN:
1287
        opp->nb_irqs = RAVEN_MAX_EXT;
1288
        opp->vid = VID_REVISION_1_3;
1289
        opp->vir = VIR_GENERIC;
1290
        opp->vector_mask = 0xFF;
1291
        opp->tfrr_reset = 4160000;
1292
        opp->ivpr_reset = IVPR_MASK_MASK | IVPR_MODE_MASK;
1293
        opp->idr_reset = 0;
1294
        opp->max_irq = RAVEN_MAX_IRQ;
1295
        opp->irq_ipi0 = RAVEN_IPI_IRQ;
1296
        opp->irq_tim0 = RAVEN_TMR_IRQ;
1297
        opp->brr1 = -1;
1298
        list = list_le;
1299
        /* Don't map MSI region */
1300
        list[2].map = false;
1301

    
1302
        /* Only UP supported today */
1303
        if (opp->nb_cpus != 1) {
1304
            return -EINVAL;
1305
        }
1306
        break;
1307
    }
1308

    
1309
    memory_region_init(&opp->mem, "openpic", 0x40000);
1310

    
1311
    for (i = 0; i < ARRAY_SIZE(list_le); i++) {
1312
        if (!list[i].map) {
1313
            continue;
1314
        }
1315

    
1316
        memory_region_init_io(&opp->sub_io_mem[i], list[i].ops, opp,
1317
                              list[i].name, list[i].size);
1318

    
1319
        memory_region_add_subregion(&opp->mem, list[i].start_addr,
1320
                                    &opp->sub_io_mem[i]);
1321
    }
1322

    
1323
    for (i = 0; i < opp->nb_cpus; i++) {
1324
        opp->dst[i].irqs = g_new(qemu_irq, OPENPIC_OUTPUT_NB);
1325
        for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
1326
            sysbus_init_irq(dev, &opp->dst[i].irqs[j]);
1327
        }
1328
    }
1329

    
1330
    register_savevm(&opp->busdev.qdev, "openpic", 0, 2,
1331
                    openpic_save, openpic_load, opp);
1332

    
1333
    sysbus_init_mmio(dev, &opp->mem);
1334
    qdev_init_gpio_in(&dev->qdev, openpic_set_irq, opp->max_irq);
1335

    
1336
    return 0;
1337
}
1338

    
1339
static Property openpic_properties[] = {
1340
    DEFINE_PROP_UINT32("model", OpenPICState, model, OPENPIC_MODEL_FSL_MPIC_20),
1341
    DEFINE_PROP_UINT32("nb_cpus", OpenPICState, nb_cpus, 1),
1342
    DEFINE_PROP_END_OF_LIST(),
1343
};
1344

    
1345
static void openpic_class_init(ObjectClass *klass, void *data)
1346
{
1347
    DeviceClass *dc = DEVICE_CLASS(klass);
1348
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
1349

    
1350
    k->init = openpic_init;
1351
    dc->props = openpic_properties;
1352
    dc->reset = openpic_reset;
1353
}
1354

    
1355
static TypeInfo openpic_info = {
1356
    .name          = "openpic",
1357
    .parent        = TYPE_SYS_BUS_DEVICE,
1358
    .instance_size = sizeof(OpenPICState),
1359
    .class_init    = openpic_class_init,
1360
};
1361

    
1362
static void openpic_register_types(void)
1363
{
1364
    type_register_static(&openpic_info);
1365
}
1366

    
1367
type_init(openpic_register_types)