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