4 * Copyright (c) 2004 Jocelyn Mayer
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:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
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
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
33 * Serial interrupts, as implemented in Raven chipset are not supported yet.
37 #include "qemu/osdep.h"
39 #include "hw/ppc/mac.h"
40 #include "hw/pci/pci.h"
41 #include "hw/ppc/openpic.h"
42 #include "hw/ppc/ppc_e500.h"
43 #include "hw/qdev-properties.h"
44 #include "hw/sysbus.h"
45 #include "migration/vmstate.h"
46 #include "hw/pci/msi.h"
47 #include "qapi/error.h"
48 #include "qemu/bitops.h"
49 #include "qapi/qmp/qerror.h"
50 #include "qemu/module.h"
51 #include "qemu/timer.h"
52 #include "qemu/error-report.h"
54 //#define DEBUG_OPENPIC
57 static const int debug_openpic
= 1;
59 static const int debug_openpic
= 0;
62 static int get_current_cpu(void);
63 #define DPRINTF(fmt, ...) do { \
64 if (debug_openpic) { \
65 info_report("Core%d: " fmt, get_current_cpu(), ## __VA_ARGS__); \
69 /* OpenPIC capability flags */
70 #define OPENPIC_FLAG_IDR_CRIT (1 << 0)
71 #define OPENPIC_FLAG_ILR (2 << 0)
73 /* OpenPIC address map */
74 #define OPENPIC_GLB_REG_START 0x0
75 #define OPENPIC_GLB_REG_SIZE 0x10F0
76 #define OPENPIC_TMR_REG_START 0x10F0
77 #define OPENPIC_TMR_REG_SIZE 0x220
78 #define OPENPIC_MSI_REG_START 0x1600
79 #define OPENPIC_MSI_REG_SIZE 0x200
80 #define OPENPIC_SUMMARY_REG_START 0x3800
81 #define OPENPIC_SUMMARY_REG_SIZE 0x800
82 #define OPENPIC_SRC_REG_START 0x10000
83 #define OPENPIC_SRC_REG_SIZE (OPENPIC_MAX_SRC * 0x20)
84 #define OPENPIC_CPU_REG_START 0x20000
85 #define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000)
87 static FslMpicInfo fsl_mpic_20
= {
91 static FslMpicInfo fsl_mpic_42
= {
95 #define FRR_NIRQ_SHIFT 16
96 #define FRR_NCPU_SHIFT 8
97 #define FRR_VID_SHIFT 0
99 #define VID_REVISION_1_2 2
100 #define VID_REVISION_1_3 3
102 #define VIR_GENERIC 0x00000000 /* Generic Vendor ID */
103 #define VIR_MPIC2A 0x00004614 /* IBM MPIC-2A */
105 #define GCR_RESET 0x80000000
106 #define GCR_MODE_PASS 0x00000000
107 #define GCR_MODE_MIXED 0x20000000
108 #define GCR_MODE_PROXY 0x60000000
110 #define TBCR_CI 0x80000000 /* count inhibit */
111 #define TCCR_TOG 0x80000000 /* toggles when decrement to zero */
113 #define IDR_EP_SHIFT 31
114 #define IDR_EP_MASK (1U << IDR_EP_SHIFT)
115 #define IDR_CI0_SHIFT 30
116 #define IDR_CI1_SHIFT 29
117 #define IDR_P1_SHIFT 1
118 #define IDR_P0_SHIFT 0
120 #define ILR_INTTGT_MASK 0x000000ff
121 #define ILR_INTTGT_INT 0x00
122 #define ILR_INTTGT_CINT 0x01 /* critical */
123 #define ILR_INTTGT_MCP 0x02 /* machine check */
125 /* The currently supported INTTGT values happen to be the same as QEMU's
126 * openpic output codes, but don't depend on this. The output codes
127 * could change (unlikely, but...) or support could be added for
128 * more INTTGT values.
130 static const int inttgt_output
[][2] = {
131 { ILR_INTTGT_INT
, OPENPIC_OUTPUT_INT
},
132 { ILR_INTTGT_CINT
, OPENPIC_OUTPUT_CINT
},
133 { ILR_INTTGT_MCP
, OPENPIC_OUTPUT_MCK
},
136 static int inttgt_to_output(int inttgt
)
140 for (i
= 0; i
< ARRAY_SIZE(inttgt_output
); i
++) {
141 if (inttgt_output
[i
][0] == inttgt
) {
142 return inttgt_output
[i
][1];
146 error_report("%s: unsupported inttgt %d", __func__
, inttgt
);
147 return OPENPIC_OUTPUT_INT
;
150 static int output_to_inttgt(int output
)
154 for (i
= 0; i
< ARRAY_SIZE(inttgt_output
); i
++) {
155 if (inttgt_output
[i
][1] == output
) {
156 return inttgt_output
[i
][0];
163 #define MSIIR_OFFSET 0x140
164 #define MSIIR_SRS_SHIFT 29
165 #define MSIIR_SRS_MASK (0x7 << MSIIR_SRS_SHIFT)
166 #define MSIIR_IBS_SHIFT 24
167 #define MSIIR_IBS_MASK (0x1f << MSIIR_IBS_SHIFT)
169 static int get_current_cpu(void)
175 return current_cpu
->cpu_index
;
178 static uint32_t openpic_cpu_read_internal(void *opaque
, hwaddr addr
,
180 static void openpic_cpu_write_internal(void *opaque
, hwaddr addr
,
181 uint32_t val
, int idx
);
182 static void openpic_reset(DeviceState
*d
);
184 /* Convert between openpic clock ticks and nanosecs. In the hardware the clock
185 frequency is driven by board inputs to the PIC which the PIC would then
186 divide by 4 or 8. For now hard code to 25MZ.
188 #define OPENPIC_TIMER_FREQ_MHZ 25
189 #define OPENPIC_TIMER_NS_PER_TICK (1000 / OPENPIC_TIMER_FREQ_MHZ)
190 static inline uint64_t ns_to_ticks(uint64_t ns
)
192 return ns
/ OPENPIC_TIMER_NS_PER_TICK
;
194 static inline uint64_t ticks_to_ns(uint64_t ticks
)
196 return ticks
* OPENPIC_TIMER_NS_PER_TICK
;
199 static inline void IRQ_setbit(IRQQueue
*q
, int n_IRQ
)
201 set_bit(n_IRQ
, q
->queue
);
204 static inline void IRQ_resetbit(IRQQueue
*q
, int n_IRQ
)
206 clear_bit(n_IRQ
, q
->queue
);
209 static void IRQ_check(OpenPICState
*opp
, IRQQueue
*q
)
216 irq
= find_next_bit(q
->queue
, opp
->max_irq
, irq
+ 1);
217 if (irq
== opp
->max_irq
) {
221 DPRINTF("IRQ_check: irq %d set ivpr_pr=%d pr=%d",
222 irq
, IVPR_PRIORITY(opp
->src
[irq
].ivpr
), priority
);
224 if (IVPR_PRIORITY(opp
->src
[irq
].ivpr
) > priority
) {
226 priority
= IVPR_PRIORITY(opp
->src
[irq
].ivpr
);
231 q
->priority
= priority
;
234 static int IRQ_get_next(OpenPICState
*opp
, IRQQueue
*q
)
242 static void IRQ_local_pipe(OpenPICState
*opp
, int n_CPU
, int n_IRQ
,
243 bool active
, bool was_active
)
249 dst
= &opp
->dst
[n_CPU
];
250 src
= &opp
->src
[n_IRQ
];
252 DPRINTF("%s: IRQ %d active %d was %d",
253 __func__
, n_IRQ
, active
, was_active
);
255 if (src
->output
!= OPENPIC_OUTPUT_INT
) {
256 DPRINTF("%s: output %d irq %d active %d was %d count %d",
257 __func__
, src
->output
, n_IRQ
, active
, was_active
,
258 dst
->outputs_active
[src
->output
]);
260 /* On Freescale MPIC, critical interrupts ignore priority,
261 * IACK, EOI, etc. Before MPIC v4.1 they also ignore
265 if (!was_active
&& dst
->outputs_active
[src
->output
]++ == 0) {
266 DPRINTF("%s: Raise OpenPIC output %d cpu %d irq %d",
267 __func__
, src
->output
, n_CPU
, n_IRQ
);
268 qemu_irq_raise(dst
->irqs
[src
->output
]);
271 if (was_active
&& --dst
->outputs_active
[src
->output
] == 0) {
272 DPRINTF("%s: Lower OpenPIC output %d cpu %d irq %d",
273 __func__
, src
->output
, n_CPU
, n_IRQ
);
274 qemu_irq_lower(dst
->irqs
[src
->output
]);
281 priority
= IVPR_PRIORITY(src
->ivpr
);
283 /* Even if the interrupt doesn't have enough priority,
284 * it is still raised, in case ctpr is lowered later.
287 IRQ_setbit(&dst
->raised
, n_IRQ
);
289 IRQ_resetbit(&dst
->raised
, n_IRQ
);
292 IRQ_check(opp
, &dst
->raised
);
294 if (active
&& priority
<= dst
->ctpr
) {
295 DPRINTF("%s: IRQ %d priority %d too low for ctpr %d on CPU %d",
296 __func__
, n_IRQ
, priority
, dst
->ctpr
, n_CPU
);
301 if (IRQ_get_next(opp
, &dst
->servicing
) >= 0 &&
302 priority
<= dst
->servicing
.priority
) {
303 DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d",
304 __func__
, n_IRQ
, dst
->servicing
.next
, n_CPU
);
306 DPRINTF("%s: Raise OpenPIC INT output cpu %d irq %d/%d",
307 __func__
, n_CPU
, n_IRQ
, dst
->raised
.next
);
308 qemu_irq_raise(opp
->dst
[n_CPU
].irqs
[OPENPIC_OUTPUT_INT
]);
311 IRQ_get_next(opp
, &dst
->servicing
);
312 if (dst
->raised
.priority
> dst
->ctpr
&&
313 dst
->raised
.priority
> dst
->servicing
.priority
) {
314 DPRINTF("%s: IRQ %d inactive, IRQ %d prio %d above %d/%d, CPU %d",
315 __func__
, n_IRQ
, dst
->raised
.next
, dst
->raised
.priority
,
316 dst
->ctpr
, dst
->servicing
.priority
, n_CPU
);
317 /* IRQ line stays asserted */
319 DPRINTF("%s: IRQ %d inactive, current prio %d/%d, CPU %d",
320 __func__
, n_IRQ
, dst
->ctpr
, dst
->servicing
.priority
, n_CPU
);
321 qemu_irq_lower(opp
->dst
[n_CPU
].irqs
[OPENPIC_OUTPUT_INT
]);
326 /* update pic state because registers for n_IRQ have changed value */
327 static void openpic_update_irq(OpenPICState
*opp
, int n_IRQ
)
330 bool active
, was_active
;
333 src
= &opp
->src
[n_IRQ
];
334 active
= src
->pending
;
336 if ((src
->ivpr
& IVPR_MASK_MASK
) && !src
->nomask
) {
337 /* Interrupt source is disabled */
338 DPRINTF("%s: IRQ %d is disabled", __func__
, n_IRQ
);
342 was_active
= !!(src
->ivpr
& IVPR_ACTIVITY_MASK
);
345 * We don't have a similar check for already-active because
346 * ctpr may have changed and we need to withdraw the interrupt.
348 if (!active
&& !was_active
) {
349 DPRINTF("%s: IRQ %d is already inactive", __func__
, n_IRQ
);
354 src
->ivpr
|= IVPR_ACTIVITY_MASK
;
356 src
->ivpr
&= ~IVPR_ACTIVITY_MASK
;
359 if (src
->destmask
== 0) {
361 DPRINTF("%s: IRQ %d has no target", __func__
, n_IRQ
);
365 if (src
->destmask
== (1 << src
->last_cpu
)) {
366 /* Only one CPU is allowed to receive this IRQ */
367 IRQ_local_pipe(opp
, src
->last_cpu
, n_IRQ
, active
, was_active
);
368 } else if (!(src
->ivpr
& IVPR_MODE_MASK
)) {
369 /* Directed delivery mode */
370 for (i
= 0; i
< opp
->nb_cpus
; i
++) {
371 if (src
->destmask
& (1 << i
)) {
372 IRQ_local_pipe(opp
, i
, n_IRQ
, active
, was_active
);
376 /* Distributed delivery mode */
377 for (i
= src
->last_cpu
+ 1; i
!= src
->last_cpu
; i
++) {
378 if (i
== opp
->nb_cpus
) {
381 if (src
->destmask
& (1 << i
)) {
382 IRQ_local_pipe(opp
, i
, n_IRQ
, active
, was_active
);
390 static void openpic_set_irq(void *opaque
, int n_IRQ
, int level
)
392 OpenPICState
*opp
= opaque
;
395 if (n_IRQ
>= OPENPIC_MAX_IRQ
) {
396 error_report("%s: IRQ %d out of range", __func__
, n_IRQ
);
400 src
= &opp
->src
[n_IRQ
];
401 DPRINTF("openpic: set irq %d = %d ivpr=0x%08x",
402 n_IRQ
, level
, src
->ivpr
);
404 /* level-sensitive irq */
405 src
->pending
= level
;
406 openpic_update_irq(opp
, n_IRQ
);
408 /* edge-sensitive irq */
411 openpic_update_irq(opp
, n_IRQ
);
414 if (src
->output
!= OPENPIC_OUTPUT_INT
) {
415 /* Edge-triggered interrupts shouldn't be used
416 * with non-INT delivery, but just in case,
417 * try to make it do something sane rather than
418 * cause an interrupt storm. This is close to
419 * what you'd probably see happen in real hardware.
422 openpic_update_irq(opp
, n_IRQ
);
427 static inline uint32_t read_IRQreg_idr(OpenPICState
*opp
, int n_IRQ
)
429 return opp
->src
[n_IRQ
].idr
;
432 static inline uint32_t read_IRQreg_ilr(OpenPICState
*opp
, int n_IRQ
)
434 if (opp
->flags
& OPENPIC_FLAG_ILR
) {
435 return output_to_inttgt(opp
->src
[n_IRQ
].output
);
441 static inline uint32_t read_IRQreg_ivpr(OpenPICState
*opp
, int n_IRQ
)
443 return opp
->src
[n_IRQ
].ivpr
;
446 static inline void write_IRQreg_idr(OpenPICState
*opp
, int n_IRQ
, uint32_t val
)
448 IRQSource
*src
= &opp
->src
[n_IRQ
];
449 uint32_t normal_mask
= (1UL << opp
->nb_cpus
) - 1;
450 uint32_t crit_mask
= 0;
451 uint32_t mask
= normal_mask
;
452 int crit_shift
= IDR_EP_SHIFT
- opp
->nb_cpus
;
455 if (opp
->flags
& OPENPIC_FLAG_IDR_CRIT
) {
456 crit_mask
= mask
<< crit_shift
;
457 mask
|= crit_mask
| IDR_EP
;
460 src
->idr
= val
& mask
;
461 DPRINTF("Set IDR %d to 0x%08x", n_IRQ
, src
->idr
);
463 if (opp
->flags
& OPENPIC_FLAG_IDR_CRIT
) {
464 if (src
->idr
& crit_mask
) {
465 if (src
->idr
& normal_mask
) {
466 DPRINTF("%s: IRQ configured for multiple output types, using "
467 "critical", __func__
);
470 src
->output
= OPENPIC_OUTPUT_CINT
;
474 for (i
= 0; i
< opp
->nb_cpus
; i
++) {
475 int n_ci
= IDR_CI0_SHIFT
- i
;
477 if (src
->idr
& (1UL << n_ci
)) {
478 src
->destmask
|= 1UL << i
;
482 src
->output
= OPENPIC_OUTPUT_INT
;
484 src
->destmask
= src
->idr
& normal_mask
;
487 src
->destmask
= src
->idr
;
491 static inline void write_IRQreg_ilr(OpenPICState
*opp
, int n_IRQ
, uint32_t val
)
493 if (opp
->flags
& OPENPIC_FLAG_ILR
) {
494 IRQSource
*src
= &opp
->src
[n_IRQ
];
496 src
->output
= inttgt_to_output(val
& ILR_INTTGT_MASK
);
497 DPRINTF("Set ILR %d to 0x%08x, output %d", n_IRQ
, src
->idr
,
500 /* TODO: on MPIC v4.0 only, set nomask for non-INT */
504 static inline void write_IRQreg_ivpr(OpenPICState
*opp
, int n_IRQ
, uint32_t val
)
508 /* NOTE when implementing newer FSL MPIC models: starting with v4.0,
509 * the polarity bit is read-only on internal interrupts.
511 mask
= IVPR_MASK_MASK
| IVPR_PRIORITY_MASK
| IVPR_SENSE_MASK
|
512 IVPR_POLARITY_MASK
| opp
->vector_mask
;
514 /* ACTIVITY bit is read-only */
515 opp
->src
[n_IRQ
].ivpr
=
516 (opp
->src
[n_IRQ
].ivpr
& IVPR_ACTIVITY_MASK
) | (val
& mask
);
518 /* For FSL internal interrupts, The sense bit is reserved and zero,
519 * and the interrupt is always level-triggered. Timers and IPIs
520 * have no sense or polarity bits, and are edge-triggered.
522 switch (opp
->src
[n_IRQ
].type
) {
523 case IRQ_TYPE_NORMAL
:
524 opp
->src
[n_IRQ
].level
= !!(opp
->src
[n_IRQ
].ivpr
& IVPR_SENSE_MASK
);
527 case IRQ_TYPE_FSLINT
:
528 opp
->src
[n_IRQ
].ivpr
&= ~IVPR_SENSE_MASK
;
531 case IRQ_TYPE_FSLSPECIAL
:
532 opp
->src
[n_IRQ
].ivpr
&= ~(IVPR_POLARITY_MASK
| IVPR_SENSE_MASK
);
536 openpic_update_irq(opp
, n_IRQ
);
537 DPRINTF("Set IVPR %d to 0x%08x -> 0x%08x", n_IRQ
, val
,
538 opp
->src
[n_IRQ
].ivpr
);
541 static void openpic_gcr_write(OpenPICState
*opp
, uint64_t val
)
543 bool mpic_proxy
= false;
545 if (val
& GCR_RESET
) {
546 openpic_reset(DEVICE(opp
));
550 opp
->gcr
&= ~opp
->mpic_mode_mask
;
551 opp
->gcr
|= val
& opp
->mpic_mode_mask
;
553 /* Set external proxy mode */
554 if ((val
& opp
->mpic_mode_mask
) == GCR_MODE_PROXY
) {
558 ppce500_set_mpic_proxy(mpic_proxy
);
561 static void openpic_gbl_write(void *opaque
, hwaddr addr
, uint64_t val
,
564 OpenPICState
*opp
= opaque
;
568 DPRINTF("%s: addr %#" HWADDR_PRIx
" <= %08" PRIx64
,
569 __func__
, addr
, val
);
574 case 0x00: /* Block Revision Register1 (BRR1) is Readonly */
584 openpic_cpu_write_internal(opp
, addr
, val
, get_current_cpu());
586 case 0x1000: /* FRR */
588 case 0x1020: /* GCR */
589 openpic_gcr_write(opp
, val
);
591 case 0x1080: /* VIR */
593 case 0x1090: /* PIR */
594 for (idx
= 0; idx
< opp
->nb_cpus
; idx
++) {
595 if ((val
& (1 << idx
)) && !(opp
->pir
& (1 << idx
))) {
596 DPRINTF("Raise OpenPIC RESET output for CPU %d", idx
);
597 dst
= &opp
->dst
[idx
];
598 qemu_irq_raise(dst
->irqs
[OPENPIC_OUTPUT_RESET
]);
599 } else if (!(val
& (1 << idx
)) && (opp
->pir
& (1 << idx
))) {
600 DPRINTF("Lower OpenPIC RESET output for CPU %d", idx
);
601 dst
= &opp
->dst
[idx
];
602 qemu_irq_lower(dst
->irqs
[OPENPIC_OUTPUT_RESET
]);
607 case 0x10A0: /* IPI_IVPR */
613 idx
= (addr
- 0x10A0) >> 4;
614 write_IRQreg_ivpr(opp
, opp
->irq_ipi0
+ idx
, val
);
617 case 0x10E0: /* SPVE */
618 opp
->spve
= val
& opp
->vector_mask
;
625 static uint64_t openpic_gbl_read(void *opaque
, hwaddr addr
, unsigned len
)
627 OpenPICState
*opp
= opaque
;
630 DPRINTF("%s: addr %#" HWADDR_PRIx
, __func__
, addr
);
636 case 0x1000: /* FRR */
639 case 0x1020: /* GCR */
642 case 0x1080: /* VIR */
645 case 0x1090: /* PIR */
648 case 0x00: /* Block Revision Register1 (BRR1) */
659 retval
= openpic_cpu_read_internal(opp
, addr
, get_current_cpu());
661 case 0x10A0: /* IPI_IVPR */
667 idx
= (addr
- 0x10A0) >> 4;
668 retval
= read_IRQreg_ivpr(opp
, opp
->irq_ipi0
+ idx
);
671 case 0x10E0: /* SPVE */
677 DPRINTF("%s: => 0x%08x", __func__
, retval
);
682 static void openpic_tmr_set_tmr(OpenPICTimer
*tmr
, uint32_t val
, bool enabled
);
684 static void qemu_timer_cb(void *opaque
)
686 OpenPICTimer
*tmr
= opaque
;
687 OpenPICState
*opp
= tmr
->opp
;
688 uint32_t n_IRQ
= tmr
->n_IRQ
;
689 uint32_t val
= tmr
->tbcr
& ~TBCR_CI
;
690 uint32_t tog
= ((tmr
->tccr
& TCCR_TOG
) ^ TCCR_TOG
); /* invert toggle. */
692 DPRINTF("%s n_IRQ=%d", __func__
, n_IRQ
);
693 /* Reload current count from base count and setup timer. */
694 tmr
->tccr
= val
| tog
;
695 openpic_tmr_set_tmr(tmr
, val
, /*enabled=*/true);
696 /* Raise the interrupt. */
697 opp
->src
[n_IRQ
].destmask
= read_IRQreg_idr(opp
, n_IRQ
);
698 openpic_set_irq(opp
, n_IRQ
, 1);
699 openpic_set_irq(opp
, n_IRQ
, 0);
702 /* If enabled is true, arranges for an interrupt to be raised val clocks into
703 the future, if enabled is false cancels the timer. */
704 static void openpic_tmr_set_tmr(OpenPICTimer
*tmr
, uint32_t val
, bool enabled
)
706 uint64_t ns
= ticks_to_ns(val
& ~TCCR_TOG
);
707 /* A count of zero causes a timer to be set to expire immediately. This
708 effectively stops the simulation since the timer is constantly expiring
709 which prevents guest code execution, so we don't honor that
710 configuration. On real hardware, this situation would generate an
711 interrupt on every clock cycle if the interrupt was unmasked. */
712 if ((ns
== 0) || !enabled
) {
713 tmr
->qemu_timer_active
= false;
714 tmr
->tccr
= tmr
->tccr
& TCCR_TOG
;
715 timer_del(tmr
->qemu_timer
); /* set timer to never expire. */
717 tmr
->qemu_timer_active
= true;
718 uint64_t now
= qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL
);
719 tmr
->origin_time
= now
;
720 timer_mod(tmr
->qemu_timer
, now
+ ns
); /* set timer expiration. */
724 /* Returns the currrent tccr value, i.e., timer value (in clocks) with
726 static uint64_t openpic_tmr_get_timer(OpenPICTimer
*tmr
)
729 if (!tmr
->qemu_timer_active
) {
732 uint64_t now
= qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL
);
733 uint64_t used
= now
- tmr
->origin_time
; /* nsecs */
734 uint32_t used_ticks
= (uint32_t)ns_to_ticks(used
);
735 uint32_t count
= (tmr
->tccr
& ~TCCR_TOG
) - used_ticks
;
736 retval
= (uint32_t)((tmr
->tccr
& TCCR_TOG
) | (count
& ~TCCR_TOG
));
741 static void openpic_tmr_write(void *opaque
, hwaddr addr
, uint64_t val
,
744 OpenPICState
*opp
= opaque
;
747 DPRINTF("%s: addr %#" HWADDR_PRIx
" <= %08" PRIx64
,
748 __func__
, (addr
+ 0x10f0), val
);
758 addr
-= 0x10; /* correct for TFRR */
759 idx
= (addr
>> 6) & 0x3;
761 switch (addr
& 0x30) {
762 case 0x00: /* TCCR */
764 case 0x10: /* TBCR */
765 /* Did the enable status change? */
766 if ((opp
->timers
[idx
].tbcr
& TBCR_CI
) != (val
& TBCR_CI
)) {
767 /* Did "Count Inhibit" transition from 1 to 0? */
768 if ((val
& TBCR_CI
) == 0) {
769 opp
->timers
[idx
].tccr
= val
& ~TCCR_TOG
;
771 openpic_tmr_set_tmr(&opp
->timers
[idx
],
773 /*enabled=*/((val
& TBCR_CI
) == 0));
775 opp
->timers
[idx
].tbcr
= val
;
777 case 0x20: /* TVPR */
778 write_IRQreg_ivpr(opp
, opp
->irq_tim0
+ idx
, val
);
781 write_IRQreg_idr(opp
, opp
->irq_tim0
+ idx
, val
);
786 static uint64_t openpic_tmr_read(void *opaque
, hwaddr addr
, unsigned len
)
788 OpenPICState
*opp
= opaque
;
789 uint32_t retval
= -1;
792 DPRINTF("%s: addr %#" HWADDR_PRIx
, __func__
, addr
+ 0x10f0);
801 addr
-= 0x10; /* correct for TFRR */
802 idx
= (addr
>> 6) & 0x3;
803 switch (addr
& 0x30) {
804 case 0x00: /* TCCR */
805 retval
= openpic_tmr_get_timer(&opp
->timers
[idx
]);
807 case 0x10: /* TBCR */
808 retval
= opp
->timers
[idx
].tbcr
;
810 case 0x20: /* TVPR */
811 retval
= read_IRQreg_ivpr(opp
, opp
->irq_tim0
+ idx
);
814 retval
= read_IRQreg_idr(opp
, opp
->irq_tim0
+ idx
);
819 DPRINTF("%s: => 0x%08x", __func__
, retval
);
824 static void openpic_src_write(void *opaque
, hwaddr addr
, uint64_t val
,
827 OpenPICState
*opp
= opaque
;
830 DPRINTF("%s: addr %#" HWADDR_PRIx
" <= %08" PRIx64
,
831 __func__
, addr
, val
);
833 addr
= addr
& 0xffff;
836 switch (addr
& 0x1f) {
838 write_IRQreg_ivpr(opp
, idx
, val
);
841 write_IRQreg_idr(opp
, idx
, val
);
844 write_IRQreg_ilr(opp
, idx
, val
);
849 static uint64_t openpic_src_read(void *opaque
, uint64_t addr
, unsigned len
)
851 OpenPICState
*opp
= opaque
;
855 DPRINTF("%s: addr %#" HWADDR_PRIx
, __func__
, addr
);
858 addr
= addr
& 0xffff;
861 switch (addr
& 0x1f) {
863 retval
= read_IRQreg_ivpr(opp
, idx
);
866 retval
= read_IRQreg_idr(opp
, idx
);
869 retval
= read_IRQreg_ilr(opp
, idx
);
873 DPRINTF("%s: => 0x%08x", __func__
, retval
);
877 static void openpic_msi_write(void *opaque
, hwaddr addr
, uint64_t val
,
880 OpenPICState
*opp
= opaque
;
881 int idx
= opp
->irq_msi
;
884 DPRINTF("%s: addr %#" HWADDR_PRIx
" <= 0x%08" PRIx64
,
885 __func__
, addr
, val
);
892 srs
= val
>> MSIIR_SRS_SHIFT
;
894 ibs
= (val
& MSIIR_IBS_MASK
) >> MSIIR_IBS_SHIFT
;
895 opp
->msi
[srs
].msir
|= 1 << ibs
;
896 openpic_set_irq(opp
, idx
, 1);
899 /* most registers are read-only, thus ignored */
904 static uint64_t openpic_msi_read(void *opaque
, hwaddr addr
, unsigned size
)
906 OpenPICState
*opp
= opaque
;
910 DPRINTF("%s: addr %#" HWADDR_PRIx
, __func__
, addr
);
925 case 0x70: /* MSIRs */
926 r
= opp
->msi
[srs
].msir
;
928 opp
->msi
[srs
].msir
= 0;
929 openpic_set_irq(opp
, opp
->irq_msi
+ srs
, 0);
931 case 0x120: /* MSISR */
932 for (i
= 0; i
< MAX_MSI
; i
++) {
933 r
|= (opp
->msi
[i
].msir
? 1 : 0) << i
;
941 static uint64_t openpic_summary_read(void *opaque
, hwaddr addr
, unsigned size
)
945 DPRINTF("%s: addr %#" HWADDR_PRIx
, __func__
, addr
);
947 /* TODO: EISR/EIMR */
952 static void openpic_summary_write(void *opaque
, hwaddr addr
, uint64_t val
,
955 DPRINTF("%s: addr %#" HWADDR_PRIx
" <= 0x%08" PRIx64
,
956 __func__
, addr
, val
);
958 /* TODO: EISR/EIMR */
961 static void openpic_cpu_write_internal(void *opaque
, hwaddr addr
,
962 uint32_t val
, int idx
)
964 OpenPICState
*opp
= opaque
;
969 DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx
" <= 0x%08x", __func__
, idx
,
972 if (idx
< 0 || idx
>= opp
->nb_cpus
) {
979 dst
= &opp
->dst
[idx
];
982 case 0x40: /* IPIDR */
986 idx
= (addr
- 0x40) >> 4;
987 /* we use IDE as mask which CPUs to deliver the IPI to still. */
988 opp
->src
[opp
->irq_ipi0
+ idx
].destmask
|= val
;
989 openpic_set_irq(opp
, opp
->irq_ipi0
+ idx
, 1);
990 openpic_set_irq(opp
, opp
->irq_ipi0
+ idx
, 0);
992 case 0x80: /* CTPR */
993 dst
->ctpr
= val
& 0x0000000F;
995 DPRINTF("%s: set CPU %d ctpr to %d, raised %d servicing %d",
996 __func__
, idx
, dst
->ctpr
, dst
->raised
.priority
,
997 dst
->servicing
.priority
);
999 if (dst
->raised
.priority
<= dst
->ctpr
) {
1000 DPRINTF("%s: Lower OpenPIC INT output cpu %d due to ctpr",
1002 qemu_irq_lower(dst
->irqs
[OPENPIC_OUTPUT_INT
]);
1003 } else if (dst
->raised
.priority
> dst
->servicing
.priority
) {
1004 DPRINTF("%s: Raise OpenPIC INT output cpu %d irq %d",
1005 __func__
, idx
, dst
->raised
.next
);
1006 qemu_irq_raise(dst
->irqs
[OPENPIC_OUTPUT_INT
]);
1010 case 0x90: /* WHOAMI */
1011 /* Read-only register */
1013 case 0xA0: /* IACK */
1014 /* Read-only register */
1016 case 0xB0: /* EOI */
1018 s_IRQ
= IRQ_get_next(opp
, &dst
->servicing
);
1021 DPRINTF("%s: EOI with no interrupt in service", __func__
);
1025 IRQ_resetbit(&dst
->servicing
, s_IRQ
);
1026 /* Set up next servicing IRQ */
1027 s_IRQ
= IRQ_get_next(opp
, &dst
->servicing
);
1028 /* Check queued interrupts. */
1029 n_IRQ
= IRQ_get_next(opp
, &dst
->raised
);
1030 src
= &opp
->src
[n_IRQ
];
1033 IVPR_PRIORITY(src
->ivpr
) > dst
->servicing
.priority
)) {
1034 DPRINTF("Raise OpenPIC INT output cpu %d irq %d",
1036 qemu_irq_raise(opp
->dst
[idx
].irqs
[OPENPIC_OUTPUT_INT
]);
1044 static void openpic_cpu_write(void *opaque
, hwaddr addr
, uint64_t val
,
1047 openpic_cpu_write_internal(opaque
, addr
, val
, (addr
& 0x1f000) >> 12);
1051 static uint32_t openpic_iack(OpenPICState
*opp
, IRQDest
*dst
, int cpu
)
1056 DPRINTF("Lower OpenPIC INT output");
1057 qemu_irq_lower(dst
->irqs
[OPENPIC_OUTPUT_INT
]);
1059 irq
= IRQ_get_next(opp
, &dst
->raised
);
1060 DPRINTF("IACK: irq=%d", irq
);
1063 /* No more interrupt pending */
1067 src
= &opp
->src
[irq
];
1068 if (!(src
->ivpr
& IVPR_ACTIVITY_MASK
) ||
1069 !(IVPR_PRIORITY(src
->ivpr
) > dst
->ctpr
)) {
1070 error_report("%s: bad raised IRQ %d ctpr %d ivpr 0x%08x",
1071 __func__
, irq
, dst
->ctpr
, src
->ivpr
);
1072 openpic_update_irq(opp
, irq
);
1075 /* IRQ enter servicing state */
1076 IRQ_setbit(&dst
->servicing
, irq
);
1077 retval
= IVPR_VECTOR(opp
, src
->ivpr
);
1081 /* edge-sensitive IRQ */
1082 src
->ivpr
&= ~IVPR_ACTIVITY_MASK
;
1084 IRQ_resetbit(&dst
->raised
, irq
);
1087 /* Timers and IPIs support multicast. */
1088 if (((irq
>= opp
->irq_ipi0
) && (irq
< (opp
->irq_ipi0
+ OPENPIC_MAX_IPI
))) ||
1089 ((irq
>= opp
->irq_tim0
) && (irq
< (opp
->irq_tim0
+ OPENPIC_MAX_TMR
)))) {
1090 DPRINTF("irq is IPI or TMR");
1091 src
->destmask
&= ~(1 << cpu
);
1092 if (src
->destmask
&& !src
->level
) {
1093 /* trigger on CPUs that didn't know about it yet */
1094 openpic_set_irq(opp
, irq
, 1);
1095 openpic_set_irq(opp
, irq
, 0);
1096 /* if all CPUs knew about it, set active bit again */
1097 src
->ivpr
|= IVPR_ACTIVITY_MASK
;
1104 static uint32_t openpic_cpu_read_internal(void *opaque
, hwaddr addr
,
1107 OpenPICState
*opp
= opaque
;
1111 DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx
, __func__
, idx
, addr
);
1112 retval
= 0xFFFFFFFF;
1114 if (idx
< 0 || idx
>= opp
->nb_cpus
) {
1121 dst
= &opp
->dst
[idx
];
1124 case 0x80: /* CTPR */
1127 case 0x90: /* WHOAMI */
1130 case 0xA0: /* IACK */
1131 retval
= openpic_iack(opp
, dst
, idx
);
1133 case 0xB0: /* EOI */
1139 DPRINTF("%s: => 0x%08x", __func__
, retval
);
1144 static uint64_t openpic_cpu_read(void *opaque
, hwaddr addr
, unsigned len
)
1146 return openpic_cpu_read_internal(opaque
, addr
, (addr
& 0x1f000) >> 12);
1149 static const MemoryRegionOps openpic_glb_ops_le
= {
1150 .write
= openpic_gbl_write
,
1151 .read
= openpic_gbl_read
,
1152 .endianness
= DEVICE_LITTLE_ENDIAN
,
1154 .min_access_size
= 4,
1155 .max_access_size
= 4,
1159 static const MemoryRegionOps openpic_glb_ops_be
= {
1160 .write
= openpic_gbl_write
,
1161 .read
= openpic_gbl_read
,
1162 .endianness
= DEVICE_BIG_ENDIAN
,
1164 .min_access_size
= 4,
1165 .max_access_size
= 4,
1169 static const MemoryRegionOps openpic_tmr_ops_le
= {
1170 .write
= openpic_tmr_write
,
1171 .read
= openpic_tmr_read
,
1172 .endianness
= DEVICE_LITTLE_ENDIAN
,
1174 .min_access_size
= 4,
1175 .max_access_size
= 4,
1179 static const MemoryRegionOps openpic_tmr_ops_be
= {
1180 .write
= openpic_tmr_write
,
1181 .read
= openpic_tmr_read
,
1182 .endianness
= DEVICE_BIG_ENDIAN
,
1184 .min_access_size
= 4,
1185 .max_access_size
= 4,
1189 static const MemoryRegionOps openpic_cpu_ops_le
= {
1190 .write
= openpic_cpu_write
,
1191 .read
= openpic_cpu_read
,
1192 .endianness
= DEVICE_LITTLE_ENDIAN
,
1194 .min_access_size
= 4,
1195 .max_access_size
= 4,
1199 static const MemoryRegionOps openpic_cpu_ops_be
= {
1200 .write
= openpic_cpu_write
,
1201 .read
= openpic_cpu_read
,
1202 .endianness
= DEVICE_BIG_ENDIAN
,
1204 .min_access_size
= 4,
1205 .max_access_size
= 4,
1209 static const MemoryRegionOps openpic_src_ops_le
= {
1210 .write
= openpic_src_write
,
1211 .read
= openpic_src_read
,
1212 .endianness
= DEVICE_LITTLE_ENDIAN
,
1214 .min_access_size
= 4,
1215 .max_access_size
= 4,
1219 static const MemoryRegionOps openpic_src_ops_be
= {
1220 .write
= openpic_src_write
,
1221 .read
= openpic_src_read
,
1222 .endianness
= DEVICE_BIG_ENDIAN
,
1224 .min_access_size
= 4,
1225 .max_access_size
= 4,
1229 static const MemoryRegionOps openpic_msi_ops_be
= {
1230 .read
= openpic_msi_read
,
1231 .write
= openpic_msi_write
,
1232 .endianness
= DEVICE_BIG_ENDIAN
,
1234 .min_access_size
= 4,
1235 .max_access_size
= 4,
1239 static const MemoryRegionOps openpic_summary_ops_be
= {
1240 .read
= openpic_summary_read
,
1241 .write
= openpic_summary_write
,
1242 .endianness
= DEVICE_BIG_ENDIAN
,
1244 .min_access_size
= 4,
1245 .max_access_size
= 4,
1249 static void openpic_reset(DeviceState
*d
)
1251 OpenPICState
*opp
= OPENPIC(d
);
1254 opp
->gcr
= GCR_RESET
;
1255 /* Initialise controller registers */
1256 opp
->frr
= ((opp
->nb_irqs
- 1) << FRR_NIRQ_SHIFT
) |
1257 ((opp
->nb_cpus
- 1) << FRR_NCPU_SHIFT
) |
1258 (opp
->vid
<< FRR_VID_SHIFT
);
1261 opp
->spve
= -1 & opp
->vector_mask
;
1262 opp
->tfrr
= opp
->tfrr_reset
;
1263 /* Initialise IRQ sources */
1264 for (i
= 0; i
< opp
->max_irq
; i
++) {
1265 opp
->src
[i
].ivpr
= opp
->ivpr_reset
;
1266 switch (opp
->src
[i
].type
) {
1267 case IRQ_TYPE_NORMAL
:
1268 opp
->src
[i
].level
= !!(opp
->ivpr_reset
& IVPR_SENSE_MASK
);
1271 case IRQ_TYPE_FSLINT
:
1272 opp
->src
[i
].ivpr
|= IVPR_POLARITY_MASK
;
1275 case IRQ_TYPE_FSLSPECIAL
:
1279 write_IRQreg_idr(opp
, i
, opp
->idr_reset
);
1281 /* Initialise IRQ destinations */
1282 for (i
= 0; i
< opp
->nb_cpus
; i
++) {
1283 opp
->dst
[i
].ctpr
= 15;
1284 opp
->dst
[i
].raised
.next
= -1;
1285 opp
->dst
[i
].raised
.priority
= 0;
1286 bitmap_clear(opp
->dst
[i
].raised
.queue
, 0, IRQQUEUE_SIZE_BITS
);
1287 opp
->dst
[i
].servicing
.next
= -1;
1288 opp
->dst
[i
].servicing
.priority
= 0;
1289 bitmap_clear(opp
->dst
[i
].servicing
.queue
, 0, IRQQUEUE_SIZE_BITS
);
1291 /* Initialise timers */
1292 for (i
= 0; i
< OPENPIC_MAX_TMR
; i
++) {
1293 opp
->timers
[i
].tccr
= 0;
1294 opp
->timers
[i
].tbcr
= TBCR_CI
;
1295 if (opp
->timers
[i
].qemu_timer_active
) {
1296 timer_del(opp
->timers
[i
].qemu_timer
); /* Inhibit timer */
1297 opp
->timers
[i
].qemu_timer_active
= false;
1300 /* Go out of RESET state */
1304 typedef struct MemReg
{
1306 MemoryRegionOps
const *ops
;
1311 static void fsl_common_init(OpenPICState
*opp
)
1314 int virq
= OPENPIC_MAX_SRC
;
1316 opp
->vid
= VID_REVISION_1_2
;
1317 opp
->vir
= VIR_GENERIC
;
1318 opp
->vector_mask
= 0xFFFF;
1319 opp
->tfrr_reset
= 0;
1320 opp
->ivpr_reset
= IVPR_MASK_MASK
;
1321 opp
->idr_reset
= 1 << 0;
1322 opp
->max_irq
= OPENPIC_MAX_IRQ
;
1324 opp
->irq_ipi0
= virq
;
1325 virq
+= OPENPIC_MAX_IPI
;
1326 opp
->irq_tim0
= virq
;
1327 virq
+= OPENPIC_MAX_TMR
;
1329 assert(virq
<= OPENPIC_MAX_IRQ
);
1333 msi_nonbroken
= true;
1334 for (i
= 0; i
< opp
->fsl
->max_ext
; i
++) {
1335 opp
->src
[i
].level
= false;
1338 /* Internal interrupts, including message and MSI */
1339 for (i
= 16; i
< OPENPIC_MAX_SRC
; i
++) {
1340 opp
->src
[i
].type
= IRQ_TYPE_FSLINT
;
1341 opp
->src
[i
].level
= true;
1344 /* timers and IPIs */
1345 for (i
= OPENPIC_MAX_SRC
; i
< virq
; i
++) {
1346 opp
->src
[i
].type
= IRQ_TYPE_FSLSPECIAL
;
1347 opp
->src
[i
].level
= false;
1350 for (i
= 0; i
< OPENPIC_MAX_TMR
; i
++) {
1351 opp
->timers
[i
].n_IRQ
= opp
->irq_tim0
+ i
;
1352 opp
->timers
[i
].qemu_timer_active
= false;
1353 opp
->timers
[i
].qemu_timer
= timer_new_ns(QEMU_CLOCK_VIRTUAL
,
1356 opp
->timers
[i
].opp
= opp
;
1360 static void map_list(OpenPICState
*opp
, const MemReg
*list
, int *count
)
1362 while (list
->name
) {
1363 assert(*count
< ARRAY_SIZE(opp
->sub_io_mem
));
1365 memory_region_init_io(&opp
->sub_io_mem
[*count
], OBJECT(opp
), list
->ops
,
1366 opp
, list
->name
, list
->size
);
1368 memory_region_add_subregion(&opp
->mem
, list
->start_addr
,
1369 &opp
->sub_io_mem
[*count
]);
1376 static const VMStateDescription vmstate_openpic_irq_queue
= {
1377 .name
= "openpic_irq_queue",
1379 .minimum_version_id
= 0,
1380 .fields
= (VMStateField
[]) {
1381 VMSTATE_BITMAP(queue
, IRQQueue
, 0, queue_size
),
1382 VMSTATE_INT32(next
, IRQQueue
),
1383 VMSTATE_INT32(priority
, IRQQueue
),
1384 VMSTATE_END_OF_LIST()
1388 static const VMStateDescription vmstate_openpic_irqdest
= {
1389 .name
= "openpic_irqdest",
1391 .minimum_version_id
= 0,
1392 .fields
= (VMStateField
[]) {
1393 VMSTATE_INT32(ctpr
, IRQDest
),
1394 VMSTATE_STRUCT(raised
, IRQDest
, 0, vmstate_openpic_irq_queue
,
1396 VMSTATE_STRUCT(servicing
, IRQDest
, 0, vmstate_openpic_irq_queue
,
1398 VMSTATE_UINT32_ARRAY(outputs_active
, IRQDest
, OPENPIC_OUTPUT_NB
),
1399 VMSTATE_END_OF_LIST()
1403 static const VMStateDescription vmstate_openpic_irqsource
= {
1404 .name
= "openpic_irqsource",
1406 .minimum_version_id
= 0,
1407 .fields
= (VMStateField
[]) {
1408 VMSTATE_UINT32(ivpr
, IRQSource
),
1409 VMSTATE_UINT32(idr
, IRQSource
),
1410 VMSTATE_UINT32(destmask
, IRQSource
),
1411 VMSTATE_INT32(last_cpu
, IRQSource
),
1412 VMSTATE_INT32(pending
, IRQSource
),
1413 VMSTATE_END_OF_LIST()
1417 static const VMStateDescription vmstate_openpic_timer
= {
1418 .name
= "openpic_timer",
1420 .minimum_version_id
= 0,
1421 .fields
= (VMStateField
[]) {
1422 VMSTATE_UINT32(tccr
, OpenPICTimer
),
1423 VMSTATE_UINT32(tbcr
, OpenPICTimer
),
1424 VMSTATE_END_OF_LIST()
1428 static const VMStateDescription vmstate_openpic_msi
= {
1429 .name
= "openpic_msi",
1431 .minimum_version_id
= 0,
1432 .fields
= (VMStateField
[]) {
1433 VMSTATE_UINT32(msir
, OpenPICMSI
),
1434 VMSTATE_END_OF_LIST()
1438 static int openpic_post_load(void *opaque
, int version_id
)
1440 OpenPICState
*opp
= (OpenPICState
*)opaque
;
1443 /* Update internal ivpr and idr variables */
1444 for (i
= 0; i
< opp
->max_irq
; i
++) {
1445 write_IRQreg_idr(opp
, i
, opp
->src
[i
].idr
);
1446 write_IRQreg_ivpr(opp
, i
, opp
->src
[i
].ivpr
);
1452 static const VMStateDescription vmstate_openpic
= {
1455 .minimum_version_id
= 3,
1456 .post_load
= openpic_post_load
,
1457 .fields
= (VMStateField
[]) {
1458 VMSTATE_UINT32(gcr
, OpenPICState
),
1459 VMSTATE_UINT32(vir
, OpenPICState
),
1460 VMSTATE_UINT32(pir
, OpenPICState
),
1461 VMSTATE_UINT32(spve
, OpenPICState
),
1462 VMSTATE_UINT32(tfrr
, OpenPICState
),
1463 VMSTATE_UINT32(max_irq
, OpenPICState
),
1464 VMSTATE_STRUCT_VARRAY_UINT32(src
, OpenPICState
, max_irq
, 0,
1465 vmstate_openpic_irqsource
, IRQSource
),
1466 VMSTATE_UINT32_EQUAL(nb_cpus
, OpenPICState
, NULL
),
1467 VMSTATE_STRUCT_VARRAY_UINT32(dst
, OpenPICState
, nb_cpus
, 0,
1468 vmstate_openpic_irqdest
, IRQDest
),
1469 VMSTATE_STRUCT_ARRAY(timers
, OpenPICState
, OPENPIC_MAX_TMR
, 0,
1470 vmstate_openpic_timer
, OpenPICTimer
),
1471 VMSTATE_STRUCT_ARRAY(msi
, OpenPICState
, MAX_MSI
, 0,
1472 vmstate_openpic_msi
, OpenPICMSI
),
1473 VMSTATE_UINT32(irq_ipi0
, OpenPICState
),
1474 VMSTATE_UINT32(irq_tim0
, OpenPICState
),
1475 VMSTATE_UINT32(irq_msi
, OpenPICState
),
1476 VMSTATE_END_OF_LIST()
1480 static void openpic_init(Object
*obj
)
1482 OpenPICState
*opp
= OPENPIC(obj
);
1484 memory_region_init(&opp
->mem
, obj
, "openpic", 0x40000);
1487 static void openpic_realize(DeviceState
*dev
, Error
**errp
)
1489 SysBusDevice
*d
= SYS_BUS_DEVICE(dev
);
1490 OpenPICState
*opp
= OPENPIC(dev
);
1493 static const MemReg list_le
[] = {
1494 {"glb", &openpic_glb_ops_le
,
1495 OPENPIC_GLB_REG_START
, OPENPIC_GLB_REG_SIZE
},
1496 {"tmr", &openpic_tmr_ops_le
,
1497 OPENPIC_TMR_REG_START
, OPENPIC_TMR_REG_SIZE
},
1498 {"src", &openpic_src_ops_le
,
1499 OPENPIC_SRC_REG_START
, OPENPIC_SRC_REG_SIZE
},
1500 {"cpu", &openpic_cpu_ops_le
,
1501 OPENPIC_CPU_REG_START
, OPENPIC_CPU_REG_SIZE
},
1504 static const MemReg list_be
[] = {
1505 {"glb", &openpic_glb_ops_be
,
1506 OPENPIC_GLB_REG_START
, OPENPIC_GLB_REG_SIZE
},
1507 {"tmr", &openpic_tmr_ops_be
,
1508 OPENPIC_TMR_REG_START
, OPENPIC_TMR_REG_SIZE
},
1509 {"src", &openpic_src_ops_be
,
1510 OPENPIC_SRC_REG_START
, OPENPIC_SRC_REG_SIZE
},
1511 {"cpu", &openpic_cpu_ops_be
,
1512 OPENPIC_CPU_REG_START
, OPENPIC_CPU_REG_SIZE
},
1515 static const MemReg list_fsl
[] = {
1516 {"msi", &openpic_msi_ops_be
,
1517 OPENPIC_MSI_REG_START
, OPENPIC_MSI_REG_SIZE
},
1518 {"summary", &openpic_summary_ops_be
,
1519 OPENPIC_SUMMARY_REG_START
, OPENPIC_SUMMARY_REG_SIZE
},
1523 if (opp
->nb_cpus
> MAX_CPU
) {
1524 error_setg(errp
, QERR_PROPERTY_VALUE_OUT_OF_RANGE
,
1525 TYPE_OPENPIC
, "nb_cpus", (uint64_t)opp
->nb_cpus
,
1526 (uint64_t)0, (uint64_t)MAX_CPU
);
1530 switch (opp
->model
) {
1531 case OPENPIC_MODEL_FSL_MPIC_20
:
1533 opp
->fsl
= &fsl_mpic_20
;
1534 opp
->brr1
= 0x00400200;
1535 opp
->flags
|= OPENPIC_FLAG_IDR_CRIT
;
1537 opp
->mpic_mode_mask
= GCR_MODE_MIXED
;
1539 fsl_common_init(opp
);
1540 map_list(opp
, list_be
, &list_count
);
1541 map_list(opp
, list_fsl
, &list_count
);
1545 case OPENPIC_MODEL_FSL_MPIC_42
:
1546 opp
->fsl
= &fsl_mpic_42
;
1547 opp
->brr1
= 0x00400402;
1548 opp
->flags
|= OPENPIC_FLAG_ILR
;
1550 opp
->mpic_mode_mask
= GCR_MODE_PROXY
;
1552 fsl_common_init(opp
);
1553 map_list(opp
, list_be
, &list_count
);
1554 map_list(opp
, list_fsl
, &list_count
);
1558 case OPENPIC_MODEL_RAVEN
:
1559 opp
->nb_irqs
= RAVEN_MAX_EXT
;
1560 opp
->vid
= VID_REVISION_1_3
;
1561 opp
->vir
= VIR_GENERIC
;
1562 opp
->vector_mask
= 0xFF;
1563 opp
->tfrr_reset
= 4160000;
1564 opp
->ivpr_reset
= IVPR_MASK_MASK
| IVPR_MODE_MASK
;
1566 opp
->max_irq
= RAVEN_MAX_IRQ
;
1567 opp
->irq_ipi0
= RAVEN_IPI_IRQ
;
1568 opp
->irq_tim0
= RAVEN_TMR_IRQ
;
1570 opp
->mpic_mode_mask
= GCR_MODE_MIXED
;
1572 if (opp
->nb_cpus
!= 1) {
1573 error_setg(errp
, "Only UP supported today");
1577 map_list(opp
, list_le
, &list_count
);
1580 case OPENPIC_MODEL_KEYLARGO
:
1581 opp
->nb_irqs
= KEYLARGO_MAX_EXT
;
1582 opp
->vid
= VID_REVISION_1_2
;
1583 opp
->vir
= VIR_GENERIC
;
1584 opp
->vector_mask
= 0xFF;
1585 opp
->tfrr_reset
= 4160000;
1586 opp
->ivpr_reset
= IVPR_MASK_MASK
| IVPR_MODE_MASK
;
1588 opp
->max_irq
= KEYLARGO_MAX_IRQ
;
1589 opp
->irq_ipi0
= KEYLARGO_IPI_IRQ
;
1590 opp
->irq_tim0
= KEYLARGO_TMR_IRQ
;
1592 opp
->mpic_mode_mask
= GCR_MODE_MIXED
;
1594 if (opp
->nb_cpus
!= 1) {
1595 error_setg(errp
, "Only UP supported today");
1599 map_list(opp
, list_le
, &list_count
);
1603 for (i
= 0; i
< opp
->nb_cpus
; i
++) {
1604 opp
->dst
[i
].irqs
= g_new0(qemu_irq
, OPENPIC_OUTPUT_NB
);
1605 for (j
= 0; j
< OPENPIC_OUTPUT_NB
; j
++) {
1606 sysbus_init_irq(d
, &opp
->dst
[i
].irqs
[j
]);
1609 opp
->dst
[i
].raised
.queue_size
= IRQQUEUE_SIZE_BITS
;
1610 opp
->dst
[i
].raised
.queue
= bitmap_new(IRQQUEUE_SIZE_BITS
);
1611 opp
->dst
[i
].servicing
.queue_size
= IRQQUEUE_SIZE_BITS
;
1612 opp
->dst
[i
].servicing
.queue
= bitmap_new(IRQQUEUE_SIZE_BITS
);
1615 sysbus_init_mmio(d
, &opp
->mem
);
1616 qdev_init_gpio_in(dev
, openpic_set_irq
, opp
->max_irq
);
1619 static Property openpic_properties
[] = {
1620 DEFINE_PROP_UINT32("model", OpenPICState
, model
, OPENPIC_MODEL_FSL_MPIC_20
),
1621 DEFINE_PROP_UINT32("nb_cpus", OpenPICState
, nb_cpus
, 1),
1622 DEFINE_PROP_END_OF_LIST(),
1625 static void openpic_class_init(ObjectClass
*oc
, void *data
)
1627 DeviceClass
*dc
= DEVICE_CLASS(oc
);
1629 dc
->realize
= openpic_realize
;
1630 device_class_set_props(dc
, openpic_properties
);
1631 dc
->reset
= openpic_reset
;
1632 dc
->vmsd
= &vmstate_openpic
;
1633 set_bit(DEVICE_CATEGORY_MISC
, dc
->categories
);
1636 static const TypeInfo openpic_info
= {
1637 .name
= TYPE_OPENPIC
,
1638 .parent
= TYPE_SYS_BUS_DEVICE
,
1639 .instance_size
= sizeof(OpenPICState
),
1640 .instance_init
= openpic_init
,
1641 .class_init
= openpic_class_init
,
1644 static void openpic_register_types(void)
1646 type_register_static(&openpic_info
);
1649 type_init(openpic_register_types
)