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