xref: /openbmc/qemu/hw/intc/openpic.c (revision 3d9569b8)
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 
37 #include "qemu/osdep.h"
38 #include "hw/hw.h"
39 #include "hw/ppc/mac.h"
40 #include "hw/pci/pci.h"
41 #include "hw/ppc/openpic.h"
42 #include "hw/ppc/ppc_e500.h"
43 #include "hw/sysbus.h"
44 #include "hw/pci/msi.h"
45 #include "qapi/error.h"
46 #include "qemu/bitops.h"
47 #include "qapi/qmp/qerror.h"
48 #include "qemu/log.h"
49 #include "qemu/module.h"
50 #include "qemu/timer.h"
51 #include "qemu/error-report.h"
52 
53 //#define DEBUG_OPENPIC
54 
55 #ifdef DEBUG_OPENPIC
56 static const int debug_openpic = 1;
57 #else
58 static const int debug_openpic = 0;
59 #endif
60 
61 static int get_current_cpu(void);
62 #define DPRINTF(fmt, ...) do { \
63         if (debug_openpic) { \
64             info_report("Core%d: " fmt, get_current_cpu(), ## __VA_ARGS__); \
65         } \
66     } while (0)
67 
68 /* OpenPIC capability flags */
69 #define OPENPIC_FLAG_IDR_CRIT     (1 << 0)
70 #define OPENPIC_FLAG_ILR          (2 << 0)
71 
72 /* OpenPIC address map */
73 #define OPENPIC_GLB_REG_START        0x0
74 #define OPENPIC_GLB_REG_SIZE         0x10F0
75 #define OPENPIC_TMR_REG_START        0x10F0
76 #define OPENPIC_TMR_REG_SIZE         0x220
77 #define OPENPIC_MSI_REG_START        0x1600
78 #define OPENPIC_MSI_REG_SIZE         0x200
79 #define OPENPIC_SUMMARY_REG_START   0x3800
80 #define OPENPIC_SUMMARY_REG_SIZE    0x800
81 #define OPENPIC_SRC_REG_START        0x10000
82 #define OPENPIC_SRC_REG_SIZE         (OPENPIC_MAX_SRC * 0x20)
83 #define OPENPIC_CPU_REG_START        0x20000
84 #define OPENPIC_CPU_REG_SIZE         0x100 + ((MAX_CPU - 1) * 0x1000)
85 
86 static FslMpicInfo fsl_mpic_20 = {
87     .max_ext = 12,
88 };
89 
90 static FslMpicInfo fsl_mpic_42 = {
91     .max_ext = 12,
92 };
93 
94 #define FRR_NIRQ_SHIFT    16
95 #define FRR_NCPU_SHIFT     8
96 #define FRR_VID_SHIFT      0
97 
98 #define VID_REVISION_1_2   2
99 #define VID_REVISION_1_3   3
100 
101 #define VIR_GENERIC      0x00000000 /* Generic Vendor ID */
102 #define VIR_MPIC2A       0x00004614 /* IBM MPIC-2A */
103 
104 #define GCR_RESET        0x80000000
105 #define GCR_MODE_PASS    0x00000000
106 #define GCR_MODE_MIXED   0x20000000
107 #define GCR_MODE_PROXY   0x60000000
108 
109 #define TBCR_CI           0x80000000 /* count inhibit */
110 #define TCCR_TOG          0x80000000 /* toggles when decrement to zero */
111 
112 #define IDR_EP_SHIFT      31
113 #define IDR_EP_MASK       (1U << IDR_EP_SHIFT)
114 #define IDR_CI0_SHIFT     30
115 #define IDR_CI1_SHIFT     29
116 #define IDR_P1_SHIFT      1
117 #define IDR_P0_SHIFT      0
118 
119 #define ILR_INTTGT_MASK   0x000000ff
120 #define ILR_INTTGT_INT    0x00
121 #define ILR_INTTGT_CINT   0x01 /* critical */
122 #define ILR_INTTGT_MCP    0x02 /* machine check */
123 
124 /* The currently supported INTTGT values happen to be the same as QEMU's
125  * openpic output codes, but don't depend on this.  The output codes
126  * could change (unlikely, but...) or support could be added for
127  * more INTTGT values.
128  */
129 static const int inttgt_output[][2] = {
130     { ILR_INTTGT_INT, OPENPIC_OUTPUT_INT },
131     { ILR_INTTGT_CINT, OPENPIC_OUTPUT_CINT },
132     { ILR_INTTGT_MCP, OPENPIC_OUTPUT_MCK },
133 };
134 
135 static int inttgt_to_output(int inttgt)
136 {
137     int i;
138 
139     for (i = 0; i < ARRAY_SIZE(inttgt_output); i++) {
140         if (inttgt_output[i][0] == inttgt) {
141             return inttgt_output[i][1];
142         }
143     }
144 
145     error_report("%s: unsupported inttgt %d", __func__, inttgt);
146     return OPENPIC_OUTPUT_INT;
147 }
148 
149 static int output_to_inttgt(int output)
150 {
151     int i;
152 
153     for (i = 0; i < ARRAY_SIZE(inttgt_output); i++) {
154         if (inttgt_output[i][1] == output) {
155             return inttgt_output[i][0];
156         }
157     }
158 
159     abort();
160 }
161 
162 #define MSIIR_OFFSET       0x140
163 #define MSIIR_SRS_SHIFT    29
164 #define MSIIR_SRS_MASK     (0x7 << MSIIR_SRS_SHIFT)
165 #define MSIIR_IBS_SHIFT    24
166 #define MSIIR_IBS_MASK     (0x1f << MSIIR_IBS_SHIFT)
167 
168 static int get_current_cpu(void)
169 {
170     if (!current_cpu) {
171         return -1;
172     }
173 
174     return current_cpu->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 static void openpic_reset(DeviceState *d);
182 
183 /* Convert between openpic clock ticks and nanosecs.  In the hardware the clock
184    frequency is driven by board inputs to the PIC which the PIC would then
185    divide by 4 or 8.  For now hard code to 25MZ.
186 */
187 #define OPENPIC_TIMER_FREQ_MHZ 25
188 #define OPENPIC_TIMER_NS_PER_TICK (1000 / OPENPIC_TIMER_FREQ_MHZ)
189 static inline uint64_t ns_to_ticks(uint64_t ns)
190 {
191     return ns    / OPENPIC_TIMER_NS_PER_TICK;
192 }
193 static inline uint64_t ticks_to_ns(uint64_t ticks)
194 {
195     return ticks * OPENPIC_TIMER_NS_PER_TICK;
196 }
197 
198 static inline void IRQ_setbit(IRQQueue *q, int n_IRQ)
199 {
200     set_bit(n_IRQ, q->queue);
201 }
202 
203 static inline void IRQ_resetbit(IRQQueue *q, int n_IRQ)
204 {
205     clear_bit(n_IRQ, q->queue);
206 }
207 
208 static void IRQ_check(OpenPICState *opp, IRQQueue *q)
209 {
210     int irq = -1;
211     int next = -1;
212     int priority = -1;
213 
214     for (;;) {
215         irq = find_next_bit(q->queue, opp->max_irq, irq + 1);
216         if (irq == opp->max_irq) {
217             break;
218         }
219 
220         DPRINTF("IRQ_check: irq %d set ivpr_pr=%d pr=%d",
221                 irq, IVPR_PRIORITY(opp->src[irq].ivpr), priority);
222 
223         if (IVPR_PRIORITY(opp->src[irq].ivpr) > priority) {
224             next = irq;
225             priority = IVPR_PRIORITY(opp->src[irq].ivpr);
226         }
227     }
228 
229     q->next = next;
230     q->priority = priority;
231 }
232 
233 static int IRQ_get_next(OpenPICState *opp, IRQQueue *q)
234 {
235     /* XXX: optimize */
236     IRQ_check(opp, q);
237 
238     return q->next;
239 }
240 
241 static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ,
242                            bool active, bool was_active)
243 {
244     IRQDest *dst;
245     IRQSource *src;
246     int priority;
247 
248     dst = &opp->dst[n_CPU];
249     src = &opp->src[n_IRQ];
250 
251     DPRINTF("%s: IRQ %d active %d was %d",
252             __func__, n_IRQ, active, was_active);
253 
254     if (src->output != OPENPIC_OUTPUT_INT) {
255         DPRINTF("%s: output %d irq %d active %d was %d count %d",
256                 __func__, src->output, n_IRQ, active, was_active,
257                 dst->outputs_active[src->output]);
258 
259         /* On Freescale MPIC, critical interrupts ignore priority,
260          * IACK, EOI, etc.  Before MPIC v4.1 they also ignore
261          * masking.
262          */
263         if (active) {
264             if (!was_active && dst->outputs_active[src->output]++ == 0) {
265                 DPRINTF("%s: Raise OpenPIC output %d cpu %d irq %d",
266                         __func__, src->output, n_CPU, n_IRQ);
267                 qemu_irq_raise(dst->irqs[src->output]);
268             }
269         } else {
270             if (was_active && --dst->outputs_active[src->output] == 0) {
271                 DPRINTF("%s: Lower OpenPIC output %d cpu %d irq %d",
272                         __func__, src->output, n_CPU, n_IRQ);
273                 qemu_irq_lower(dst->irqs[src->output]);
274             }
275         }
276 
277         return;
278     }
279 
280     priority = IVPR_PRIORITY(src->ivpr);
281 
282     /* Even if the interrupt doesn't have enough priority,
283      * it is still raised, in case ctpr is lowered later.
284      */
285     if (active) {
286         IRQ_setbit(&dst->raised, n_IRQ);
287     } else {
288         IRQ_resetbit(&dst->raised, n_IRQ);
289     }
290 
291     IRQ_check(opp, &dst->raised);
292 
293     if (active && priority <= dst->ctpr) {
294         DPRINTF("%s: IRQ %d priority %d too low for ctpr %d on CPU %d",
295                 __func__, n_IRQ, priority, dst->ctpr, n_CPU);
296         active = 0;
297     }
298 
299     if (active) {
300         if (IRQ_get_next(opp, &dst->servicing) >= 0 &&
301                 priority <= dst->servicing.priority) {
302             DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d",
303                     __func__, n_IRQ, dst->servicing.next, n_CPU);
304         } else {
305             DPRINTF("%s: Raise OpenPIC INT output cpu %d irq %d/%d",
306                     __func__, n_CPU, n_IRQ, dst->raised.next);
307             qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
308         }
309     } else {
310         IRQ_get_next(opp, &dst->servicing);
311         if (dst->raised.priority > dst->ctpr &&
312                 dst->raised.priority > dst->servicing.priority) {
313             DPRINTF("%s: IRQ %d inactive, IRQ %d prio %d above %d/%d, CPU %d",
314                     __func__, n_IRQ, dst->raised.next, dst->raised.priority,
315                     dst->ctpr, dst->servicing.priority, n_CPU);
316             /* IRQ line stays asserted */
317         } else {
318             DPRINTF("%s: IRQ %d inactive, current prio %d/%d, CPU %d",
319                     __func__, n_IRQ, dst->ctpr, dst->servicing.priority, n_CPU);
320             qemu_irq_lower(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
321         }
322     }
323 }
324 
325 /* update pic state because registers for n_IRQ have changed value */
326 static void openpic_update_irq(OpenPICState *opp, int n_IRQ)
327 {
328     IRQSource *src;
329     bool active, was_active;
330     int i;
331 
332     src = &opp->src[n_IRQ];
333     active = src->pending;
334 
335     if ((src->ivpr & IVPR_MASK_MASK) && !src->nomask) {
336         /* Interrupt source is disabled */
337         DPRINTF("%s: IRQ %d is disabled", __func__, n_IRQ);
338         active = false;
339     }
340 
341     was_active = !!(src->ivpr & IVPR_ACTIVITY_MASK);
342 
343     /*
344      * We don't have a similar check for already-active because
345      * ctpr may have changed and we need to withdraw the interrupt.
346      */
347     if (!active && !was_active) {
348         DPRINTF("%s: IRQ %d is already inactive", __func__, n_IRQ);
349         return;
350     }
351 
352     if (active) {
353         src->ivpr |= IVPR_ACTIVITY_MASK;
354     } else {
355         src->ivpr &= ~IVPR_ACTIVITY_MASK;
356     }
357 
358     if (src->destmask == 0) {
359         /* No target */
360         DPRINTF("%s: IRQ %d has no target", __func__, n_IRQ);
361         return;
362     }
363 
364     if (src->destmask == (1 << src->last_cpu)) {
365         /* Only one CPU is allowed to receive this IRQ */
366         IRQ_local_pipe(opp, src->last_cpu, n_IRQ, active, was_active);
367     } else if (!(src->ivpr & IVPR_MODE_MASK)) {
368         /* Directed delivery mode */
369         for (i = 0; i < opp->nb_cpus; i++) {
370             if (src->destmask & (1 << i)) {
371                 IRQ_local_pipe(opp, i, n_IRQ, active, was_active);
372             }
373         }
374     } else {
375         /* Distributed delivery mode */
376         for (i = src->last_cpu + 1; i != src->last_cpu; i++) {
377             if (i == opp->nb_cpus) {
378                 i = 0;
379             }
380             if (src->destmask & (1 << i)) {
381                 IRQ_local_pipe(opp, i, n_IRQ, active, was_active);
382                 src->last_cpu = i;
383                 break;
384             }
385         }
386     }
387 }
388 
389 static void openpic_set_irq(void *opaque, int n_IRQ, int level)
390 {
391     OpenPICState *opp = opaque;
392     IRQSource *src;
393 
394     if (n_IRQ >= OPENPIC_MAX_IRQ) {
395         error_report("%s: IRQ %d out of range", __func__, n_IRQ);
396         abort();
397     }
398 
399     src = &opp->src[n_IRQ];
400     DPRINTF("openpic: set irq %d = %d ivpr=0x%08x",
401             n_IRQ, level, src->ivpr);
402     if (src->level) {
403         /* level-sensitive irq */
404         src->pending = level;
405         openpic_update_irq(opp, n_IRQ);
406     } else {
407         /* edge-sensitive irq */
408         if (level) {
409             src->pending = 1;
410             openpic_update_irq(opp, n_IRQ);
411         }
412 
413         if (src->output != OPENPIC_OUTPUT_INT) {
414             /* Edge-triggered interrupts shouldn't be used
415              * with non-INT delivery, but just in case,
416              * try to make it do something sane rather than
417              * cause an interrupt storm.  This is close to
418              * what you'd probably see happen in real hardware.
419              */
420             src->pending = 0;
421             openpic_update_irq(opp, n_IRQ);
422         }
423     }
424 }
425 
426 static inline uint32_t read_IRQreg_idr(OpenPICState *opp, int n_IRQ)
427 {
428     return opp->src[n_IRQ].idr;
429 }
430 
431 static inline uint32_t read_IRQreg_ilr(OpenPICState *opp, int n_IRQ)
432 {
433     if (opp->flags & OPENPIC_FLAG_ILR) {
434         return output_to_inttgt(opp->src[n_IRQ].output);
435     }
436 
437     return 0xffffffff;
438 }
439 
440 static inline uint32_t read_IRQreg_ivpr(OpenPICState *opp, int n_IRQ)
441 {
442     return opp->src[n_IRQ].ivpr;
443 }
444 
445 static inline void write_IRQreg_idr(OpenPICState *opp, int n_IRQ, uint32_t val)
446 {
447     IRQSource *src = &opp->src[n_IRQ];
448     uint32_t normal_mask = (1UL << opp->nb_cpus) - 1;
449     uint32_t crit_mask = 0;
450     uint32_t mask = normal_mask;
451     int crit_shift = IDR_EP_SHIFT - opp->nb_cpus;
452     int i;
453 
454     if (opp->flags & OPENPIC_FLAG_IDR_CRIT) {
455         crit_mask = mask << crit_shift;
456         mask |= crit_mask | IDR_EP;
457     }
458 
459     src->idr = val & mask;
460     DPRINTF("Set IDR %d to 0x%08x", n_IRQ, src->idr);
461 
462     if (opp->flags & OPENPIC_FLAG_IDR_CRIT) {
463         if (src->idr & crit_mask) {
464             if (src->idr & normal_mask) {
465                 DPRINTF("%s: IRQ configured for multiple output types, using "
466                         "critical", __func__);
467             }
468 
469             src->output = OPENPIC_OUTPUT_CINT;
470             src->nomask = true;
471             src->destmask = 0;
472 
473             for (i = 0; i < opp->nb_cpus; i++) {
474                 int n_ci = IDR_CI0_SHIFT - i;
475 
476                 if (src->idr & (1UL << n_ci)) {
477                     src->destmask |= 1UL << i;
478                 }
479             }
480         } else {
481             src->output = OPENPIC_OUTPUT_INT;
482             src->nomask = false;
483             src->destmask = src->idr & normal_mask;
484         }
485     } else {
486         src->destmask = src->idr;
487     }
488 }
489 
490 static inline void write_IRQreg_ilr(OpenPICState *opp, int n_IRQ, uint32_t val)
491 {
492     if (opp->flags & OPENPIC_FLAG_ILR) {
493         IRQSource *src = &opp->src[n_IRQ];
494 
495         src->output = inttgt_to_output(val & ILR_INTTGT_MASK);
496         DPRINTF("Set ILR %d to 0x%08x, output %d", n_IRQ, src->idr,
497                 src->output);
498 
499         /* TODO: on MPIC v4.0 only, set nomask for non-INT */
500     }
501 }
502 
503 static inline void write_IRQreg_ivpr(OpenPICState *opp, int n_IRQ, uint32_t val)
504 {
505     uint32_t mask;
506 
507     /* NOTE when implementing newer FSL MPIC models: starting with v4.0,
508      * the polarity bit is read-only on internal interrupts.
509      */
510     mask = IVPR_MASK_MASK | IVPR_PRIORITY_MASK | IVPR_SENSE_MASK |
511            IVPR_POLARITY_MASK | opp->vector_mask;
512 
513     /* ACTIVITY bit is read-only */
514     opp->src[n_IRQ].ivpr =
515         (opp->src[n_IRQ].ivpr & IVPR_ACTIVITY_MASK) | (val & mask);
516 
517     /* For FSL internal interrupts, The sense bit is reserved and zero,
518      * and the interrupt is always level-triggered.  Timers and IPIs
519      * have no sense or polarity bits, and are edge-triggered.
520      */
521     switch (opp->src[n_IRQ].type) {
522     case IRQ_TYPE_NORMAL:
523         opp->src[n_IRQ].level = !!(opp->src[n_IRQ].ivpr & IVPR_SENSE_MASK);
524         break;
525 
526     case IRQ_TYPE_FSLINT:
527         opp->src[n_IRQ].ivpr &= ~IVPR_SENSE_MASK;
528         break;
529 
530     case IRQ_TYPE_FSLSPECIAL:
531         opp->src[n_IRQ].ivpr &= ~(IVPR_POLARITY_MASK | IVPR_SENSE_MASK);
532         break;
533     }
534 
535     openpic_update_irq(opp, n_IRQ);
536     DPRINTF("Set IVPR %d to 0x%08x -> 0x%08x", n_IRQ, val,
537             opp->src[n_IRQ].ivpr);
538 }
539 
540 static void openpic_gcr_write(OpenPICState *opp, uint64_t val)
541 {
542     bool mpic_proxy = false;
543 
544     if (val & GCR_RESET) {
545         openpic_reset(DEVICE(opp));
546         return;
547     }
548 
549     opp->gcr &= ~opp->mpic_mode_mask;
550     opp->gcr |= val & opp->mpic_mode_mask;
551 
552     /* Set external proxy mode */
553     if ((val & opp->mpic_mode_mask) == GCR_MODE_PROXY) {
554         mpic_proxy = true;
555     }
556 
557     ppce500_set_mpic_proxy(mpic_proxy);
558 }
559 
560 static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,
561                               unsigned len)
562 {
563     OpenPICState *opp = opaque;
564     IRQDest *dst;
565     int idx;
566 
567     DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64,
568             __func__, addr, val);
569     if (addr & 0xF) {
570         return;
571     }
572     switch (addr) {
573     case 0x00: /* Block Revision Register1 (BRR1) is Readonly */
574         break;
575     case 0x40:
576     case 0x50:
577     case 0x60:
578     case 0x70:
579     case 0x80:
580     case 0x90:
581     case 0xA0:
582     case 0xB0:
583         openpic_cpu_write_internal(opp, addr, val, get_current_cpu());
584         break;
585     case 0x1000: /* FRR */
586         break;
587     case 0x1020: /* GCR */
588         openpic_gcr_write(opp, val);
589         break;
590     case 0x1080: /* VIR */
591         break;
592     case 0x1090: /* PIR */
593         for (idx = 0; idx < opp->nb_cpus; idx++) {
594             if ((val & (1 << idx)) && !(opp->pir & (1 << idx))) {
595                 DPRINTF("Raise OpenPIC RESET output for CPU %d", idx);
596                 dst = &opp->dst[idx];
597                 qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_RESET]);
598             } else if (!(val & (1 << idx)) && (opp->pir & (1 << idx))) {
599                 DPRINTF("Lower OpenPIC RESET output for CPU %d", idx);
600                 dst = &opp->dst[idx];
601                 qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_RESET]);
602             }
603         }
604         opp->pir = val;
605         break;
606     case 0x10A0: /* IPI_IVPR */
607     case 0x10B0:
608     case 0x10C0:
609     case 0x10D0:
610         {
611             int idx;
612             idx = (addr - 0x10A0) >> 4;
613             write_IRQreg_ivpr(opp, opp->irq_ipi0 + idx, val);
614         }
615         break;
616     case 0x10E0: /* SPVE */
617         opp->spve = val & opp->vector_mask;
618         break;
619     default:
620         break;
621     }
622 }
623 
624 static uint64_t openpic_gbl_read(void *opaque, hwaddr addr, unsigned len)
625 {
626     OpenPICState *opp = opaque;
627     uint32_t retval;
628 
629     DPRINTF("%s: addr %#" HWADDR_PRIx, __func__, addr);
630     retval = 0xFFFFFFFF;
631     if (addr & 0xF) {
632         return retval;
633     }
634     switch (addr) {
635     case 0x1000: /* FRR */
636         retval = opp->frr;
637         break;
638     case 0x1020: /* GCR */
639         retval = opp->gcr;
640         break;
641     case 0x1080: /* VIR */
642         retval = opp->vir;
643         break;
644     case 0x1090: /* PIR */
645         retval = 0x00000000;
646         break;
647     case 0x00: /* Block Revision Register1 (BRR1) */
648         retval = opp->brr1;
649         break;
650     case 0x40:
651     case 0x50:
652     case 0x60:
653     case 0x70:
654     case 0x80:
655     case 0x90:
656     case 0xA0:
657     case 0xB0:
658         retval = openpic_cpu_read_internal(opp, addr, get_current_cpu());
659         break;
660     case 0x10A0: /* IPI_IVPR */
661     case 0x10B0:
662     case 0x10C0:
663     case 0x10D0:
664         {
665             int idx;
666             idx = (addr - 0x10A0) >> 4;
667             retval = read_IRQreg_ivpr(opp, opp->irq_ipi0 + idx);
668         }
669         break;
670     case 0x10E0: /* SPVE */
671         retval = opp->spve;
672         break;
673     default:
674         break;
675     }
676     DPRINTF("%s: => 0x%08x", __func__, retval);
677 
678     return retval;
679 }
680 
681 static void openpic_tmr_set_tmr(OpenPICTimer *tmr, uint32_t val, bool enabled);
682 
683 static void qemu_timer_cb(void *opaque)
684 {
685     OpenPICTimer *tmr = opaque;
686     OpenPICState *opp = tmr->opp;
687     uint32_t    n_IRQ = tmr->n_IRQ;
688     uint32_t val =   tmr->tbcr & ~TBCR_CI;
689     uint32_t tog = ((tmr->tccr & TCCR_TOG) ^ TCCR_TOG);  /* invert toggle. */
690 
691     DPRINTF("%s n_IRQ=%d", __func__, n_IRQ);
692     /* Reload current count from base count and setup timer. */
693     tmr->tccr = val | tog;
694     openpic_tmr_set_tmr(tmr, val, /*enabled=*/true);
695     /* Raise the interrupt. */
696     opp->src[n_IRQ].destmask = read_IRQreg_idr(opp, n_IRQ);
697     openpic_set_irq(opp, n_IRQ, 1);
698     openpic_set_irq(opp, n_IRQ, 0);
699 }
700 
701 /* If enabled is true, arranges for an interrupt to be raised val clocks into
702    the future, if enabled is false cancels the timer. */
703 static void openpic_tmr_set_tmr(OpenPICTimer *tmr, uint32_t val, bool enabled)
704 {
705     uint64_t ns = ticks_to_ns(val & ~TCCR_TOG);
706     /* A count of zero causes a timer to be set to expire immediately.  This
707        effectively stops the simulation since the timer is constantly expiring
708        which prevents guest code execution, so we don't honor that
709        configuration.  On real hardware, this situation would generate an
710        interrupt on every clock cycle if the interrupt was unmasked. */
711     if ((ns == 0) || !enabled) {
712         tmr->qemu_timer_active = false;
713         tmr->tccr = tmr->tccr & TCCR_TOG;
714         timer_del(tmr->qemu_timer); /* set timer to never expire. */
715     } else {
716         tmr->qemu_timer_active = true;
717         uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
718         tmr->origin_time = now;
719         timer_mod(tmr->qemu_timer, now + ns);     /* set timer expiration. */
720     }
721 }
722 
723 /* Returns the currrent tccr value, i.e., timer value (in clocks) with
724    appropriate TOG. */
725 static uint64_t openpic_tmr_get_timer(OpenPICTimer *tmr)
726 {
727     uint64_t retval;
728     if (!tmr->qemu_timer_active) {
729         retval = tmr->tccr;
730     } else {
731         uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
732         uint64_t used = now - tmr->origin_time;  /* nsecs */
733         uint32_t used_ticks = (uint32_t)ns_to_ticks(used);
734         uint32_t count = (tmr->tccr & ~TCCR_TOG) - used_ticks;
735         retval = (uint32_t)((tmr->tccr & TCCR_TOG) | (count & ~TCCR_TOG));
736     }
737     return retval;
738 }
739 
740 static void openpic_tmr_write(void *opaque, hwaddr addr, uint64_t val,
741                               unsigned len)
742 {
743     OpenPICState *opp = opaque;
744     int idx;
745 
746     DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64,
747             __func__, (addr + 0x10f0), val);
748     if (addr & 0xF) {
749         return;
750     }
751 
752     if (addr == 0) {
753         /* TFRR */
754         opp->tfrr = val;
755         return;
756     }
757     addr -= 0x10;  /* correct for TFRR */
758     idx = (addr >> 6) & 0x3;
759 
760     switch (addr & 0x30) {
761     case 0x00: /* TCCR */
762         break;
763     case 0x10: /* TBCR */
764         /* Did the enable status change? */
765         if ((opp->timers[idx].tbcr & TBCR_CI) != (val & TBCR_CI)) {
766             /* Did "Count Inhibit" transition from 1 to 0? */
767             if ((val & TBCR_CI) == 0) {
768                 opp->timers[idx].tccr = val & ~TCCR_TOG;
769             }
770             openpic_tmr_set_tmr(&opp->timers[idx],
771                                 (val & ~TBCR_CI),
772                                 /*enabled=*/((val & TBCR_CI) == 0));
773         }
774         opp->timers[idx].tbcr = val;
775         break;
776     case 0x20: /* TVPR */
777         write_IRQreg_ivpr(opp, opp->irq_tim0 + idx, val);
778         break;
779     case 0x30: /* TDR */
780         write_IRQreg_idr(opp, opp->irq_tim0 + idx, val);
781         break;
782     }
783 }
784 
785 static uint64_t openpic_tmr_read(void *opaque, hwaddr addr, unsigned len)
786 {
787     OpenPICState *opp = opaque;
788     uint32_t retval = -1;
789     int idx;
790 
791     DPRINTF("%s: addr %#" HWADDR_PRIx, __func__, addr + 0x10f0);
792     if (addr & 0xF) {
793         goto out;
794     }
795     if (addr == 0) {
796         /* TFRR */
797         retval = opp->tfrr;
798         goto out;
799     }
800     addr -= 0x10;  /* correct for TFRR */
801     idx = (addr >> 6) & 0x3;
802     switch (addr & 0x30) {
803     case 0x00: /* TCCR */
804         retval = openpic_tmr_get_timer(&opp->timers[idx]);
805         break;
806     case 0x10: /* TBCR */
807         retval = opp->timers[idx].tbcr;
808         break;
809     case 0x20: /* TVPR */
810         retval = read_IRQreg_ivpr(opp, opp->irq_tim0 + idx);
811         break;
812     case 0x30: /* TDR */
813         retval = read_IRQreg_idr(opp, opp->irq_tim0 + idx);
814         break;
815     }
816 
817 out:
818     DPRINTF("%s: => 0x%08x", __func__, retval);
819 
820     return retval;
821 }
822 
823 static void openpic_src_write(void *opaque, hwaddr addr, uint64_t val,
824                               unsigned len)
825 {
826     OpenPICState *opp = opaque;
827     int idx;
828 
829     DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64,
830             __func__, addr, val);
831 
832     addr = addr & 0xffff;
833     idx = addr >> 5;
834 
835     switch (addr & 0x1f) {
836     case 0x00:
837         write_IRQreg_ivpr(opp, idx, val);
838         break;
839     case 0x10:
840         write_IRQreg_idr(opp, idx, val);
841         break;
842     case 0x18:
843         write_IRQreg_ilr(opp, idx, val);
844         break;
845     }
846 }
847 
848 static uint64_t openpic_src_read(void *opaque, uint64_t addr, unsigned len)
849 {
850     OpenPICState *opp = opaque;
851     uint32_t retval;
852     int idx;
853 
854     DPRINTF("%s: addr %#" HWADDR_PRIx, __func__, addr);
855     retval = 0xFFFFFFFF;
856 
857     addr = addr & 0xffff;
858     idx = addr >> 5;
859 
860     switch (addr & 0x1f) {
861     case 0x00:
862         retval = read_IRQreg_ivpr(opp, idx);
863         break;
864     case 0x10:
865         retval = read_IRQreg_idr(opp, idx);
866         break;
867     case 0x18:
868         retval = read_IRQreg_ilr(opp, idx);
869         break;
870     }
871 
872     DPRINTF("%s: => 0x%08x", __func__, retval);
873     return retval;
874 }
875 
876 static void openpic_msi_write(void *opaque, hwaddr addr, uint64_t val,
877                               unsigned size)
878 {
879     OpenPICState *opp = opaque;
880     int idx = opp->irq_msi;
881     int srs, ibs;
882 
883     DPRINTF("%s: addr %#" HWADDR_PRIx " <= 0x%08" PRIx64,
884             __func__, addr, val);
885     if (addr & 0xF) {
886         return;
887     }
888 
889     switch (addr) {
890     case MSIIR_OFFSET:
891         srs = val >> MSIIR_SRS_SHIFT;
892         idx += srs;
893         ibs = (val & MSIIR_IBS_MASK) >> MSIIR_IBS_SHIFT;
894         opp->msi[srs].msir |= 1 << ibs;
895         openpic_set_irq(opp, idx, 1);
896         break;
897     default:
898         /* most registers are read-only, thus ignored */
899         break;
900     }
901 }
902 
903 static uint64_t openpic_msi_read(void *opaque, hwaddr addr, unsigned size)
904 {
905     OpenPICState *opp = opaque;
906     uint64_t r = 0;
907     int i, srs;
908 
909     DPRINTF("%s: addr %#" HWADDR_PRIx, __func__, addr);
910     if (addr & 0xF) {
911         return -1;
912     }
913 
914     srs = addr >> 4;
915 
916     switch (addr) {
917     case 0x00:
918     case 0x10:
919     case 0x20:
920     case 0x30:
921     case 0x40:
922     case 0x50:
923     case 0x60:
924     case 0x70: /* MSIRs */
925         r = opp->msi[srs].msir;
926         /* Clear on read */
927         opp->msi[srs].msir = 0;
928         openpic_set_irq(opp, opp->irq_msi + srs, 0);
929         break;
930     case 0x120: /* MSISR */
931         for (i = 0; i < MAX_MSI; i++) {
932             r |= (opp->msi[i].msir ? 1 : 0) << i;
933         }
934         break;
935     }
936 
937     return r;
938 }
939 
940 static uint64_t openpic_summary_read(void *opaque, hwaddr addr, unsigned size)
941 {
942     uint64_t r = 0;
943 
944     DPRINTF("%s: addr %#" HWADDR_PRIx, __func__, addr);
945 
946     /* TODO: EISR/EIMR */
947 
948     return r;
949 }
950 
951 static void openpic_summary_write(void *opaque, hwaddr addr, uint64_t val,
952                                   unsigned size)
953 {
954     DPRINTF("%s: addr %#" HWADDR_PRIx " <= 0x%08" PRIx64,
955             __func__, addr, val);
956 
957     /* TODO: EISR/EIMR */
958 }
959 
960 static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
961                                        uint32_t val, int idx)
962 {
963     OpenPICState *opp = opaque;
964     IRQSource *src;
965     IRQDest *dst;
966     int s_IRQ, n_IRQ;
967 
968     DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx " <= 0x%08x", __func__, idx,
969             addr, val);
970 
971     if (idx < 0 || idx >= opp->nb_cpus) {
972         return;
973     }
974 
975     if (addr & 0xF) {
976         return;
977     }
978     dst = &opp->dst[idx];
979     addr &= 0xFF0;
980     switch (addr) {
981     case 0x40: /* IPIDR */
982     case 0x50:
983     case 0x60:
984     case 0x70:
985         idx = (addr - 0x40) >> 4;
986         /* we use IDE as mask which CPUs to deliver the IPI to still. */
987         opp->src[opp->irq_ipi0 + idx].destmask |= val;
988         openpic_set_irq(opp, opp->irq_ipi0 + idx, 1);
989         openpic_set_irq(opp, opp->irq_ipi0 + idx, 0);
990         break;
991     case 0x80: /* CTPR */
992         dst->ctpr = val & 0x0000000F;
993 
994         DPRINTF("%s: set CPU %d ctpr to %d, raised %d servicing %d",
995                 __func__, idx, dst->ctpr, dst->raised.priority,
996                 dst->servicing.priority);
997 
998         if (dst->raised.priority <= dst->ctpr) {
999             DPRINTF("%s: Lower OpenPIC INT output cpu %d due to ctpr",
1000                     __func__, idx);
1001             qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);
1002         } else if (dst->raised.priority > dst->servicing.priority) {
1003             DPRINTF("%s: Raise OpenPIC INT output cpu %d irq %d",
1004                     __func__, idx, dst->raised.next);
1005             qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]);
1006         }
1007 
1008         break;
1009     case 0x90: /* WHOAMI */
1010         /* Read-only register */
1011         break;
1012     case 0xA0: /* IACK */
1013         /* Read-only register */
1014         break;
1015     case 0xB0: /* EOI */
1016         DPRINTF("EOI");
1017         s_IRQ = IRQ_get_next(opp, &dst->servicing);
1018 
1019         if (s_IRQ < 0) {
1020             DPRINTF("%s: EOI with no interrupt in service", __func__);
1021             break;
1022         }
1023 
1024         IRQ_resetbit(&dst->servicing, s_IRQ);
1025         /* Set up next servicing IRQ */
1026         s_IRQ = IRQ_get_next(opp, &dst->servicing);
1027         /* Check queued interrupts. */
1028         n_IRQ = IRQ_get_next(opp, &dst->raised);
1029         src = &opp->src[n_IRQ];
1030         if (n_IRQ != -1 &&
1031             (s_IRQ == -1 ||
1032              IVPR_PRIORITY(src->ivpr) > dst->servicing.priority)) {
1033             DPRINTF("Raise OpenPIC INT output cpu %d irq %d",
1034                     idx, n_IRQ);
1035             qemu_irq_raise(opp->dst[idx].irqs[OPENPIC_OUTPUT_INT]);
1036         }
1037         break;
1038     default:
1039         break;
1040     }
1041 }
1042 
1043 static void openpic_cpu_write(void *opaque, hwaddr addr, uint64_t val,
1044                               unsigned len)
1045 {
1046     openpic_cpu_write_internal(opaque, addr, val, (addr & 0x1f000) >> 12);
1047 }
1048 
1049 
1050 static uint32_t openpic_iack(OpenPICState *opp, IRQDest *dst, int cpu)
1051 {
1052     IRQSource *src;
1053     int retval, irq;
1054 
1055     DPRINTF("Lower OpenPIC INT output");
1056     qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);
1057 
1058     irq = IRQ_get_next(opp, &dst->raised);
1059     DPRINTF("IACK: irq=%d", irq);
1060 
1061     if (irq == -1) {
1062         /* No more interrupt pending */
1063         return opp->spve;
1064     }
1065 
1066     src = &opp->src[irq];
1067     if (!(src->ivpr & IVPR_ACTIVITY_MASK) ||
1068             !(IVPR_PRIORITY(src->ivpr) > dst->ctpr)) {
1069         error_report("%s: bad raised IRQ %d ctpr %d ivpr 0x%08x",
1070                 __func__, irq, dst->ctpr, src->ivpr);
1071         openpic_update_irq(opp, irq);
1072         retval = opp->spve;
1073     } else {
1074         /* IRQ enter servicing state */
1075         IRQ_setbit(&dst->servicing, irq);
1076         retval = IVPR_VECTOR(opp, src->ivpr);
1077     }
1078 
1079     if (!src->level) {
1080         /* edge-sensitive IRQ */
1081         src->ivpr &= ~IVPR_ACTIVITY_MASK;
1082         src->pending = 0;
1083         IRQ_resetbit(&dst->raised, irq);
1084     }
1085 
1086     /* Timers and IPIs support multicast. */
1087     if (((irq >= opp->irq_ipi0) && (irq < (opp->irq_ipi0 + OPENPIC_MAX_IPI))) ||
1088         ((irq >= opp->irq_tim0) && (irq < (opp->irq_tim0 + OPENPIC_MAX_TMR)))) {
1089         DPRINTF("irq is IPI or TMR");
1090         src->destmask &= ~(1 << cpu);
1091         if (src->destmask && !src->level) {
1092             /* trigger on CPUs that didn't know about it yet */
1093             openpic_set_irq(opp, irq, 1);
1094             openpic_set_irq(opp, irq, 0);
1095             /* if all CPUs knew about it, set active bit again */
1096             src->ivpr |= IVPR_ACTIVITY_MASK;
1097         }
1098     }
1099 
1100     return retval;
1101 }
1102 
1103 static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
1104                                           int idx)
1105 {
1106     OpenPICState *opp = opaque;
1107     IRQDest *dst;
1108     uint32_t retval;
1109 
1110     DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx, __func__, idx, addr);
1111     retval = 0xFFFFFFFF;
1112 
1113     if (idx < 0 || idx >= opp->nb_cpus) {
1114         return retval;
1115     }
1116 
1117     if (addr & 0xF) {
1118         return retval;
1119     }
1120     dst = &opp->dst[idx];
1121     addr &= 0xFF0;
1122     switch (addr) {
1123     case 0x80: /* CTPR */
1124         retval = dst->ctpr;
1125         break;
1126     case 0x90: /* WHOAMI */
1127         retval = idx;
1128         break;
1129     case 0xA0: /* IACK */
1130         retval = openpic_iack(opp, dst, idx);
1131         break;
1132     case 0xB0: /* EOI */
1133         retval = 0;
1134         break;
1135     default:
1136         break;
1137     }
1138     DPRINTF("%s: => 0x%08x", __func__, retval);
1139 
1140     return retval;
1141 }
1142 
1143 static uint64_t openpic_cpu_read(void *opaque, hwaddr addr, unsigned len)
1144 {
1145     return openpic_cpu_read_internal(opaque, addr, (addr & 0x1f000) >> 12);
1146 }
1147 
1148 static const MemoryRegionOps openpic_glb_ops_le = {
1149     .write = openpic_gbl_write,
1150     .read  = openpic_gbl_read,
1151     .endianness = DEVICE_LITTLE_ENDIAN,
1152     .impl = {
1153         .min_access_size = 4,
1154         .max_access_size = 4,
1155     },
1156 };
1157 
1158 static const MemoryRegionOps openpic_glb_ops_be = {
1159     .write = openpic_gbl_write,
1160     .read  = openpic_gbl_read,
1161     .endianness = DEVICE_BIG_ENDIAN,
1162     .impl = {
1163         .min_access_size = 4,
1164         .max_access_size = 4,
1165     },
1166 };
1167 
1168 static const MemoryRegionOps openpic_tmr_ops_le = {
1169     .write = openpic_tmr_write,
1170     .read  = openpic_tmr_read,
1171     .endianness = DEVICE_LITTLE_ENDIAN,
1172     .impl = {
1173         .min_access_size = 4,
1174         .max_access_size = 4,
1175     },
1176 };
1177 
1178 static const MemoryRegionOps openpic_tmr_ops_be = {
1179     .write = openpic_tmr_write,
1180     .read  = openpic_tmr_read,
1181     .endianness = DEVICE_BIG_ENDIAN,
1182     .impl = {
1183         .min_access_size = 4,
1184         .max_access_size = 4,
1185     },
1186 };
1187 
1188 static const MemoryRegionOps openpic_cpu_ops_le = {
1189     .write = openpic_cpu_write,
1190     .read  = openpic_cpu_read,
1191     .endianness = DEVICE_LITTLE_ENDIAN,
1192     .impl = {
1193         .min_access_size = 4,
1194         .max_access_size = 4,
1195     },
1196 };
1197 
1198 static const MemoryRegionOps openpic_cpu_ops_be = {
1199     .write = openpic_cpu_write,
1200     .read  = openpic_cpu_read,
1201     .endianness = DEVICE_BIG_ENDIAN,
1202     .impl = {
1203         .min_access_size = 4,
1204         .max_access_size = 4,
1205     },
1206 };
1207 
1208 static const MemoryRegionOps openpic_src_ops_le = {
1209     .write = openpic_src_write,
1210     .read  = openpic_src_read,
1211     .endianness = DEVICE_LITTLE_ENDIAN,
1212     .impl = {
1213         .min_access_size = 4,
1214         .max_access_size = 4,
1215     },
1216 };
1217 
1218 static const MemoryRegionOps openpic_src_ops_be = {
1219     .write = openpic_src_write,
1220     .read  = openpic_src_read,
1221     .endianness = DEVICE_BIG_ENDIAN,
1222     .impl = {
1223         .min_access_size = 4,
1224         .max_access_size = 4,
1225     },
1226 };
1227 
1228 static const MemoryRegionOps openpic_msi_ops_be = {
1229     .read = openpic_msi_read,
1230     .write = openpic_msi_write,
1231     .endianness = DEVICE_BIG_ENDIAN,
1232     .impl = {
1233         .min_access_size = 4,
1234         .max_access_size = 4,
1235     },
1236 };
1237 
1238 static const MemoryRegionOps openpic_summary_ops_be = {
1239     .read = openpic_summary_read,
1240     .write = openpic_summary_write,
1241     .endianness = DEVICE_BIG_ENDIAN,
1242     .impl = {
1243         .min_access_size = 4,
1244         .max_access_size = 4,
1245     },
1246 };
1247 
1248 static void openpic_reset(DeviceState *d)
1249 {
1250     OpenPICState *opp = OPENPIC(d);
1251     int i;
1252 
1253     opp->gcr = GCR_RESET;
1254     /* Initialise controller registers */
1255     opp->frr = ((opp->nb_irqs - 1) << FRR_NIRQ_SHIFT) |
1256                ((opp->nb_cpus - 1) << FRR_NCPU_SHIFT) |
1257                (opp->vid << FRR_VID_SHIFT);
1258 
1259     opp->pir = 0;
1260     opp->spve = -1 & opp->vector_mask;
1261     opp->tfrr = opp->tfrr_reset;
1262     /* Initialise IRQ sources */
1263     for (i = 0; i < opp->max_irq; i++) {
1264         opp->src[i].ivpr = opp->ivpr_reset;
1265         switch (opp->src[i].type) {
1266         case IRQ_TYPE_NORMAL:
1267             opp->src[i].level = !!(opp->ivpr_reset & IVPR_SENSE_MASK);
1268             break;
1269 
1270         case IRQ_TYPE_FSLINT:
1271             opp->src[i].ivpr |= IVPR_POLARITY_MASK;
1272             break;
1273 
1274         case IRQ_TYPE_FSLSPECIAL:
1275             break;
1276         }
1277 
1278         write_IRQreg_idr(opp, i, opp->idr_reset);
1279     }
1280     /* Initialise IRQ destinations */
1281     for (i = 0; i < opp->nb_cpus; i++) {
1282         opp->dst[i].ctpr      = 15;
1283         opp->dst[i].raised.next = -1;
1284         opp->dst[i].raised.priority = 0;
1285         bitmap_clear(opp->dst[i].raised.queue, 0, IRQQUEUE_SIZE_BITS);
1286         opp->dst[i].servicing.next = -1;
1287         opp->dst[i].servicing.priority = 0;
1288         bitmap_clear(opp->dst[i].servicing.queue, 0, IRQQUEUE_SIZE_BITS);
1289     }
1290     /* Initialise timers */
1291     for (i = 0; i < OPENPIC_MAX_TMR; i++) {
1292         opp->timers[i].tccr = 0;
1293         opp->timers[i].tbcr = TBCR_CI;
1294         if (opp->timers[i].qemu_timer_active) {
1295             timer_del(opp->timers[i].qemu_timer);  /* Inhibit timer */
1296             opp->timers[i].qemu_timer_active = false;
1297         }
1298     }
1299     /* Go out of RESET state */
1300     opp->gcr = 0;
1301 }
1302 
1303 typedef struct MemReg {
1304     const char             *name;
1305     MemoryRegionOps const  *ops;
1306     hwaddr      start_addr;
1307     ram_addr_t              size;
1308 } MemReg;
1309 
1310 static void fsl_common_init(OpenPICState *opp)
1311 {
1312     int i;
1313     int virq = OPENPIC_MAX_SRC;
1314 
1315     opp->vid = VID_REVISION_1_2;
1316     opp->vir = VIR_GENERIC;
1317     opp->vector_mask = 0xFFFF;
1318     opp->tfrr_reset = 0;
1319     opp->ivpr_reset = IVPR_MASK_MASK;
1320     opp->idr_reset = 1 << 0;
1321     opp->max_irq = OPENPIC_MAX_IRQ;
1322 
1323     opp->irq_ipi0 = virq;
1324     virq += OPENPIC_MAX_IPI;
1325     opp->irq_tim0 = virq;
1326     virq += OPENPIC_MAX_TMR;
1327 
1328     assert(virq <= OPENPIC_MAX_IRQ);
1329 
1330     opp->irq_msi = 224;
1331 
1332     msi_nonbroken = true;
1333     for (i = 0; i < opp->fsl->max_ext; i++) {
1334         opp->src[i].level = false;
1335     }
1336 
1337     /* Internal interrupts, including message and MSI */
1338     for (i = 16; i < OPENPIC_MAX_SRC; i++) {
1339         opp->src[i].type = IRQ_TYPE_FSLINT;
1340         opp->src[i].level = true;
1341     }
1342 
1343     /* timers and IPIs */
1344     for (i = OPENPIC_MAX_SRC; i < virq; i++) {
1345         opp->src[i].type = IRQ_TYPE_FSLSPECIAL;
1346         opp->src[i].level = false;
1347     }
1348 
1349     for (i = 0; i < OPENPIC_MAX_TMR; i++) {
1350         opp->timers[i].n_IRQ = opp->irq_tim0 + i;
1351         opp->timers[i].qemu_timer_active = false;
1352         opp->timers[i].qemu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
1353                                                  &qemu_timer_cb,
1354                                                  &opp->timers[i]);
1355         opp->timers[i].opp = opp;
1356     }
1357 }
1358 
1359 static void map_list(OpenPICState *opp, const MemReg *list, int *count)
1360 {
1361     while (list->name) {
1362         assert(*count < ARRAY_SIZE(opp->sub_io_mem));
1363 
1364         memory_region_init_io(&opp->sub_io_mem[*count], OBJECT(opp), list->ops,
1365                               opp, list->name, list->size);
1366 
1367         memory_region_add_subregion(&opp->mem, list->start_addr,
1368                                     &opp->sub_io_mem[*count]);
1369 
1370         (*count)++;
1371         list++;
1372     }
1373 }
1374 
1375 static const VMStateDescription vmstate_openpic_irq_queue = {
1376     .name = "openpic_irq_queue",
1377     .version_id = 0,
1378     .minimum_version_id = 0,
1379     .fields = (VMStateField[]) {
1380         VMSTATE_BITMAP(queue, IRQQueue, 0, queue_size),
1381         VMSTATE_INT32(next, IRQQueue),
1382         VMSTATE_INT32(priority, IRQQueue),
1383         VMSTATE_END_OF_LIST()
1384     }
1385 };
1386 
1387 static const VMStateDescription vmstate_openpic_irqdest = {
1388     .name = "openpic_irqdest",
1389     .version_id = 0,
1390     .minimum_version_id = 0,
1391     .fields = (VMStateField[]) {
1392         VMSTATE_INT32(ctpr, IRQDest),
1393         VMSTATE_STRUCT(raised, IRQDest, 0, vmstate_openpic_irq_queue,
1394                        IRQQueue),
1395         VMSTATE_STRUCT(servicing, IRQDest, 0, vmstate_openpic_irq_queue,
1396                        IRQQueue),
1397         VMSTATE_UINT32_ARRAY(outputs_active, IRQDest, OPENPIC_OUTPUT_NB),
1398         VMSTATE_END_OF_LIST()
1399     }
1400 };
1401 
1402 static const VMStateDescription vmstate_openpic_irqsource = {
1403     .name = "openpic_irqsource",
1404     .version_id = 0,
1405     .minimum_version_id = 0,
1406     .fields = (VMStateField[]) {
1407         VMSTATE_UINT32(ivpr, IRQSource),
1408         VMSTATE_UINT32(idr, IRQSource),
1409         VMSTATE_UINT32(destmask, IRQSource),
1410         VMSTATE_INT32(last_cpu, IRQSource),
1411         VMSTATE_INT32(pending, IRQSource),
1412         VMSTATE_END_OF_LIST()
1413     }
1414 };
1415 
1416 static const VMStateDescription vmstate_openpic_timer = {
1417     .name = "openpic_timer",
1418     .version_id = 0,
1419     .minimum_version_id = 0,
1420     .fields = (VMStateField[]) {
1421         VMSTATE_UINT32(tccr, OpenPICTimer),
1422         VMSTATE_UINT32(tbcr, OpenPICTimer),
1423         VMSTATE_END_OF_LIST()
1424     }
1425 };
1426 
1427 static const VMStateDescription vmstate_openpic_msi = {
1428     .name = "openpic_msi",
1429     .version_id = 0,
1430     .minimum_version_id = 0,
1431     .fields = (VMStateField[]) {
1432         VMSTATE_UINT32(msir, OpenPICMSI),
1433         VMSTATE_END_OF_LIST()
1434     }
1435 };
1436 
1437 static int openpic_post_load(void *opaque, int version_id)
1438 {
1439     OpenPICState *opp = (OpenPICState *)opaque;
1440     int i;
1441 
1442     /* Update internal ivpr and idr variables */
1443     for (i = 0; i < opp->max_irq; i++) {
1444         write_IRQreg_idr(opp, i, opp->src[i].idr);
1445         write_IRQreg_ivpr(opp, i, opp->src[i].ivpr);
1446     }
1447 
1448     return 0;
1449 }
1450 
1451 static const VMStateDescription vmstate_openpic = {
1452     .name = "openpic",
1453     .version_id = 3,
1454     .minimum_version_id = 3,
1455     .post_load = openpic_post_load,
1456     .fields = (VMStateField[]) {
1457         VMSTATE_UINT32(gcr, OpenPICState),
1458         VMSTATE_UINT32(vir, OpenPICState),
1459         VMSTATE_UINT32(pir, OpenPICState),
1460         VMSTATE_UINT32(spve, OpenPICState),
1461         VMSTATE_UINT32(tfrr, OpenPICState),
1462         VMSTATE_UINT32(max_irq, OpenPICState),
1463         VMSTATE_STRUCT_VARRAY_UINT32(src, OpenPICState, max_irq, 0,
1464                                      vmstate_openpic_irqsource, IRQSource),
1465         VMSTATE_UINT32_EQUAL(nb_cpus, OpenPICState, NULL),
1466         VMSTATE_STRUCT_VARRAY_UINT32(dst, OpenPICState, nb_cpus, 0,
1467                                      vmstate_openpic_irqdest, IRQDest),
1468         VMSTATE_STRUCT_ARRAY(timers, OpenPICState, OPENPIC_MAX_TMR, 0,
1469                              vmstate_openpic_timer, OpenPICTimer),
1470         VMSTATE_STRUCT_ARRAY(msi, OpenPICState, MAX_MSI, 0,
1471                              vmstate_openpic_msi, OpenPICMSI),
1472         VMSTATE_UINT32(irq_ipi0, OpenPICState),
1473         VMSTATE_UINT32(irq_tim0, OpenPICState),
1474         VMSTATE_UINT32(irq_msi, OpenPICState),
1475         VMSTATE_END_OF_LIST()
1476     }
1477 };
1478 
1479 static void openpic_init(Object *obj)
1480 {
1481     OpenPICState *opp = OPENPIC(obj);
1482 
1483     memory_region_init(&opp->mem, obj, "openpic", 0x40000);
1484 }
1485 
1486 static void openpic_realize(DeviceState *dev, Error **errp)
1487 {
1488     SysBusDevice *d = SYS_BUS_DEVICE(dev);
1489     OpenPICState *opp = OPENPIC(dev);
1490     int i, j;
1491     int list_count = 0;
1492     static const MemReg list_le[] = {
1493         {"glb", &openpic_glb_ops_le,
1494                 OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE},
1495         {"tmr", &openpic_tmr_ops_le,
1496                 OPENPIC_TMR_REG_START, OPENPIC_TMR_REG_SIZE},
1497         {"src", &openpic_src_ops_le,
1498                 OPENPIC_SRC_REG_START, OPENPIC_SRC_REG_SIZE},
1499         {"cpu", &openpic_cpu_ops_le,
1500                 OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE},
1501         {NULL}
1502     };
1503     static const MemReg list_be[] = {
1504         {"glb", &openpic_glb_ops_be,
1505                 OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE},
1506         {"tmr", &openpic_tmr_ops_be,
1507                 OPENPIC_TMR_REG_START, OPENPIC_TMR_REG_SIZE},
1508         {"src", &openpic_src_ops_be,
1509                 OPENPIC_SRC_REG_START, OPENPIC_SRC_REG_SIZE},
1510         {"cpu", &openpic_cpu_ops_be,
1511                 OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE},
1512         {NULL}
1513     };
1514     static const MemReg list_fsl[] = {
1515         {"msi", &openpic_msi_ops_be,
1516                 OPENPIC_MSI_REG_START, OPENPIC_MSI_REG_SIZE},
1517         {"summary", &openpic_summary_ops_be,
1518                 OPENPIC_SUMMARY_REG_START, OPENPIC_SUMMARY_REG_SIZE},
1519         {NULL}
1520     };
1521 
1522     if (opp->nb_cpus > MAX_CPU) {
1523         error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
1524                    TYPE_OPENPIC, "nb_cpus", (uint64_t)opp->nb_cpus,
1525                    (uint64_t)0, (uint64_t)MAX_CPU);
1526         return;
1527     }
1528 
1529     switch (opp->model) {
1530     case OPENPIC_MODEL_FSL_MPIC_20:
1531     default:
1532         opp->fsl = &fsl_mpic_20;
1533         opp->brr1 = 0x00400200;
1534         opp->flags |= OPENPIC_FLAG_IDR_CRIT;
1535         opp->nb_irqs = 80;
1536         opp->mpic_mode_mask = GCR_MODE_MIXED;
1537 
1538         fsl_common_init(opp);
1539         map_list(opp, list_be, &list_count);
1540         map_list(opp, list_fsl, &list_count);
1541 
1542         break;
1543 
1544     case OPENPIC_MODEL_FSL_MPIC_42:
1545         opp->fsl = &fsl_mpic_42;
1546         opp->brr1 = 0x00400402;
1547         opp->flags |= OPENPIC_FLAG_ILR;
1548         opp->nb_irqs = 196;
1549         opp->mpic_mode_mask = GCR_MODE_PROXY;
1550 
1551         fsl_common_init(opp);
1552         map_list(opp, list_be, &list_count);
1553         map_list(opp, list_fsl, &list_count);
1554 
1555         break;
1556 
1557     case OPENPIC_MODEL_RAVEN:
1558         opp->nb_irqs = RAVEN_MAX_EXT;
1559         opp->vid = VID_REVISION_1_3;
1560         opp->vir = VIR_GENERIC;
1561         opp->vector_mask = 0xFF;
1562         opp->tfrr_reset = 4160000;
1563         opp->ivpr_reset = IVPR_MASK_MASK | IVPR_MODE_MASK;
1564         opp->idr_reset = 0;
1565         opp->max_irq = RAVEN_MAX_IRQ;
1566         opp->irq_ipi0 = RAVEN_IPI_IRQ;
1567         opp->irq_tim0 = RAVEN_TMR_IRQ;
1568         opp->brr1 = -1;
1569         opp->mpic_mode_mask = GCR_MODE_MIXED;
1570 
1571         if (opp->nb_cpus != 1) {
1572             error_setg(errp, "Only UP supported today");
1573             return;
1574         }
1575 
1576         map_list(opp, list_le, &list_count);
1577         break;
1578 
1579     case OPENPIC_MODEL_KEYLARGO:
1580         opp->nb_irqs = KEYLARGO_MAX_EXT;
1581         opp->vid = VID_REVISION_1_2;
1582         opp->vir = VIR_GENERIC;
1583         opp->vector_mask = 0xFF;
1584         opp->tfrr_reset = 4160000;
1585         opp->ivpr_reset = IVPR_MASK_MASK | IVPR_MODE_MASK;
1586         opp->idr_reset = 0;
1587         opp->max_irq = KEYLARGO_MAX_IRQ;
1588         opp->irq_ipi0 = KEYLARGO_IPI_IRQ;
1589         opp->irq_tim0 = KEYLARGO_TMR_IRQ;
1590         opp->brr1 = -1;
1591         opp->mpic_mode_mask = GCR_MODE_MIXED;
1592 
1593         if (opp->nb_cpus != 1) {
1594             error_setg(errp, "Only UP supported today");
1595             return;
1596         }
1597 
1598         map_list(opp, list_le, &list_count);
1599         break;
1600     }
1601 
1602     for (i = 0; i < opp->nb_cpus; i++) {
1603         opp->dst[i].irqs = g_new0(qemu_irq, OPENPIC_OUTPUT_NB);
1604         for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
1605             sysbus_init_irq(d, &opp->dst[i].irqs[j]);
1606         }
1607 
1608         opp->dst[i].raised.queue_size = IRQQUEUE_SIZE_BITS;
1609         opp->dst[i].raised.queue = bitmap_new(IRQQUEUE_SIZE_BITS);
1610         opp->dst[i].servicing.queue_size = IRQQUEUE_SIZE_BITS;
1611         opp->dst[i].servicing.queue = bitmap_new(IRQQUEUE_SIZE_BITS);
1612     }
1613 
1614     sysbus_init_mmio(d, &opp->mem);
1615     qdev_init_gpio_in(dev, openpic_set_irq, opp->max_irq);
1616 }
1617 
1618 static Property openpic_properties[] = {
1619     DEFINE_PROP_UINT32("model", OpenPICState, model, OPENPIC_MODEL_FSL_MPIC_20),
1620     DEFINE_PROP_UINT32("nb_cpus", OpenPICState, nb_cpus, 1),
1621     DEFINE_PROP_END_OF_LIST(),
1622 };
1623 
1624 static void openpic_class_init(ObjectClass *oc, void *data)
1625 {
1626     DeviceClass *dc = DEVICE_CLASS(oc);
1627 
1628     dc->realize = openpic_realize;
1629     dc->props = openpic_properties;
1630     dc->reset = openpic_reset;
1631     dc->vmsd = &vmstate_openpic;
1632     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
1633 }
1634 
1635 static const TypeInfo openpic_info = {
1636     .name          = TYPE_OPENPIC,
1637     .parent        = TYPE_SYS_BUS_DEVICE,
1638     .instance_size = sizeof(OpenPICState),
1639     .instance_init = openpic_init,
1640     .class_init    = openpic_class_init,
1641 };
1642 
1643 static void openpic_register_types(void)
1644 {
1645     type_register_static(&openpic_info);
1646 }
1647 
1648 type_init(openpic_register_types)
1649