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