Statistics
| Branch: | Revision:

root / hw / openpic.c @ e99fd8af

History | View | Annotate | Download (36.7 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

    
43
//#define DEBUG_OPENPIC
44

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

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

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

    
65
/* OpenPIC capability flags */
66
#define OPENPIC_FLAG_IDE_CRIT     (1 << 0)
67

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

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

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

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

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

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

    
123
#define FREP_NIRQ_SHIFT   16
124
#define FREP_NCPU_SHIFT    8
125
#define FREP_VID_SHIFT     0
126

    
127
#define VID_REVISION_1_2   2
128
#define VID_REVISION_1_3   3
129

    
130
#define VENI_GENERIC      0x00000000 /* Generic Vendor ID */
131

    
132
#define GLBC_RESET        0x80000000
133

    
134
#define TIBC_CI           0x80000000 /* count inhibit */
135
#define TICC_TOG          0x80000000 /* toggles when decrement to zero */
136

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

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

    
150
#define BF_WIDTH(_bits_) \
151
(((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8))
152

    
153
static inline void set_bit(uint32_t *field, int bit)
154
{
155
    field[bit >> 5] |= 1 << (bit & 0x1F);
156
}
157

    
158
static inline void reset_bit(uint32_t *field, int bit)
159
{
160
    field[bit >> 5] &= ~(1 << (bit & 0x1F));
161
}
162

    
163
static inline int test_bit(uint32_t *field, int bit)
164
{
165
    return (field[bit >> 5] & 1 << (bit & 0x1F)) != 0;
166
}
167

    
168
static int get_current_cpu(void)
169
{
170
    if (!cpu_single_env) {
171
        return -1;
172
    }
173

    
174
    return cpu_single_env->cpu_index;
175
}
176

    
177
static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
178
                                          int idx);
179
static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
180
                                       uint32_t val, int idx);
181

    
182
typedef struct IRQQueue {
183
    uint32_t queue[BF_WIDTH(MAX_IRQ)];
184
    int next;
185
    int priority;
186
    int pending;    /* nr of pending bits in queue */
187
} IRQQueue;
188

    
189
typedef struct IRQSource {
190
    uint32_t ipvp;  /* IRQ vector/priority register */
191
    uint32_t ide;   /* IRQ destination register */
192
    int last_cpu;
193
    int pending;    /* TRUE if IRQ is pending */
194
} IRQSource;
195

    
196
#define IPVP_MASK_SHIFT       31
197
#define IPVP_MASK_MASK        (1 << IPVP_MASK_SHIFT)
198
#define IPVP_ACTIVITY_SHIFT   30
199
#define IPVP_ACTIVITY_MASK    (1 << IPVP_ACTIVITY_SHIFT)
200
#define IPVP_MODE_SHIFT       29
201
#define IPVP_MODE_MASK        (1 << IPVP_MODE_SHIFT)
202
#define IPVP_POLARITY_SHIFT   23
203
#define IPVP_POLARITY_MASK    (1 << IPVP_POLARITY_SHIFT)
204
#define IPVP_SENSE_SHIFT      22
205
#define IPVP_SENSE_MASK       (1 << IPVP_SENSE_SHIFT)
206

    
207
#define IPVP_PRIORITY_MASK     (0xF << 16)
208
#define IPVP_PRIORITY(_ipvpr_) ((int)(((_ipvpr_) & IPVP_PRIORITY_MASK) >> 16))
209
#define IPVP_VECTOR(opp, _ipvpr_) ((_ipvpr_) & (opp)->vector_mask)
210

    
211
/* IDE[EP/CI] are only for FSL MPIC prior to v4.0 */
212
#define IDE_EP      0x80000000  /* external pin */
213
#define IDE_CI      0x40000000  /* critical interrupt */
214

    
215
typedef struct IRQDest {
216
    uint32_t pctp; /* CPU current task priority */
217
    IRQQueue raised;
218
    IRQQueue servicing;
219
    qemu_irq *irqs;
220
} IRQDest;
221

    
222
typedef struct OpenPICState {
223
    SysBusDevice busdev;
224
    MemoryRegion mem;
225

    
226
    /* Behavior control */
227
    uint32_t model;
228
    uint32_t flags;
229
    uint32_t nb_irqs;
230
    uint32_t vid;
231
    uint32_t veni; /* Vendor identification register */
232
    uint32_t vector_mask;
233
    uint32_t tifr_reset;
234
    uint32_t ipvp_reset;
235
    uint32_t ide_reset;
236
    uint32_t brr1;
237

    
238
    /* Sub-regions */
239
    MemoryRegion sub_io_mem[5];
240

    
241
    /* Global registers */
242
    uint32_t frep; /* Feature reporting register */
243
    uint32_t glbc; /* Global configuration register  */
244
    uint32_t pint; /* Processor initialization register */
245
    uint32_t spve; /* Spurious vector register */
246
    uint32_t tifr; /* Timer frequency reporting register */
247
    /* Source registers */
248
    IRQSource src[MAX_IRQ];
249
    /* Local registers per output pin */
250
    IRQDest dst[MAX_CPU];
251
    uint32_t nb_cpus;
252
    /* Timer registers */
253
    struct {
254
        uint32_t ticc;  /* Global timer current count register */
255
        uint32_t tibc;  /* Global timer base count register */
256
    } timers[MAX_TMR];
257
    /* Shared MSI registers */
258
    struct {
259
        uint32_t msir;   /* Shared Message Signaled Interrupt Register */
260
    } msi[MAX_MSI];
261
    uint32_t max_irq;
262
    uint32_t irq_ipi0;
263
    uint32_t irq_tim0;
264
    uint32_t irq_msi;
265
} OpenPICState;
266

    
267
static void openpic_irq_raise(OpenPICState *opp, int n_CPU, IRQSource *src);
268

    
269
static inline void IRQ_setbit(IRQQueue *q, int n_IRQ)
270
{
271
    q->pending++;
272
    set_bit(q->queue, n_IRQ);
273
}
274

    
275
static inline void IRQ_resetbit(IRQQueue *q, int n_IRQ)
276
{
277
    q->pending--;
278
    reset_bit(q->queue, n_IRQ);
279
}
280

    
281
static inline int IRQ_testbit(IRQQueue *q, int n_IRQ)
282
{
283
    return test_bit(q->queue, n_IRQ);
284
}
285

    
286
static void IRQ_check(OpenPICState *opp, IRQQueue *q)
287
{
288
    int next, i;
289
    int priority;
290

    
291
    next = -1;
292
    priority = -1;
293

    
294
    if (!q->pending) {
295
        /* IRQ bitmap is empty */
296
        goto out;
297
    }
298

    
299
    for (i = 0; i < opp->max_irq; i++) {
300
        if (IRQ_testbit(q, i)) {
301
            DPRINTF("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n",
302
                    i, IPVP_PRIORITY(opp->src[i].ipvp), priority);
303
            if (IPVP_PRIORITY(opp->src[i].ipvp) > priority) {
304
                next = i;
305
                priority = IPVP_PRIORITY(opp->src[i].ipvp);
306
            }
307
        }
308
    }
309

    
310
out:
311
    q->next = next;
312
    q->priority = priority;
313
}
314

    
315
static int IRQ_get_next(OpenPICState *opp, IRQQueue *q)
316
{
317
    if (q->next == -1) {
318
        /* XXX: optimize */
319
        IRQ_check(opp, q);
320
    }
321

    
322
    return q->next;
323
}
324

    
325
static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ)
326
{
327
    IRQDest *dst;
328
    IRQSource *src;
329
    int priority;
330

    
331
    dst = &opp->dst[n_CPU];
332
    src = &opp->src[n_IRQ];
333
    priority = IPVP_PRIORITY(src->ipvp);
334
    if (priority <= dst->pctp) {
335
        /* Too low priority */
336
        DPRINTF("%s: IRQ %d has too low priority on CPU %d\n",
337
                __func__, n_IRQ, n_CPU);
338
        return;
339
    }
340
    if (IRQ_testbit(&dst->raised, n_IRQ)) {
341
        /* Interrupt miss */
342
        DPRINTF("%s: IRQ %d was missed on CPU %d\n",
343
                __func__, n_IRQ, n_CPU);
344
        return;
345
    }
346
    src->ipvp |= IPVP_ACTIVITY_MASK;
347
    IRQ_setbit(&dst->raised, n_IRQ);
348
    if (priority < dst->raised.priority) {
349
        /* An higher priority IRQ is already raised */
350
        DPRINTF("%s: IRQ %d is hidden by raised IRQ %d on CPU %d\n",
351
                __func__, n_IRQ, dst->raised.next, n_CPU);
352
        return;
353
    }
354
    IRQ_get_next(opp, &dst->raised);
355
    if (IRQ_get_next(opp, &dst->servicing) != -1 &&
356
        priority <= dst->servicing.priority) {
357
        DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n",
358
                __func__, n_IRQ, dst->servicing.next, n_CPU);
359
        /* Already servicing a higher priority IRQ */
360
        return;
361
    }
362
    DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", n_CPU, n_IRQ);
363
    openpic_irq_raise(opp, n_CPU, src);
364
}
365

    
366
/* update pic state because registers for n_IRQ have changed value */
367
static void openpic_update_irq(OpenPICState *opp, int n_IRQ)
368
{
369
    IRQSource *src;
370
    int i;
371

    
372
    src = &opp->src[n_IRQ];
373

    
374
    if (!src->pending) {
375
        /* no irq pending */
376
        DPRINTF("%s: IRQ %d is not pending\n", __func__, n_IRQ);
377
        return;
378
    }
379
    if (src->ipvp & IPVP_MASK_MASK) {
380
        /* Interrupt source is disabled */
381
        DPRINTF("%s: IRQ %d is disabled\n", __func__, n_IRQ);
382
        return;
383
    }
384
    if (IPVP_PRIORITY(src->ipvp) == 0) {
385
        /* Priority set to zero */
386
        DPRINTF("%s: IRQ %d has 0 priority\n", __func__, n_IRQ);
387
        return;
388
    }
389
    if (src->ipvp & IPVP_ACTIVITY_MASK) {
390
        /* IRQ already active */
391
        DPRINTF("%s: IRQ %d is already active\n", __func__, n_IRQ);
392
        return;
393
    }
394
    if (src->ide == 0) {
395
        /* No target */
396
        DPRINTF("%s: IRQ %d has no target\n", __func__, n_IRQ);
397
        return;
398
    }
399

    
400
    if (src->ide == (1 << src->last_cpu)) {
401
        /* Only one CPU is allowed to receive this IRQ */
402
        IRQ_local_pipe(opp, src->last_cpu, n_IRQ);
403
    } else if (!(src->ipvp & IPVP_MODE_MASK)) {
404
        /* Directed delivery mode */
405
        for (i = 0; i < opp->nb_cpus; i++) {
406
            if (src->ide & (1 << i)) {
407
                IRQ_local_pipe(opp, i, n_IRQ);
408
            }
409
        }
410
    } else {
411
        /* Distributed delivery mode */
412
        for (i = src->last_cpu + 1; i != src->last_cpu; i++) {
413
            if (i == opp->nb_cpus) {
414
                i = 0;
415
            }
416
            if (src->ide & (1 << i)) {
417
                IRQ_local_pipe(opp, i, n_IRQ);
418
                src->last_cpu = i;
419
                break;
420
            }
421
        }
422
    }
423
}
424

    
425
static void openpic_set_irq(void *opaque, int n_IRQ, int level)
426
{
427
    OpenPICState *opp = opaque;
428
    IRQSource *src;
429

    
430
    src = &opp->src[n_IRQ];
431
    DPRINTF("openpic: set irq %d = %d ipvp=0x%08x\n",
432
            n_IRQ, level, src->ipvp);
433
    if (src->ipvp & IPVP_SENSE_MASK) {
434
        /* level-sensitive irq */
435
        src->pending = level;
436
        if (!level) {
437
            src->ipvp &= ~IPVP_ACTIVITY_MASK;
438
        }
439
    } else {
440
        /* edge-sensitive irq */
441
        if (level) {
442
            src->pending = 1;
443
        }
444
    }
445
    openpic_update_irq(opp, n_IRQ);
446
}
447

    
448
static void openpic_reset(DeviceState *d)
449
{
450
    OpenPICState *opp = FROM_SYSBUS(typeof (*opp), sysbus_from_qdev(d));
451
    int i;
452

    
453
    opp->glbc = GLBC_RESET;
454
    /* Initialise controller registers */
455
    opp->frep = ((opp->nb_irqs - 1) << FREP_NIRQ_SHIFT) |
456
                ((opp->nb_cpus - 1) << FREP_NCPU_SHIFT) |
457
                (opp->vid << FREP_VID_SHIFT);
458

    
459
    opp->pint = 0;
460
    opp->spve = -1 & opp->vector_mask;
461
    opp->tifr = opp->tifr_reset;
462
    /* Initialise IRQ sources */
463
    for (i = 0; i < opp->max_irq; i++) {
464
        opp->src[i].ipvp = opp->ipvp_reset;
465
        opp->src[i].ide  = opp->ide_reset;
466
    }
467
    /* Initialise IRQ destinations */
468
    for (i = 0; i < MAX_CPU; i++) {
469
        opp->dst[i].pctp      = 15;
470
        memset(&opp->dst[i].raised, 0, sizeof(IRQQueue));
471
        opp->dst[i].raised.next = -1;
472
        memset(&opp->dst[i].servicing, 0, sizeof(IRQQueue));
473
        opp->dst[i].servicing.next = -1;
474
    }
475
    /* Initialise timers */
476
    for (i = 0; i < MAX_TMR; i++) {
477
        opp->timers[i].ticc = 0;
478
        opp->timers[i].tibc = TIBC_CI;
479
    }
480
    /* Go out of RESET state */
481
    opp->glbc = 0;
482
}
483

    
484
static inline uint32_t read_IRQreg_ide(OpenPICState *opp, int n_IRQ)
485
{
486
    return opp->src[n_IRQ].ide;
487
}
488

    
489
static inline uint32_t read_IRQreg_ipvp(OpenPICState *opp, int n_IRQ)
490
{
491
    return opp->src[n_IRQ].ipvp;
492
}
493

    
494
static inline void write_IRQreg_ide(OpenPICState *opp, int n_IRQ, uint32_t val)
495
{
496
    uint32_t tmp;
497

    
498
    tmp = val & (IDE_EP | IDE_CI);
499
    tmp |= val & ((1ULL << MAX_CPU) - 1);
500
    opp->src[n_IRQ].ide = tmp;
501
    DPRINTF("Set IDE %d to 0x%08x\n", n_IRQ, opp->src[n_IRQ].ide);
502
}
503

    
504
static inline void write_IRQreg_ipvp(OpenPICState *opp, int n_IRQ, uint32_t val)
505
{
506
    /* NOTE: not fully accurate for special IRQs, but simple and sufficient */
507
    /* ACTIVITY bit is read-only */
508
    opp->src[n_IRQ].ipvp = (opp->src[n_IRQ].ipvp & IPVP_ACTIVITY_MASK) |
509
        (val & (IPVP_MASK_MASK | IPVP_PRIORITY_MASK | opp->vector_mask));
510
    openpic_update_irq(opp, n_IRQ);
511
    DPRINTF("Set IPVP %d to 0x%08x -> 0x%08x\n", n_IRQ, val,
512
            opp->src[n_IRQ].ipvp);
513
}
514

    
515
static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,
516
                              unsigned len)
517
{
518
    OpenPICState *opp = opaque;
519
    IRQDest *dst;
520
    int idx;
521

    
522
    DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n",
523
            __func__, addr, val);
524
    if (addr & 0xF) {
525
        return;
526
    }
527
    switch (addr) {
528
    case 0x00: /* Block Revision Register1 (BRR1) is Readonly */
529
        break;
530
    case 0x40:
531
    case 0x50:
532
    case 0x60:
533
    case 0x70:
534
    case 0x80:
535
    case 0x90:
536
    case 0xA0:
537
    case 0xB0:
538
        openpic_cpu_write_internal(opp, addr, val, get_current_cpu());
539
        break;
540
    case 0x1000: /* FREP */
541
        break;
542
    case 0x1020: /* GLBC */
543
        if (val & GLBC_RESET) {
544
            openpic_reset(&opp->busdev.qdev);
545
        }
546
        break;
547
    case 0x1080: /* VENI */
548
        break;
549
    case 0x1090: /* PINT */
550
        for (idx = 0; idx < opp->nb_cpus; idx++) {
551
            if ((val & (1 << idx)) && !(opp->pint & (1 << idx))) {
552
                DPRINTF("Raise OpenPIC RESET output for CPU %d\n", idx);
553
                dst = &opp->dst[idx];
554
                qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_RESET]);
555
            } else if (!(val & (1 << idx)) && (opp->pint & (1 << idx))) {
556
                DPRINTF("Lower OpenPIC RESET output for CPU %d\n", idx);
557
                dst = &opp->dst[idx];
558
                qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_RESET]);
559
            }
560
        }
561
        opp->pint = val;
562
        break;
563
    case 0x10A0: /* IPI_IPVP */
564
    case 0x10B0:
565
    case 0x10C0:
566
    case 0x10D0:
567
        {
568
            int idx;
569
            idx = (addr - 0x10A0) >> 4;
570
            write_IRQreg_ipvp(opp, opp->irq_ipi0 + idx, val);
571
        }
572
        break;
573
    case 0x10E0: /* SPVE */
574
        opp->spve = val & opp->vector_mask;
575
        break;
576
    default:
577
        break;
578
    }
579
}
580

    
581
static uint64_t openpic_gbl_read(void *opaque, hwaddr addr, unsigned len)
582
{
583
    OpenPICState *opp = opaque;
584
    uint32_t retval;
585

    
586
    DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
587
    retval = 0xFFFFFFFF;
588
    if (addr & 0xF) {
589
        return retval;
590
    }
591
    switch (addr) {
592
    case 0x1000: /* FREP */
593
        retval = opp->frep;
594
        break;
595
    case 0x1020: /* GLBC */
596
        retval = opp->glbc;
597
        break;
598
    case 0x1080: /* VENI */
599
        retval = opp->veni;
600
        break;
601
    case 0x1090: /* PINT */
602
        retval = 0x00000000;
603
        break;
604
    case 0x00: /* Block Revision Register1 (BRR1) */
605
        retval = opp->brr1;
606
        break;
607
    case 0x40:
608
    case 0x50:
609
    case 0x60:
610
    case 0x70:
611
    case 0x80:
612
    case 0x90:
613
    case 0xA0:
614
    case 0xB0:
615
        retval = openpic_cpu_read_internal(opp, addr, get_current_cpu());
616
        break;
617
    case 0x10A0: /* IPI_IPVP */
618
    case 0x10B0:
619
    case 0x10C0:
620
    case 0x10D0:
621
        {
622
            int idx;
623
            idx = (addr - 0x10A0) >> 4;
624
            retval = read_IRQreg_ipvp(opp, opp->irq_ipi0 + idx);
625
        }
626
        break;
627
    case 0x10E0: /* SPVE */
628
        retval = opp->spve;
629
        break;
630
    default:
631
        break;
632
    }
633
    DPRINTF("%s: => 0x%08x\n", __func__, retval);
634

    
635
    return retval;
636
}
637

    
638
static void openpic_tmr_write(void *opaque, hwaddr addr, uint64_t val,
639
                                unsigned len)
640
{
641
    OpenPICState *opp = opaque;
642
    int idx;
643

    
644
    DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n",
645
            __func__, addr, val);
646
    if (addr & 0xF) {
647
        return;
648
    }
649
    idx = (addr >> 6) & 0x3;
650
    addr = addr & 0x30;
651

    
652
    if (addr == 0x0) {
653
        /* TIFR (TFRR) */
654
        opp->tifr = val;
655
        return;
656
    }
657
    switch (addr & 0x30) {
658
    case 0x00: /* TICC (GTCCR) */
659
        break;
660
    case 0x10: /* TIBC (GTBCR) */
661
        if ((opp->timers[idx].ticc & TICC_TOG) != 0 &&
662
            (val & TIBC_CI) == 0 &&
663
            (opp->timers[idx].tibc & TIBC_CI) != 0) {
664
            opp->timers[idx].ticc &= ~TICC_TOG;
665
        }
666
        opp->timers[idx].tibc = val;
667
        break;
668
    case 0x20: /* TIVP (GTIVPR) */
669
        write_IRQreg_ipvp(opp, opp->irq_tim0 + idx, val);
670
        break;
671
    case 0x30: /* TIDE (GTIDR) */
672
        write_IRQreg_ide(opp, opp->irq_tim0 + idx, val);
673
        break;
674
    }
675
}
676

    
677
static uint64_t openpic_tmr_read(void *opaque, hwaddr addr, unsigned len)
678
{
679
    OpenPICState *opp = opaque;
680
    uint32_t retval = -1;
681
    int idx;
682

    
683
    DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
684
    if (addr & 0xF) {
685
        goto out;
686
    }
687
    idx = (addr >> 6) & 0x3;
688
    if (addr == 0x0) {
689
        /* TIFR (TFRR) */
690
        retval = opp->tifr;
691
        goto out;
692
    }
693
    switch (addr & 0x30) {
694
    case 0x00: /* TICC (GTCCR) */
695
        retval = opp->timers[idx].ticc;
696
        break;
697
    case 0x10: /* TIBC (GTBCR) */
698
        retval = opp->timers[idx].tibc;
699
        break;
700
    case 0x20: /* TIPV (TIPV) */
701
        retval = read_IRQreg_ipvp(opp, opp->irq_tim0 + idx);
702
        break;
703
    case 0x30: /* TIDE (TIDR) */
704
        retval = read_IRQreg_ide(opp, opp->irq_tim0 + idx);
705
        break;
706
    }
707

    
708
out:
709
    DPRINTF("%s: => 0x%08x\n", __func__, retval);
710

    
711
    return retval;
712
}
713

    
714
static void openpic_src_write(void *opaque, hwaddr addr, uint64_t val,
715
                              unsigned len)
716
{
717
    OpenPICState *opp = opaque;
718
    int idx;
719

    
720
    DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n",
721
            __func__, addr, val);
722
    if (addr & 0xF) {
723
        return;
724
    }
725
    addr = addr & 0xFFF0;
726
    idx = addr >> 5;
727
    if (addr & 0x10) {
728
        /* EXDE / IFEDE / IEEDE */
729
        write_IRQreg_ide(opp, idx, val);
730
    } else {
731
        /* EXVP / IFEVP / IEEVP */
732
        write_IRQreg_ipvp(opp, idx, val);
733
    }
734
}
735

    
736
static uint64_t openpic_src_read(void *opaque, uint64_t addr, unsigned len)
737
{
738
    OpenPICState *opp = opaque;
739
    uint32_t retval;
740
    int idx;
741

    
742
    DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
743
    retval = 0xFFFFFFFF;
744
    if (addr & 0xF) {
745
        return retval;
746
    }
747
    addr = addr & 0xFFF0;
748
    idx = addr >> 5;
749
    if (addr & 0x10) {
750
        /* EXDE / IFEDE / IEEDE */
751
        retval = read_IRQreg_ide(opp, idx);
752
    } else {
753
        /* EXVP / IFEVP / IEEVP */
754
        retval = read_IRQreg_ipvp(opp, idx);
755
    }
756
    DPRINTF("%s: => 0x%08x\n", __func__, retval);
757

    
758
    return retval;
759
}
760

    
761
static void openpic_msi_write(void *opaque, hwaddr addr, uint64_t val,
762
                              unsigned size)
763
{
764
    OpenPICState *opp = opaque;
765
    int idx = opp->irq_msi;
766
    int srs, ibs;
767

    
768
    DPRINTF("%s: addr %#" HWADDR_PRIx " <= 0x%08" PRIx64 "\n",
769
            __func__, addr, val);
770
    if (addr & 0xF) {
771
        return;
772
    }
773

    
774
    switch (addr) {
775
    case MSIIR_OFFSET:
776
        srs = val >> MSIIR_SRS_SHIFT;
777
        idx += srs;
778
        ibs = (val & MSIIR_IBS_MASK) >> MSIIR_IBS_SHIFT;
779
        opp->msi[srs].msir |= 1 << ibs;
780
        openpic_set_irq(opp, idx, 1);
781
        break;
782
    default:
783
        /* most registers are read-only, thus ignored */
784
        break;
785
    }
786
}
787

    
788
static uint64_t openpic_msi_read(void *opaque, hwaddr addr, unsigned size)
789
{
790
    OpenPICState *opp = opaque;
791
    uint64_t r = 0;
792
    int i, srs;
793

    
794
    DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
795
    if (addr & 0xF) {
796
        return -1;
797
    }
798

    
799
    srs = addr >> 4;
800

    
801
    switch (addr) {
802
    case 0x00:
803
    case 0x10:
804
    case 0x20:
805
    case 0x30:
806
    case 0x40:
807
    case 0x50:
808
    case 0x60:
809
    case 0x70: /* MSIRs */
810
        r = opp->msi[srs].msir;
811
        /* Clear on read */
812
        opp->msi[srs].msir = 0;
813
        openpic_set_irq(opp, opp->irq_msi + srs, 0);
814
        break;
815
    case 0x120: /* MSISR */
816
        for (i = 0; i < MAX_MSI; i++) {
817
            r |= (opp->msi[i].msir ? 1 : 0) << i;
818
        }
819
        break;
820
    }
821

    
822
    return r;
823
}
824

    
825
static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
826
                                       uint32_t val, int idx)
827
{
828
    OpenPICState *opp = opaque;
829
    IRQSource *src;
830
    IRQDest *dst;
831
    int s_IRQ, n_IRQ;
832

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

    
836
    if (idx < 0) {
837
        return;
838
    }
839

    
840
    if (addr & 0xF) {
841
        return;
842
    }
843
    dst = &opp->dst[idx];
844
    addr &= 0xFF0;
845
    switch (addr) {
846
    case 0x40: /* IPIDR */
847
    case 0x50:
848
    case 0x60:
849
    case 0x70:
850
        idx = (addr - 0x40) >> 4;
851
        /* we use IDE as mask which CPUs to deliver the IPI to still. */
852
        write_IRQreg_ide(opp, opp->irq_ipi0 + idx,
853
                         opp->src[opp->irq_ipi0 + idx].ide | val);
854
        openpic_set_irq(opp, opp->irq_ipi0 + idx, 1);
855
        openpic_set_irq(opp, opp->irq_ipi0 + idx, 0);
856
        break;
857
    case 0x80: /* PCTP */
858
        dst->pctp = val & 0x0000000F;
859
        break;
860
    case 0x90: /* WHOAMI */
861
        /* Read-only register */
862
        break;
863
    case 0xA0: /* PIAC */
864
        /* Read-only register */
865
        break;
866
    case 0xB0: /* PEOI */
867
        DPRINTF("PEOI\n");
868
        s_IRQ = IRQ_get_next(opp, &dst->servicing);
869
        IRQ_resetbit(&dst->servicing, s_IRQ);
870
        dst->servicing.next = -1;
871
        /* Set up next servicing IRQ */
872
        s_IRQ = IRQ_get_next(opp, &dst->servicing);
873
        /* Check queued interrupts. */
874
        n_IRQ = IRQ_get_next(opp, &dst->raised);
875
        src = &opp->src[n_IRQ];
876
        if (n_IRQ != -1 &&
877
            (s_IRQ == -1 ||
878
             IPVP_PRIORITY(src->ipvp) > dst->servicing.priority)) {
879
            DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n",
880
                    idx, n_IRQ);
881
            openpic_irq_raise(opp, idx, src);
882
        }
883
        break;
884
    default:
885
        break;
886
    }
887
}
888

    
889
static void openpic_cpu_write(void *opaque, hwaddr addr, uint64_t val,
890
                              unsigned len)
891
{
892
    openpic_cpu_write_internal(opaque, addr, val, (addr & 0x1f000) >> 12);
893
}
894

    
895
static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
896
                                          int idx)
897
{
898
    OpenPICState *opp = opaque;
899
    IRQSource *src;
900
    IRQDest *dst;
901
    uint32_t retval;
902
    int n_IRQ;
903

    
904
    DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx "\n", __func__, idx, addr);
905
    retval = 0xFFFFFFFF;
906

    
907
    if (idx < 0) {
908
        return retval;
909
    }
910

    
911
    if (addr & 0xF) {
912
        return retval;
913
    }
914
    dst = &opp->dst[idx];
915
    addr &= 0xFF0;
916
    switch (addr) {
917
    case 0x80: /* PCTP */
918
        retval = dst->pctp;
919
        break;
920
    case 0x90: /* WHOAMI */
921
        retval = idx;
922
        break;
923
    case 0xA0: /* PIAC */
924
        DPRINTF("Lower OpenPIC INT output\n");
925
        qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);
926
        n_IRQ = IRQ_get_next(opp, &dst->raised);
927
        DPRINTF("PIAC: irq=%d\n", n_IRQ);
928
        if (n_IRQ == -1) {
929
            /* No more interrupt pending */
930
            retval = opp->spve;
931
        } else {
932
            src = &opp->src[n_IRQ];
933
            if (!(src->ipvp & IPVP_ACTIVITY_MASK) ||
934
                !(IPVP_PRIORITY(src->ipvp) > dst->pctp)) {
935
                /* - Spurious level-sensitive IRQ
936
                 * - Priorities has been changed
937
                 *   and the pending IRQ isn't allowed anymore
938
                 */
939
                src->ipvp &= ~IPVP_ACTIVITY_MASK;
940
                retval = opp->spve;
941
            } else {
942
                /* IRQ enter servicing state */
943
                IRQ_setbit(&dst->servicing, n_IRQ);
944
                retval = IPVP_VECTOR(opp, src->ipvp);
945
            }
946
            IRQ_resetbit(&dst->raised, n_IRQ);
947
            dst->raised.next = -1;
948
            if (!(src->ipvp & IPVP_SENSE_MASK)) {
949
                /* edge-sensitive IRQ */
950
                src->ipvp &= ~IPVP_ACTIVITY_MASK;
951
                src->pending = 0;
952
            }
953

    
954
            if ((n_IRQ >= opp->irq_ipi0) &&  (n_IRQ < (opp->irq_ipi0 + MAX_IPI))) {
955
                src->ide &= ~(1 << idx);
956
                if (src->ide && !(src->ipvp & IPVP_SENSE_MASK)) {
957
                    /* trigger on CPUs that didn't know about it yet */
958
                    openpic_set_irq(opp, n_IRQ, 1);
959
                    openpic_set_irq(opp, n_IRQ, 0);
960
                    /* if all CPUs knew about it, set active bit again */
961
                    src->ipvp |= IPVP_ACTIVITY_MASK;
962
                }
963
            }
964
        }
965
        break;
966
    case 0xB0: /* PEOI */
967
        retval = 0;
968
        break;
969
    default:
970
        break;
971
    }
972
    DPRINTF("%s: => 0x%08x\n", __func__, retval);
973

    
974
    return retval;
975
}
976

    
977
static uint64_t openpic_cpu_read(void *opaque, hwaddr addr, unsigned len)
978
{
979
    return openpic_cpu_read_internal(opaque, addr, (addr & 0x1f000) >> 12);
980
}
981

    
982
static const MemoryRegionOps openpic_glb_ops_le = {
983
    .write = openpic_gbl_write,
984
    .read  = openpic_gbl_read,
985
    .endianness = DEVICE_LITTLE_ENDIAN,
986
    .impl = {
987
        .min_access_size = 4,
988
        .max_access_size = 4,
989
    },
990
};
991

    
992
static const MemoryRegionOps openpic_glb_ops_be = {
993
    .write = openpic_gbl_write,
994
    .read  = openpic_gbl_read,
995
    .endianness = DEVICE_BIG_ENDIAN,
996
    .impl = {
997
        .min_access_size = 4,
998
        .max_access_size = 4,
999
    },
1000
};
1001

    
1002
static const MemoryRegionOps openpic_tmr_ops_le = {
1003
    .write = openpic_tmr_write,
1004
    .read  = openpic_tmr_read,
1005
    .endianness = DEVICE_LITTLE_ENDIAN,
1006
    .impl = {
1007
        .min_access_size = 4,
1008
        .max_access_size = 4,
1009
    },
1010
};
1011

    
1012
static const MemoryRegionOps openpic_tmr_ops_be = {
1013
    .write = openpic_tmr_write,
1014
    .read  = openpic_tmr_read,
1015
    .endianness = DEVICE_BIG_ENDIAN,
1016
    .impl = {
1017
        .min_access_size = 4,
1018
        .max_access_size = 4,
1019
    },
1020
};
1021

    
1022
static const MemoryRegionOps openpic_cpu_ops_le = {
1023
    .write = openpic_cpu_write,
1024
    .read  = openpic_cpu_read,
1025
    .endianness = DEVICE_LITTLE_ENDIAN,
1026
    .impl = {
1027
        .min_access_size = 4,
1028
        .max_access_size = 4,
1029
    },
1030
};
1031

    
1032
static const MemoryRegionOps openpic_cpu_ops_be = {
1033
    .write = openpic_cpu_write,
1034
    .read  = openpic_cpu_read,
1035
    .endianness = DEVICE_BIG_ENDIAN,
1036
    .impl = {
1037
        .min_access_size = 4,
1038
        .max_access_size = 4,
1039
    },
1040
};
1041

    
1042
static const MemoryRegionOps openpic_src_ops_le = {
1043
    .write = openpic_src_write,
1044
    .read  = openpic_src_read,
1045
    .endianness = DEVICE_LITTLE_ENDIAN,
1046
    .impl = {
1047
        .min_access_size = 4,
1048
        .max_access_size = 4,
1049
    },
1050
};
1051

    
1052
static const MemoryRegionOps openpic_src_ops_be = {
1053
    .write = openpic_src_write,
1054
    .read  = openpic_src_read,
1055
    .endianness = DEVICE_BIG_ENDIAN,
1056
    .impl = {
1057
        .min_access_size = 4,
1058
        .max_access_size = 4,
1059
    },
1060
};
1061

    
1062
static const MemoryRegionOps openpic_msi_ops_le = {
1063
    .read = openpic_msi_read,
1064
    .write = openpic_msi_write,
1065
    .endianness = DEVICE_LITTLE_ENDIAN,
1066
    .impl = {
1067
        .min_access_size = 4,
1068
        .max_access_size = 4,
1069
    },
1070
};
1071

    
1072
static const MemoryRegionOps openpic_msi_ops_be = {
1073
    .read = openpic_msi_read,
1074
    .write = openpic_msi_write,
1075
    .endianness = DEVICE_BIG_ENDIAN,
1076
    .impl = {
1077
        .min_access_size = 4,
1078
        .max_access_size = 4,
1079
    },
1080
};
1081

    
1082
static void openpic_save_IRQ_queue(QEMUFile* f, IRQQueue *q)
1083
{
1084
    unsigned int i;
1085

    
1086
    for (i = 0; i < BF_WIDTH(MAX_IRQ); i++)
1087
        qemu_put_be32s(f, &q->queue[i]);
1088

    
1089
    qemu_put_sbe32s(f, &q->next);
1090
    qemu_put_sbe32s(f, &q->priority);
1091
}
1092

    
1093
static void openpic_save(QEMUFile* f, void *opaque)
1094
{
1095
    OpenPICState *opp = (OpenPICState *)opaque;
1096
    unsigned int i;
1097

    
1098
    qemu_put_be32s(f, &opp->glbc);
1099
    qemu_put_be32s(f, &opp->veni);
1100
    qemu_put_be32s(f, &opp->pint);
1101
    qemu_put_be32s(f, &opp->spve);
1102
    qemu_put_be32s(f, &opp->tifr);
1103

    
1104
    for (i = 0; i < opp->max_irq; i++) {
1105
        qemu_put_be32s(f, &opp->src[i].ipvp);
1106
        qemu_put_be32s(f, &opp->src[i].ide);
1107
        qemu_put_sbe32s(f, &opp->src[i].last_cpu);
1108
        qemu_put_sbe32s(f, &opp->src[i].pending);
1109
    }
1110

    
1111
    qemu_put_be32s(f, &opp->nb_cpus);
1112

    
1113
    for (i = 0; i < opp->nb_cpus; i++) {
1114
        qemu_put_be32s(f, &opp->dst[i].pctp);
1115
        openpic_save_IRQ_queue(f, &opp->dst[i].raised);
1116
        openpic_save_IRQ_queue(f, &opp->dst[i].servicing);
1117
    }
1118

    
1119
    for (i = 0; i < MAX_TMR; i++) {
1120
        qemu_put_be32s(f, &opp->timers[i].ticc);
1121
        qemu_put_be32s(f, &opp->timers[i].tibc);
1122
    }
1123
}
1124

    
1125
static void openpic_load_IRQ_queue(QEMUFile* f, IRQQueue *q)
1126
{
1127
    unsigned int i;
1128

    
1129
    for (i = 0; i < BF_WIDTH(MAX_IRQ); i++)
1130
        qemu_get_be32s(f, &q->queue[i]);
1131

    
1132
    qemu_get_sbe32s(f, &q->next);
1133
    qemu_get_sbe32s(f, &q->priority);
1134
}
1135

    
1136
static int openpic_load(QEMUFile* f, void *opaque, int version_id)
1137
{
1138
    OpenPICState *opp = (OpenPICState *)opaque;
1139
    unsigned int i;
1140

    
1141
    if (version_id != 1) {
1142
        return -EINVAL;
1143
    }
1144

    
1145
    qemu_get_be32s(f, &opp->glbc);
1146
    qemu_get_be32s(f, &opp->veni);
1147
    qemu_get_be32s(f, &opp->pint);
1148
    qemu_get_be32s(f, &opp->spve);
1149
    qemu_get_be32s(f, &opp->tifr);
1150

    
1151
    for (i = 0; i < opp->max_irq; i++) {
1152
        qemu_get_be32s(f, &opp->src[i].ipvp);
1153
        qemu_get_be32s(f, &opp->src[i].ide);
1154
        qemu_get_sbe32s(f, &opp->src[i].last_cpu);
1155
        qemu_get_sbe32s(f, &opp->src[i].pending);
1156
    }
1157

    
1158
    qemu_get_be32s(f, &opp->nb_cpus);
1159

    
1160
    for (i = 0; i < opp->nb_cpus; i++) {
1161
        qemu_get_be32s(f, &opp->dst[i].pctp);
1162
        openpic_load_IRQ_queue(f, &opp->dst[i].raised);
1163
        openpic_load_IRQ_queue(f, &opp->dst[i].servicing);
1164
    }
1165

    
1166
    for (i = 0; i < MAX_TMR; i++) {
1167
        qemu_get_be32s(f, &opp->timers[i].ticc);
1168
        qemu_get_be32s(f, &opp->timers[i].tibc);
1169
    }
1170

    
1171
    return 0;
1172
}
1173

    
1174
static void openpic_irq_raise(OpenPICState *opp, int n_CPU, IRQSource *src)
1175
{
1176
    int n_ci = IDR_CI0_SHIFT - n_CPU;
1177

    
1178
    if ((opp->flags & OPENPIC_FLAG_IDE_CRIT) && (src->ide & (1 << n_ci))) {
1179
        qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_CINT]);
1180
    } else {
1181
        qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
1182
    }
1183
}
1184

    
1185
typedef struct MemReg {
1186
    const char             *name;
1187
    MemoryRegionOps const  *ops;
1188
    bool                   map;
1189
    hwaddr      start_addr;
1190
    ram_addr_t              size;
1191
} MemReg;
1192

    
1193
static int openpic_init(SysBusDevice *dev)
1194
{
1195
    OpenPICState *opp = FROM_SYSBUS(typeof (*opp), dev);
1196
    int i, j;
1197
    MemReg list_le[] = {
1198
        {"glb", &openpic_glb_ops_le, true,
1199
                OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE},
1200
        {"tmr", &openpic_tmr_ops_le, true,
1201
                OPENPIC_TMR_REG_START, OPENPIC_TMR_REG_SIZE},
1202
        {"msi", &openpic_msi_ops_le, true,
1203
                OPENPIC_MSI_REG_START, OPENPIC_MSI_REG_SIZE},
1204
        {"src", &openpic_src_ops_le, true,
1205
                OPENPIC_SRC_REG_START, OPENPIC_SRC_REG_SIZE},
1206
        {"cpu", &openpic_cpu_ops_le, true,
1207
                OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE},
1208
    };
1209
    MemReg list_be[] = {
1210
        {"glb", &openpic_glb_ops_be, true,
1211
                OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE},
1212
        {"tmr", &openpic_tmr_ops_be, true,
1213
                OPENPIC_TMR_REG_START, OPENPIC_TMR_REG_SIZE},
1214
        {"msi", &openpic_msi_ops_be, true,
1215
                OPENPIC_MSI_REG_START, OPENPIC_MSI_REG_SIZE},
1216
        {"src", &openpic_src_ops_be, true,
1217
                OPENPIC_SRC_REG_START, OPENPIC_SRC_REG_SIZE},
1218
        {"cpu", &openpic_cpu_ops_be, true,
1219
                OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE},
1220
    };
1221
    MemReg *list;
1222

    
1223
    switch (opp->model) {
1224
    case OPENPIC_MODEL_FSL_MPIC_20:
1225
    default:
1226
        opp->flags |= OPENPIC_FLAG_IDE_CRIT;
1227
        opp->nb_irqs = 80;
1228
        opp->vid = VID_REVISION_1_2;
1229
        opp->veni = VENI_GENERIC;
1230
        opp->vector_mask = 0xFFFF;
1231
        opp->tifr_reset = 0;
1232
        opp->ipvp_reset = IPVP_MASK_MASK;
1233
        opp->ide_reset = 1 << 0;
1234
        opp->max_irq = FSL_MPIC_20_MAX_IRQ;
1235
        opp->irq_ipi0 = FSL_MPIC_20_IPI_IRQ;
1236
        opp->irq_tim0 = FSL_MPIC_20_TMR_IRQ;
1237
        opp->irq_msi = FSL_MPIC_20_MSI_IRQ;
1238
        opp->brr1 = FSL_BRR1_IPID | FSL_BRR1_IPMJ | FSL_BRR1_IPMN;
1239
        msi_supported = true;
1240
        list = list_be;
1241
        break;
1242
    case OPENPIC_MODEL_RAVEN:
1243
        opp->nb_irqs = RAVEN_MAX_EXT;
1244
        opp->vid = VID_REVISION_1_3;
1245
        opp->veni = VENI_GENERIC;
1246
        opp->vector_mask = 0xFF;
1247
        opp->tifr_reset = 4160000;
1248
        opp->ipvp_reset = IPVP_MASK_MASK | IPVP_MODE_MASK;
1249
        opp->ide_reset = 0;
1250
        opp->max_irq = RAVEN_MAX_IRQ;
1251
        opp->irq_ipi0 = RAVEN_IPI_IRQ;
1252
        opp->irq_tim0 = RAVEN_TMR_IRQ;
1253
        opp->brr1 = -1;
1254
        list = list_le;
1255
        /* Don't map MSI region */
1256
        list[2].map = false;
1257

    
1258
        /* Only UP supported today */
1259
        if (opp->nb_cpus != 1) {
1260
            return -EINVAL;
1261
        }
1262
        break;
1263
    }
1264

    
1265
    memory_region_init(&opp->mem, "openpic", 0x40000);
1266

    
1267
    for (i = 0; i < ARRAY_SIZE(list_le); i++) {
1268
        if (!list[i].map) {
1269
            continue;
1270
        }
1271

    
1272
        memory_region_init_io(&opp->sub_io_mem[i], list[i].ops, opp,
1273
                              list[i].name, list[i].size);
1274

    
1275
        memory_region_add_subregion(&opp->mem, list[i].start_addr,
1276
                                    &opp->sub_io_mem[i]);
1277
    }
1278

    
1279
    for (i = 0; i < opp->nb_cpus; i++) {
1280
        opp->dst[i].irqs = g_new(qemu_irq, OPENPIC_OUTPUT_NB);
1281
        for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
1282
            sysbus_init_irq(dev, &opp->dst[i].irqs[j]);
1283
        }
1284
    }
1285

    
1286
    register_savevm(&opp->busdev.qdev, "openpic", 0, 2,
1287
                    openpic_save, openpic_load, opp);
1288

    
1289
    sysbus_init_mmio(dev, &opp->mem);
1290
    qdev_init_gpio_in(&dev->qdev, openpic_set_irq, opp->max_irq);
1291

    
1292
    return 0;
1293
}
1294

    
1295
static Property openpic_properties[] = {
1296
    DEFINE_PROP_UINT32("model", OpenPICState, model, OPENPIC_MODEL_FSL_MPIC_20),
1297
    DEFINE_PROP_UINT32("nb_cpus", OpenPICState, nb_cpus, 1),
1298
    DEFINE_PROP_END_OF_LIST(),
1299
};
1300

    
1301
static void openpic_class_init(ObjectClass *klass, void *data)
1302
{
1303
    DeviceClass *dc = DEVICE_CLASS(klass);
1304
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
1305

    
1306
    k->init = openpic_init;
1307
    dc->props = openpic_properties;
1308
    dc->reset = openpic_reset;
1309
}
1310

    
1311
static TypeInfo openpic_info = {
1312
    .name          = "openpic",
1313
    .parent        = TYPE_SYS_BUS_DEVICE,
1314
    .instance_size = sizeof(OpenPICState),
1315
    .class_init    = openpic_class_init,
1316
};
1317

    
1318
static void openpic_register_types(void)
1319
{
1320
    type_register_static(&openpic_info);
1321
}
1322

    
1323
type_init(openpic_register_types)