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.
43 //#define DEBUG_OPENPIC
46 static const int debug_openpic
= 1;
48 static const int debug_openpic
= 0;
51 #define DPRINTF(fmt, ...) do { \
52 if (debug_openpic) { \
53 printf(fmt , ## __VA_ARGS__); \
62 #define MAX_IRQ (MAX_SRC + MAX_IPI + MAX_TMR)
63 #define VID 0x03 /* MPIC version ID */
65 /* OpenPIC capability flags */
66 #define OPENPIC_FLAG_IDR_CRIT (1 << 0)
68 /* OpenPIC address map */
69 #define OPENPIC_GLB_REG_START 0x0
70 #define OPENPIC_GLB_REG_SIZE 0x10F0
71 #define OPENPIC_TMR_REG_START 0x10F0
72 #define OPENPIC_TMR_REG_SIZE 0x220
73 #define OPENPIC_MSI_REG_START 0x1600
74 #define OPENPIC_MSI_REG_SIZE 0x200
75 #define OPENPIC_SRC_REG_START 0x10000
76 #define OPENPIC_SRC_REG_SIZE (MAX_SRC * 0x20)
77 #define OPENPIC_CPU_REG_START 0x20000
78 #define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000)
81 #define RAVEN_MAX_CPU 2
82 #define RAVEN_MAX_EXT 48
83 #define RAVEN_MAX_IRQ 64
84 #define RAVEN_MAX_TMR MAX_TMR
85 #define RAVEN_MAX_IPI MAX_IPI
87 /* Interrupt definitions */
88 #define RAVEN_FE_IRQ (RAVEN_MAX_EXT) /* Internal functional IRQ */
89 #define RAVEN_ERR_IRQ (RAVEN_MAX_EXT + 1) /* Error IRQ */
90 #define RAVEN_TMR_IRQ (RAVEN_MAX_EXT + 2) /* First timer IRQ */
91 #define RAVEN_IPI_IRQ (RAVEN_TMR_IRQ + RAVEN_MAX_TMR) /* First IPI IRQ */
92 /* First doorbell IRQ */
93 #define RAVEN_DBL_IRQ (RAVEN_IPI_IRQ + (RAVEN_MAX_CPU * RAVEN_MAX_IPI))
96 #define FSL_MPIC_20_MAX_CPU 1
97 #define FSL_MPIC_20_MAX_EXT 12
98 #define FSL_MPIC_20_MAX_INT 64
99 #define FSL_MPIC_20_MAX_IRQ MAX_IRQ
101 /* Interrupt definitions */
102 /* IRQs, accessible through the IRQ region */
103 #define FSL_MPIC_20_EXT_IRQ 0x00
104 #define FSL_MPIC_20_INT_IRQ 0x10
105 #define FSL_MPIC_20_MSG_IRQ 0xb0
106 #define FSL_MPIC_20_MSI_IRQ 0xe0
107 /* These are available through separate regions, but
108 for simplicity's sake mapped into the same number space */
109 #define FSL_MPIC_20_TMR_IRQ 0x100
110 #define FSL_MPIC_20_IPI_IRQ 0x104
113 * Block Revision Register1 (BRR1): QEMU does not fully emulate
114 * any version on MPIC. So to start with, set the IP version to 0.
116 * NOTE: This is Freescale MPIC specific register. Keep it here till
117 * this code is refactored for different variants of OPENPIC and MPIC.
119 #define FSL_BRR1_IPID (0x0040 << 16) /* 16 bit IP-block ID */
120 #define FSL_BRR1_IPMJ (0x00 << 8) /* 8 bit IP major number */
121 #define FSL_BRR1_IPMN 0x00 /* 8 bit IP minor number */
123 #define FRR_NIRQ_SHIFT 16
124 #define FRR_NCPU_SHIFT 8
125 #define FRR_VID_SHIFT 0
127 #define VID_REVISION_1_2 2
128 #define VID_REVISION_1_3 3
130 #define VIR_GENERIC 0x00000000 /* Generic Vendor ID */
132 #define GCR_RESET 0x80000000
134 #define TBCR_CI 0x80000000 /* count inhibit */
135 #define TCCR_TOG 0x80000000 /* toggles when decrement to zero */
137 #define IDR_EP_SHIFT 31
138 #define IDR_EP_MASK (1 << IDR_EP_SHIFT)
139 #define IDR_CI0_SHIFT 30
140 #define IDR_CI1_SHIFT 29
141 #define IDR_P1_SHIFT 1
142 #define IDR_P0_SHIFT 0
144 #define MSIIR_OFFSET 0x140
145 #define MSIIR_SRS_SHIFT 29
146 #define MSIIR_SRS_MASK (0x7 << MSIIR_SRS_SHIFT)
147 #define MSIIR_IBS_SHIFT 24
148 #define MSIIR_IBS_MASK (0x1f << MSIIR_IBS_SHIFT)
150 #define BF_WIDTH(_bits_) \
151 (((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8))
153 static inline void set_bit(uint32_t *field
, int bit
)
155 field
[bit
>> 5] |= 1 << (bit
& 0x1F);
158 static inline void reset_bit(uint32_t *field
, int bit
)
160 field
[bit
>> 5] &= ~(1 << (bit
& 0x1F));
163 static inline int test_bit(uint32_t *field
, int bit
)
165 return (field
[bit
>> 5] & 1 << (bit
& 0x1F)) != 0;
168 static int get_current_cpu(void)
170 if (!cpu_single_env
) {
174 return cpu_single_env
->cpu_index
;
177 static uint32_t openpic_cpu_read_internal(void *opaque
, hwaddr addr
,
179 static void openpic_cpu_write_internal(void *opaque
, hwaddr addr
,
180 uint32_t val
, int idx
);
182 typedef struct IRQQueue
{
183 uint32_t queue
[BF_WIDTH(MAX_IRQ
)];
188 typedef struct IRQSource
{
189 uint32_t ivpr
; /* IRQ vector/priority register */
190 uint32_t idr
; /* IRQ destination register */
191 uint32_t destmask
; /* bitmap of CPU destinations */
193 int output
; /* IRQ level, e.g. OPENPIC_OUTPUT_INT */
194 int pending
; /* TRUE if IRQ is pending */
195 bool nomask
:1; /* critical interrupts ignore mask on some FSL MPICs */
198 #define IVPR_MASK_SHIFT 31
199 #define IVPR_MASK_MASK (1 << IVPR_MASK_SHIFT)
200 #define IVPR_ACTIVITY_SHIFT 30
201 #define IVPR_ACTIVITY_MASK (1 << IVPR_ACTIVITY_SHIFT)
202 #define IVPR_MODE_SHIFT 29
203 #define IVPR_MODE_MASK (1 << IVPR_MODE_SHIFT)
204 #define IVPR_POLARITY_SHIFT 23
205 #define IVPR_POLARITY_MASK (1 << IVPR_POLARITY_SHIFT)
206 #define IVPR_SENSE_SHIFT 22
207 #define IVPR_SENSE_MASK (1 << IVPR_SENSE_SHIFT)
209 #define IVPR_PRIORITY_MASK (0xF << 16)
210 #define IVPR_PRIORITY(_ivprr_) ((int)(((_ivprr_) & IVPR_PRIORITY_MASK) >> 16))
211 #define IVPR_VECTOR(opp, _ivprr_) ((_ivprr_) & (opp)->vector_mask)
213 /* IDR[EP/CI] are only for FSL MPIC prior to v4.0 */
214 #define IDR_EP 0x80000000 /* external pin */
215 #define IDR_CI 0x40000000 /* critical interrupt */
217 typedef struct IRQDest
{
218 int32_t ctpr
; /* CPU current task priority */
224 typedef struct OpenPICState
{
228 /* Behavior control */
233 uint32_t vir
; /* Vendor identification register */
234 uint32_t vector_mask
;
241 MemoryRegion sub_io_mem
[5];
243 /* Global registers */
244 uint32_t frr
; /* Feature reporting register */
245 uint32_t gcr
; /* Global configuration register */
246 uint32_t pir
; /* Processor initialization register */
247 uint32_t spve
; /* Spurious vector register */
248 uint32_t tfrr
; /* Timer frequency reporting register */
249 /* Source registers */
250 IRQSource src
[MAX_IRQ
];
251 /* Local registers per output pin */
252 IRQDest dst
[MAX_CPU
];
254 /* Timer registers */
256 uint32_t tccr
; /* Global timer current count register */
257 uint32_t tbcr
; /* Global timer base count register */
259 /* Shared MSI registers */
261 uint32_t msir
; /* Shared Message Signaled Interrupt Register */
269 static inline void IRQ_setbit(IRQQueue
*q
, int n_IRQ
)
271 set_bit(q
->queue
, n_IRQ
);
274 static inline void IRQ_resetbit(IRQQueue
*q
, int n_IRQ
)
276 reset_bit(q
->queue
, n_IRQ
);
279 static inline int IRQ_testbit(IRQQueue
*q
, int n_IRQ
)
281 return test_bit(q
->queue
, n_IRQ
);
284 static void IRQ_check(OpenPICState
*opp
, IRQQueue
*q
)
291 for (i
= 0; i
< opp
->max_irq
; i
++) {
292 if (IRQ_testbit(q
, i
)) {
293 DPRINTF("IRQ_check: irq %d set ivpr_pr=%d pr=%d\n",
294 i
, IVPR_PRIORITY(opp
->src
[i
].ivpr
), priority
);
295 if (IVPR_PRIORITY(opp
->src
[i
].ivpr
) > priority
) {
297 priority
= IVPR_PRIORITY(opp
->src
[i
].ivpr
);
302 q
->priority
= priority
;
305 static int IRQ_get_next(OpenPICState
*opp
, IRQQueue
*q
)
313 static void IRQ_local_pipe(OpenPICState
*opp
, int n_CPU
, int n_IRQ
)
319 dst
= &opp
->dst
[n_CPU
];
320 src
= &opp
->src
[n_IRQ
];
322 if (src
->output
!= OPENPIC_OUTPUT_INT
) {
323 /* On Freescale MPIC, critical interrupts ignore priority,
324 * IACK, EOI, etc. Before MPIC v4.1 they also ignore
327 src
->ivpr
|= IVPR_ACTIVITY_MASK
;
328 DPRINTF("%s: Raise OpenPIC output %d cpu %d irq %d\n",
329 __func__
, src
->output
, n_CPU
, n_IRQ
);
330 qemu_irq_raise(opp
->dst
[n_CPU
].irqs
[src
->output
]);
334 priority
= IVPR_PRIORITY(src
->ivpr
);
335 if (priority
<= dst
->ctpr
) {
336 /* Too low priority */
337 DPRINTF("%s: IRQ %d has too low priority on CPU %d\n",
338 __func__
, n_IRQ
, n_CPU
);
341 if (IRQ_testbit(&dst
->raised
, n_IRQ
)) {
343 DPRINTF("%s: IRQ %d was missed on CPU %d\n",
344 __func__
, n_IRQ
, n_CPU
);
347 src
->ivpr
|= IVPR_ACTIVITY_MASK
;
348 IRQ_setbit(&dst
->raised
, n_IRQ
);
349 if (priority
< dst
->raised
.priority
) {
350 /* An higher priority IRQ is already raised */
351 DPRINTF("%s: IRQ %d is hidden by raised IRQ %d on CPU %d\n",
352 __func__
, n_IRQ
, dst
->raised
.next
, n_CPU
);
355 IRQ_check(opp
, &dst
->raised
);
356 if (IRQ_get_next(opp
, &dst
->servicing
) != -1 &&
357 priority
<= dst
->servicing
.priority
) {
358 DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n",
359 __func__
, n_IRQ
, dst
->servicing
.next
, n_CPU
);
360 /* Already servicing a higher priority IRQ */
363 DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", n_CPU
, n_IRQ
);
364 qemu_irq_raise(opp
->dst
[n_CPU
].irqs
[OPENPIC_OUTPUT_INT
]);
367 /* update pic state because registers for n_IRQ have changed value */
368 static void openpic_update_irq(OpenPICState
*opp
, int n_IRQ
)
373 src
= &opp
->src
[n_IRQ
];
377 DPRINTF("%s: IRQ %d is not pending\n", __func__
, n_IRQ
);
380 if ((src
->ivpr
& IVPR_MASK_MASK
) && !src
->nomask
) {
381 /* Interrupt source is disabled */
382 DPRINTF("%s: IRQ %d is disabled\n", __func__
, n_IRQ
);
385 if (IVPR_PRIORITY(src
->ivpr
) == 0) {
386 /* Priority set to zero */
387 DPRINTF("%s: IRQ %d has 0 priority\n", __func__
, n_IRQ
);
390 if (src
->ivpr
& IVPR_ACTIVITY_MASK
) {
391 /* IRQ already active */
392 DPRINTF("%s: IRQ %d is already active\n", __func__
, n_IRQ
);
397 DPRINTF("%s: IRQ %d has no target\n", __func__
, n_IRQ
);
401 if (src
->idr
== (1 << src
->last_cpu
)) {
402 /* Only one CPU is allowed to receive this IRQ */
403 IRQ_local_pipe(opp
, src
->last_cpu
, n_IRQ
);
404 } else if (!(src
->ivpr
& IVPR_MODE_MASK
)) {
405 /* Directed delivery mode */
406 for (i
= 0; i
< opp
->nb_cpus
; i
++) {
407 if (src
->destmask
& (1 << i
)) {
408 IRQ_local_pipe(opp
, i
, n_IRQ
);
412 /* Distributed delivery mode */
413 for (i
= src
->last_cpu
+ 1; i
!= src
->last_cpu
; i
++) {
414 if (i
== opp
->nb_cpus
) {
417 if (src
->destmask
& (1 << i
)) {
418 IRQ_local_pipe(opp
, i
, n_IRQ
);
426 static void openpic_set_irq(void *opaque
, int n_IRQ
, int level
)
428 OpenPICState
*opp
= opaque
;
431 src
= &opp
->src
[n_IRQ
];
432 DPRINTF("openpic: set irq %d = %d ivpr=0x%08x\n",
433 n_IRQ
, level
, src
->ivpr
);
434 if (src
->ivpr
& IVPR_SENSE_MASK
) {
435 /* level-sensitive irq */
436 src
->pending
= level
;
438 src
->ivpr
&= ~IVPR_ACTIVITY_MASK
;
441 /* edge-sensitive irq */
446 openpic_update_irq(opp
, n_IRQ
);
449 static void openpic_reset(DeviceState
*d
)
451 OpenPICState
*opp
= FROM_SYSBUS(typeof (*opp
), sysbus_from_qdev(d
));
454 opp
->gcr
= GCR_RESET
;
455 /* Initialise controller registers */
456 opp
->frr
= ((opp
->nb_irqs
- 1) << FRR_NIRQ_SHIFT
) |
457 ((opp
->nb_cpus
- 1) << FRR_NCPU_SHIFT
) |
458 (opp
->vid
<< FRR_VID_SHIFT
);
461 opp
->spve
= -1 & opp
->vector_mask
;
462 opp
->tfrr
= opp
->tfrr_reset
;
463 /* Initialise IRQ sources */
464 for (i
= 0; i
< opp
->max_irq
; i
++) {
465 opp
->src
[i
].ivpr
= opp
->ivpr_reset
;
466 opp
->src
[i
].idr
= opp
->idr_reset
;
468 /* Initialise IRQ destinations */
469 for (i
= 0; i
< MAX_CPU
; i
++) {
470 opp
->dst
[i
].ctpr
= 15;
471 memset(&opp
->dst
[i
].raised
, 0, sizeof(IRQQueue
));
472 opp
->dst
[i
].raised
.next
= -1;
473 memset(&opp
->dst
[i
].servicing
, 0, sizeof(IRQQueue
));
474 opp
->dst
[i
].servicing
.next
= -1;
476 /* Initialise timers */
477 for (i
= 0; i
< MAX_TMR
; i
++) {
478 opp
->timers
[i
].tccr
= 0;
479 opp
->timers
[i
].tbcr
= TBCR_CI
;
481 /* Go out of RESET state */
485 static inline uint32_t read_IRQreg_idr(OpenPICState
*opp
, int n_IRQ
)
487 return opp
->src
[n_IRQ
].idr
;
490 static inline uint32_t read_IRQreg_ivpr(OpenPICState
*opp
, int n_IRQ
)
492 return opp
->src
[n_IRQ
].ivpr
;
495 static inline void write_IRQreg_idr(OpenPICState
*opp
, int n_IRQ
, uint32_t val
)
497 IRQSource
*src
= &opp
->src
[n_IRQ
];
498 uint32_t normal_mask
= (1UL << opp
->nb_cpus
) - 1;
499 uint32_t crit_mask
= 0;
500 uint32_t mask
= normal_mask
;
501 int crit_shift
= IDR_EP_SHIFT
- opp
->nb_cpus
;
504 if (opp
->flags
& OPENPIC_FLAG_IDR_CRIT
) {
505 crit_mask
= mask
<< crit_shift
;
506 mask
|= crit_mask
| IDR_EP
;
509 src
->idr
= val
& mask
;
510 DPRINTF("Set IDR %d to 0x%08x\n", n_IRQ
, src
->idr
);
512 if (opp
->flags
& OPENPIC_FLAG_IDR_CRIT
) {
513 if (src
->idr
& crit_mask
) {
514 if (src
->idr
& normal_mask
) {
515 DPRINTF("%s: IRQ configured for multiple output types, using "
516 "critical\n", __func__
);
519 src
->output
= OPENPIC_OUTPUT_CINT
;
523 for (i
= 0; i
< opp
->nb_cpus
; i
++) {
524 int n_ci
= IDR_CI0_SHIFT
- i
;
526 if (src
->idr
& (1UL << n_ci
)) {
527 src
->destmask
|= 1UL << i
;
531 src
->output
= OPENPIC_OUTPUT_INT
;
533 src
->destmask
= src
->idr
& normal_mask
;
536 src
->destmask
= src
->idr
;
540 static inline void write_IRQreg_ivpr(OpenPICState
*opp
, int n_IRQ
, uint32_t val
)
542 /* NOTE: not fully accurate for special IRQs, but simple and sufficient */
543 /* ACTIVITY bit is read-only */
544 opp
->src
[n_IRQ
].ivpr
= (opp
->src
[n_IRQ
].ivpr
& IVPR_ACTIVITY_MASK
) |
545 (val
& (IVPR_MASK_MASK
| IVPR_PRIORITY_MASK
| opp
->vector_mask
));
546 openpic_update_irq(opp
, n_IRQ
);
547 DPRINTF("Set IVPR %d to 0x%08x -> 0x%08x\n", n_IRQ
, val
,
548 opp
->src
[n_IRQ
].ivpr
);
551 static void openpic_gbl_write(void *opaque
, hwaddr addr
, uint64_t val
,
554 OpenPICState
*opp
= opaque
;
558 DPRINTF("%s: addr %#" HWADDR_PRIx
" <= %08" PRIx64
"\n",
559 __func__
, addr
, val
);
564 case 0x00: /* Block Revision Register1 (BRR1) is Readonly */
574 openpic_cpu_write_internal(opp
, addr
, val
, get_current_cpu());
576 case 0x1000: /* FRR */
578 case 0x1020: /* GCR */
579 if (val
& GCR_RESET
) {
580 openpic_reset(&opp
->busdev
.qdev
);
583 case 0x1080: /* VIR */
585 case 0x1090: /* PIR */
586 for (idx
= 0; idx
< opp
->nb_cpus
; idx
++) {
587 if ((val
& (1 << idx
)) && !(opp
->pir
& (1 << idx
))) {
588 DPRINTF("Raise OpenPIC RESET output for CPU %d\n", idx
);
589 dst
= &opp
->dst
[idx
];
590 qemu_irq_raise(dst
->irqs
[OPENPIC_OUTPUT_RESET
]);
591 } else if (!(val
& (1 << idx
)) && (opp
->pir
& (1 << idx
))) {
592 DPRINTF("Lower OpenPIC RESET output for CPU %d\n", idx
);
593 dst
= &opp
->dst
[idx
];
594 qemu_irq_lower(dst
->irqs
[OPENPIC_OUTPUT_RESET
]);
599 case 0x10A0: /* IPI_IVPR */
605 idx
= (addr
- 0x10A0) >> 4;
606 write_IRQreg_ivpr(opp
, opp
->irq_ipi0
+ idx
, val
);
609 case 0x10E0: /* SPVE */
610 opp
->spve
= val
& opp
->vector_mask
;
617 static uint64_t openpic_gbl_read(void *opaque
, hwaddr addr
, unsigned len
)
619 OpenPICState
*opp
= opaque
;
622 DPRINTF("%s: addr %#" HWADDR_PRIx
"\n", __func__
, addr
);
628 case 0x1000: /* FRR */
631 case 0x1020: /* GCR */
634 case 0x1080: /* VIR */
637 case 0x1090: /* PIR */
640 case 0x00: /* Block Revision Register1 (BRR1) */
651 retval
= openpic_cpu_read_internal(opp
, addr
, get_current_cpu());
653 case 0x10A0: /* IPI_IVPR */
659 idx
= (addr
- 0x10A0) >> 4;
660 retval
= read_IRQreg_ivpr(opp
, opp
->irq_ipi0
+ idx
);
663 case 0x10E0: /* SPVE */
669 DPRINTF("%s: => 0x%08x\n", __func__
, retval
);
674 static void openpic_tmr_write(void *opaque
, hwaddr addr
, uint64_t val
,
677 OpenPICState
*opp
= opaque
;
680 DPRINTF("%s: addr %#" HWADDR_PRIx
" <= %08" PRIx64
"\n",
681 __func__
, addr
, val
);
685 idx
= (addr
>> 6) & 0x3;
693 switch (addr
& 0x30) {
694 case 0x00: /* TCCR */
696 case 0x10: /* TBCR */
697 if ((opp
->timers
[idx
].tccr
& TCCR_TOG
) != 0 &&
698 (val
& TBCR_CI
) == 0 &&
699 (opp
->timers
[idx
].tbcr
& TBCR_CI
) != 0) {
700 opp
->timers
[idx
].tccr
&= ~TCCR_TOG
;
702 opp
->timers
[idx
].tbcr
= val
;
704 case 0x20: /* TVPR */
705 write_IRQreg_ivpr(opp
, opp
->irq_tim0
+ idx
, val
);
708 write_IRQreg_idr(opp
, opp
->irq_tim0
+ idx
, val
);
713 static uint64_t openpic_tmr_read(void *opaque
, hwaddr addr
, unsigned len
)
715 OpenPICState
*opp
= opaque
;
716 uint32_t retval
= -1;
719 DPRINTF("%s: addr %#" HWADDR_PRIx
"\n", __func__
, addr
);
723 idx
= (addr
>> 6) & 0x3;
729 switch (addr
& 0x30) {
730 case 0x00: /* TCCR */
731 retval
= opp
->timers
[idx
].tccr
;
733 case 0x10: /* TBCR */
734 retval
= opp
->timers
[idx
].tbcr
;
736 case 0x20: /* TIPV */
737 retval
= read_IRQreg_ivpr(opp
, opp
->irq_tim0
+ idx
);
739 case 0x30: /* TIDE (TIDR) */
740 retval
= read_IRQreg_idr(opp
, opp
->irq_tim0
+ idx
);
745 DPRINTF("%s: => 0x%08x\n", __func__
, retval
);
750 static void openpic_src_write(void *opaque
, hwaddr addr
, uint64_t val
,
753 OpenPICState
*opp
= opaque
;
756 DPRINTF("%s: addr %#" HWADDR_PRIx
" <= %08" PRIx64
"\n",
757 __func__
, addr
, val
);
761 addr
= addr
& 0xFFF0;
764 /* EXDE / IFEDE / IEEDE */
765 write_IRQreg_idr(opp
, idx
, val
);
767 /* EXVP / IFEVP / IEEVP */
768 write_IRQreg_ivpr(opp
, idx
, val
);
772 static uint64_t openpic_src_read(void *opaque
, uint64_t addr
, unsigned len
)
774 OpenPICState
*opp
= opaque
;
778 DPRINTF("%s: addr %#" HWADDR_PRIx
"\n", __func__
, addr
);
783 addr
= addr
& 0xFFF0;
786 /* EXDE / IFEDE / IEEDE */
787 retval
= read_IRQreg_idr(opp
, idx
);
789 /* EXVP / IFEVP / IEEVP */
790 retval
= read_IRQreg_ivpr(opp
, idx
);
792 DPRINTF("%s: => 0x%08x\n", __func__
, retval
);
797 static void openpic_msi_write(void *opaque
, hwaddr addr
, uint64_t val
,
800 OpenPICState
*opp
= opaque
;
801 int idx
= opp
->irq_msi
;
804 DPRINTF("%s: addr %#" HWADDR_PRIx
" <= 0x%08" PRIx64
"\n",
805 __func__
, addr
, val
);
812 srs
= val
>> MSIIR_SRS_SHIFT
;
814 ibs
= (val
& MSIIR_IBS_MASK
) >> MSIIR_IBS_SHIFT
;
815 opp
->msi
[srs
].msir
|= 1 << ibs
;
816 openpic_set_irq(opp
, idx
, 1);
819 /* most registers are read-only, thus ignored */
824 static uint64_t openpic_msi_read(void *opaque
, hwaddr addr
, unsigned size
)
826 OpenPICState
*opp
= opaque
;
830 DPRINTF("%s: addr %#" HWADDR_PRIx
"\n", __func__
, addr
);
845 case 0x70: /* MSIRs */
846 r
= opp
->msi
[srs
].msir
;
848 opp
->msi
[srs
].msir
= 0;
849 openpic_set_irq(opp
, opp
->irq_msi
+ srs
, 0);
851 case 0x120: /* MSISR */
852 for (i
= 0; i
< MAX_MSI
; i
++) {
853 r
|= (opp
->msi
[i
].msir
? 1 : 0) << i
;
861 static void openpic_cpu_write_internal(void *opaque
, hwaddr addr
,
862 uint32_t val
, int idx
)
864 OpenPICState
*opp
= opaque
;
869 DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx
" <= 0x%08x\n", __func__
, idx
,
879 dst
= &opp
->dst
[idx
];
882 case 0x40: /* IPIDR */
886 idx
= (addr
- 0x40) >> 4;
887 /* we use IDE as mask which CPUs to deliver the IPI to still. */
888 write_IRQreg_idr(opp
, opp
->irq_ipi0
+ idx
,
889 opp
->src
[opp
->irq_ipi0
+ idx
].idr
| val
);
890 openpic_set_irq(opp
, opp
->irq_ipi0
+ idx
, 1);
891 openpic_set_irq(opp
, opp
->irq_ipi0
+ idx
, 0);
893 case 0x80: /* CTPR */
894 dst
->ctpr
= val
& 0x0000000F;
896 case 0x90: /* WHOAMI */
897 /* Read-only register */
899 case 0xA0: /* IACK */
900 /* Read-only register */
904 s_IRQ
= IRQ_get_next(opp
, &dst
->servicing
);
905 IRQ_resetbit(&dst
->servicing
, s_IRQ
);
906 /* Set up next servicing IRQ */
907 s_IRQ
= IRQ_get_next(opp
, &dst
->servicing
);
908 /* Check queued interrupts. */
909 n_IRQ
= IRQ_get_next(opp
, &dst
->raised
);
910 src
= &opp
->src
[n_IRQ
];
913 IVPR_PRIORITY(src
->ivpr
) > dst
->servicing
.priority
)) {
914 DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n",
916 qemu_irq_raise(opp
->dst
[idx
].irqs
[OPENPIC_OUTPUT_INT
]);
924 static void openpic_cpu_write(void *opaque
, hwaddr addr
, uint64_t val
,
927 openpic_cpu_write_internal(opaque
, addr
, val
, (addr
& 0x1f000) >> 12);
930 static uint32_t openpic_cpu_read_internal(void *opaque
, hwaddr addr
,
933 OpenPICState
*opp
= opaque
;
939 DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx
"\n", __func__
, idx
, addr
);
949 dst
= &opp
->dst
[idx
];
952 case 0x80: /* CTPR */
955 case 0x90: /* WHOAMI */
958 case 0xA0: /* IACK */
959 DPRINTF("Lower OpenPIC INT output\n");
960 qemu_irq_lower(dst
->irqs
[OPENPIC_OUTPUT_INT
]);
961 n_IRQ
= IRQ_get_next(opp
, &dst
->raised
);
962 DPRINTF("IACK: irq=%d\n", n_IRQ
);
964 /* No more interrupt pending */
967 src
= &opp
->src
[n_IRQ
];
968 if (!(src
->ivpr
& IVPR_ACTIVITY_MASK
) ||
969 !(IVPR_PRIORITY(src
->ivpr
) > dst
->ctpr
)) {
970 /* - Spurious level-sensitive IRQ
971 * - Priorities has been changed
972 * and the pending IRQ isn't allowed anymore
974 src
->ivpr
&= ~IVPR_ACTIVITY_MASK
;
977 /* IRQ enter servicing state */
978 IRQ_setbit(&dst
->servicing
, n_IRQ
);
979 retval
= IVPR_VECTOR(opp
, src
->ivpr
);
981 IRQ_resetbit(&dst
->raised
, n_IRQ
);
982 if (!(src
->ivpr
& IVPR_SENSE_MASK
)) {
983 /* edge-sensitive IRQ */
984 src
->ivpr
&= ~IVPR_ACTIVITY_MASK
;
988 if ((n_IRQ
>= opp
->irq_ipi0
) && (n_IRQ
< (opp
->irq_ipi0
+ MAX_IPI
))) {
989 src
->idr
&= ~(1 << idx
);
990 if (src
->idr
&& !(src
->ivpr
& IVPR_SENSE_MASK
)) {
991 /* trigger on CPUs that didn't know about it yet */
992 openpic_set_irq(opp
, n_IRQ
, 1);
993 openpic_set_irq(opp
, n_IRQ
, 0);
994 /* if all CPUs knew about it, set active bit again */
995 src
->ivpr
|= IVPR_ACTIVITY_MASK
;
1000 case 0xB0: /* EOI */
1006 DPRINTF("%s: => 0x%08x\n", __func__
, retval
);
1011 static uint64_t openpic_cpu_read(void *opaque
, hwaddr addr
, unsigned len
)
1013 return openpic_cpu_read_internal(opaque
, addr
, (addr
& 0x1f000) >> 12);
1016 static const MemoryRegionOps openpic_glb_ops_le
= {
1017 .write
= openpic_gbl_write
,
1018 .read
= openpic_gbl_read
,
1019 .endianness
= DEVICE_LITTLE_ENDIAN
,
1021 .min_access_size
= 4,
1022 .max_access_size
= 4,
1026 static const MemoryRegionOps openpic_glb_ops_be
= {
1027 .write
= openpic_gbl_write
,
1028 .read
= openpic_gbl_read
,
1029 .endianness
= DEVICE_BIG_ENDIAN
,
1031 .min_access_size
= 4,
1032 .max_access_size
= 4,
1036 static const MemoryRegionOps openpic_tmr_ops_le
= {
1037 .write
= openpic_tmr_write
,
1038 .read
= openpic_tmr_read
,
1039 .endianness
= DEVICE_LITTLE_ENDIAN
,
1041 .min_access_size
= 4,
1042 .max_access_size
= 4,
1046 static const MemoryRegionOps openpic_tmr_ops_be
= {
1047 .write
= openpic_tmr_write
,
1048 .read
= openpic_tmr_read
,
1049 .endianness
= DEVICE_BIG_ENDIAN
,
1051 .min_access_size
= 4,
1052 .max_access_size
= 4,
1056 static const MemoryRegionOps openpic_cpu_ops_le
= {
1057 .write
= openpic_cpu_write
,
1058 .read
= openpic_cpu_read
,
1059 .endianness
= DEVICE_LITTLE_ENDIAN
,
1061 .min_access_size
= 4,
1062 .max_access_size
= 4,
1066 static const MemoryRegionOps openpic_cpu_ops_be
= {
1067 .write
= openpic_cpu_write
,
1068 .read
= openpic_cpu_read
,
1069 .endianness
= DEVICE_BIG_ENDIAN
,
1071 .min_access_size
= 4,
1072 .max_access_size
= 4,
1076 static const MemoryRegionOps openpic_src_ops_le
= {
1077 .write
= openpic_src_write
,
1078 .read
= openpic_src_read
,
1079 .endianness
= DEVICE_LITTLE_ENDIAN
,
1081 .min_access_size
= 4,
1082 .max_access_size
= 4,
1086 static const MemoryRegionOps openpic_src_ops_be
= {
1087 .write
= openpic_src_write
,
1088 .read
= openpic_src_read
,
1089 .endianness
= DEVICE_BIG_ENDIAN
,
1091 .min_access_size
= 4,
1092 .max_access_size
= 4,
1096 static const MemoryRegionOps openpic_msi_ops_le
= {
1097 .read
= openpic_msi_read
,
1098 .write
= openpic_msi_write
,
1099 .endianness
= DEVICE_LITTLE_ENDIAN
,
1101 .min_access_size
= 4,
1102 .max_access_size
= 4,
1106 static const MemoryRegionOps openpic_msi_ops_be
= {
1107 .read
= openpic_msi_read
,
1108 .write
= openpic_msi_write
,
1109 .endianness
= DEVICE_BIG_ENDIAN
,
1111 .min_access_size
= 4,
1112 .max_access_size
= 4,
1116 static void openpic_save_IRQ_queue(QEMUFile
* f
, IRQQueue
*q
)
1120 for (i
= 0; i
< BF_WIDTH(MAX_IRQ
); i
++)
1121 qemu_put_be32s(f
, &q
->queue
[i
]);
1123 qemu_put_sbe32s(f
, &q
->next
);
1124 qemu_put_sbe32s(f
, &q
->priority
);
1127 static void openpic_save(QEMUFile
* f
, void *opaque
)
1129 OpenPICState
*opp
= (OpenPICState
*)opaque
;
1132 qemu_put_be32s(f
, &opp
->gcr
);
1133 qemu_put_be32s(f
, &opp
->vir
);
1134 qemu_put_be32s(f
, &opp
->pir
);
1135 qemu_put_be32s(f
, &opp
->spve
);
1136 qemu_put_be32s(f
, &opp
->tfrr
);
1138 qemu_put_be32s(f
, &opp
->nb_cpus
);
1140 for (i
= 0; i
< opp
->nb_cpus
; i
++) {
1141 qemu_put_sbe32s(f
, &opp
->dst
[i
].ctpr
);
1142 openpic_save_IRQ_queue(f
, &opp
->dst
[i
].raised
);
1143 openpic_save_IRQ_queue(f
, &opp
->dst
[i
].servicing
);
1146 for (i
= 0; i
< MAX_TMR
; i
++) {
1147 qemu_put_be32s(f
, &opp
->timers
[i
].tccr
);
1148 qemu_put_be32s(f
, &opp
->timers
[i
].tbcr
);
1151 for (i
= 0; i
< opp
->max_irq
; i
++) {
1152 qemu_put_be32s(f
, &opp
->src
[i
].ivpr
);
1153 qemu_put_be32s(f
, &opp
->src
[i
].idr
);
1154 qemu_put_sbe32s(f
, &opp
->src
[i
].last_cpu
);
1155 qemu_put_sbe32s(f
, &opp
->src
[i
].pending
);
1159 static void openpic_load_IRQ_queue(QEMUFile
* f
, IRQQueue
*q
)
1163 for (i
= 0; i
< BF_WIDTH(MAX_IRQ
); i
++)
1164 qemu_get_be32s(f
, &q
->queue
[i
]);
1166 qemu_get_sbe32s(f
, &q
->next
);
1167 qemu_get_sbe32s(f
, &q
->priority
);
1170 static int openpic_load(QEMUFile
* f
, void *opaque
, int version_id
)
1172 OpenPICState
*opp
= (OpenPICState
*)opaque
;
1175 if (version_id
!= 1) {
1179 qemu_get_be32s(f
, &opp
->gcr
);
1180 qemu_get_be32s(f
, &opp
->vir
);
1181 qemu_get_be32s(f
, &opp
->pir
);
1182 qemu_get_be32s(f
, &opp
->spve
);
1183 qemu_get_be32s(f
, &opp
->tfrr
);
1185 qemu_get_be32s(f
, &opp
->nb_cpus
);
1187 for (i
= 0; i
< opp
->nb_cpus
; i
++) {
1188 qemu_get_sbe32s(f
, &opp
->dst
[i
].ctpr
);
1189 openpic_load_IRQ_queue(f
, &opp
->dst
[i
].raised
);
1190 openpic_load_IRQ_queue(f
, &opp
->dst
[i
].servicing
);
1193 for (i
= 0; i
< MAX_TMR
; i
++) {
1194 qemu_get_be32s(f
, &opp
->timers
[i
].tccr
);
1195 qemu_get_be32s(f
, &opp
->timers
[i
].tbcr
);
1198 for (i
= 0; i
< opp
->max_irq
; i
++) {
1201 val
= qemu_get_be32(f
);
1202 write_IRQreg_idr(opp
, i
, val
);
1203 val
= qemu_get_be32(f
);
1204 write_IRQreg_ivpr(opp
, i
, val
);
1206 qemu_get_be32s(f
, &opp
->src
[i
].ivpr
);
1207 qemu_get_be32s(f
, &opp
->src
[i
].idr
);
1208 qemu_get_sbe32s(f
, &opp
->src
[i
].last_cpu
);
1209 qemu_get_sbe32s(f
, &opp
->src
[i
].pending
);
1215 typedef struct MemReg
{
1217 MemoryRegionOps
const *ops
;
1223 static int openpic_init(SysBusDevice
*dev
)
1225 OpenPICState
*opp
= FROM_SYSBUS(typeof (*opp
), dev
);
1227 MemReg list_le
[] = {
1228 {"glb", &openpic_glb_ops_le
, true,
1229 OPENPIC_GLB_REG_START
, OPENPIC_GLB_REG_SIZE
},
1230 {"tmr", &openpic_tmr_ops_le
, true,
1231 OPENPIC_TMR_REG_START
, OPENPIC_TMR_REG_SIZE
},
1232 {"msi", &openpic_msi_ops_le
, true,
1233 OPENPIC_MSI_REG_START
, OPENPIC_MSI_REG_SIZE
},
1234 {"src", &openpic_src_ops_le
, true,
1235 OPENPIC_SRC_REG_START
, OPENPIC_SRC_REG_SIZE
},
1236 {"cpu", &openpic_cpu_ops_le
, true,
1237 OPENPIC_CPU_REG_START
, OPENPIC_CPU_REG_SIZE
},
1239 MemReg list_be
[] = {
1240 {"glb", &openpic_glb_ops_be
, true,
1241 OPENPIC_GLB_REG_START
, OPENPIC_GLB_REG_SIZE
},
1242 {"tmr", &openpic_tmr_ops_be
, true,
1243 OPENPIC_TMR_REG_START
, OPENPIC_TMR_REG_SIZE
},
1244 {"msi", &openpic_msi_ops_be
, true,
1245 OPENPIC_MSI_REG_START
, OPENPIC_MSI_REG_SIZE
},
1246 {"src", &openpic_src_ops_be
, true,
1247 OPENPIC_SRC_REG_START
, OPENPIC_SRC_REG_SIZE
},
1248 {"cpu", &openpic_cpu_ops_be
, true,
1249 OPENPIC_CPU_REG_START
, OPENPIC_CPU_REG_SIZE
},
1253 switch (opp
->model
) {
1254 case OPENPIC_MODEL_FSL_MPIC_20
:
1256 opp
->flags
|= OPENPIC_FLAG_IDR_CRIT
;
1258 opp
->vid
= VID_REVISION_1_2
;
1259 opp
->vir
= VIR_GENERIC
;
1260 opp
->vector_mask
= 0xFFFF;
1261 opp
->tfrr_reset
= 0;
1262 opp
->ivpr_reset
= IVPR_MASK_MASK
;
1263 opp
->idr_reset
= 1 << 0;
1264 opp
->max_irq
= FSL_MPIC_20_MAX_IRQ
;
1265 opp
->irq_ipi0
= FSL_MPIC_20_IPI_IRQ
;
1266 opp
->irq_tim0
= FSL_MPIC_20_TMR_IRQ
;
1267 opp
->irq_msi
= FSL_MPIC_20_MSI_IRQ
;
1268 opp
->brr1
= FSL_BRR1_IPID
| FSL_BRR1_IPMJ
| FSL_BRR1_IPMN
;
1269 msi_supported
= true;
1272 case OPENPIC_MODEL_RAVEN
:
1273 opp
->nb_irqs
= RAVEN_MAX_EXT
;
1274 opp
->vid
= VID_REVISION_1_3
;
1275 opp
->vir
= VIR_GENERIC
;
1276 opp
->vector_mask
= 0xFF;
1277 opp
->tfrr_reset
= 4160000;
1278 opp
->ivpr_reset
= IVPR_MASK_MASK
| IVPR_MODE_MASK
;
1280 opp
->max_irq
= RAVEN_MAX_IRQ
;
1281 opp
->irq_ipi0
= RAVEN_IPI_IRQ
;
1282 opp
->irq_tim0
= RAVEN_TMR_IRQ
;
1285 /* Don't map MSI region */
1286 list
[2].map
= false;
1288 /* Only UP supported today */
1289 if (opp
->nb_cpus
!= 1) {
1295 memory_region_init(&opp
->mem
, "openpic", 0x40000);
1297 for (i
= 0; i
< ARRAY_SIZE(list_le
); i
++) {
1302 memory_region_init_io(&opp
->sub_io_mem
[i
], list
[i
].ops
, opp
,
1303 list
[i
].name
, list
[i
].size
);
1305 memory_region_add_subregion(&opp
->mem
, list
[i
].start_addr
,
1306 &opp
->sub_io_mem
[i
]);
1309 for (i
= 0; i
< opp
->nb_cpus
; i
++) {
1310 opp
->dst
[i
].irqs
= g_new(qemu_irq
, OPENPIC_OUTPUT_NB
);
1311 for (j
= 0; j
< OPENPIC_OUTPUT_NB
; j
++) {
1312 sysbus_init_irq(dev
, &opp
->dst
[i
].irqs
[j
]);
1316 register_savevm(&opp
->busdev
.qdev
, "openpic", 0, 2,
1317 openpic_save
, openpic_load
, opp
);
1319 sysbus_init_mmio(dev
, &opp
->mem
);
1320 qdev_init_gpio_in(&dev
->qdev
, openpic_set_irq
, opp
->max_irq
);
1325 static Property openpic_properties
[] = {
1326 DEFINE_PROP_UINT32("model", OpenPICState
, model
, OPENPIC_MODEL_FSL_MPIC_20
),
1327 DEFINE_PROP_UINT32("nb_cpus", OpenPICState
, nb_cpus
, 1),
1328 DEFINE_PROP_END_OF_LIST(),
1331 static void openpic_class_init(ObjectClass
*klass
, void *data
)
1333 DeviceClass
*dc
= DEVICE_CLASS(klass
);
1334 SysBusDeviceClass
*k
= SYS_BUS_DEVICE_CLASS(klass
);
1336 k
->init
= openpic_init
;
1337 dc
->props
= openpic_properties
;
1338 dc
->reset
= openpic_reset
;
1341 static TypeInfo openpic_info
= {
1343 .parent
= TYPE_SYS_BUS_DEVICE
,
1344 .instance_size
= sizeof(OpenPICState
),
1345 .class_init
= openpic_class_init
,
1348 static void openpic_register_types(void)
1350 type_register_static(&openpic_info
);
1353 type_init(openpic_register_types
)