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